001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.deploy;
016    
017    import com.liferay.portal.kernel.configuration.Filter;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.CharPool;
021    import com.liferay.portal.kernel.util.FileUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.PropsKeys;
024    import com.liferay.portal.kernel.util.ServerDetector;
025    import com.liferay.portal.kernel.util.StreamUtil;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.SystemProperties;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.spring.context.PortalContextLoaderListener;
031    import com.liferay.portal.util.PrefsPropsUtil;
032    import com.liferay.portal.util.PropsUtil;
033    import com.liferay.portal.util.PropsValues;
034    import com.liferay.util.ant.CopyTask;
035    import com.liferay.util.ant.DeleteTask;
036    
037    import java.io.File;
038    import java.io.FileOutputStream;
039    import java.io.IOException;
040    import java.io.InputStream;
041    
042    import java.util.HashMap;
043    import java.util.Map;
044    
045    import javax.portlet.PortletPreferences;
046    
047    import org.apache.commons.io.FileUtils;
048    
049    /**
050     * @author Brian Wing Shun Chan
051     */
052    public class DeployUtil {
053    
054            public static void copyDependencyXml(
055                            String fileName, String targetDir, String targetFileName,
056                            Map<String, String> filterMap, boolean overwrite)
057                    throws Exception {
058    
059                    File file = new File(getResourcePath(fileName));
060                    File targetFile = new File(targetDir, targetFileName);
061    
062                    if (!targetFile.exists()) {
063                            CopyTask.copyFile(
064                                    file, new File(targetDir), targetFileName, filterMap, overwrite,
065                                    true);
066                    }
067            }
068    
069            public static String getAutoDeployDestDir() throws Exception {
070                    String destDir = PrefsPropsUtil.getString(
071                            PropsKeys.AUTO_DEPLOY_DEST_DIR, PropsValues.AUTO_DEPLOY_DEST_DIR);
072    
073                    if (Validator.isNull(destDir)) {
074                            destDir = getAutoDeployServerDestDir();
075                    }
076    
077                    FileUtil.mkdirs(destDir);
078    
079                    return destDir;
080            }
081    
082            public static String getAutoDeployServerDestDir() throws Exception {
083                    String destDir = null;
084    
085                    String serverId = GetterUtil.getString(ServerDetector.getServerId());
086    
087                    if (serverId.equals(ServerDetector.JBOSS_ID) &&
088                            ServerDetector.isJBoss5()) {
089    
090                            String name = "auto.deploy." + serverId + ".dest.dir";
091    
092                            PortletPreferences portletPreferences =
093                                    PrefsPropsUtil.getPreferences(true);
094    
095                            String value = PropsUtil.get(name, new Filter("5"));
096    
097                            destDir = portletPreferences.getValue(name, value);
098                    }
099                    else if (serverId.equals(ServerDetector.TOMCAT_ID)) {
100                            destDir = PrefsPropsUtil.getString(
101                                    PropsKeys.AUTO_DEPLOY_TOMCAT_DEST_DIR,
102                                    PropsValues.AUTO_DEPLOY_TOMCAT_DEST_DIR);
103                    }
104                    else {
105                            destDir = PrefsPropsUtil.getString(
106                                    "auto.deploy." + serverId + ".dest.dir");
107                    }
108    
109                    if (Validator.isNull(destDir)) {
110                            destDir = PrefsPropsUtil.getString(
111                                    PropsKeys.AUTO_DEPLOY_DEFAULT_DEST_DIR,
112                                    PropsValues.AUTO_DEPLOY_DEFAULT_DEST_DIR);
113                    }
114    
115                    destDir = StringUtil.replace(
116                            destDir, CharPool.BACK_SLASH, CharPool.SLASH);
117    
118                    return destDir;
119            }
120    
121            public static String getResourcePath(String resource) throws Exception {
122                    return _instance._getResourcePath(resource);
123            }
124    
125            public static void redeployJetty(String context) throws Exception {
126                    String contextsDirName = System.getProperty("jetty.home") + "/contexts";
127    
128                    if (_isPortalContext(context)) {
129                            throw new UnsupportedOperationException(
130                                    "This method is meant for redeploying plugins, not the portal");
131                    }
132    
133                    File contextXml = new File(contextsDirName, context + ".xml");
134    
135                    if (contextXml.exists()) {
136                            FileUtils.touch(contextXml);
137                    }
138                    else {
139                            Map<String, String> filterMap = new HashMap<String, String>();
140    
141                            filterMap.put("context", context);
142    
143                            copyDependencyXml(
144                                    "jetty-context-configure.xml", contextXml.getParent(),
145                                    contextXml.getName(), filterMap, true);
146                    }
147            }
148    
149            public static void redeployTomcat(String context) throws Exception {
150                    if (_isPortalContext(context)) {
151                            throw new UnsupportedOperationException(
152                                    "This method is meant for redeploying plugins, not the portal");
153                    }
154    
155                    File webXml = new File(
156                            getAutoDeployDestDir(), context + "/WEB-INF/web.xml");
157    
158                    FileUtils.touch(webXml);
159            }
160    
161            public static void undeploy(String appServerType, File deployDir)
162                    throws Exception {
163    
164                    boolean undeployEnabled = PrefsPropsUtil.getBoolean(
165                            PropsKeys.HOT_UNDEPLOY_ENABLED, PropsValues.HOT_UNDEPLOY_ENABLED);
166    
167                    if (!undeployEnabled) {
168                            return;
169                    }
170    
171                    if (!appServerType.equals(ServerDetector.GLASSFISH_ID) &&
172                            !appServerType.equals(ServerDetector.JBOSS_ID) &&
173                            !appServerType.equals(ServerDetector.JETTY_ID) &&
174                            !appServerType.equals(ServerDetector.TOMCAT_ID) &&
175                            !appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
176    
177                            return;
178                    }
179    
180                    if (!deployDir.exists()) {
181                            String deployDirPath = deployDir.getAbsolutePath();
182    
183                            if (StringUtil.endsWith(deployDirPath, ".war")) {
184                                    deployDirPath = deployDirPath.substring(
185                                            0, deployDirPath.length() - 4);
186                            }
187                            else {
188                                    deployDirPath = deployDirPath.concat(".war");
189                            }
190    
191                            deployDir = new File(deployDirPath);
192                    }
193    
194                    if (!deployDir.exists()) {
195                            return;
196                    }
197    
198                    if (deployDir.isFile()) {
199                            FileUtil.delete(deployDir);
200                    }
201                    else {
202                            File webXml = new File(deployDir + "/WEB-INF/web.xml");
203    
204                            if (!webXml.exists()) {
205                                    return;
206                            }
207    
208                            if (_log.isInfoEnabled()) {
209                                    _log.info("Undeploy " + deployDir);
210                            }
211    
212                            FileUtil.delete(deployDir + "/WEB-INF/web.xml");
213    
214                            DeleteTask.deleteDirectory(deployDir);
215                    }
216    
217                    if (appServerType.equals(ServerDetector.JETTY_ID)) {
218                            FileUtil.delete(
219                                    System.getProperty("jetty.home") + "/contexts/" +
220                                            deployDir.getName() + ".xml");
221                    }
222    
223                    if (appServerType.equals(ServerDetector.JBOSS_ID)) {
224                            File deployedFile = new File(
225                                    deployDir.getParent(), deployDir.getName() + ".deployed");
226    
227                            FileUtil.delete(deployedFile);
228                    }
229    
230                    int undeployInterval = PrefsPropsUtil.getInteger(
231                            PropsKeys.HOT_UNDEPLOY_INTERVAL, PropsValues.HOT_UNDEPLOY_INTERVAL);
232    
233                    if (_log.isInfoEnabled()) {
234                            _log.info(
235                                    "Wait " + undeployInterval +
236                                            " ms to allow the plugin time to fully undeploy");
237                    }
238    
239                    if (undeployInterval > 0) {
240                            Thread.sleep(undeployInterval);
241                    }
242            }
243    
244            private static boolean _isPortalContext(String context) {
245                    if (Validator.isNull(context) || context.equals(StringPool.SLASH) ||
246                            context.equals(
247                                    PortalContextLoaderListener.getPortalServletContextPath())) {
248    
249                            return true;
250                    }
251    
252                    return false;
253            }
254    
255            private DeployUtil() {
256            }
257    
258            private String _getResourcePath(String resource) throws IOException {
259                    Class<?> clazz = getClass();
260    
261                    InputStream inputStream = clazz.getResourceAsStream(
262                            "dependencies/" + resource);
263    
264                    if (inputStream == null) {
265                            return null;
266                    }
267    
268                    String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
269    
270                    File file = new File(
271                            tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" +
272                                    resource);
273    
274                    //if (!file.exists() || resource.startsWith("ext-")) {
275                            File parentFile = file.getParentFile();
276    
277                            if (parentFile != null) {
278                                    FileUtil.mkdirs(parentFile);
279                            }
280    
281                            StreamUtil.transfer(inputStream, new FileOutputStream(file));
282                    //}
283    
284                    return FileUtil.getAbsolutePath(file);
285            }
286    
287            private static Log _log = LogFactoryUtil.getLog(DeployUtil.class);
288    
289            private static DeployUtil _instance = new DeployUtil();
290    
291    }