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.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.CharPool;
020    import com.liferay.portal.kernel.util.FileUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.PropsKeys;
023    import com.liferay.portal.kernel.util.ServerDetector;
024    import com.liferay.portal.kernel.util.StreamUtil;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.util.SystemProperties;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.spring.context.PortalContextLoaderListener;
030    import com.liferay.portal.util.PortalUtil;
031    import com.liferay.portal.util.PrefsPropsUtil;
032    import com.liferay.portal.util.PropsValues;
033    import com.liferay.util.ant.CopyTask;
034    import com.liferay.util.ant.DeleteTask;
035    
036    import java.io.File;
037    import java.io.FileOutputStream;
038    import java.io.IOException;
039    import java.io.InputStream;
040    
041    import java.nio.file.Files;
042    import java.nio.file.Path;
043    import java.nio.file.Paths;
044    
045    import java.util.HashMap;
046    import java.util.Map;
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.TOMCAT_ID)) {
089                            destDir = PrefsPropsUtil.getString(
090                                    PropsKeys.AUTO_DEPLOY_TOMCAT_DEST_DIR,
091                                    PropsValues.AUTO_DEPLOY_TOMCAT_DEST_DIR);
092                    }
093                    else {
094                            destDir = PrefsPropsUtil.getString(
095                                    "auto.deploy." + serverId + ".dest.dir");
096                    }
097    
098                    if (Validator.isNull(destDir)) {
099                            destDir = PrefsPropsUtil.getString(
100                                    PropsKeys.AUTO_DEPLOY_DEFAULT_DEST_DIR,
101                                    PropsValues.AUTO_DEPLOY_DEFAULT_DEST_DIR);
102                    }
103    
104                    destDir = StringUtil.replace(
105                            destDir, CharPool.BACK_SLASH, CharPool.SLASH);
106    
107                    return destDir;
108            }
109    
110            public static String getResourcePath(String resource) throws Exception {
111                    return _instance._getResourcePath(resource);
112            }
113    
114            public static void redeployJetty(String context) throws Exception {
115                    String contextsDirName = getJettyHome() + "/contexts";
116    
117                    if (_isPortalContext(context)) {
118                            throw new UnsupportedOperationException(
119                                    "This method is meant for redeploying plugins, not the portal");
120                    }
121    
122                    File contextXml = new File(contextsDirName, context + ".xml");
123    
124                    if (contextXml.exists()) {
125                            FileUtils.touch(contextXml);
126                    }
127                    else {
128                            Map<String, String> filterMap = new HashMap<>();
129    
130                            filterMap.put("context", context);
131    
132                            copyDependencyXml(
133                                    "jetty-context-configure.xml", contextXml.getParent(),
134                                    contextXml.getName(), filterMap, true);
135                    }
136            }
137    
138            public static void redeployTomcat(String context) throws Exception {
139                    if (_isPortalContext(context)) {
140                            throw new UnsupportedOperationException(
141                                    "This method is meant for redeploying plugins, not the portal");
142                    }
143    
144                    File webXml = new File(
145                            getAutoDeployDestDir(), context + "/WEB-INF/web.xml");
146    
147                    FileUtils.touch(webXml);
148            }
149    
150            public static void undeploy(String appServerType, File deployDir)
151                    throws Exception {
152    
153                    boolean undeployEnabled = PrefsPropsUtil.getBoolean(
154                            PropsKeys.HOT_UNDEPLOY_ENABLED, PropsValues.HOT_UNDEPLOY_ENABLED);
155    
156                    if (!undeployEnabled) {
157                            return;
158                    }
159    
160                    if (!appServerType.equals(ServerDetector.GLASSFISH_ID) &&
161                            !appServerType.equals(ServerDetector.JBOSS_ID) &&
162                            !appServerType.equals(ServerDetector.JETTY_ID) &&
163                            !appServerType.equals(ServerDetector.TOMCAT_ID) &&
164                            !appServerType.equals(ServerDetector.WEBLOGIC_ID) &&
165                            !appServerType.equals(ServerDetector.WILDFLY_ID)) {
166    
167                            return;
168                    }
169    
170                    if (!deployDir.exists()) {
171                            String deployDirPath = deployDir.getAbsolutePath();
172    
173                            if (StringUtil.endsWith(deployDirPath, ".war")) {
174                                    deployDirPath = deployDirPath.substring(
175                                            0, deployDirPath.length() - 4);
176                            }
177                            else {
178                                    deployDirPath = deployDirPath.concat(".war");
179                            }
180    
181                            deployDir = new File(deployDirPath);
182                    }
183    
184                    if (!deployDir.exists()) {
185                            return;
186                    }
187    
188                    if (deployDir.isFile()) {
189                            FileUtil.delete(deployDir);
190                    }
191                    else {
192                            File webXml = new File(deployDir + "/WEB-INF/web.xml");
193    
194                            if (!webXml.exists()) {
195                                    return;
196                            }
197    
198                            if (_log.isInfoEnabled()) {
199                                    _log.info("Undeploy " + deployDir);
200                            }
201    
202                            FileUtil.delete(deployDir + "/WEB-INF/web.xml");
203    
204                            DeleteTask.deleteDirectory(deployDir);
205                    }
206    
207                    if (appServerType.equals(ServerDetector.JETTY_ID)) {
208                            FileUtil.delete(
209                                    getJettyHome() + "/contexts/" + deployDir.getName() + ".xml");
210                    }
211    
212                    if (appServerType.equals(ServerDetector.JBOSS_ID) ||
213                            appServerType.equals(ServerDetector.WILDFLY_ID)) {
214    
215                            File deployedFile = new File(
216                                    deployDir.getParent(), deployDir.getName() + ".deployed");
217    
218                            FileUtil.delete(deployedFile);
219                    }
220    
221                    int undeployInterval = PrefsPropsUtil.getInteger(
222                            PropsKeys.HOT_UNDEPLOY_INTERVAL, PropsValues.HOT_UNDEPLOY_INTERVAL);
223    
224                    if (_log.isInfoEnabled()) {
225                            _log.info(
226                                    "Wait " + undeployInterval +
227                                            " ms to allow the plugin time to fully undeploy");
228                    }
229    
230                    if (undeployInterval > 0) {
231                            Thread.sleep(undeployInterval);
232                    }
233            }
234    
235            private static boolean _isPortalContext(String context) {
236                    if (Validator.isNull(context) || context.equals(StringPool.SLASH) ||
237                            context.equals(
238                                    PortalContextLoaderListener.getPortalServletContextPath())) {
239    
240                            return true;
241                    }
242    
243                    return false;
244            }
245    
246            private static String getJettyHome() {
247                    String jettyHome = System.getProperty("jetty.home");
248    
249                    if (jettyHome == null) {
250                            jettyHome = PortalUtil.getGlobalLibDir() + "../../..";
251                    }
252    
253                    return jettyHome;
254            }
255    
256            private DeployUtil() {
257            }
258    
259            private String _getResourcePath(String resource) throws IOException {
260                    Class<?> clazz = getClass();
261    
262                    InputStream inputStream = clazz.getResourceAsStream(
263                            "dependencies/" + resource);
264    
265                    if (inputStream == null) {
266                            return null;
267                    }
268    
269                    Path tempDirPath = Files.createTempDirectory(
270                            Paths.get(SystemProperties.get(SystemProperties.TMP_DIR)), null);
271    
272                    File file = new File(
273                            tempDirPath + "/liferay/com/liferay/portal/deploy/dependencies/" +
274                                    resource);
275    
276                    //if (!file.exists() || resource.startsWith("ext-")) {
277    
278                    File parentFile = file.getParentFile();
279    
280                    if (parentFile != null) {
281                            FileUtil.mkdirs(parentFile);
282                    }
283    
284                    StreamUtil.transfer(inputStream, new FileOutputStream(file));
285    
286                    //}
287    
288                    return FileUtil.getAbsolutePath(file);
289            }
290    
291            private static final Log _log = LogFactoryUtil.getLog(DeployUtil.class);
292    
293            private static final DeployUtil _instance = new DeployUtil();
294    
295    }