001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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                            !appServerType.equals(ServerDetector.WILDFLY_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                                    System.getProperty("jetty.home") + "/contexts/" +
221                                            deployDir.getName() + ".xml");
222                    }
223    
224                    if (appServerType.equals(ServerDetector.JBOSS_ID) ||
225                            appServerType.equals(ServerDetector.WILDFLY_ID)) {
226    
227                            File deployedFile = new File(
228                                    deployDir.getParent(), deployDir.getName() + ".deployed");
229    
230                            FileUtil.delete(deployedFile);
231                    }
232    
233                    int undeployInterval = PrefsPropsUtil.getInteger(
234                            PropsKeys.HOT_UNDEPLOY_INTERVAL, PropsValues.HOT_UNDEPLOY_INTERVAL);
235    
236                    if (_log.isInfoEnabled()) {
237                            _log.info(
238                                    "Wait " + undeployInterval +
239                                            " ms to allow the plugin time to fully undeploy");
240                    }
241    
242                    if (undeployInterval > 0) {
243                            Thread.sleep(undeployInterval);
244                    }
245            }
246    
247            private static boolean _isPortalContext(String context) {
248                    if (Validator.isNull(context) || context.equals(StringPool.SLASH) ||
249                            context.equals(
250                                    PortalContextLoaderListener.getPortalServletContextPath())) {
251    
252                            return true;
253                    }
254    
255                    return false;
256            }
257    
258            private DeployUtil() {
259            }
260    
261            private String _getResourcePath(String resource) throws IOException {
262                    Class<?> clazz = getClass();
263    
264                    InputStream inputStream = clazz.getResourceAsStream(
265                            "dependencies/" + resource);
266    
267                    if (inputStream == null) {
268                            return null;
269                    }
270    
271                    String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
272    
273                    File file = new File(
274                            tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" +
275                                    resource);
276    
277                    //if (!file.exists() || resource.startsWith("ext-")) {
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                    return FileUtil.getAbsolutePath(file);
288            }
289    
290            private static Log _log = LogFactoryUtil.getLog(DeployUtil.class);
291    
292            private static DeployUtil _instance = new DeployUtil();
293    
294    }