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