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