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