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.tools.deploy;
016    
017    import com.liferay.portal.deploy.DeployUtil;
018    import com.liferay.portal.kernel.deploy.Deployer;
019    import com.liferay.portal.kernel.deploy.auto.AutoDeployException;
020    import com.liferay.portal.kernel.deploy.auto.AutoDeployer;
021    import com.liferay.portal.kernel.deploy.auto.context.AutoDeploymentContext;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.plugin.License;
025    import com.liferay.portal.kernel.plugin.PluginPackage;
026    import com.liferay.portal.kernel.servlet.PluginContextListener;
027    import com.liferay.portal.kernel.servlet.PortalClassLoaderServlet;
028    import com.liferay.portal.kernel.servlet.PortalDelegateServlet;
029    import com.liferay.portal.kernel.servlet.PortletServlet;
030    import com.liferay.portal.kernel.servlet.SecurePluginContextListener;
031    import com.liferay.portal.kernel.servlet.SecureServlet;
032    import com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener;
033    import com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter;
034    import com.liferay.portal.kernel.util.CharPool;
035    import com.liferay.portal.kernel.util.FileUtil;
036    import com.liferay.portal.kernel.util.GetterUtil;
037    import com.liferay.portal.kernel.util.HttpUtil;
038    import com.liferay.portal.kernel.util.OSDetector;
039    import com.liferay.portal.kernel.util.PropertiesUtil;
040    import com.liferay.portal.kernel.util.PropsKeys;
041    import com.liferay.portal.kernel.util.ServerDetector;
042    import com.liferay.portal.kernel.util.StreamUtil;
043    import com.liferay.portal.kernel.util.StringBundler;
044    import com.liferay.portal.kernel.util.StringPool;
045    import com.liferay.portal.kernel.util.StringUtil;
046    import com.liferay.portal.kernel.util.SystemProperties;
047    import com.liferay.portal.kernel.util.TextFormatter;
048    import com.liferay.portal.kernel.util.Time;
049    import com.liferay.portal.kernel.util.Validator;
050    import com.liferay.portal.kernel.xml.Document;
051    import com.liferay.portal.kernel.xml.Element;
052    import com.liferay.portal.kernel.xml.SAXReaderUtil;
053    import com.liferay.portal.plugin.PluginPackageUtil;
054    import com.liferay.portal.tools.WebXMLBuilder;
055    import com.liferay.portal.util.ExtRegistry;
056    import com.liferay.portal.util.InitUtil;
057    import com.liferay.portal.util.PortalUtil;
058    import com.liferay.portal.util.PrefsPropsUtil;
059    import com.liferay.portal.util.PropsUtil;
060    import com.liferay.portal.util.PropsValues;
061    import com.liferay.portal.webserver.DynamicResourceServlet;
062    import com.liferay.util.ant.CopyTask;
063    import com.liferay.util.ant.DeleteTask;
064    import com.liferay.util.ant.ExpandTask;
065    import com.liferay.util.ant.UpToDateTask;
066    import com.liferay.util.ant.WarTask;
067    import com.liferay.util.xml.DocUtil;
068    import com.liferay.util.xml.XMLFormatter;
069    
070    import java.io.File;
071    import java.io.FileInputStream;
072    import java.io.IOException;
073    import java.io.InputStream;
074    
075    import java.util.ArrayList;
076    import java.util.HashMap;
077    import java.util.List;
078    import java.util.Map;
079    import java.util.Properties;
080    import java.util.Set;
081    import java.util.zip.ZipEntry;
082    import java.util.zip.ZipFile;
083    
084    import org.apache.oro.io.GlobFilenameFilter;
085    
086    /**
087     * @author Brian Wing Shun Chan
088     * @author Sandeep Soni
089     */
090    public class BaseDeployer implements AutoDeployer, Deployer {
091    
092            public static final String DEPLOY_TO_PREFIX = "DEPLOY_TO__";
093    
094            public static void main(String[] args) {
095                    InitUtil.initWithSpring();
096    
097                    List<String> wars = new ArrayList<String>();
098                    List<String> jars = new ArrayList<String>();
099    
100                    for (String arg : args) {
101                            String fileName = arg.toLowerCase();
102    
103                            if (fileName.endsWith(".war")) {
104                                    wars.add(arg);
105                            }
106                            else if (fileName.endsWith(".jar")) {
107                                    jars.add(arg);
108                            }
109                    }
110    
111                    new BaseDeployer(wars, jars);
112            }
113    
114            public BaseDeployer() {
115            }
116    
117            public BaseDeployer(List<String> wars, List<String> jars) {
118                    baseDir = System.getProperty("deployer.base.dir");
119                    destDir = System.getProperty("deployer.dest.dir");
120                    appServerType = System.getProperty("deployer.app.server.type");
121                    auiTaglibDTD = System.getProperty("deployer.aui.taglib.dtd");
122                    portletTaglibDTD = System.getProperty("deployer.portlet.taglib.dtd");
123                    portletExtTaglibDTD = System.getProperty(
124                            "deployer.portlet.ext.taglib.dtd");
125                    securityTaglibDTD = System.getProperty("deployer.security.taglib.dtd");
126                    themeTaglibDTD = System.getProperty("deployer.theme.taglib.dtd");
127                    uiTaglibDTD = System.getProperty("deployer.ui.taglib.dtd");
128                    utilTaglibDTD = System.getProperty("deployer.util.taglib.dtd");
129                    unpackWar = GetterUtil.getBoolean(
130                            System.getProperty("deployer.unpack.war"), true);
131                    filePattern = System.getProperty("deployer.file.pattern");
132                    jbossPrefix = GetterUtil.getString(
133                            System.getProperty("deployer.jboss.prefix"));
134                    tomcatLibDir = System.getProperty("deployer.tomcat.lib.dir");
135                    this.wars = wars;
136                    this.jars = jars;
137    
138                    checkArguments();
139    
140                    String context = System.getProperty("deployer.context");
141    
142                    try {
143                            deploy(context);
144                    }
145                    catch (Exception e) {
146                            _log.error(e, e);
147                    }
148            }
149    
150            @Override
151            public void addExtJar(List<String> jars, String resource) throws Exception {
152                    Set<String> servletContextNames = ExtRegistry.getServletContextNames();
153    
154                    for (String servletContextName : servletContextNames) {
155                            String extResource =
156                                    "ext-" + servletContextName + resource.substring(3);
157    
158                            String path = DeployUtil.getResourcePath(extResource);
159    
160                            if (_log.isDebugEnabled()) {
161                                    if (path == null) {
162                                            _log.debug("Resource " + extResource + " is not available");
163                                    }
164                                    else {
165                                            _log.debug(
166                                                    "Resource " + extResource + " is available at " + path);
167                                    }
168                            }
169    
170                            if (path != null) {
171                                    jars.add(path);
172                            }
173                    }
174            }
175    
176            @Override
177            public void addRequiredJar(List<String> jars, String resource)
178                    throws Exception {
179    
180                    String path = DeployUtil.getResourcePath(resource);
181    
182                    if (path == null) {
183                            throw new RuntimeException(
184                                    "Resource " + resource + " does not exist");
185                    }
186    
187                    if (_log.isDebugEnabled()) {
188                            _log.debug("Resource " + resource + " is available at " + path);
189                    }
190    
191                    jars.add(path);
192            }
193    
194            @Override
195            public int autoDeploy(AutoDeploymentContext autoDeploymentContext)
196                    throws AutoDeployException {
197    
198                    List<String> wars = new ArrayList<String>();
199    
200                    File file = autoDeploymentContext.getFile();
201    
202                    wars.add(file.getName());
203    
204                    this.wars = wars;
205    
206                    try {
207                            return deployFile(autoDeploymentContext);
208                    }
209                    catch (Exception e) {
210                            throw new AutoDeployException(e);
211                    }
212            }
213    
214            @Override
215            public void checkArguments() {
216                    if (Validator.isNull(baseDir)) {
217                            throw new IllegalArgumentException(
218                                    "The system property deployer.base.dir is not set");
219                    }
220    
221                    if (Validator.isNull(destDir)) {
222                            throw new IllegalArgumentException(
223                                    "The system property deployer.dest.dir is not set");
224                    }
225    
226                    if (Validator.isNull(appServerType)) {
227                            throw new IllegalArgumentException(
228                                    "The system property deployer.app.server.type is not set");
229                    }
230    
231                    if (!appServerType.equals(ServerDetector.GERONIMO_ID) &&
232                            !appServerType.equals(ServerDetector.GLASSFISH_ID) &&
233                            !appServerType.equals(ServerDetector.JBOSS_ID) &&
234                            !appServerType.equals(ServerDetector.JONAS_ID) &&
235                            !appServerType.equals(ServerDetector.JETTY_ID) &&
236                            !appServerType.equals(ServerDetector.OC4J_ID) &&
237                            !appServerType.equals(ServerDetector.RESIN_ID) &&
238                            !appServerType.equals(ServerDetector.TOMCAT_ID) &&
239                            !appServerType.equals(ServerDetector.WEBLOGIC_ID) &&
240                            !appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
241    
242                            throw new IllegalArgumentException(
243                                    appServerType + " is not a valid application server type");
244                    }
245    
246                    if (appServerType.equals(ServerDetector.GLASSFISH_ID) ||
247                            appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
248    
249                            unpackWar = false;
250                    }
251    
252                    if (Validator.isNotNull(jbossPrefix) &&
253                            !Validator.isNumber(jbossPrefix)) {
254    
255                            jbossPrefix = "1";
256                    }
257            }
258    
259            @Override
260            public AutoDeployer cloneAutoDeployer() throws AutoDeployException {
261                    try {
262                            Class<?> clazz = getClass();
263    
264                            Deployer deployer = (Deployer)clazz.newInstance();
265    
266                            deployer.setAppServerType(appServerType);
267                            deployer.setAuiTaglibDTD(auiTaglibDTD);
268                            deployer.setBaseDir(baseDir);
269                            deployer.setDestDir(destDir);
270                            deployer.setFilePattern(filePattern);
271                            deployer.setJars(jars);
272                            deployer.setJbossPrefix(jbossPrefix);
273                            deployer.setPortletExtTaglibDTD(portletExtTaglibDTD);
274                            deployer.setPortletTaglibDTD(portletTaglibDTD);
275                            deployer.setSecurityTaglibDTD(securityTaglibDTD);
276                            deployer.setThemeTaglibDTD(themeTaglibDTD);
277                            deployer.setTomcatLibDir(tomcatLibDir);
278                            deployer.setUiTaglibDTD(uiTaglibDTD);
279                            deployer.setUnpackWar(unpackWar);
280                            deployer.setUtilTaglibDTD(utilTaglibDTD);
281                            deployer.setWars(wars);
282    
283                            return (AutoDeployer)deployer;
284                    }
285                    catch (Exception e) {
286                            throw new AutoDeployException(e);
287                    }
288            }
289    
290            @Override
291            public void copyDependencyXml(String fileName, String targetDir)
292                    throws Exception {
293    
294                    copyDependencyXml(fileName, targetDir, null);
295            }
296    
297            @Override
298            public void copyDependencyXml(
299                            String fileName, String targetDir, Map<String, String> filterMap)
300                    throws Exception {
301    
302                    copyDependencyXml(fileName, targetDir, filterMap, false);
303            }
304    
305            @Override
306            public void copyDependencyXml(
307                            String fileName, String targetDir, Map<String, String> filterMap,
308                            boolean overwrite)
309                    throws Exception {
310    
311                    DeployUtil.copyDependencyXml(
312                            fileName, targetDir, fileName, filterMap, overwrite);
313            }
314    
315            public void copyDtds(File srcFile, PluginPackage pluginPackage)
316                    throws Exception {
317    
318                    File portalLog4jXml = new File(
319                            srcFile.getAbsolutePath() +
320                                    "/WEB-INF/classes/META-INF/portal-log4j.xml");
321    
322                    if (!portalLog4jXml.exists()) {
323                            return;
324                    }
325    
326                    InputStream is = null;
327    
328                    try {
329                            Class<?> clazz = getClass();
330    
331                            ClassLoader classLoader = clazz.getClassLoader();
332    
333                            is = classLoader.getResourceAsStream("META-INF/log4j.dtd");
334    
335                            File file = new File(
336                                    srcFile.getAbsolutePath() +
337                                            "/WEB-INF/classes/META-INF/log4j.dtd");
338    
339                            FileUtil.write(file, is);
340                    }
341                    finally {
342                            StreamUtil.cleanUp(is);
343                    }
344            }
345    
346            @Override
347            public void copyJars(File srcFile, PluginPackage pluginPackage)
348                    throws Exception {
349    
350                    for (int i = 0; i < jars.size(); i++) {
351                            String jarFullName = jars.get(i);
352    
353                            String jarName = jarFullName.substring(
354                                    jarFullName.lastIndexOf("/") + 1);
355    
356                            FileUtil.copyFile(
357                                    jarFullName, srcFile + "/WEB-INF/lib/" + jarName, false);
358                    }
359            }
360    
361            public void copyPortalDependencies(File srcFile) throws Exception {
362                    Properties properties = getPluginPackageProperties(srcFile);
363    
364                    if (properties == null) {
365                            return;
366                    }
367    
368                    // jars
369    
370                    String[] portalJars = StringUtil.split(
371                            properties.getProperty(
372                                    "portal-dependency-jars",
373                                    properties.getProperty("portal.dependency.jars")));
374    
375                    for (String portalJar : portalJars) {
376                            portalJar = portalJar.trim();
377    
378                            portalJar = fixPortalDependencyJar(portalJar);
379    
380                            if (_log.isDebugEnabled()) {
381                                    _log.debug("Copy portal JAR " + portalJar);
382                            }
383    
384                            try {
385                                    String portalJarPath = PortalUtil.getPortalLibDir() + portalJar;
386    
387                                    FileUtil.copyFile(
388                                            portalJarPath, srcFile + "/WEB-INF/lib/" + portalJar, true);
389                            }
390                            catch (Exception e) {
391                                    _log.error("Unable to copy portal JAR " + portalJar, e);
392                            }
393                    }
394    
395                    // tlds
396    
397                    String[] portalTlds = StringUtil.split(
398                            properties.getProperty(
399                                    "portal-dependency-tlds",
400                                    properties.getProperty("portal.dependency.tlds")));
401    
402                    for (String portalTld : portalTlds) {
403                            portalTld = portalTld.trim();
404    
405                            if (_log.isDebugEnabled()) {
406                                    _log.debug("Copy portal TLD " + portalTld);
407                            }
408    
409                            try {
410                                    String portalTldPath = DeployUtil.getResourcePath(portalTld);
411    
412                                    FileUtil.copyFile(
413                                            portalTldPath, srcFile + "/WEB-INF/tld/" + portalTld, true);
414                            }
415                            catch (Exception e) {
416                                    _log.error("Unable to copy portal TLD " + portalTld, e);
417                            }
418                    }
419    
420                    // commons-logging*.jar
421    
422                    File pluginLibDir = new File(srcFile + "/WEB-INF/lib/");
423    
424                    if (PropsValues.AUTO_DEPLOY_COPY_COMMONS_LOGGING) {
425                            String[] commonsLoggingJars = pluginLibDir.list(
426                                    new GlobFilenameFilter("commons-logging*.jar"));
427    
428                            if ((commonsLoggingJars == null) ||
429                                    (commonsLoggingJars.length == 0)) {
430    
431                                    String portalJarPath =
432                                            PortalUtil.getPortalLibDir() + "commons-logging.jar";
433    
434                                    FileUtil.copyFile(
435                                            portalJarPath, srcFile + "/WEB-INF/lib/commons-logging.jar",
436                                            true);
437                            }
438                    }
439    
440                    // log4j*.jar
441    
442                    if (PropsValues.AUTO_DEPLOY_COPY_LOG4J) {
443                            String[] log4jJars = pluginLibDir.list(
444                                    new GlobFilenameFilter("log4j*.jar"));
445    
446                            if ((log4jJars == null) || (log4jJars.length == 0)) {
447                                    String portalJarPath =
448                                            PortalUtil.getPortalLibDir() + "log4j.jar";
449    
450                                    FileUtil.copyFile(
451                                            portalJarPath, srcFile + "/WEB-INF/lib/log4j.jar", true);
452    
453                                    portalJarPath =
454                                            PortalUtil.getPortalLibDir() + "log4j-extras.jar";
455    
456                                    FileUtil.copyFile(
457                                            portalJarPath, srcFile + "/WEB-INF/lib/log4j-extras.jar",
458                                            true);
459                            }
460                    }
461            }
462    
463            @Override
464            public void copyProperties(File srcFile, PluginPackage pluginPackage)
465                    throws Exception {
466    
467                    if (PropsValues.AUTO_DEPLOY_COPY_COMMONS_LOGGING) {
468                            copyDependencyXml(
469                                    "logging.properties", srcFile + "/WEB-INF/classes");
470                    }
471    
472                    if (PropsValues.AUTO_DEPLOY_COPY_LOG4J) {
473                            copyDependencyXml("log4j.properties", srcFile + "/WEB-INF/classes");
474                    }
475    
476                    File servicePropertiesFile = new File(
477                            srcFile.getAbsolutePath() + "/WEB-INF/classes/service.properties");
478    
479                    if (!servicePropertiesFile.exists()) {
480                            return;
481                    }
482    
483                    File portletPropertiesFile = new File(
484                            srcFile.getAbsolutePath() +
485                                    "/WEB-INF/classes/portlet.properties");
486    
487                    if (portletPropertiesFile.exists()) {
488                            return;
489                    }
490    
491                    String pluginPackageName = null;
492    
493                    if (pluginPackage != null) {
494                            pluginPackageName = pluginPackage.getName();
495                    }
496                    else {
497                            pluginPackageName = srcFile.getName();
498                    }
499    
500                    FileUtil.write(
501                            portletPropertiesFile, "plugin.package.name=" + pluginPackageName);
502            }
503    
504            @Override
505            public void copyTlds(File srcFile, PluginPackage pluginPackage)
506                    throws Exception {
507    
508                    if (Validator.isNotNull(auiTaglibDTD)) {
509                            FileUtil.copyFile(
510                                    auiTaglibDTD, srcFile + "/WEB-INF/tld/aui.tld", true);
511                    }
512    
513                    if (Validator.isNotNull(portletTaglibDTD)) {
514                            FileUtil.copyFile(
515                                    portletTaglibDTD, srcFile + "/WEB-INF/tld/liferay-portlet.tld",
516                                    true);
517                    }
518    
519                    if (Validator.isNotNull(portletExtTaglibDTD)) {
520                            FileUtil.copyFile(
521                                    portletExtTaglibDTD,
522                                    srcFile + "/WEB-INF/tld/liferay-portlet-ext.tld", true);
523                    }
524    
525                    if (Validator.isNotNull(securityTaglibDTD)) {
526                            FileUtil.copyFile(
527                                    securityTaglibDTD,
528                                    srcFile + "/WEB-INF/tld/liferay-security.tld", true);
529                    }
530    
531                    if (Validator.isNotNull(themeTaglibDTD)) {
532                            FileUtil.copyFile(
533                                    themeTaglibDTD, srcFile + "/WEB-INF/tld/liferay-theme.tld",
534                                    true);
535                    }
536    
537                    if (Validator.isNotNull(uiTaglibDTD)) {
538                            FileUtil.copyFile(
539                                    uiTaglibDTD, srcFile + "/WEB-INF/tld/liferay-ui.tld", true);
540                    }
541    
542                    if (Validator.isNotNull(utilTaglibDTD)) {
543                            FileUtil.copyFile(
544                                    utilTaglibDTD, srcFile + "/WEB-INF/tld/liferay-util.tld", true);
545                    }
546            }
547    
548            public void copyTomcatContextXml(File targetDir) throws Exception {
549                    if (!appServerType.equals(ServerDetector.TOMCAT_ID)) {
550                            return;
551                    }
552    
553                    File targetFile = new File(targetDir, "META-INF/context.xml");
554    
555                    if (targetFile.exists()) {
556                            return;
557                    }
558    
559                    String contextPath = DeployUtil.getResourcePath("context.xml");
560    
561                    String content = FileUtil.read(contextPath);
562    
563                    if (!PropsValues.AUTO_DEPLOY_UNPACK_WAR) {
564                            content = StringUtil.replace(
565                                    content, "antiResourceLocking=\"true\"", StringPool.BLANK);
566                    }
567    
568                    FileUtil.write(targetFile, content);
569            }
570    
571            @Override
572            public void copyXmls(
573                            File srcFile, String displayName, PluginPackage pluginPackage)
574                    throws Exception {
575    
576                    if (appServerType.equals(ServerDetector.GERONIMO_ID)) {
577                            copyDependencyXml("geronimo-web.xml", srcFile + "/WEB-INF");
578                    }
579                    else if (appServerType.equals(ServerDetector.JBOSS_ID)) {
580                            if (ServerDetector.isJBoss5()) {
581                                    copyDependencyXml("jboss-web.xml", srcFile + "/WEB-INF");
582                            }
583                            else {
584                                    copyDependencyXml(
585                                            "jboss-deployment-structure.xml", srcFile + "/WEB-INF");
586                            }
587                    }
588                    else if (appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
589                            copyDependencyXml("weblogic.xml", srcFile + "/WEB-INF");
590                    }
591                    else if (appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
592                            copyDependencyXml("ibm-web-ext.xmi", srcFile + "/WEB-INF");
593                    }
594    
595                    copyDependencyXml("web.xml", srcFile + "/WEB-INF");
596            }
597    
598            public void deploy(String context) throws Exception {
599                    try {
600                            File baseDirFile = new File(baseDir);
601    
602                            File[] files = baseDirFile.listFiles();
603    
604                            if (files == null) {
605                                    return;
606                            }
607    
608                            files = FileUtil.sortFiles(files);
609    
610                            for (File srcFile : files) {
611                                    String fileName = srcFile.getName().toLowerCase();
612    
613                                    boolean deploy = false;
614    
615                                    if (fileName.endsWith(".war") || fileName.endsWith(".zip")) {
616                                            deploy = true;
617    
618                                            if (wars.size() > 0) {
619                                                    if (!wars.contains(srcFile.getName())) {
620                                                            deploy = false;
621                                                    }
622                                            }
623                                            else if (Validator.isNotNull(filePattern)) {
624                                                    if (!StringUtil.matchesIgnoreCase(
625                                                                    fileName, filePattern)) {
626    
627                                                            deploy = false;
628                                                    }
629                                            }
630                                    }
631    
632                                    if (deploy) {
633                                            AutoDeploymentContext autoDeploymentContext =
634                                                    new AutoDeploymentContext();
635    
636                                            autoDeploymentContext.setContext(context);
637                                            autoDeploymentContext.setFile(srcFile);
638    
639                                            deployFile(autoDeploymentContext);
640                                    }
641                            }
642                    }
643                    catch (Exception e) {
644                            _log.error(e, e);
645                    }
646            }
647    
648            public void deployDirectory(
649                            File srcFile, File mergeDir, File deployDir, String displayName,
650                            boolean overwrite, PluginPackage pluginPackage)
651                    throws Exception {
652    
653                    rewriteFiles(srcFile);
654    
655                    mergeDirectory(mergeDir, srcFile);
656    
657                    processPluginPackageProperties(srcFile, displayName, pluginPackage);
658    
659                    copyDtds(srcFile, pluginPackage);
660                    copyJars(srcFile, pluginPackage);
661                    copyProperties(srcFile, pluginPackage);
662                    copyTlds(srcFile, pluginPackage);
663                    copyXmls(srcFile, displayName, pluginPackage);
664                    copyPortalDependencies(srcFile);
665    
666                    updateGeronimoWebXml(srcFile, displayName, pluginPackage);
667    
668                    File webXml = new File(srcFile + "/WEB-INF/web.xml");
669    
670                    updateWebXml(webXml, srcFile, displayName, pluginPackage);
671    
672                    File extLibGlobalDir = new File(
673                            srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/global");
674    
675                    if (extLibGlobalDir.exists()) {
676                            File globalLibDir = new File(PortalUtil.getGlobalLibDir());
677    
678                            CopyTask.copyDirectory(
679                                    extLibGlobalDir, globalLibDir, "*.jar", StringPool.BLANK,
680                                    overwrite, true);
681                    }
682    
683                    File extLibPortalDir = new File(
684                            srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/portal");
685    
686                    if (extLibPortalDir.exists()) {
687                            File portalLibDir = new File(PortalUtil.getPortalLibDir());
688    
689                            CopyTask.copyDirectory(
690                                    extLibPortalDir, portalLibDir, "*.jar", StringPool.BLANK,
691                                    overwrite, true);
692                    }
693    
694                    if ((deployDir == null) || baseDir.equals(destDir)) {
695                            return;
696                    }
697    
698                    updateDeployDirectory(srcFile);
699    
700                    String excludes = StringPool.BLANK;
701    
702                    if (appServerType.equals(ServerDetector.JBOSS_ID)) {
703                            excludes += "**/WEB-INF/lib/log4j.jar,";
704                    }
705                    else if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
706                            String[] libs = FileUtil.listFiles(tomcatLibDir);
707    
708                            for (String lib : libs) {
709                                    excludes += "**/WEB-INF/lib/" + lib + ",";
710                            }
711    
712                            File contextXml = new File(srcFile + "/META-INF/context.xml");
713    
714                            if (contextXml.exists()) {
715                                    String content = FileUtil.read(contextXml);
716    
717                                    if (content.contains(_PORTAL_CLASS_LOADER)) {
718                                            excludes += "**/WEB-INF/lib/util-bridges.jar,";
719                                            excludes += "**/WEB-INF/lib/util-java.jar,";
720                                            excludes += "**/WEB-INF/lib/util-taglib.jar,";
721                                    }
722                            }
723    
724                            try {
725    
726                                    // LEP-2990
727    
728                                    Class.forName("javax.el.ELContext");
729    
730                                    excludes += "**/WEB-INF/lib/el-api.jar,";
731                            }
732                            catch (ClassNotFoundException cnfe) {
733                            }
734                    }
735    
736                    // LPS-11268
737    
738                    Properties properties = getPluginPackageProperties(srcFile);
739    
740                    if (properties != null) {
741                            String deployExcludes = properties.getProperty("deploy-excludes");
742    
743                            if (deployExcludes != null) {
744                                    excludes += deployExcludes.trim();
745    
746                                    if (!excludes.endsWith(",")) {
747                                            excludes += ",";
748                                    }
749                            }
750    
751                            deployExcludes = properties.getProperty(
752                                    "deploy-excludes-" + appServerType);
753    
754                            if (deployExcludes != null) {
755                                    excludes += deployExcludes.trim();
756    
757                                    if (!excludes.endsWith(",")) {
758                                            excludes += ",";
759                                    }
760                            }
761                    }
762    
763                    if (_log.isDebugEnabled()) {
764                            _log.debug("Excludes " + excludes);
765                    }
766    
767                    if (!unpackWar) {
768                            File tempDir = new File(
769                                    SystemProperties.get(SystemProperties.TMP_DIR) +
770                                            File.separator + Time.getTimestamp());
771    
772                            excludes += "**/WEB-INF/web.xml";
773    
774                            WarTask.war(srcFile, tempDir, excludes, webXml);
775    
776                            if (isJEEDeploymentEnabled()) {
777                                    File tempWarDir = new File(
778                                            tempDir.getParent(), deployDir.getName());
779    
780                                    if (tempWarDir.exists()) {
781                                            tempWarDir.delete();
782                                    }
783    
784                                    if (!tempDir.renameTo(tempWarDir)) {
785                                            tempWarDir = tempDir;
786                                    }
787    
788                                    DeploymentHandler deploymentHandler = getDeploymentHandler();
789    
790                                    deploymentHandler.deploy(tempWarDir, displayName);
791    
792                                    deploymentHandler.releaseDeploymentManager();
793    
794                                    DeleteTask.deleteDirectory(tempWarDir);
795                            }
796                            else {
797                                    if (!tempDir.renameTo(deployDir)) {
798                                            WarTask.war(srcFile, deployDir, excludes, webXml);
799                                    }
800    
801                                    DeleteTask.deleteDirectory(tempDir);
802                            }
803                    }
804                    else {
805    
806                            // The deployer might only copy files that have been modified.
807                            // However, the deployer always copies and overwrites web.xml after
808                            // the other files have been copied because application servers
809                            // usually detect that a WAR has been modified based on the web.xml
810                            // timestamp.
811    
812                            excludes += "**/WEB-INF/web.xml";
813    
814                            CopyTask.copyDirectory(
815                                    srcFile, deployDir, StringPool.BLANK, excludes, overwrite,
816                                    true);
817    
818                            CopyTask.copyDirectory(
819                                    srcFile, deployDir, "**/WEB-INF/web.xml", StringPool.BLANK,
820                                    true, false);
821    
822                            if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
823    
824                                    // See org.apache.catalina.startup.HostConfig to see how Tomcat
825                                    // checks to make sure that web.xml was modified 5 seconds after
826                                    // WEB-INF
827    
828                                    File deployWebXml = new File(deployDir + "/WEB-INF/web.xml");
829    
830                                    deployWebXml.setLastModified(
831                                            System.currentTimeMillis() + (Time.SECOND * 6));
832                            }
833                    }
834    
835                    if (appServerType.equals(ServerDetector.JETTY_ID)) {
836                            DeployUtil.redeployJetty(displayName);
837                    }
838            }
839    
840            public void deployDirectory(
841                            File srcFile, String displayName, boolean override,
842                            PluginPackage pluginPackage)
843                    throws Exception {
844    
845                    deployDirectory(
846                            srcFile, null, null, displayName, override, pluginPackage);
847            }
848    
849            public int deployFile(AutoDeploymentContext autoDeploymentContext)
850                    throws Exception {
851    
852                    File srcFile = autoDeploymentContext.getFile();
853    
854                    PluginPackage pluginPackage = readPluginPackage(srcFile);
855    
856                    if (_log.isInfoEnabled()) {
857                            _log.info("Deploying " + srcFile.getName());
858                    }
859    
860                    String autoDeploymentContextAppServerType =
861                            autoDeploymentContext.getAppServerType();
862    
863                    if (Validator.isNotNull(autoDeploymentContextAppServerType)) {
864                            appServerType = autoDeploymentContextAppServerType;
865                    }
866    
867                    String specifiedContext = autoDeploymentContext.getContext();
868    
869                    String displayName = specifiedContext;
870                    boolean overwrite = false;
871                    String preliminaryContext = specifiedContext;
872    
873                    // The order of priority of the context is: 1.) the specified context,
874                    // 2.) if the file name starts with DEPLOY_TO_PREFIX, use the file name
875                    // after the prefix, or 3.) the recommended deployment context as
876                    // specified in liferay-plugin-package.properties, or 4.) the file name.
877    
878                    if (Validator.isNull(specifiedContext) &&
879                            srcFile.getName().startsWith(DEPLOY_TO_PREFIX)) {
880    
881                            displayName = srcFile.getName().substring(
882                                    DEPLOY_TO_PREFIX.length(), srcFile.getName().length() - 4);
883    
884                            overwrite = true;
885                            preliminaryContext = displayName;
886                    }
887    
888                    if (preliminaryContext == null) {
889                            preliminaryContext = getDisplayName(srcFile);
890                    }
891    
892                    if (pluginPackage != null) {
893                            if (!PluginPackageUtil.isCurrentVersionSupported(
894                                            pluginPackage.getLiferayVersions())) {
895    
896                                    throw new AutoDeployException(
897                                            srcFile.getName() +
898                                                    " does not support this version of Liferay");
899                            }
900    
901                            if (displayName == null) {
902                                    displayName = pluginPackage.getRecommendedDeploymentContext();
903                            }
904    
905                            if (Validator.isNull(displayName)) {
906                                    displayName = getDisplayName(srcFile);
907                            }
908    
909                            pluginPackage.setContext(displayName);
910    
911                            PluginPackageUtil.updateInstallingPluginPackage(
912                                    preliminaryContext, pluginPackage);
913                    }
914    
915                    String deployDir = null;
916    
917                    if (Validator.isNotNull(displayName)) {
918                            deployDir = displayName + ".war";
919                    }
920                    else {
921                            deployDir = srcFile.getName();
922                            displayName = getDisplayName(srcFile);
923                    }
924    
925                    if (appServerType.equals(ServerDetector.JBOSS_ID)) {
926                            deployDir = jbossPrefix + deployDir;
927                    }
928                    else if (appServerType.equals(ServerDetector.GERONIMO_ID) ||
929                                     appServerType.equals(ServerDetector.GLASSFISH_ID) ||
930                                     appServerType.equals(ServerDetector.JETTY_ID) ||
931                                     appServerType.equals(ServerDetector.JONAS_ID) ||
932                                     appServerType.equals(ServerDetector.OC4J_ID) ||
933                                     appServerType.equals(ServerDetector.RESIN_ID) ||
934                                     appServerType.equals(ServerDetector.TOMCAT_ID) ||
935                                     appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
936    
937                            if (unpackWar) {
938                                    deployDir = deployDir.substring(0, deployDir.length() - 4);
939                            }
940                    }
941    
942                    String destDir = this.destDir;
943    
944                    if (autoDeploymentContext.getDestDir() != null) {
945                            destDir = autoDeploymentContext.getDestDir();
946                    }
947    
948                    File deployDirFile = new File(destDir + "/" + deployDir);
949    
950                    try {
951                            PluginPackage previousPluginPackage = readPluginPackage(
952                                    deployDirFile);
953    
954                            if ((pluginPackage != null) && (previousPluginPackage != null)) {
955                                    String name = pluginPackage.getName();
956                                    String previousVersion = previousPluginPackage.getVersion();
957                                    String version = pluginPackage.getVersion();
958    
959                                    if (_log.isInfoEnabled()) {
960                                            _log.info(
961                                                    "Updating " + name + " from version " +
962                                                            previousVersion + " to version " + version);
963                                    }
964    
965                                    if (pluginPackage.isPreviousVersionThan(
966                                                    previousPluginPackage)) {
967    
968                                            if (_log.isInfoEnabled()) {
969                                                    _log.info(
970                                                            "Not updating " + name + " because version " +
971                                                                    previousVersion + " is newer than version " +
972                                                                            version);
973                                            }
974    
975                                            return AutoDeployer.CODE_SKIP_NEWER_VERSION;
976                                    }
977    
978                                    overwrite = true;
979                            }
980    
981                            File mergeDirFile = new File(
982                                    srcFile.getParent() + "/merge/" + srcFile.getName());
983    
984                            if (srcFile.isDirectory()) {
985                                    deployDirectory(
986                                            srcFile, mergeDirFile, deployDirFile, displayName,
987                                            overwrite, pluginPackage);
988                            }
989                            else {
990                                    boolean deployed = deployFile(
991                                            srcFile, mergeDirFile, deployDirFile, displayName,
992                                            overwrite, pluginPackage);
993    
994                                    if (!deployed) {
995                                            String context = preliminaryContext;
996    
997                                            if (pluginPackage != null) {
998                                                    context = pluginPackage.getContext();
999                                            }
1000    
1001                                            PluginPackageUtil.endPluginPackageInstallation(context);
1002                                    }
1003                                    else {
1004                                            postDeploy(destDir, deployDir);
1005                                    }
1006                            }
1007    
1008                            return AutoDeployer.CODE_DEFAULT;
1009                    }
1010                    catch (Exception e) {
1011                            if (pluginPackage != null) {
1012                                    PluginPackageUtil.endPluginPackageInstallation(
1013                                            pluginPackage.getContext());
1014                            }
1015    
1016                            throw e;
1017                    }
1018            }
1019    
1020            public boolean deployFile(
1021                            File srcFile, File mergeDir, File deployDir, String displayName,
1022                            boolean overwrite, PluginPackage pluginPackage)
1023                    throws Exception {
1024    
1025                    boolean undeployOnRedeploy = false;
1026    
1027                    try {
1028                            undeployOnRedeploy = PrefsPropsUtil.getBoolean(
1029                                    PropsKeys.HOT_UNDEPLOY_ON_REDEPLOY,
1030                                    PropsValues.HOT_UNDEPLOY_ON_REDEPLOY);
1031                    }
1032                    catch (Exception e) {
1033    
1034                            // This will only happen when running the deploy tool in Ant in the
1035                            // classical way where the WAR file is actually massaged and
1036                            // packaged.
1037    
1038                    }
1039    
1040                    if (undeployOnRedeploy) {
1041                            DeployUtil.undeploy(appServerType, deployDir);
1042                    }
1043    
1044                    if (!overwrite && UpToDateTask.isUpToDate(srcFile, deployDir)) {
1045                            if (_log.isInfoEnabled()) {
1046                                    _log.info(deployDir + " is already up to date");
1047                            }
1048    
1049                            return false;
1050                    }
1051    
1052                    File tempDir = new File(
1053                            SystemProperties.get(SystemProperties.TMP_DIR) + File.separator +
1054                                    Time.getTimestamp());
1055    
1056                    ExpandTask.expand(srcFile, tempDir);
1057    
1058                    deployDirectory(
1059                            tempDir, mergeDir, deployDir, displayName, overwrite,
1060                            pluginPackage);
1061    
1062                    DeleteTask.deleteDirectory(tempDir);
1063    
1064                    return true;
1065            }
1066    
1067            public String downloadJar(String jar) throws Exception {
1068                    String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
1069    
1070                    File file = new File(
1071                            tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" + jar);
1072    
1073                    if (!file.exists()) {
1074                            synchronized (this) {
1075                                    String url = PropsUtil.get(
1076                                            PropsKeys.LIBRARY_DOWNLOAD_URL + jar);
1077    
1078                                    if (_log.isInfoEnabled()) {
1079                                            _log.info("Downloading library from " + url);
1080                                    }
1081    
1082                                    byte[] bytes = HttpUtil.URLtoByteArray(url);
1083    
1084                                    FileUtil.write(file, bytes);
1085                            }
1086                    }
1087    
1088                    return FileUtil.getAbsolutePath(file);
1089            }
1090    
1091            public String fixPortalDependencyJar(String portalJar) {
1092                    if (portalJar.equals("antlr.jar")) {
1093                            portalJar = "antlr2.jar";
1094                    }
1095    
1096                    return portalJar;
1097            }
1098    
1099            public DeploymentHandler getDeploymentHandler() {
1100                    String prefix = "auto.deploy." + ServerDetector.getServerId() + ".jee.";
1101    
1102                    String dmId = PropsUtil.get(prefix + "dm.id");
1103                    String dmUser = PropsUtil.get(prefix + "dm.user");
1104                    String dmPassword = PropsUtil.get(prefix + "dm.passwd");
1105                    String dfClassName = PropsUtil.get(prefix + "df.classname");
1106    
1107                    return new DeploymentHandler(dmId, dmUser, dmPassword, dfClassName);
1108            }
1109    
1110            public String getDisplayName(File srcFile) {
1111                    String displayName = srcFile.getName();
1112    
1113                    if (StringUtil.endsWith(displayName, ".war") ||
1114                            StringUtil.endsWith(displayName, ".xml")) {
1115    
1116                            displayName = displayName.substring(0, displayName.length() - 4);
1117                    }
1118    
1119                    if (appServerType.equals(ServerDetector.JBOSS_ID) &&
1120                            Validator.isNotNull(jbossPrefix) &&
1121                            displayName.startsWith(jbossPrefix)) {
1122    
1123                            displayName = displayName.substring(1);
1124                    }
1125    
1126                    return displayName;
1127            }
1128    
1129            public String getDynamicResourceServletContent() {
1130                    StringBundler sb = new StringBundler();
1131    
1132                    sb.append("<servlet>");
1133                    sb.append("<servlet-name>");
1134                    sb.append("Dynamic Resource Servlet");
1135                    sb.append("</servlet-name>");
1136                    sb.append("<servlet-class>");
1137                    sb.append(PortalClassLoaderServlet.class.getName());
1138                    sb.append("</servlet-class>");
1139                    sb.append("<init-param>");
1140                    sb.append("<param-name>");
1141                    sb.append("servlet-class");
1142                    sb.append("</param-name>");
1143                    sb.append("<param-value>");
1144                    sb.append(DynamicResourceServlet.class.getName());
1145                    sb.append("</param-value>");
1146                    sb.append("</init-param>");
1147                    sb.append("<load-on-startup>1</load-on-startup>");
1148                    sb.append("</servlet>");
1149    
1150                    for (String allowedPath :
1151                                    PropsValues.DYNAMIC_RESOURCE_SERVLET_ALLOWED_PATHS) {
1152    
1153                            sb.append("<servlet-mapping>");
1154                            sb.append("<servlet-name>");
1155                            sb.append("Dynamic Resource Servlet");
1156                            sb.append("</servlet-name>");
1157                            sb.append("<url-pattern>");
1158                            sb.append(allowedPath);
1159    
1160                            if (!allowedPath.endsWith(StringPool.SLASH)) {
1161                                    sb.append(StringPool.SLASH);
1162                            }
1163    
1164                            sb.append(StringPool.STAR);
1165                            sb.append("</url-pattern>");
1166                            sb.append("</servlet-mapping>");
1167                    }
1168    
1169                    return sb.toString();
1170            }
1171    
1172            public String getExtraContent(
1173                            double webXmlVersion, File srcFile, String displayName)
1174                    throws Exception {
1175    
1176                    StringBundler sb = new StringBundler();
1177    
1178                    sb.append("<display-name>");
1179                    sb.append(displayName);
1180                    sb.append("</display-name>");
1181    
1182                    if (webXmlVersion < 2.4) {
1183                            sb.append("<context-param>");
1184                            sb.append("<param-name>liferay-invoker-enabled</param-name>");
1185                            sb.append("<param-value>false</param-value>");
1186                            sb.append("</context-param>");
1187                    }
1188    
1189                    sb.append("<listener>");
1190                    sb.append("<listener-class>");
1191                    sb.append(SerializableSessionAttributeListener.class.getName());
1192                    sb.append("</listener-class>");
1193                    sb.append("</listener>");
1194    
1195                    sb.append(getDynamicResourceServletContent());
1196    
1197                    File serverConfigWsdd = new File(
1198                            srcFile + "/WEB-INF/server-config.wsdd");
1199    
1200                    if (serverConfigWsdd.exists()) {
1201                            File webXml = new File(srcFile + "/WEB-INF/web.xml");
1202    
1203                            String content = FileUtil.read(webXml);
1204    
1205                            if (!content.contains("axis.servicesPath")) {
1206                                    String remotingContent = FileUtil.read(
1207                                            DeployUtil.getResourcePath("remoting-web.xml"));
1208    
1209                                    sb.append(remotingContent);
1210                            }
1211                    }
1212    
1213                    boolean hasTaglib = false;
1214    
1215                    if (Validator.isNotNull(auiTaglibDTD) ||
1216                            Validator.isNotNull(portletTaglibDTD) ||
1217                            Validator.isNotNull(portletExtTaglibDTD) ||
1218                            Validator.isNotNull(securityTaglibDTD) ||
1219                            Validator.isNotNull(themeTaglibDTD) ||
1220                            Validator.isNotNull(uiTaglibDTD) ||
1221                            Validator.isNotNull(utilTaglibDTD)) {
1222    
1223                            hasTaglib = true;
1224                    }
1225    
1226                    if (hasTaglib && (webXmlVersion > 2.3)) {
1227                            sb.append("<jsp-config>");
1228                    }
1229    
1230                    if (Validator.isNotNull(auiTaglibDTD)) {
1231                            sb.append("<taglib>");
1232                            sb.append("<taglib-uri>http://liferay.com/tld/aui</taglib-uri>");
1233                            sb.append("<taglib-location>");
1234                            sb.append("/WEB-INF/tld/aui.tld");
1235                            sb.append("</taglib-location>");
1236                            sb.append("</taglib>");
1237                    }
1238    
1239                    if (Validator.isNotNull(portletTaglibDTD)) {
1240                            sb.append("<taglib>");
1241                            sb.append(
1242                                    "<taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>");
1243                            sb.append("<taglib-location>");
1244                            sb.append("/WEB-INF/tld/liferay-portlet.tld");
1245                            sb.append("</taglib-location>");
1246                            sb.append("</taglib>");
1247                    }
1248    
1249                    if (Validator.isNotNull(portletExtTaglibDTD)) {
1250                            sb.append("<taglib>");
1251                            sb.append("<taglib-uri>");
1252                            sb.append("http://liferay.com/tld/portlet");
1253                            sb.append("</taglib-uri>");
1254                            sb.append("<taglib-location>");
1255                            sb.append("/WEB-INF/tld/liferay-portlet-ext.tld");
1256                            sb.append("</taglib-location>");
1257                            sb.append("</taglib>");
1258                    }
1259    
1260                    if (Validator.isNotNull(securityTaglibDTD)) {
1261                            sb.append("<taglib>");
1262                            sb.append("<taglib-uri>");
1263                            sb.append("http://liferay.com/tld/security");
1264                            sb.append("</taglib-uri>");
1265                            sb.append("<taglib-location>");
1266                            sb.append("/WEB-INF/tld/liferay-security.tld");
1267                            sb.append("</taglib-location>");
1268                            sb.append("</taglib>");
1269                    }
1270    
1271                    if (Validator.isNotNull(themeTaglibDTD)) {
1272                            sb.append("<taglib>");
1273                            sb.append("<taglib-uri>http://liferay.com/tld/theme</taglib-uri>");
1274                            sb.append("<taglib-location>");
1275                            sb.append("/WEB-INF/tld/liferay-theme.tld");
1276                            sb.append("</taglib-location>");
1277                            sb.append("</taglib>");
1278                    }
1279    
1280                    if (Validator.isNotNull(uiTaglibDTD)) {
1281                            sb.append("<taglib>");
1282                            sb.append("<taglib-uri>http://liferay.com/tld/ui</taglib-uri>");
1283                            sb.append("<taglib-location>");
1284                            sb.append("/WEB-INF/tld/liferay-ui.tld");
1285                            sb.append("</taglib-location>");
1286                            sb.append("</taglib>");
1287                    }
1288    
1289                    if (Validator.isNotNull(utilTaglibDTD)) {
1290                            sb.append("<taglib>");
1291                            sb.append("<taglib-uri>http://liferay.com/tld/util</taglib-uri>");
1292                            sb.append("<taglib-location>");
1293                            sb.append("/WEB-INF/tld/liferay-util.tld");
1294                            sb.append("</taglib-location>");
1295                            sb.append("</taglib>");
1296                    }
1297    
1298                    if (hasTaglib && (webXmlVersion > 2.3)) {
1299                            sb.append("</jsp-config>");
1300                    }
1301    
1302                    return sb.toString();
1303            }
1304    
1305            public String getExtraFiltersContent(double webXmlVersion, File srcFile)
1306                    throws Exception {
1307    
1308                    return getSessionFiltersContent();
1309            }
1310    
1311            public String getIgnoreFiltersContent(File srcFile) throws Exception {
1312                    boolean ignoreFiltersEnabled = true;
1313    
1314                    Properties properties = getPluginPackageProperties(srcFile);
1315    
1316                    if (properties != null) {
1317                            ignoreFiltersEnabled = GetterUtil.getBoolean(
1318                                    properties.getProperty("ignore-filters-enabled"), true);
1319                    }
1320    
1321                    if (ignoreFiltersEnabled) {
1322                            String ignoreFiltersContent = FileUtil.read(
1323                                    DeployUtil.getResourcePath("ignore-filters-web.xml"));
1324    
1325                            return ignoreFiltersContent;
1326                    }
1327                    else {
1328                            return StringPool.BLANK;
1329                    }
1330            }
1331    
1332            public String getInvokerFilterContent() {
1333                    StringBundler sb = new StringBundler(4);
1334    
1335                    sb.append(getInvokerFilterContent("ERROR"));
1336                    sb.append(getInvokerFilterContent("FORWARD"));
1337                    sb.append(getInvokerFilterContent("INCLUDE"));
1338                    sb.append(getInvokerFilterContent("REQUEST"));
1339    
1340                    return sb.toString();
1341            }
1342    
1343            public String getInvokerFilterContent(String dispatcher) {
1344                    StringBundler sb = new StringBundler(23);
1345    
1346                    sb.append("<filter>");
1347                    sb.append("<filter-name>Invoker Filter - ");
1348                    sb.append(dispatcher);
1349                    sb.append("</filter-name>");
1350                    sb.append("<filter-class>");
1351                    sb.append(InvokerFilter.class.getName());
1352                    sb.append("</filter-class>");
1353                    sb.append("<init-param>");
1354                    sb.append("<param-name>dispatcher</param-name>");
1355                    sb.append("<param-value>");
1356                    sb.append(dispatcher);
1357                    sb.append("</param-value>");
1358                    sb.append("</init-param>");
1359                    sb.append("</filter>");
1360    
1361                    sb.append("<filter-mapping>");
1362                    sb.append("<filter-name>Invoker Filter - ");
1363                    sb.append(dispatcher);
1364                    sb.append("</filter-name>");
1365                    sb.append("<url-pattern>/*</url-pattern>");
1366                    sb.append("<dispatcher>");
1367                    sb.append(dispatcher);
1368                    sb.append("</dispatcher>");
1369                    sb.append("</filter-mapping>");
1370    
1371                    return sb.toString();
1372            }
1373    
1374            public String getPluginPackageLicensesXml(List<License> licenses) {
1375                    if (licenses.isEmpty()) {
1376                            return StringPool.BLANK;
1377                    }
1378    
1379                    StringBundler sb = new StringBundler(5 * licenses.size() + 2);
1380    
1381                    for (int i = 0; i < licenses.size(); i++) {
1382                            License license = licenses.get(i);
1383    
1384                            if (i == 0) {
1385                                    sb.append("\r\n");
1386                            }
1387    
1388                            sb.append("\t\t<license osi-approved=\"");
1389                            sb.append(license.isOsiApproved());
1390                            sb.append("\">");
1391                            sb.append(license.getName());
1392                            sb.append("</license>\r\n");
1393    
1394                            if ((i + 1) == licenses.size()) {
1395                                    sb.append("\t");
1396                            }
1397                    }
1398    
1399                    return sb.toString();
1400            }
1401    
1402            public String getPluginPackageLiferayVersionsXml(
1403                    List<String> liferayVersions) {
1404    
1405                    if (liferayVersions.isEmpty()) {
1406                            return StringPool.BLANK;
1407                    }
1408    
1409                    StringBundler sb = new StringBundler(liferayVersions.size() * 3 + 2);
1410    
1411                    for (int i = 0; i < liferayVersions.size(); i++) {
1412                            String liferayVersion = liferayVersions.get(i);
1413    
1414                            if (i == 0) {
1415                                    sb.append("\r\n");
1416                            }
1417    
1418                            sb.append("\t\t<liferay-version>");
1419                            sb.append(liferayVersion);
1420                            sb.append("</liferay-version>\r\n");
1421    
1422                            if ((i + 1) == liferayVersions.size()) {
1423                                    sb.append("\t");
1424                            }
1425                    }
1426    
1427                    return sb.toString();
1428            }
1429    
1430            public Properties getPluginPackageProperties(File srcFile)
1431                    throws Exception {
1432    
1433                    File propertiesFile = new File(
1434                            srcFile + "/WEB-INF/liferay-plugin-package.properties");
1435    
1436                    if (!propertiesFile.exists()) {
1437                            return null;
1438                    }
1439    
1440                    String propertiesString = FileUtil.read(propertiesFile);
1441    
1442                    return PropertiesUtil.load(propertiesString);
1443            }
1444    
1445            public String getPluginPackageRequiredDeploymentContextsXml(
1446                    List<String> requiredDeploymentContexts) {
1447    
1448                    if (requiredDeploymentContexts.isEmpty()) {
1449                            return StringPool.BLANK;
1450                    }
1451    
1452                    StringBundler sb = new StringBundler(
1453                            requiredDeploymentContexts.size() * 3 + 2);
1454    
1455                    for (int i = 0; i < requiredDeploymentContexts.size(); i++) {
1456                            String requiredDeploymentContext = requiredDeploymentContexts.get(
1457                                    i);
1458    
1459                            if (i == 0) {
1460                                    sb.append("\r\n");
1461                            }
1462    
1463                            sb.append("\t\t<required-deployment-context>");
1464                            sb.append(requiredDeploymentContext);
1465                            sb.append("</required-deployment-context>\r\n");
1466    
1467                            if ((i + 1) == requiredDeploymentContexts.size()) {
1468                                    sb.append("\t");
1469                            }
1470                    }
1471    
1472                    return sb.toString();
1473            }
1474    
1475            public String getPluginPackageTagsXml(List<String> tags) {
1476                    if (tags.isEmpty()) {
1477                            return StringPool.BLANK;
1478                    }
1479    
1480                    StringBundler sb = new StringBundler(tags.size() * 3 + 2);
1481    
1482                    for (int i = 0; i < tags.size(); i++) {
1483                            String tag = tags.get(i);
1484    
1485                            if (i == 0) {
1486                                    sb.append("\r\n");
1487                            }
1488    
1489                            sb.append("\t\t<tag>");
1490                            sb.append(tag);
1491                            sb.append("</tag>\r\n");
1492    
1493                            if ((i + 1) == tags.size()) {
1494                                    sb.append("\t");
1495                            }
1496                    }
1497    
1498                    return sb.toString();
1499            }
1500    
1501            public Map<String, String> getPluginPackageXmlFilterMap(
1502                    PluginPackage pluginPackage) {
1503    
1504                    List<String> pluginTypes = pluginPackage.getTypes();
1505    
1506                    String pluginType = pluginTypes.get(0);
1507    
1508                    if (!pluginType.equals(getPluginType())) {
1509                            return null;
1510                    }
1511    
1512                    Map<String, String> filterMap = new HashMap<String, String>();
1513    
1514                    filterMap.put("author", pluginPackage.getAuthor());
1515                    filterMap.put("change_log", pluginPackage.getChangeLog());
1516                    filterMap.put(
1517                            "licenses",
1518                            getPluginPackageLicensesXml(pluginPackage.getLicenses()));
1519                    filterMap.put(
1520                            "liferay_versions",
1521                            getPluginPackageLiferayVersionsXml(
1522                                    pluginPackage.getLiferayVersions()));
1523                    filterMap.put("long_description", pluginPackage.getLongDescription());
1524                    filterMap.put("module_artifact_id", pluginPackage.getArtifactId());
1525                    filterMap.put("module_group_id", pluginPackage.getGroupId());
1526                    filterMap.put("module_version", pluginPackage.getVersion());
1527                    filterMap.put("page_url", pluginPackage.getPageURL());
1528                    filterMap.put("plugin_name", pluginPackage.getName());
1529                    filterMap.put("plugin_type", pluginType);
1530                    filterMap.put(
1531                            "plugin_type_name",
1532                            TextFormatter.format(pluginType, TextFormatter.J));
1533                    filterMap.put(
1534                            "recommended_deployment_context",
1535                            pluginPackage.getRecommendedDeploymentContext());
1536                    filterMap.put(
1537                            "required_deployment_contexts",
1538                            getPluginPackageRequiredDeploymentContextsXml(
1539                                    pluginPackage.getRequiredDeploymentContexts()));
1540                    filterMap.put("short_description", pluginPackage.getShortDescription());
1541                    filterMap.put("tags", getPluginPackageTagsXml(pluginPackage.getTags()));
1542    
1543                    return filterMap;
1544            }
1545    
1546            public String getPluginType() {
1547                    return null;
1548            }
1549    
1550            public String getServletContextIncludeFiltersContent(
1551                            double webXmlVersion, File srcFile)
1552                    throws Exception {
1553    
1554                    if (webXmlVersion < 2.4) {
1555                            return StringPool.BLANK;
1556                    }
1557    
1558                    Properties properties = getPluginPackageProperties(srcFile);
1559    
1560                    if (properties == null) {
1561                            return StringPool.BLANK;
1562                    }
1563    
1564                    if (!GetterUtil.getBoolean(
1565                                    properties.getProperty(
1566                                            "servlet-context-include-filters-enabled"), true)) {
1567    
1568                            return StringPool.BLANK;
1569                    }
1570    
1571                    return FileUtil.read(
1572                            DeployUtil.getResourcePath(
1573                                    "servlet-context-include-filters-web.xml"));
1574            }
1575    
1576            public String getSessionFiltersContent() throws Exception {
1577                    String sessionFiltersContent = FileUtil.read(
1578                            DeployUtil.getResourcePath("session-filters-web.xml"));
1579    
1580                    return sessionFiltersContent;
1581            }
1582    
1583            public String getSpeedFiltersContent(File srcFile) throws Exception {
1584                    boolean speedFiltersEnabled = true;
1585    
1586                    Properties properties = getPluginPackageProperties(srcFile);
1587    
1588                    if (properties != null) {
1589                            speedFiltersEnabled = GetterUtil.getBoolean(
1590                                    properties.getProperty("speed-filters-enabled"), true);
1591                    }
1592    
1593                    if (speedFiltersEnabled) {
1594                            String speedFiltersContent = FileUtil.read(
1595                                    DeployUtil.getResourcePath("speed-filters-web.xml"));
1596    
1597                            return speedFiltersContent;
1598                    }
1599                    else {
1600                            return StringPool.BLANK;
1601                    }
1602            }
1603    
1604            public boolean isJEEDeploymentEnabled() {
1605                    return GetterUtil.getBoolean(
1606                            PropsUtil.get(
1607                                    "auto.deploy." + ServerDetector.getServerId() +
1608                                            ".jee.deployment.enabled"));
1609            }
1610    
1611            public void mergeDirectory(File mergeDir, File targetDir) {
1612                    if ((mergeDir == null) || !mergeDir.exists()) {
1613                            return;
1614                    }
1615    
1616                    CopyTask.copyDirectory(mergeDir, targetDir, null, null, true, false);
1617            }
1618    
1619            public void postDeploy(String destDir, String deployDir) throws Exception {
1620                    if (appServerType.equals(ServerDetector.GLASSFISH_ID)) {
1621                            postDeployGlassfish(destDir, deployDir);
1622                    }
1623                    else if (appServerType.equals(ServerDetector.JBOSS_ID)) {
1624                            postDeployJBoss(destDir, deployDir);
1625                    }
1626                    else if (appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
1627                            postDeployWebSphere(destDir, deployDir);
1628                    }
1629            }
1630    
1631            public void postDeployGlassfish(String destDir, String deployDir)
1632                    throws Exception {
1633    
1634                    FileUtil.delete(destDir + "/.autodeploystatus/" + deployDir);
1635            }
1636    
1637            public void postDeployJBoss(String destDir, String deployDir)
1638                    throws Exception {
1639    
1640                    FileUtil.write(
1641                            destDir + "/" + deployDir + ".dodeploy", StringPool.BLANK);
1642            }
1643    
1644            public void postDeployWebSphere(String destDir, String deployDir)
1645                    throws Exception {
1646    
1647                    if (Validator.isNull(
1648                                    PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_MANAGER_QUERY)) {
1649    
1650                            if (_log.isInfoEnabled()) {
1651                                    StringBundler sb = new StringBundler();
1652    
1653                                    sb.append("Do not install the plugin with wsadmin since the ");
1654                                    sb.append("property \"");
1655                                    sb.append(
1656                                            PropsKeys.AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_MANAGER_QUERY);
1657                                    sb.append("\"is not configured");
1658    
1659                                    _log.info(sb.toString());
1660                            }
1661    
1662                            return;
1663                    }
1664    
1665                    String wsadminContent = FileUtil.read(
1666                            DeployUtil.getResourcePath("wsadmin.py"));
1667    
1668                    String adminAppListOptions =
1669                            PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_MANAGER_LIST_OPTIONS;
1670    
1671                    if (Validator.isNotNull(adminAppListOptions)) {
1672                            adminAppListOptions =
1673                                    StringPool.APOSTROPHE + adminAppListOptions +
1674                                            StringPool.APOSTROPHE;
1675                    }
1676    
1677                    wsadminContent = StringUtil.replace(
1678                            wsadminContent,
1679                            new String[] {
1680                                    "${auto.deploy.websphere.wsadmin.app.manager.install.options}",
1681                                    "${auto.deploy.websphere.wsadmin.app.manager.list.options}",
1682                                    "${auto.deploy.websphere.wsadmin.app.manager.query}",
1683                                    "${auto.deploy.websphere.wsadmin.app.manager.update.options}"
1684                            },
1685                            new String[] {
1686                                    PropsValues.
1687                                            AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_MANAGER_INSTALL_OPTIONS,
1688                                    adminAppListOptions,
1689                                    PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_MANAGER_QUERY,
1690                                    PropsValues.
1691                                            AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_MANAGER_UPDATE_OPTIONS
1692                            });
1693    
1694                    String pluginServletContextName = deployDir.substring(
1695                            0, deployDir.length() - 4);
1696    
1697                    String pluginApplicationName = pluginServletContextName;
1698    
1699                    if (Validator.isNotNull(
1700                                    PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_NAME_SUFFIX)) {
1701    
1702                            pluginApplicationName +=
1703                                    PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_APP_NAME_SUFFIX;
1704                    }
1705    
1706                    wsadminContent = StringUtil.replace(
1707                            wsadminContent,
1708                            new String[] {
1709                                    "${auto.deploy.dest.dir}",
1710                                    "${auto.deploy.websphere.wsadmin.app.name}",
1711                                    "${plugin.servlet.context.name}"
1712                            },
1713                            new String[] {
1714                                    destDir, pluginApplicationName, pluginServletContextName
1715                            });
1716    
1717                    String wsadminFileName = FileUtil.createTempFileName("py");
1718    
1719                    FileUtil.write(wsadminFileName, wsadminContent);
1720    
1721                    String webSphereHome = System.getenv("WAS_HOME");
1722    
1723                    List<String> commands = new ArrayList<String>();
1724    
1725                    if (OSDetector.isWindows()) {
1726                            commands.add(webSphereHome + "\\bin\\wsadmin.bat");
1727                    }
1728                    else {
1729                            commands.add(webSphereHome + "/bin/wsadmin.sh");
1730                    }
1731    
1732                    if (Validator.isNotNull(
1733                                    PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_PROPERTIES_FILE)) {
1734    
1735                            commands.add("-p");
1736                            commands.add(
1737                                    PropsValues.AUTO_DEPLOY_WEBSPHERE_WSADMIN_PROPERTIES_FILE);
1738                    }
1739    
1740                    commands.add("-f");
1741                    commands.add(wsadminFileName);
1742    
1743                    if (_log.isInfoEnabled()) {
1744                            StringBundler sb = new StringBundler(commands.size() + 1);
1745    
1746                            sb.append("Installing plugin by executing");
1747    
1748                            for (String command : commands) {
1749                                    sb.append(StringPool.SPACE);
1750                                    sb.append(command);
1751                            }
1752    
1753                            _log.info(sb.toString());
1754                    }
1755    
1756                    ProcessBuilder processBuilder = new ProcessBuilder(commands);
1757    
1758                    processBuilder.redirectErrorStream(true);
1759    
1760                    Process process = processBuilder.start();
1761    
1762                    if (_log.isInfoEnabled()) {
1763                            InputStream inputStream = process.getInputStream();
1764    
1765                            String output = StringUtil.read(inputStream);
1766    
1767                            for (String line : StringUtil.split(output, CharPool.NEW_LINE)) {
1768                                    _log.info("Process output: " + line);
1769                            }
1770    
1771                            int exitValue = process.exitValue();
1772    
1773                            if (exitValue == 0) {
1774                                    _log.info(
1775                                            "Successfully executed command with an exit value of " +
1776                                                    exitValue);
1777                            }
1778                            else {
1779                                    _log.info(
1780                                            "Unsuccessfully executed command with an exit value of " +
1781                                                    exitValue);
1782                            }
1783                    }
1784    
1785                    FileUtil.delete(wsadminFileName);
1786            }
1787    
1788            @Override
1789            public Map<String, String> processPluginPackageProperties(
1790                            File srcFile, String displayName, PluginPackage pluginPackage)
1791                    throws Exception {
1792    
1793                    if (pluginPackage == null) {
1794                            return null;
1795                    }
1796    
1797                    Properties properties = getPluginPackageProperties(srcFile);
1798    
1799                    if ((properties == null) || (properties.size() == 0)) {
1800                            return null;
1801                    }
1802    
1803                    Map<String, String> filterMap = getPluginPackageXmlFilterMap(
1804                            pluginPackage);
1805    
1806                    if (filterMap == null) {
1807                            return null;
1808                    }
1809    
1810                    copyDependencyXml(
1811                            "liferay-plugin-package.xml", srcFile + "/WEB-INF", filterMap,
1812                            true);
1813    
1814                    return filterMap;
1815            }
1816    
1817            /**
1818             * @see PluginPackageUtil#_readPluginPackageServletContext(
1819             *      javax.servlet.ServletContext)
1820             */
1821            @Override
1822            public PluginPackage readPluginPackage(File file) {
1823                    if (!file.exists()) {
1824                            return null;
1825                    }
1826    
1827                    InputStream is = null;
1828                    ZipFile zipFile = null;
1829    
1830                    try {
1831                            boolean parseProps = false;
1832    
1833                            if (file.isDirectory()) {
1834                                    String path = file.getPath();
1835    
1836                                    File pluginPackageXmlFile = new File(
1837                                            file.getParent() + "/merge/" + file.getName() +
1838                                                    "/WEB-INF/liferay-plugin-package.xml");
1839    
1840                                    if (pluginPackageXmlFile.exists()) {
1841                                            is = new FileInputStream(pluginPackageXmlFile);
1842                                    }
1843                                    else {
1844                                            pluginPackageXmlFile = new File(
1845                                                    path + "/WEB-INF/liferay-plugin-package.xml");
1846    
1847                                            if (pluginPackageXmlFile.exists()) {
1848                                                    is = new FileInputStream(pluginPackageXmlFile);
1849                                            }
1850                                    }
1851    
1852                                    File pluginPackagePropertiesFile = new File(
1853                                            file.getParent() + "/merge/" + file.getName() +
1854                                                    "/WEB-INF/liferay-plugin-package.properties");
1855    
1856                                    if ((is == null) && pluginPackagePropertiesFile.exists()) {
1857                                            is = new FileInputStream(pluginPackagePropertiesFile);
1858    
1859                                            parseProps = true;
1860                                    }
1861                                    else {
1862                                            pluginPackagePropertiesFile = new File(
1863                                                    path + "/WEB-INF/liferay-plugin-package.properties");
1864    
1865                                            if ((is == null) && pluginPackagePropertiesFile.exists()) {
1866                                                    is = new FileInputStream(pluginPackagePropertiesFile);
1867    
1868                                                    parseProps = true;
1869                                            }
1870                                    }
1871                            }
1872                            else {
1873                                    zipFile = new ZipFile(file);
1874    
1875                                    File pluginPackageXmlFile = new File(
1876                                            file.getParent() + "/merge/" + file.getName() +
1877                                                    "/WEB-INF/liferay-plugin-package.xml");
1878    
1879                                    if (pluginPackageXmlFile.exists()) {
1880                                            is = new FileInputStream(pluginPackageXmlFile);
1881                                    }
1882                                    else {
1883                                            ZipEntry zipEntry = zipFile.getEntry(
1884                                                    "WEB-INF/liferay-plugin-package.xml");
1885    
1886                                            if (zipEntry != null) {
1887                                                    is = zipFile.getInputStream(zipEntry);
1888                                            }
1889                                    }
1890    
1891                                    File pluginPackagePropertiesFile = new File(
1892                                            file.getParent() + "/merge/" + file.getName() +
1893                                                    "/WEB-INF/liferay-plugin-package.properties");
1894    
1895                                    if ((is == null) && pluginPackagePropertiesFile.exists()) {
1896                                            is = new FileInputStream(pluginPackagePropertiesFile);
1897    
1898                                            parseProps = true;
1899                                    }
1900                                    else {
1901                                            ZipEntry zipEntry = zipFile.getEntry(
1902                                                    "WEB-INF/liferay-plugin-package.properties");
1903    
1904                                            if ((is == null) && (zipEntry != null)) {
1905                                                    is = zipFile.getInputStream(zipEntry);
1906    
1907                                                    parseProps = true;
1908                                            }
1909                                    }
1910                            }
1911    
1912                            if (is == null) {
1913                                    if (_log.isInfoEnabled()) {
1914                                            _log.info(
1915                                                    file.getPath() + " does not have a " +
1916                                                            "WEB-INF/liferay-plugin-package.xml or " +
1917                                                                    "WEB-INF/liferay-plugin-package.properties");
1918                                    }
1919    
1920                                    return null;
1921                            }
1922    
1923                            if (parseProps) {
1924                                    String displayName = getDisplayName(file);
1925    
1926                                    String propertiesString = StringUtil.read(is);
1927    
1928                                    Properties properties = PropertiesUtil.load(propertiesString);
1929    
1930                                    return PluginPackageUtil.readPluginPackageProperties(
1931                                            displayName, properties);
1932                            }
1933                            else {
1934                                    String xml = StringUtil.read(is);
1935    
1936                                    xml = XMLFormatter.fixProlog(xml);
1937    
1938                                    return PluginPackageUtil.readPluginPackageXml(xml);
1939                            }
1940                    }
1941                    catch (Exception e) {
1942                            _log.error(file.getPath() + ": " + e.toString());
1943                    }
1944                    finally {
1945                            if (is != null) {
1946                                    try {
1947                                            is.close();
1948                                    }
1949                                    catch (IOException ioe) {
1950                                    }
1951                            }
1952    
1953                            if (zipFile != null) {
1954                                    try {
1955                                            zipFile.close();
1956                                    }
1957                                    catch (IOException ioe) {
1958                                    }
1959                            }
1960                    }
1961    
1962                    return null;
1963            }
1964    
1965            public void rewriteFiles(File srcDir) throws Exception {
1966                    String[] fileNames = FileUtil.listFiles(srcDir + "/WEB-INF/");
1967    
1968                    for (String fileName : fileNames) {
1969                            String shortFileName = GetterUtil.getString(
1970                                    FileUtil.getShortFileName(fileName));
1971    
1972                            // LEP-6415
1973    
1974                            if (shortFileName.equalsIgnoreCase("mule-config.xml")) {
1975                                    continue;
1976                            }
1977    
1978                            String ext = GetterUtil.getString(FileUtil.getExtension(fileName));
1979    
1980                            if (!ext.equalsIgnoreCase("xml")) {
1981                                    continue;
1982                            }
1983    
1984                            // Make sure to rewrite any XML files to include external entities
1985                            // into same file. See LEP-3142.
1986    
1987                            File file = new File(srcDir + "/WEB-INF/" + fileName);
1988    
1989                            try {
1990                                    Document doc = SAXReaderUtil.read(file);
1991    
1992                                    String content = doc.formattedString(StringPool.TAB, true);
1993    
1994                                    FileUtil.write(file, content);
1995                            }
1996                            catch (Exception e) {
1997                                    if (_log.isWarnEnabled()) {
1998                                            _log.warn(
1999                                                    "Unable to format " + file + ": " + e.getMessage());
2000                                    }
2001                            }
2002                    }
2003            }
2004    
2005            public String secureWebXml(
2006                            String content, boolean hasCustomServletListener,
2007                            boolean securityManagerEnabled)
2008                    throws Exception {
2009    
2010                    if (!hasCustomServletListener && !securityManagerEnabled) {
2011                            return content;
2012                    }
2013    
2014                    Document document = SAXReaderUtil.read(content);
2015    
2016                    Element rootElement = document.getRootElement();
2017    
2018                    List<String> listenerClasses = new ArrayList<String>();
2019    
2020                    List<Element> listenerElements = rootElement.elements("listener");
2021    
2022                    for (Element listenerElement : listenerElements) {
2023                            String listenerClass = GetterUtil.getString(
2024                                    listenerElement.elementText("listener-class"));
2025    
2026                            if (listenerClass.equals(
2027                                            SecurePluginContextListener.class.getName())) {
2028    
2029                                    continue;
2030                            }
2031    
2032                            listenerClasses.add(listenerClass);
2033    
2034                            listenerElement.detach();
2035                    }
2036    
2037                    Element contextParamElement = rootElement.addElement("context-param");
2038    
2039                    DocUtil.add(contextParamElement, "param-name", "portalListenerClasses");
2040                    DocUtil.add(
2041                            contextParamElement, "param-value",
2042                            StringUtil.merge(listenerClasses));
2043    
2044                    if (!securityManagerEnabled) {
2045                            return document.compactString();
2046                    }
2047    
2048                    List<Element> servletElements = rootElement.elements("servlet");
2049    
2050                    for (Element servletElement : servletElements) {
2051                            Element servletClassElement = servletElement.element(
2052                                    "servlet-class");
2053    
2054                            String servletClass = GetterUtil.getString(
2055                                    servletClassElement.getText());
2056    
2057                            if (servletClass.equals(
2058                                            PortalClassLoaderServlet.class.getName()) ||
2059                                    servletClass.equals(PortalDelegateServlet.class.getName()) ||
2060                                    servletClass.equals(PortletServlet.class.getName())) {
2061    
2062                                    continue;
2063                            }
2064    
2065                            servletClassElement.setText(SecureServlet.class.getName());
2066    
2067                            Element initParamElement = servletElement.addElement("init-param");
2068    
2069                            DocUtil.add(initParamElement, "param-name", "servlet-class");
2070                            DocUtil.add(initParamElement, "param-value", servletClass);
2071                    }
2072    
2073                    return document.compactString();
2074            }
2075    
2076            @Override
2077            public void setAppServerType(String appServerType) {
2078                    this.appServerType = appServerType;
2079            }
2080    
2081            @Override
2082            public void setAuiTaglibDTD(String auiTaglibDTD) {
2083                    this.auiTaglibDTD = auiTaglibDTD;
2084            }
2085    
2086            @Override
2087            public void setBaseDir(String baseDir) {
2088                    this.baseDir = baseDir;
2089            }
2090    
2091            @Override
2092            public void setDestDir(String destDir) {
2093                    this.destDir = destDir;
2094            }
2095    
2096            @Override
2097            public void setFilePattern(String filePattern) {
2098                    this.filePattern = filePattern;
2099            }
2100    
2101            @Override
2102            public void setJars(List<String> jars) {
2103                    this.jars = jars;
2104            }
2105    
2106            @Override
2107            public void setJbossPrefix(String jbossPrefix) {
2108                    this.jbossPrefix = jbossPrefix;
2109            }
2110    
2111            @Override
2112            public void setPortletExtTaglibDTD(String portletExtTaglibDTD) {
2113                    this.portletExtTaglibDTD = portletExtTaglibDTD;
2114            }
2115    
2116            @Override
2117            public void setPortletTaglibDTD(String portletTaglibDTD) {
2118                    this.portletTaglibDTD = portletTaglibDTD;
2119            }
2120    
2121            @Override
2122            public void setSecurityTaglibDTD(String securityTaglibDTD) {
2123                    this.securityTaglibDTD = securityTaglibDTD;
2124            }
2125    
2126            @Override
2127            public void setThemeTaglibDTD(String themeTaglibDTD) {
2128                    this.themeTaglibDTD = themeTaglibDTD;
2129            }
2130    
2131            @Override
2132            public void setTomcatLibDir(String tomcatLibDir) {
2133                    this.tomcatLibDir = tomcatLibDir;
2134            }
2135    
2136            @Override
2137            public void setUiTaglibDTD(String uiTaglibDTD) {
2138                    this.uiTaglibDTD = uiTaglibDTD;
2139            }
2140    
2141            @Override
2142            public void setUnpackWar(boolean unpackWar) {
2143                    this.unpackWar = unpackWar;
2144            }
2145    
2146            @Override
2147            public void setUtilTaglibDTD(String utilTaglibDTD) {
2148                    this.utilTaglibDTD = utilTaglibDTD;
2149            }
2150    
2151            @Override
2152            public void setWars(List<String> wars) {
2153                    this.wars = wars;
2154            }
2155    
2156            public void updateDeployDirectory(File srcFile) throws Exception {
2157            }
2158    
2159            public void updateGeronimoWebXml(
2160                            File srcFile, String displayName, PluginPackage pluginPackage)
2161                    throws Exception {
2162    
2163                    if (!appServerType.equals(ServerDetector.GERONIMO_ID)) {
2164                            return;
2165                    }
2166    
2167                    File geronimoWebXml = new File(srcFile + "/WEB-INF/geronimo-web.xml");
2168    
2169                    Document document = SAXReaderUtil.read(geronimoWebXml);
2170    
2171                    Element rootElement = document.getRootElement();
2172    
2173                    Element environmentElement = rootElement.element("environment");
2174    
2175                    Element moduleIdElement = environmentElement.element("moduleId");
2176    
2177                    Element artifactIdElement = moduleIdElement.element("artifactId");
2178    
2179                    artifactIdElement.setText(displayName);
2180    
2181                    Element versionElement = moduleIdElement.element("version");
2182    
2183                    versionElement.setText(pluginPackage.getVersion());
2184    
2185                    String content = document.formattedString();
2186    
2187                    FileUtil.write(geronimoWebXml, content);
2188    
2189                    if (_log.isInfoEnabled()) {
2190                            _log.info("Modifying Geronimo " + geronimoWebXml);
2191                    }
2192            }
2193    
2194            public String updateLiferayWebXml(
2195                            double webXmlVersion, File srcFile, String webXmlContent)
2196                    throws Exception {
2197    
2198                    boolean liferayWebXmlEnabled = true;
2199    
2200                    Properties properties = getPluginPackageProperties(srcFile);
2201    
2202                    if (properties != null) {
2203                            liferayWebXmlEnabled = GetterUtil.getBoolean(
2204                                    properties.getProperty("liferay-web-xml-enabled"), true);
2205                    }
2206    
2207                    webXmlContent = WebXMLBuilder.organizeWebXML(webXmlContent);
2208    
2209                    int x = webXmlContent.indexOf("<filter>");
2210                    int y = webXmlContent.lastIndexOf("</filter-mapping>");
2211    
2212                    String webXmlFiltersContent = StringPool.BLANK;
2213    
2214                    if ((x == -1) || (y == -1)) {
2215                            x = webXmlContent.lastIndexOf("</display-name>") + 15;
2216                            y = x;
2217                    }
2218                    else {
2219                            if (liferayWebXmlEnabled && (webXmlVersion > 2.3)) {
2220                                    webXmlFiltersContent = webXmlContent.substring(x, y + 17);
2221    
2222                                    y = y + 17;
2223                            }
2224                            else {
2225                                    x = y + 17;
2226                                    y = y + 17;
2227                            }
2228                    }
2229    
2230                    if (webXmlVersion < 2.4) {
2231                            webXmlContent =
2232                                    webXmlContent.substring(0, x) +
2233                                            getExtraFiltersContent(webXmlVersion, srcFile) +
2234                                                    webXmlContent.substring(y);
2235    
2236                            return webXmlContent;
2237                    }
2238    
2239                    String filtersContent =
2240                            webXmlFiltersContent +
2241                                    getExtraFiltersContent(webXmlVersion, srcFile);
2242    
2243                    String liferayWebXmlContent = FileUtil.read(
2244                            DeployUtil.getResourcePath("web.xml"));
2245    
2246                    int z = liferayWebXmlContent.indexOf("</web-app>");
2247    
2248                    liferayWebXmlContent =
2249                            liferayWebXmlContent.substring(0, z) + filtersContent +
2250                                    liferayWebXmlContent.substring(z);
2251    
2252                    liferayWebXmlContent = WebXMLBuilder.organizeWebXML(
2253                            liferayWebXmlContent);
2254    
2255                    FileUtil.write(
2256                            srcFile + "/WEB-INF/liferay-web.xml", liferayWebXmlContent);
2257    
2258                    webXmlContent =
2259                            webXmlContent.substring(0, x) + getInvokerFilterContent() +
2260                                    webXmlContent.substring(y);
2261    
2262                    return webXmlContent;
2263            }
2264    
2265            @Override
2266            public void updateWebXml(
2267                            File webXml, File srcFile, String displayName,
2268                            PluginPackage pluginPackage)
2269                    throws Exception {
2270    
2271                    // Check version
2272    
2273                    String content = FileUtil.read(webXml);
2274    
2275                    content = WebXMLBuilder.organizeWebXML(content);
2276    
2277                    int x = content.indexOf("<display-name>");
2278    
2279                    if (x != -1) {
2280                            int y = content.indexOf("</display-name>", x);
2281    
2282                            y = content.indexOf(">", y) + 1;
2283    
2284                            content = content.substring(0, x) + content.substring(y);
2285                    }
2286    
2287                    Document document = SAXReaderUtil.read(content);
2288    
2289                    Element rootElement = document.getRootElement();
2290    
2291                    double webXmlVersion = GetterUtil.getDouble(
2292                            rootElement.attributeValue("version"), 2.3);
2293    
2294                    if (!PropsValues.TCK_URL && (webXmlVersion <= 2.3)) {
2295                            throw new AutoDeployException(
2296                                    webXml.getName() +
2297                                            " must be updated to the Servlet 2.4 specification");
2298                    }
2299    
2300                    // Plugin context listener
2301    
2302                    StringBundler sb = new StringBundler(5);
2303    
2304                    sb.append("<listener>");
2305                    sb.append("<listener-class>");
2306    
2307                    boolean hasCustomServletListener = false;
2308    
2309                    List<Element> listenerElements = rootElement.elements("listener");
2310    
2311                    for (Element listenerElement : listenerElements) {
2312                            String listenerClass = GetterUtil.getString(
2313                                    listenerElement.elementText("listener-class"));
2314    
2315                            if (listenerClass.equals(
2316                                            SerializableSessionAttributeListener.class.getName()) ||
2317                                    listenerClass.equals(
2318                                            SecurePluginContextListener.class.getName())) {
2319    
2320                                    continue;
2321                            }
2322    
2323                            hasCustomServletListener = true;
2324    
2325                            break;
2326                    }
2327    
2328                    boolean securityManagerEnabled = false;
2329    
2330                    Properties properties = getPluginPackageProperties(srcFile);
2331    
2332                    if (properties != null) {
2333                            securityManagerEnabled = GetterUtil.getBoolean(
2334                                    properties.getProperty("security-manager-enabled"));
2335                    }
2336    
2337                    if (hasCustomServletListener || securityManagerEnabled) {
2338                            sb.append(SecurePluginContextListener.class.getName());
2339                    }
2340                    else {
2341                            sb.append(PluginContextListener.class.getName());
2342                    }
2343    
2344                    sb.append("</listener-class>");
2345                    sb.append("</listener>");
2346    
2347                    String pluginContextListenerContent = sb.toString();
2348    
2349                    // Merge content
2350    
2351                    String extraContent = getExtraContent(
2352                            webXmlVersion, srcFile, displayName);
2353    
2354                    int pos = content.indexOf("<listener>");
2355    
2356                    if (pos == -1) {
2357                            pos = content.indexOf("</web-app>");
2358                    }
2359    
2360                    String newContent =
2361                            content.substring(0, pos) + pluginContextListenerContent +
2362                                    extraContent + content.substring(pos);
2363    
2364                    // Update liferay-web.xml
2365    
2366                    newContent = updateLiferayWebXml(webXmlVersion, srcFile, newContent);
2367    
2368                    // Update web.xml
2369    
2370                    newContent = secureWebXml(
2371                            newContent, hasCustomServletListener, securityManagerEnabled);
2372    
2373                    newContent = WebXMLBuilder.organizeWebXML(newContent);
2374    
2375                    FileUtil.write(webXml, newContent, true);
2376    
2377                    if (_log.isInfoEnabled()) {
2378                            _log.info("Modifying Servlet " + webXmlVersion + " " + webXml);
2379                    }
2380            }
2381    
2382            protected String appServerType;
2383            protected String auiTaglibDTD;
2384            protected String baseDir;
2385            protected String destDir;
2386            protected String filePattern;
2387            protected List<String> jars;
2388            protected String jbossPrefix;
2389            protected String portletExtTaglibDTD;
2390            protected String portletTaglibDTD;
2391            protected String securityTaglibDTD;
2392            protected String themeTaglibDTD;
2393            protected String tomcatLibDir;
2394            protected String uiTaglibDTD;
2395            protected boolean unpackWar;
2396            protected String utilTaglibDTD;
2397            protected List<String> wars;
2398    
2399            private static final String _PORTAL_CLASS_LOADER =
2400                    "com.liferay.support.tomcat.loader.PortalClassLoader";
2401    
2402            private static Log _log = LogFactoryUtil.getLog(BaseDeployer.class);
2403    
2404    }