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