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