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