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