/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.deploy; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.PropsKeys; import com.liferay.portal.kernel.util.ServerDetector; import com.liferay.portal.kernel.util.StreamUtil; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.SystemProperties; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.spring.context.PortalContextLoaderListener; import com.liferay.portal.util.PrefsPropsUtil; import com.liferay.portal.util.PropsValues; import com.liferay.util.ant.CopyTask; import com.liferay.util.ant.DeleteTask; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; /** * @author Brian Wing Shun Chan */ public class DeployUtil { public static void copyDependencyXml( String fileName, String targetDir, String targetFileName, Map<String, String> filterMap, boolean overwrite) throws Exception { File file = new File(getResourcePath(fileName)); File targetFile = new File(targetDir, targetFileName); if (!targetFile.exists()) { CopyTask.copyFile( file, new File(targetDir), targetFileName, filterMap, overwrite, true); } } public static String getAutoDeployDestDir() throws Exception { String destDir = PrefsPropsUtil.getString( PropsKeys.AUTO_DEPLOY_DEST_DIR, PropsValues.AUTO_DEPLOY_DEST_DIR); if (Validator.isNull(destDir)) { destDir = getAutoDeployServerDestDir(); } FileUtil.mkdirs(destDir); return destDir; } public static String getAutoDeployServerDestDir() throws Exception { String destDir = null; String serverId = GetterUtil.getString(ServerDetector.getServerId()); if (serverId.equals(ServerDetector.TOMCAT_ID)) { destDir = PrefsPropsUtil.getString( PropsKeys.AUTO_DEPLOY_TOMCAT_DEST_DIR, PropsValues.AUTO_DEPLOY_TOMCAT_DEST_DIR); } else { destDir = PrefsPropsUtil.getString( "auto.deploy." + serverId + ".dest.dir"); } if (Validator.isNull(destDir)) { destDir = PrefsPropsUtil.getString( PropsKeys.AUTO_DEPLOY_DEFAULT_DEST_DIR, PropsValues.AUTO_DEPLOY_DEFAULT_DEST_DIR); } destDir = StringUtil.replace( destDir, CharPool.BACK_SLASH, CharPool.SLASH); return destDir; } public static String getResourcePath(String resource) throws Exception { return _instance._getResourcePath(resource); } public static void redeployJetty(String context) throws Exception { String contextsDirName = _getJettyHome() + "/contexts"; if (_isPortalContext(context)) { throw new UnsupportedOperationException( "This method is meant for redeploying plugins, not the portal"); } File contextXml = new File(contextsDirName, context + ".xml"); if (contextXml.exists()) { FileUtils.touch(contextXml); } else { Map<String, String> filterMap = new HashMap<>(); filterMap.put("context", context); copyDependencyXml( "jetty-context-configure.xml", contextXml.getParent(), contextXml.getName(), filterMap, true); } } public static void redeployTomcat(String context) throws Exception { if (_isPortalContext(context)) { throw new UnsupportedOperationException( "This method is meant for redeploying plugins, not the portal"); } File webXml = new File( getAutoDeployDestDir(), context + "/WEB-INF/web.xml"); FileUtils.touch(webXml); } public static void undeploy(String appServerType, File deployDir) throws Exception { boolean undeployEnabled = PrefsPropsUtil.getBoolean( PropsKeys.HOT_UNDEPLOY_ENABLED, PropsValues.HOT_UNDEPLOY_ENABLED); if (!undeployEnabled) { return; } if (!appServerType.equals(ServerDetector.GLASSFISH_ID) && !appServerType.equals(ServerDetector.JBOSS_ID) && !appServerType.equals(ServerDetector.JETTY_ID) && !appServerType.equals(ServerDetector.TOMCAT_ID) && !appServerType.equals(ServerDetector.WEBLOGIC_ID) && !appServerType.equals(ServerDetector.WILDFLY_ID)) { return; } if (!deployDir.exists()) { String deployDirPath = deployDir.getAbsolutePath(); if (StringUtil.endsWith(deployDirPath, ".war")) { deployDirPath = deployDirPath.substring( 0, deployDirPath.length() - 4); } else { deployDirPath = deployDirPath.concat(".war"); } deployDir = new File(deployDirPath); } if (!deployDir.exists()) { return; } if (deployDir.isFile()) { FileUtil.delete(deployDir); } else { File webXml = new File(deployDir + "/WEB-INF/web.xml"); if (!webXml.exists()) { return; } if (_log.isInfoEnabled()) { _log.info("Undeploy " + deployDir); } FileUtil.delete(deployDir + "/WEB-INF/web.xml"); DeleteTask.deleteDirectory(deployDir); } if (appServerType.equals(ServerDetector.JETTY_ID)) { FileUtil.delete( _getJettyHome() + "/contexts/" + deployDir.getName() + ".xml"); } if (appServerType.equals(ServerDetector.JBOSS_ID) || appServerType.equals(ServerDetector.WILDFLY_ID)) { File deployedFile = new File( deployDir.getParent(), deployDir.getName() + ".deployed"); FileUtil.delete(deployedFile); } int undeployInterval = PrefsPropsUtil.getInteger( PropsKeys.HOT_UNDEPLOY_INTERVAL, PropsValues.HOT_UNDEPLOY_INTERVAL); if (_log.isInfoEnabled()) { _log.info( "Wait " + undeployInterval + " ms to allow the plugin time to fully undeploy"); } if (undeployInterval > 0) { Thread.sleep(undeployInterval); } } private static String _getJettyHome() { String jettyHome = System.getProperty("jetty.home"); if (jettyHome == null) { jettyHome = PortalUtil.getGlobalLibDir() + "../../.."; } return jettyHome; } private static boolean _isPortalContext(String context) { if (Validator.isNull(context) || context.equals(StringPool.SLASH) || context.equals( PortalContextLoaderListener.getPortalServletContextPath())) { return true; } return false; } private DeployUtil() { } private String _getResourcePath(String resource) throws IOException { Class<?> clazz = getClass(); InputStream inputStream = clazz.getResourceAsStream( "dependencies/" + resource); if (inputStream == null) { return null; } Path tempDirPath = Files.createTempDirectory( Paths.get(SystemProperties.get(SystemProperties.TMP_DIR)), null); File file = new File( tempDirPath + "/liferay/com/liferay/portal/deploy/dependencies/" + resource); //if (!file.exists() || resource.startsWith("ext-")) { File parentFile = file.getParentFile(); if (parentFile != null) { FileUtil.mkdirs(parentFile); } StreamUtil.transfer(inputStream, new FileOutputStream(file)); //} return FileUtil.getAbsolutePath(file); } private static final Log _log = LogFactoryUtil.getLog(DeployUtil.class); private static final DeployUtil _instance = new DeployUtil(); }