001    /**
002     * Copyright (c) 2000-present 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.PortalUtil;
032    import com.liferay.portal.util.PrefsPropsUtil;
033    import com.liferay.portal.util.PropsUtil;
034    import com.liferay.portal.util.PropsValues;
035    import com.liferay.util.ant.CopyTask;
036    import com.liferay.util.ant.DeleteTask;
037    
038    import java.io.File;
039    import java.io.FileOutputStream;
040    import java.io.IOException;
041    import java.io.InputStream;
042    
043    import java.util.HashMap;
044    import java.util.Map;
045    
046    import javax.portlet.PortletPreferences;
047    
048    import org.apache.commons.io.FileUtils;
049    
050    /**
051     * @author Brian Wing Shun Chan
052     */
053    public class DeployUtil {
054    
055            public static void copyDependencyXml(
056                            String fileName, String targetDir, String targetFileName,
057                            Map<String, String> filterMap, boolean overwrite)
058                    throws Exception {
059    
060                    File file = new File(getResourcePath(fileName));
061                    File targetFile = new File(targetDir, targetFileName);
062    
063                    if (!targetFile.exists()) {
064                            CopyTask.copyFile(
065                                    file, new File(targetDir), targetFileName, filterMap, overwrite,
066                                    true);
067                    }
068            }
069    
070            public static String getAutoDeployDestDir() throws Exception {
071                    String destDir = PrefsPropsUtil.getString(
072                            PropsKeys.AUTO_DEPLOY_DEST_DIR, PropsValues.AUTO_DEPLOY_DEST_DIR);
073    
074                    if (Validator.isNull(destDir)) {
075                            destDir = getAutoDeployServerDestDir();
076                    }
077    
078                    FileUtil.mkdirs(destDir);
079    
080                    return destDir;
081            }
082    
083            public static String getAutoDeployServerDestDir() throws Exception {
084                    String destDir = null;
085    
086                    String serverId = GetterUtil.getString(ServerDetector.getServerId());
087    
088                    if (serverId.equals(ServerDetector.JBOSS_ID) &&
089                            ServerDetector.isJBoss5()) {
090    
091                            String name = "auto.deploy." + serverId + ".dest.dir";
092    
093                            PortletPreferences portletPreferences =
094                                    PrefsPropsUtil.getPreferences(true);
095    
096                            String value = PropsUtil.get(name, new Filter("5"));
097    
098                            destDir = portletPreferences.getValue(name, value);
099                    }
100                    else if (serverId.equals(ServerDetector.TOMCAT_ID)) {
101                            destDir = PrefsPropsUtil.getString(
102                                    PropsKeys.AUTO_DEPLOY_TOMCAT_DEST_DIR,
103                                    PropsValues.AUTO_DEPLOY_TOMCAT_DEST_DIR);
104                    }
105                    else {
106                            destDir = PrefsPropsUtil.getString(
107                                    "auto.deploy." + serverId + ".dest.dir");
108                    }
109    
110                    if (Validator.isNull(destDir)) {
111                            destDir = PrefsPropsUtil.getString(
112                                    PropsKeys.AUTO_DEPLOY_DEFAULT_DEST_DIR,
113                                    PropsValues.AUTO_DEPLOY_DEFAULT_DEST_DIR);
114                    }
115    
116                    destDir = StringUtil.replace(
117                            destDir, CharPool.BACK_SLASH, CharPool.SLASH);
118    
119                    return destDir;
120            }
121    
122            public static String getResourcePath(String resource) throws Exception {
123                    return _instance._getResourcePath(resource);
124            }
125    
126            public static void redeployJetty(String context) throws Exception {
127                    String contextsDirName = getJettyHome() + "/contexts";
128    
129                    if (_isPortalContext(context)) {
130                            throw new UnsupportedOperationException(
131                                    "This method is meant for redeploying plugins, not the portal");
132                    }
133    
134                    File contextXml = new File(contextsDirName, context + ".xml");
135    
136                    if (contextXml.exists()) {
137                            FileUtils.touch(contextXml);
138                    }
139                    else {
140                            Map<String, String> filterMap = new HashMap<>();
141    
142                            filterMap.put("context", context);
143    
144                            copyDependencyXml(
145                                    "jetty-context-configure.xml", contextXml.getParent(),
146                                    contextXml.getName(), filterMap, true);
147                    }
148            }
149    
150            public static void redeployTomcat(String context) throws Exception {
151                    if (_isPortalContext(context)) {
152                            throw new UnsupportedOperationException(
153                                    "This method is meant for redeploying plugins, not the portal");
154                    }
155    
156                    File webXml = new File(
157                            getAutoDeployDestDir(), context + "/WEB-INF/web.xml");
158    
159                    FileUtils.touch(webXml);
160            }
161    
162            public static void undeploy(String appServerType, File deployDir)
163                    throws Exception {
164    
165                    boolean undeployEnabled = PrefsPropsUtil.getBoolean(
166                            PropsKeys.HOT_UNDEPLOY_ENABLED, PropsValues.HOT_UNDEPLOY_ENABLED);
167    
168                    if (!undeployEnabled) {
169                            return;
170                    }
171    
172                    if (!appServerType.equals(ServerDetector.GLASSFISH_ID) &&
173                            !appServerType.equals(ServerDetector.JBOSS_ID) &&
174                            !appServerType.equals(ServerDetector.JETTY_ID) &&
175                            !appServerType.equals(ServerDetector.TOMCAT_ID) &&
176                            !appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
177    
178                            return;
179                    }
180    
181                    if (!deployDir.exists()) {
182                            String deployDirPath = deployDir.getAbsolutePath();
183    
184                            if (StringUtil.endsWith(deployDirPath, ".war")) {
185                                    deployDirPath = deployDirPath.substring(
186                                            0, deployDirPath.length() - 4);
187                            }
188                            else {
189                                    deployDirPath = deployDirPath.concat(".war");
190                            }
191    
192                            deployDir = new File(deployDirPath);
193                    }
194    
195                    if (!deployDir.exists()) {
196                            return;
197                    }
198    
199                    if (deployDir.isFile()) {
200                            FileUtil.delete(deployDir);
201                    }
202                    else {
203                            File webXml = new File(deployDir + "/WEB-INF/web.xml");
204    
205                            if (!webXml.exists()) {
206                                    return;
207                            }
208    
209                            if (_log.isInfoEnabled()) {
210                                    _log.info("Undeploy " + deployDir);
211                            }
212    
213                            FileUtil.delete(deployDir + "/WEB-INF/web.xml");
214    
215                            DeleteTask.deleteDirectory(deployDir);
216                    }
217    
218                    if (appServerType.equals(ServerDetector.JETTY_ID)) {
219                            FileUtil.delete(
220                                    getJettyHome() + "/contexts/" + 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 static String getJettyHome() {
256                    String jettyHome = System.getProperty("jetty.home");
257    
258                    if (jettyHome == null) {
259                            jettyHome = PortalUtil.getGlobalLibDir() + "../../..";
260                    }
261    
262                    return jettyHome;
263            }
264    
265            private DeployUtil() {
266            }
267    
268            private String _getResourcePath(String resource) throws IOException {
269                    Class<?> clazz = getClass();
270    
271                    InputStream inputStream = clazz.getResourceAsStream(
272                            "dependencies/" + resource);
273    
274                    if (inputStream == null) {
275                            return null;
276                    }
277    
278                    String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
279    
280                    File file = new File(
281                            tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" +
282                                    resource);
283    
284                    //if (!file.exists() || resource.startsWith("ext-")) {
285                            File parentFile = file.getParentFile();
286    
287                            if (parentFile != null) {
288                                    FileUtil.mkdirs(parentFile);
289                            }
290    
291                            StreamUtil.transfer(inputStream, new FileOutputStream(file));
292                    //}
293    
294                    return FileUtil.getAbsolutePath(file);
295            }
296    
297            private static final Log _log = LogFactoryUtil.getLog(DeployUtil.class);
298    
299            private static final DeployUtil _instance = new DeployUtil();
300    
301    }