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