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