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