001
014
015 package com.liferay.portal.tools.deploy;
016
017 import com.liferay.portal.deploy.DeployUtil;
018 import com.liferay.portal.kernel.deploy.Deployer;
019 import com.liferay.portal.kernel.deploy.auto.AutoDeployException;
020 import com.liferay.portal.kernel.deploy.auto.AutoDeployer;
021 import com.liferay.portal.kernel.deploy.auto.context.AutoDeploymentContext;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.plugin.License;
025 import com.liferay.portal.kernel.plugin.PluginPackage;
026 import com.liferay.portal.kernel.servlet.PluginContextListener;
027 import com.liferay.portal.kernel.servlet.PortalClassLoaderServlet;
028 import com.liferay.portal.kernel.servlet.PortalDelegateServlet;
029 import com.liferay.portal.kernel.servlet.PortletServlet;
030 import com.liferay.portal.kernel.servlet.SecurePluginContextListener;
031 import com.liferay.portal.kernel.servlet.SecureServlet;
032 import com.liferay.portal.kernel.servlet.SerializableSessionAttributeListener;
033 import com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter;
034 import com.liferay.portal.kernel.util.ArrayUtil;
035 import com.liferay.portal.kernel.util.FileUtil;
036 import com.liferay.portal.kernel.util.GetterUtil;
037 import com.liferay.portal.kernel.util.HttpUtil;
038 import com.liferay.portal.kernel.util.PropertiesUtil;
039 import com.liferay.portal.kernel.util.PropsKeys;
040 import com.liferay.portal.kernel.util.ServerDetector;
041 import com.liferay.portal.kernel.util.StringBundler;
042 import com.liferay.portal.kernel.util.StringPool;
043 import com.liferay.portal.kernel.util.StringUtil;
044 import com.liferay.portal.kernel.util.SystemProperties;
045 import com.liferay.portal.kernel.util.TextFormatter;
046 import com.liferay.portal.kernel.util.Time;
047 import com.liferay.portal.kernel.util.Validator;
048 import com.liferay.portal.kernel.xml.Document;
049 import com.liferay.portal.kernel.xml.Element;
050 import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
051 import com.liferay.portal.plugin.PluginPackageUtil;
052 import com.liferay.portal.security.lang.SecurityManagerUtil;
053 import com.liferay.portal.tools.ToolDependencies;
054 import com.liferay.portal.tools.WebXMLBuilder;
055 import com.liferay.portal.tools.deploy.extension.DeploymentExtension;
056 import com.liferay.portal.util.ExtRegistry;
057 import com.liferay.portal.util.PortalUtil;
058 import com.liferay.portal.util.PrefsPropsUtil;
059 import com.liferay.portal.util.PropsUtil;
060 import com.liferay.portal.util.PropsValues;
061 import com.liferay.portal.webserver.DynamicResourceServlet;
062 import com.liferay.util.ant.CopyTask;
063 import com.liferay.util.ant.DeleteTask;
064 import com.liferay.util.ant.ExpandTask;
065 import com.liferay.util.ant.UpToDateTask;
066 import com.liferay.util.ant.WarTask;
067 import com.liferay.util.xml.DocUtil;
068 import com.liferay.util.xml.XMLUtil;
069
070 import java.io.File;
071 import java.io.FileInputStream;
072 import java.io.IOException;
073 import java.io.InputStream;
074
075 import java.nio.file.Files;
076 import java.nio.file.Path;
077 import java.nio.file.Paths;
078
079 import java.util.ArrayList;
080 import java.util.HashMap;
081 import java.util.List;
082 import java.util.Map;
083 import java.util.Properties;
084 import java.util.ServiceLoader;
085 import java.util.Set;
086 import java.util.zip.ZipEntry;
087 import java.util.zip.ZipFile;
088
089 import org.apache.oro.io.GlobFilenameFilter;
090
091
095 public class BaseDeployer implements AutoDeployer, Deployer {
096
097 public static final String DEPLOY_TO_PREFIX = "DEPLOY_TO__";
098
099 public static void main(String[] args) {
100 ToolDependencies.wireDeployers();
101
102 List<String> wars = new ArrayList<>();
103 List<String> jars = new ArrayList<>();
104
105 for (String arg : args) {
106 String fileName = StringUtil.toLowerCase(arg);
107
108 if (fileName.endsWith(".war")) {
109 wars.add(arg);
110 }
111 else if (fileName.endsWith(".jar")) {
112 jars.add(arg);
113 }
114 }
115
116 new BaseDeployer(wars, jars);
117 }
118
119 public BaseDeployer() {
120 for (DeploymentExtension deploymentExtension : ServiceLoader.load(
121 DeploymentExtension.class,
122 BaseDeployer.class.getClassLoader())) {
123
124 _deploymentExtensions.add(deploymentExtension);
125 }
126 }
127
128 public BaseDeployer(List<String> wars, List<String> jars) {
129 this();
130
131 baseDir = System.getProperty("deployer.base.dir");
132 destDir = System.getProperty("deployer.dest.dir");
133 appServerType = System.getProperty("deployer.app.server.type");
134 auiTaglibDTD = System.getProperty("deployer.aui.taglib.dtd");
135 portletTaglibDTD = System.getProperty("deployer.portlet.taglib.dtd");
136 portletExtTaglibDTD = System.getProperty(
137 "deployer.portlet.ext.taglib.dtd");
138 securityTaglibDTD = System.getProperty("deployer.security.taglib.dtd");
139 themeTaglibDTD = System.getProperty("deployer.theme.taglib.dtd");
140 uiTaglibDTD = System.getProperty("deployer.ui.taglib.dtd");
141 utilTaglibDTD = System.getProperty("deployer.util.taglib.dtd");
142 unpackWar = GetterUtil.getBoolean(
143 System.getProperty("deployer.unpack.war"), true);
144 filePattern = System.getProperty("deployer.file.pattern");
145 jbossPrefix = GetterUtil.getString(
146 System.getProperty("deployer.jboss.prefix"));
147 tomcatLibDir = System.getProperty("deployer.tomcat.lib.dir");
148 wildflyPrefix = GetterUtil.getString(
149 System.getProperty("deployer.wildfly.prefix"));
150 this.wars = wars;
151 this.jars = jars;
152
153 checkArguments();
154
155 String context = System.getProperty("deployer.context");
156
157 try {
158 deploy(context);
159 }
160 catch (Exception e) {
161 _log.error(e, e);
162 }
163 }
164
165 @Override
166 public void addExtJar(List<String> jars, String resource) throws Exception {
167 Set<String> servletContextNames = ExtRegistry.getServletContextNames();
168
169 for (String servletContextName : servletContextNames) {
170 String extResource =
171 "ext-" + servletContextName + resource.substring(3);
172
173 String path = DeployUtil.getResourcePath(extResource);
174
175 if (_log.isDebugEnabled()) {
176 if (path == null) {
177 _log.debug("Resource " + extResource + " is not available");
178 }
179 else {
180 _log.debug(
181 "Resource " + extResource + " is available at " + path);
182 }
183 }
184
185 if (path != null) {
186 jars.add(path);
187 }
188 }
189 }
190
191 @Override
192 public void addRequiredJar(List<String> jars, String resource)
193 throws Exception {
194
195 String path = DeployUtil.getResourcePath(resource);
196
197 if (path == null) {
198 throw new RuntimeException(
199 "Resource " + resource + " does not exist");
200 }
201
202 if (_log.isDebugEnabled()) {
203 _log.debug("Resource " + resource + " is available at " + path);
204 }
205
206 jars.add(path);
207 }
208
209 @Override
210 public int autoDeploy(AutoDeploymentContext autoDeploymentContext)
211 throws AutoDeployException {
212
213 List<String> wars = new ArrayList<>();
214
215 File file = autoDeploymentContext.getFile();
216
217 wars.add(file.getName());
218
219 this.wars = wars;
220
221 try {
222 return deployFile(autoDeploymentContext);
223 }
224 catch (Exception e) {
225 throw new AutoDeployException(e);
226 }
227 }
228
229 @Override
230 public void checkArguments() {
231 if (Validator.isNull(baseDir)) {
232 throw new IllegalArgumentException(
233 "The system property deployer.base.dir is not set");
234 }
235
236 if (Validator.isNull(destDir)) {
237 throw new IllegalArgumentException(
238 "The system property deployer.dest.dir is not set");
239 }
240
241 if (Validator.isNull(appServerType)) {
242 throw new IllegalArgumentException(
243 "The system property deployer.app.server.type is not set");
244 }
245
246 if (!appServerType.equals(ServerDetector.GLASSFISH_ID) &&
247 !appServerType.equals(ServerDetector.JBOSS_ID) &&
248 !appServerType.equals(ServerDetector.JONAS_ID) &&
249 !appServerType.equals(ServerDetector.JETTY_ID) &&
250 !appServerType.equals(ServerDetector.OC4J_ID) &&
251 !appServerType.equals(ServerDetector.RESIN_ID) &&
252 !appServerType.equals(ServerDetector.TOMCAT_ID) &&
253 !appServerType.equals(ServerDetector.WEBLOGIC_ID) &&
254 !appServerType.equals(ServerDetector.WEBSPHERE_ID) &&
255 !appServerType.equals(ServerDetector.WILDFLY_ID)) {
256
257 throw new IllegalArgumentException(
258 appServerType + " is not a valid application server type");
259 }
260
261 if (appServerType.equals(ServerDetector.GLASSFISH_ID) ||
262 appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
263
264 unpackWar = false;
265 }
266
267 if (Validator.isNotNull(jbossPrefix) &&
268 !Validator.isNumber(jbossPrefix)) {
269
270 jbossPrefix = "1";
271 }
272
273 if (Validator.isNotNull(wildflyPrefix) &&
274 !Validator.isNumber(wildflyPrefix)) {
275
276 wildflyPrefix = "1";
277 }
278 }
279
280 @Override
281 public AutoDeployer cloneAutoDeployer() throws AutoDeployException {
282 try {
283 Class<?> clazz = getClass();
284
285 Deployer deployer = (Deployer)clazz.newInstance();
286
287 deployer.setAppServerType(appServerType);
288 deployer.setAuiTaglibDTD(auiTaglibDTD);
289 deployer.setBaseDir(baseDir);
290 deployer.setDestDir(destDir);
291 deployer.setFilePattern(filePattern);
292 deployer.setJars(jars);
293 deployer.setJbossPrefix(jbossPrefix);
294 deployer.setPortletExtTaglibDTD(portletExtTaglibDTD);
295 deployer.setPortletTaglibDTD(portletTaglibDTD);
296 deployer.setSecurityTaglibDTD(securityTaglibDTD);
297 deployer.setThemeTaglibDTD(themeTaglibDTD);
298 deployer.setTomcatLibDir(tomcatLibDir);
299 deployer.setUiTaglibDTD(uiTaglibDTD);
300 deployer.setUnpackWar(unpackWar);
301 deployer.setUtilTaglibDTD(utilTaglibDTD);
302 deployer.setWars(wars);
303 deployer.setWildflyPrefix(wildflyPrefix);
304
305 return (AutoDeployer)deployer;
306 }
307 catch (Exception e) {
308 throw new AutoDeployException(e);
309 }
310 }
311
312 @Override
313 public void copyDependencyXml(String fileName, String targetDir)
314 throws Exception {
315
316 copyDependencyXml(fileName, targetDir, null);
317 }
318
319 @Override
320 public void copyDependencyXml(
321 String fileName, String targetDir, Map<String, String> filterMap)
322 throws Exception {
323
324 copyDependencyXml(fileName, targetDir, filterMap, false);
325 }
326
327 @Override
328 public void copyDependencyXml(
329 String fileName, String targetDir, Map<String, String> filterMap,
330 boolean overwrite)
331 throws Exception {
332
333 DeployUtil.copyDependencyXml(
334 fileName, targetDir, fileName, filterMap, overwrite);
335 }
336
337 @Override
338 public void copyJars(File srcFile, PluginPackage pluginPackage)
339 throws Exception {
340
341 for (int i = 0; i < jars.size(); i++) {
342 String jarFullName = jars.get(i);
343
344 String jarName = jarFullName.substring(
345 jarFullName.lastIndexOf("/") + 1);
346
347 if (!FileUtil.exists(jarFullName)) {
348 DeployUtil.getResourcePath(jarName);
349 }
350
351 FileUtil.copyFile(
352 jarFullName, srcFile + "/WEB-INF/lib/" + jarName, false);
353 }
354 }
355
356 public void copyPortalDependencies(File srcFile) throws Exception {
357 Properties properties = getPluginPackageProperties(srcFile);
358
359 if (properties == null) {
360 return;
361 }
362
363
364
365 String[] portalJars = StringUtil.split(
366 properties.getProperty(
367 "portal-dependency-jars",
368 properties.getProperty("portal.dependency.jars")));
369
370 for (String portalJar : portalJars) {
371 portalJar = portalJar.trim();
372
373 portalJar = fixPortalDependencyJar(portalJar);
374
375 if (_log.isDebugEnabled()) {
376 _log.debug("Copy portal JAR " + portalJar);
377 }
378
379 try {
380 String portalJarPath = PortalUtil.getPortalLibDir() + portalJar;
381
382 FileUtil.copyFile(
383 portalJarPath, srcFile + "/WEB-INF/lib/" + portalJar, true);
384 }
385 catch (Exception e) {
386 _log.error("Unable to copy portal JAR " + portalJar, e);
387 }
388 }
389
390
391
392 String[] portalTlds = StringUtil.split(
393 properties.getProperty(
394 "portal-dependency-tlds",
395 properties.getProperty("portal.dependency.tlds")));
396
397 for (String portalTld : portalTlds) {
398 portalTld = portalTld.trim();
399
400 if (_log.isDebugEnabled()) {
401 _log.debug("Copy portal TLD " + portalTld);
402 }
403
404 try {
405 String portalTldPath = DeployUtil.getResourcePath(portalTld);
406
407 FileUtil.copyFile(
408 portalTldPath, srcFile + "/WEB-INF/tld/" + portalTld, true);
409 }
410 catch (Exception e) {
411 _log.error("Unable to copy portal TLD " + portalTld, e);
412 }
413 }
414
415
416
417 File pluginLibDir = new File(srcFile + "/WEB-INF/lib/");
418
419 if (PropsValues.AUTO_DEPLOY_COPY_COMMONS_LOGGING) {
420 String[] commonsLoggingJars = pluginLibDir.list(
421 new GlobFilenameFilter("commons-logging*.jar"));
422
423 if (ArrayUtil.isEmpty(commonsLoggingJars)) {
424 String portalJarPath =
425 PortalUtil.getPortalLibDir() + "commons-logging.jar";
426
427 FileUtil.copyFile(
428 portalJarPath, srcFile + "/WEB-INF/lib/commons-logging.jar",
429 true);
430 }
431 }
432
433
434
435 if (PropsValues.AUTO_DEPLOY_COPY_LOG4J) {
436 String[] log4jJars = pluginLibDir.list(
437 new GlobFilenameFilter("log4j*.jar"));
438
439 if (ArrayUtil.isEmpty(log4jJars)) {
440 String portalJarPath =
441 PortalUtil.getPortalLibDir() + "log4j.jar";
442
443 FileUtil.copyFile(
444 portalJarPath, srcFile + "/WEB-INF/lib/log4j.jar", true);
445
446 portalJarPath =
447 PortalUtil.getPortalLibDir() + "log4j-extras.jar";
448
449 FileUtil.copyFile(
450 portalJarPath, srcFile + "/WEB-INF/lib/log4j-extras.jar",
451 true);
452 }
453 }
454 }
455
456 @Override
457 public void copyProperties(File srcFile, PluginPackage pluginPackage)
458 throws Exception {
459
460 if (PropsValues.AUTO_DEPLOY_COPY_COMMONS_LOGGING) {
461 copyDependencyXml(
462 "logging.properties", srcFile + "/WEB-INF/classes");
463 }
464
465 if (PropsValues.AUTO_DEPLOY_COPY_LOG4J) {
466 copyDependencyXml("log4j.properties", srcFile + "/WEB-INF/classes");
467 }
468
469 File servicePropertiesFile = new File(
470 srcFile.getAbsolutePath() + "/WEB-INF/classes/service.properties");
471
472 if (!servicePropertiesFile.exists()) {
473 return;
474 }
475
476 File portletPropertiesFile = new File(
477 srcFile.getAbsolutePath() + "/WEB-INF/classes/portlet.properties");
478
479 if (portletPropertiesFile.exists()) {
480 return;
481 }
482
483 String pluginPackageName = null;
484
485 if (pluginPackage != null) {
486 pluginPackageName = pluginPackage.getName();
487 }
488 else {
489 pluginPackageName = srcFile.getName();
490 }
491
492 FileUtil.write(
493 portletPropertiesFile, "plugin.package.name=" + pluginPackageName);
494 }
495
496 @Override
497 public void copyTlds(File srcFile, PluginPackage pluginPackage)
498 throws Exception {
499
500 if (Validator.isNotNull(auiTaglibDTD)) {
501 FileUtil.copyFile(
502 auiTaglibDTD, srcFile + "/WEB-INF/tld/liferay-aui.tld", true);
503 }
504
505 if (Validator.isNotNull(portletTaglibDTD)) {
506 FileUtil.copyFile(
507 portletTaglibDTD, srcFile + "/WEB-INF/tld/liferay-portlet.tld",
508 true);
509 }
510
511 if (Validator.isNotNull(portletExtTaglibDTD)) {
512 FileUtil.copyFile(
513 portletExtTaglibDTD,
514 srcFile + "/WEB-INF/tld/liferay-portlet-ext.tld", true);
515 }
516
517 if (Validator.isNotNull(securityTaglibDTD)) {
518 FileUtil.copyFile(
519 securityTaglibDTD,
520 srcFile + "/WEB-INF/tld/liferay-security.tld", true);
521 }
522
523 if (Validator.isNotNull(themeTaglibDTD)) {
524 FileUtil.copyFile(
525 themeTaglibDTD, srcFile + "/WEB-INF/tld/liferay-theme.tld",
526 true);
527 }
528
529 if (Validator.isNotNull(uiTaglibDTD)) {
530 FileUtil.copyFile(
531 uiTaglibDTD, srcFile + "/WEB-INF/tld/liferay-ui.tld", true);
532 }
533
534 if (Validator.isNotNull(utilTaglibDTD)) {
535 FileUtil.copyFile(
536 utilTaglibDTD, srcFile + "/WEB-INF/tld/liferay-util.tld", true);
537 }
538 }
539
540 public void copyTomcatContextXml(File targetDir) throws Exception {
541 if (!appServerType.equals(ServerDetector.TOMCAT_ID) ||
542 SecurityManagerUtil.ENABLED) {
543
544 return;
545 }
546
547 File targetFile = new File(targetDir, "META-INF/context.xml");
548
549 if (targetFile.exists()) {
550 return;
551 }
552
553 String contextPath = DeployUtil.getResourcePath("context.xml");
554
555 String content = FileUtil.read(contextPath);
556
557 if (!PropsValues.AUTO_DEPLOY_UNPACK_WAR) {
558 content = StringUtil.replace(
559 content, "antiResourceLocking=\"true\"", StringPool.BLANK);
560 }
561
562 FileUtil.write(targetFile, content);
563 }
564
565 @Override
566 public void copyXmls(
567 File srcFile, String displayName, PluginPackage pluginPackage)
568 throws Exception {
569
570 if (appServerType.equals(ServerDetector.JBOSS_ID)) {
571 copyDependencyXml(
572 "jboss-deployment-structure.xml", srcFile + "/WEB-INF");
573 }
574 else if (appServerType.equals(ServerDetector.WILDFLY_ID)) {
575 copyDependencyXml(
576 "jboss-deployment-structure.xml", srcFile + "/WEB-INF");
577 }
578
579 for (DeploymentExtension deploymentExtension : _deploymentExtensions) {
580 if (Validator.equals(
581 appServerType, deploymentExtension.getServerId())) {
582
583 deploymentExtension.copyXmls(this, srcFile);
584 }
585 }
586
587 copyDependencyXml("web.xml", srcFile + "/WEB-INF");
588 }
589
590 public void deploy(String context) throws Exception {
591 try {
592 File baseDirFile = new File(baseDir);
593
594 File[] files = baseDirFile.listFiles();
595
596 if (files == null) {
597 return;
598 }
599
600 files = FileUtil.sortFiles(files);
601
602 for (File srcFile : files) {
603 String fileName = StringUtil.toLowerCase(srcFile.getName());
604
605 boolean deploy = false;
606
607 if (fileName.endsWith(".war") || fileName.endsWith(".zip")) {
608 deploy = true;
609
610 if (!wars.isEmpty()) {
611 if (!wars.contains(srcFile.getName())) {
612 deploy = false;
613 }
614 }
615 else if (Validator.isNotNull(filePattern)) {
616 if (!StringUtil.matchesIgnoreCase(
617 fileName, filePattern)) {
618
619 deploy = false;
620 }
621 }
622 }
623
624 if (deploy) {
625 AutoDeploymentContext autoDeploymentContext =
626 new AutoDeploymentContext();
627
628 autoDeploymentContext.setContext(context);
629 autoDeploymentContext.setFile(srcFile);
630
631 deployFile(autoDeploymentContext);
632 }
633 }
634 }
635 catch (Exception e) {
636 _log.error(e, e);
637 }
638 }
639
640 public void deployDirectory(
641 File srcFile, File mergeDir, File deployDir, String displayName,
642 boolean overwrite, PluginPackage pluginPackage)
643 throws Exception {
644
645 rewriteFiles(srcFile);
646
647 mergeDirectory(mergeDir, srcFile);
648
649 processPluginPackageProperties(srcFile, displayName, pluginPackage);
650
651 copyJars(srcFile, pluginPackage);
652 copyProperties(srcFile, pluginPackage);
653 copyTlds(srcFile, pluginPackage);
654 copyXmls(srcFile, displayName, pluginPackage);
655 copyPortalDependencies(srcFile);
656
657 File webXml = new File(srcFile + "/WEB-INF/web.xml");
658
659 updateWebXml(webXml, srcFile, displayName, pluginPackage);
660
661 File extLibGlobalDir = new File(
662 srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/global");
663
664 if (extLibGlobalDir.exists()) {
665 File globalLibDir = new File(PortalUtil.getGlobalLibDir());
666
667 CopyTask.copyDirectory(
668 extLibGlobalDir, globalLibDir, "*.jar", StringPool.BLANK,
669 overwrite, true);
670 }
671
672 File extLibPortalDir = new File(
673 srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/portal");
674
675 if (extLibPortalDir.exists()) {
676 File portalLibDir = new File(PortalUtil.getPortalLibDir());
677
678 CopyTask.copyDirectory(
679 extLibPortalDir, portalLibDir, "*.jar", StringPool.BLANK,
680 overwrite, true);
681 }
682
683 if ((deployDir == null) || baseDir.equals(destDir)) {
684 return;
685 }
686
687 updateDeployDirectory(srcFile);
688
689 String excludes = StringPool.BLANK;
690
691 if (appServerType.equals(ServerDetector.JBOSS_ID) ||
692 appServerType.equals(ServerDetector.WILDFLY_ID )) {
693
694 excludes += "**/WEB-INF/lib/log4j.jar,";
695 }
696 else if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
697 String[] libs = FileUtil.listFiles(tomcatLibDir);
698
699 for (String lib : libs) {
700 excludes += "**/WEB-INF/lib/" + lib + ",";
701 }
702
703 File contextXml = new File(srcFile + "/META-INF/context.xml");
704
705 if (contextXml.exists()) {
706 String content = FileUtil.read(contextXml);
707
708 if (content.contains(_PORTAL_CLASS_LOADER)) {
709 excludes += "**/WEB-INF/lib/util-bridges.jar,";
710 excludes += "**/WEB-INF/lib/util-java.jar,";
711 excludes += "**/WEB-INF/lib/util-taglib.jar,";
712 }
713 }
714
715 try {
716
717
718
719 Class.forName("javax.el.ELContext");
720
721 excludes += "**/WEB-INF/lib/el-api.jar,";
722 }
723 catch (ClassNotFoundException cnfe) {
724 }
725 }
726
727
728
729 Properties properties = getPluginPackageProperties(srcFile);
730
731 if (properties != null) {
732 String deployExcludes = properties.getProperty("deploy-excludes");
733
734 if (deployExcludes != null) {
735 excludes += deployExcludes.trim();
736
737 if (!excludes.endsWith(",")) {
738 excludes += ",";
739 }
740 }
741
742 deployExcludes = properties.getProperty(
743 "deploy-excludes-" + appServerType);
744
745 if (deployExcludes != null) {
746 excludes += deployExcludes.trim();
747
748 if (!excludes.endsWith(",")) {
749 excludes += ",";
750 }
751 }
752 }
753
754 if (_log.isDebugEnabled()) {
755 _log.debug("Excludes " + excludes);
756 }
757
758 if (!unpackWar) {
759 Path tempDirPath = Files.createTempDirectory(
760 Paths.get(SystemProperties.get(SystemProperties.TMP_DIR)),
761 null);
762
763 File tempDir = tempDirPath.toFile();
764
765 excludes += "/WEB-INF/web.xml";
766
767 WarTask.war(srcFile, tempDir, excludes, webXml);
768
769 if (isJEEDeploymentEnabled()) {
770 File tempWarDir = new File(
771 tempDir.getParent(), deployDir.getName());
772
773 if (tempWarDir.exists()) {
774 tempWarDir.delete();
775 }
776
777 if (!tempDir.renameTo(tempWarDir)) {
778 tempWarDir = tempDir;
779 }
780
781 DeploymentHandler deploymentHandler = getDeploymentHandler();
782
783 deploymentHandler.deploy(tempWarDir, displayName);
784
785 deploymentHandler.releaseDeploymentManager();
786
787 DeleteTask.deleteDirectory(tempWarDir);
788 }
789 else {
790 if (!tempDir.renameTo(deployDir)) {
791 WarTask.war(srcFile, deployDir, excludes, webXml);
792 }
793
794 if (tempDir.isDirectory()) {
795 DeleteTask.deleteDirectory(tempDir);
796 }
797 else {
798 tempDir.delete();
799 }
800 }
801 }
802 else {
803
804
805
806
807
808
809
810 excludes += "**/WEB-INF/web.xml";
811
812 CopyTask.copyDirectory(
813 srcFile, deployDir, StringPool.BLANK, excludes, overwrite,
814 true);
815
816 CopyTask.copyDirectory(
817 srcFile, deployDir, "**/WEB-INF/web.xml", StringPool.BLANK,
818 true, false);
819
820 if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
821
822
823
824
825
826 File deployWebXml = new File(deployDir + "/WEB-INF/web.xml");
827
828 deployWebXml.setLastModified(
829 System.currentTimeMillis() + (Time.SECOND * 6));
830 }
831 }
832
833 if (appServerType.equals(ServerDetector.JETTY_ID)) {
834 DeployUtil.redeployJetty(displayName);
835 }
836 }
837
838 public void deployDirectory(
839 File srcFile, String displayName, boolean override,
840 PluginPackage pluginPackage)
841 throws Exception {
842
843 deployDirectory(
844 srcFile, null, null, displayName, override, pluginPackage);
845 }
846
847 public int deployFile(AutoDeploymentContext autoDeploymentContext)
848 throws Exception {
849
850 File srcFile = autoDeploymentContext.getFile();
851
852 PluginPackage pluginPackage = autoDeploymentContext.getPluginPackage();
853
854 if (pluginPackage == null) {
855 pluginPackage = readPluginPackage(srcFile);
856
857 autoDeploymentContext.setPluginPackage(pluginPackage);
858 }
859
860 if (_log.isInfoEnabled()) {
861 _log.info("Deploying " + srcFile.getName());
862 }
863
864 String autoDeploymentContextAppServerType =
865 autoDeploymentContext.getAppServerType();
866
867 if (Validator.isNotNull(autoDeploymentContextAppServerType)) {
868 appServerType = autoDeploymentContextAppServerType;
869 }
870
871 String specifiedContext = autoDeploymentContext.getContext();
872
873 String displayName = specifiedContext;
874 boolean overwrite = false;
875 String preliminaryContext = specifiedContext;
876
877
878
879
880
881
882 if (Validator.isNull(specifiedContext) &&
883 srcFile.getName().startsWith(DEPLOY_TO_PREFIX)) {
884
885 displayName = srcFile.getName().substring(
886 DEPLOY_TO_PREFIX.length(), srcFile.getName().length() - 4);
887
888 overwrite = true;
889 preliminaryContext = displayName;
890 }
891
892 if (preliminaryContext == null) {
893 preliminaryContext = getDisplayName(srcFile);
894 }
895
896 if (pluginPackage != null) {
897 if (!PluginPackageUtil.isCurrentVersionSupported(
898 pluginPackage.getLiferayVersions())) {
899
900 throw new AutoDeployException(
901 srcFile.getName() +
902 " does not support this version of Liferay");
903 }
904
905 if (displayName == null) {
906 displayName = pluginPackage.getRecommendedDeploymentContext();
907 }
908
909 if (Validator.isNull(displayName)) {
910 displayName = getDisplayName(srcFile);
911 }
912
913 pluginPackage.setContext(displayName);
914
915 PluginPackageUtil.updateInstallingPluginPackage(
916 preliminaryContext, pluginPackage);
917 }
918
919 String deployDir = null;
920
921 if (Validator.isNotNull(displayName)) {
922 deployDir = displayName + ".war";
923 }
924 else {
925 deployDir = srcFile.getName();
926 displayName = getDisplayName(srcFile);
927 }
928
929 if (appServerType.equals(ServerDetector.JBOSS_ID)) {
930 deployDir = jbossPrefix + deployDir;
931 }
932 else if (appServerType.equals(ServerDetector.WILDFLY_ID)) {
933 deployDir = wildflyPrefix + deployDir;
934 }
935 else if (appServerType.equals(ServerDetector.GLASSFISH_ID) ||
936 appServerType.equals(ServerDetector.JETTY_ID) ||
937 appServerType.equals(ServerDetector.JONAS_ID) ||
938 appServerType.equals(ServerDetector.OC4J_ID) ||
939 appServerType.equals(ServerDetector.RESIN_ID) ||
940 appServerType.equals(ServerDetector.TOMCAT_ID) ||
941 appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
942
943 if (unpackWar) {
944 deployDir = deployDir.substring(0, deployDir.length() - 4);
945 }
946 }
947
948 String destDir = this.destDir;
949
950 if (autoDeploymentContext.getDestDir() != null) {
951 destDir = autoDeploymentContext.getDestDir();
952 }
953
954 File deployDirFile = new File(destDir + "/" + deployDir);
955
956 try {
957 PluginPackage previousPluginPackage = readPluginPackage(
958 deployDirFile);
959
960 if ((pluginPackage != null) && (previousPluginPackage != null)) {
961 String name = pluginPackage.getName();
962 String previousVersion = previousPluginPackage.getVersion();
963 String version = pluginPackage.getVersion();
964
965 if (_log.isInfoEnabled()) {
966 _log.info(
967 "Updating " + name + " from version " +
968 previousVersion + " to version " + version);
969 }
970
971 if (pluginPackage.isPreviousVersionThan(
972 previousPluginPackage)) {
973
974 if (_log.isInfoEnabled()) {
975 _log.info(
976 "Not updating " + name + " because version " +
977 previousVersion + " is newer than version " +
978 version);
979 }
980
981 return AutoDeployer.CODE_SKIP_NEWER_VERSION;
982 }
983
984 overwrite = true;
985 }
986
987 File mergeDirFile = new File(
988 srcFile.getParent() + "/merge/" + srcFile.getName());
989
990 if (srcFile.isDirectory()) {
991 deployDirectory(
992 srcFile, mergeDirFile, deployDirFile, displayName,
993 overwrite, pluginPackage);
994 }
995 else {
996 boolean deployed = deployFile(
997 srcFile, mergeDirFile, deployDirFile, displayName,
998 overwrite, pluginPackage);
999
1000 if (!deployed) {
1001 String context = preliminaryContext;
1002
1003 if (pluginPackage != null) {
1004 context = pluginPackage.getContext();
1005 }
1006
1007 PluginPackageUtil.endPluginPackageInstallation(context);
1008 }
1009 else {
1010 postDeploy(destDir, deployDir);
1011 }
1012 }
1013
1014 return AutoDeployer.CODE_DEFAULT;
1015 }
1016 catch (Exception e) {
1017 if (pluginPackage != null) {
1018 PluginPackageUtil.endPluginPackageInstallation(
1019 pluginPackage.getContext());
1020 }
1021
1022 throw e;
1023 }
1024 }
1025
1026 public boolean deployFile(
1027 File srcFile, File mergeDir, File deployDir, String displayName,
1028 boolean overwrite, PluginPackage pluginPackage)
1029 throws Exception {
1030
1031 boolean undeployOnRedeploy = false;
1032
1033 try {
1034 undeployOnRedeploy = PrefsPropsUtil.getBoolean(
1035 PropsKeys.HOT_UNDEPLOY_ON_REDEPLOY,
1036 PropsValues.HOT_UNDEPLOY_ON_REDEPLOY);
1037 }
1038 catch (Exception e) {
1039
1040
1041
1042
1043
1044 }
1045
1046 if (undeployOnRedeploy) {
1047 DeployUtil.undeploy(appServerType, deployDir);
1048 }
1049
1050 if (!overwrite && UpToDateTask.isUpToDate(srcFile, deployDir)) {
1051 if (_log.isInfoEnabled()) {
1052 _log.info(deployDir + " is already up to date");
1053 }
1054
1055 return false;
1056 }
1057
1058 Path tempDirPath = Files.createTempDirectory(
1059 Paths.get(SystemProperties.get(SystemProperties.TMP_DIR)), null);
1060
1061 File tempDir = tempDirPath.toFile();
1062
1063 ExpandTask.expand(srcFile, tempDir);
1064
1065 deployDirectory(
1066 tempDir, mergeDir, deployDir, displayName, overwrite,
1067 pluginPackage);
1068
1069 DeleteTask.deleteDirectory(tempDir);
1070
1071 return true;
1072 }
1073
1074 public String downloadJar(String jar) throws Exception {
1075 String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
1076
1077 File file = new File(
1078 tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" + jar);
1079
1080 if (!file.exists()) {
1081 synchronized (this) {
1082 String url = PropsUtil.get(
1083 PropsKeys.LIBRARY_DOWNLOAD_URL + jar);
1084
1085 if (_log.isInfoEnabled()) {
1086 _log.info("Downloading library from " + url);
1087 }
1088
1089 byte[] bytes = HttpUtil.URLtoByteArray(url);
1090
1091 FileUtil.write(file, bytes);
1092 }
1093 }
1094
1095 return FileUtil.getAbsolutePath(file);
1096 }
1097
1098 public String fixPortalDependencyJar(String portalJar) {
1099 if (portalJar.equals("antlr.jar")) {
1100 portalJar = "antlr2.jar";
1101 }
1102
1103 return portalJar;
1104 }
1105
1106 public DeploymentHandler getDeploymentHandler() {
1107 String prefix = "auto.deploy." + ServerDetector.getServerId() + ".jee.";
1108
1109 String dmId = PropsUtil.get(prefix + "dm.id");
1110 String dmUser = PropsUtil.get(prefix + "dm.user");
1111 String dmPassword = PropsUtil.get(prefix + "dm.passwd");
1112 String dfClassName = PropsUtil.get(prefix + "df.classname");
1113
1114 return new DeploymentHandler(dmId, dmUser, dmPassword, dfClassName);
1115 }
1116
1117 public String getDisplayName(File srcFile) {
1118 String displayName = srcFile.getName();
1119
1120 if (StringUtil.endsWith(displayName, ".war") ||
1121 StringUtil.endsWith(displayName, ".xml")) {
1122
1123 displayName = displayName.substring(0, displayName.length() - 4);
1124 }
1125
1126 if ((appServerType.equals(ServerDetector.JBOSS_ID) &&
1127 Validator.isNotNull(jbossPrefix) &&
1128 displayName.startsWith(jbossPrefix)) ||
1129 (appServerType.equals(ServerDetector.WILDFLY_ID) &&
1130 Validator.isNotNull(wildflyPrefix) &&
1131 displayName.startsWith(wildflyPrefix))) {
1132
1133 displayName = displayName.substring(1);
1134 }
1135
1136 return displayName;
1137 }
1138
1139 public String getDynamicResourceServletContent() {
1140 StringBundler sb = new StringBundler();
1141
1142 sb.append("<servlet>");
1143 sb.append("<servlet-name>");
1144 sb.append("Dynamic Resource Servlet");
1145 sb.append("</servlet-name>");
1146 sb.append("<servlet-class>");
1147 sb.append(PortalClassLoaderServlet.class.getName());
1148 sb.append("</servlet-class>");
1149 sb.append("<init-param>");
1150 sb.append("<param-name>");
1151 sb.append("servlet-class");
1152 sb.append("</param-name>");
1153 sb.append("<param-value>");
1154 sb.append(DynamicResourceServlet.class.getName());
1155 sb.append("</param-value>");
1156 sb.append("</init-param>");
1157 sb.append("<load-on-startup>1</load-on-startup>");
1158 sb.append("</servlet>");
1159
1160 for (String allowedPath :
1161 PropsValues.DYNAMIC_RESOURCE_SERVLET_ALLOWED_PATHS) {
1162
1163 sb.append("<servlet-mapping>");
1164 sb.append("<servlet-name>");
1165 sb.append("Dynamic Resource Servlet");
1166 sb.append("</servlet-name>");
1167 sb.append("<url-pattern>");
1168 sb.append(allowedPath);
1169
1170 if (!allowedPath.endsWith(StringPool.SLASH)) {
1171 sb.append(StringPool.SLASH);
1172 }
1173
1174 sb.append(StringPool.STAR);
1175 sb.append("</url-pattern>");
1176 sb.append("</servlet-mapping>");
1177 }
1178
1179 return sb.toString();
1180 }
1181
1182 public String getExtraContent(
1183 double webXmlVersion, File srcFile, String displayName)
1184 throws Exception {
1185
1186 StringBundler sb = new StringBundler();
1187
1188 sb.append("<display-name>");
1189 sb.append(displayName);
1190 sb.append("</display-name>");
1191
1192 if (webXmlVersion < 2.4) {
1193 sb.append("<context-param>");
1194 sb.append("<param-name>liferay-invoker-enabled</param-name>");
1195 sb.append("<param-value>false</param-value>");
1196 sb.append("</context-param>");
1197 }
1198
1199 if (PropsValues.SESSION_VERIFY_SERIALIZABLE_ATTRIBUTE) {
1200 sb.append("<listener>");
1201 sb.append("<listener-class>");
1202 sb.append(SerializableSessionAttributeListener.class.getName());
1203 sb.append("</listener-class>");
1204 sb.append("</listener>");
1205 }
1206
1207 sb.append(getDynamicResourceServletContent());
1208
1209 File serverConfigWsdd = new File(
1210 srcFile + "/WEB-INF/server-config.wsdd");
1211
1212 if (serverConfigWsdd.exists()) {
1213 File webXml = new File(srcFile + "/WEB-INF/web.xml");
1214
1215 String content = FileUtil.read(webXml);
1216
1217 if (!content.contains("axis.servicesPath")) {
1218 String remotingContent = FileUtil.read(
1219 DeployUtil.getResourcePath("remoting-web.xml"));
1220
1221 sb.append(remotingContent);
1222 }
1223 }
1224
1225 boolean hasTaglib = false;
1226
1227 if (Validator.isNotNull(auiTaglibDTD) ||
1228 Validator.isNotNull(portletTaglibDTD) ||
1229 Validator.isNotNull(portletExtTaglibDTD) ||
1230 Validator.isNotNull(securityTaglibDTD) ||
1231 Validator.isNotNull(themeTaglibDTD) ||
1232 Validator.isNotNull(uiTaglibDTD) ||
1233 Validator.isNotNull(utilTaglibDTD)) {
1234
1235 hasTaglib = true;
1236 }
1237
1238 if (hasTaglib && (webXmlVersion > 2.3)) {
1239 sb.append("<jsp-config>");
1240 }
1241
1242 if (Validator.isNotNull(auiTaglibDTD)) {
1243 sb.append("<taglib>");
1244 sb.append("<taglib-uri>http:
1245 sb.append("<taglib-location>");
1246 sb.append("/WEB-INF/tld/liferay-aui.tld");
1247 sb.append("</taglib-location>");
1248 sb.append("</taglib>");
1249 }
1250
1251 if (Validator.isNotNull(portletTaglibDTD)) {
1252 sb.append("<taglib>");
1253 sb.append(
1254 "<taglib-uri>http:
1255 sb.append("<taglib-location>");
1256 sb.append("/WEB-INF/tld/liferay-portlet.tld");
1257 sb.append("</taglib-location>");
1258 sb.append("</taglib>");
1259 }
1260
1261 if (Validator.isNotNull(portletExtTaglibDTD)) {
1262 sb.append("<taglib>");
1263 sb.append("<taglib-uri>");
1264 sb.append("http:
1265 sb.append("</taglib-uri>");
1266 sb.append("<taglib-location>");
1267 sb.append("/WEB-INF/tld/liferay-portlet-ext.tld");
1268 sb.append("</taglib-location>");
1269 sb.append("</taglib>");
1270 }
1271
1272 if (Validator.isNotNull(securityTaglibDTD)) {
1273 sb.append("<taglib>");
1274 sb.append("<taglib-uri>");
1275 sb.append("http:
1276 sb.append("</taglib-uri>");
1277 sb.append("<taglib-location>");
1278 sb.append("/WEB-INF/tld/liferay-security.tld");
1279 sb.append("</taglib-location>");
1280 sb.append("</taglib>");
1281 }
1282
1283 if (Validator.isNotNull(themeTaglibDTD)) {
1284 sb.append("<taglib>");
1285 sb.append("<taglib-uri>http:
1286 sb.append("<taglib-location>");
1287 sb.append("/WEB-INF/tld/liferay-theme.tld");
1288 sb.append("</taglib-location>");
1289 sb.append("</taglib>");
1290 }
1291
1292 if (Validator.isNotNull(uiTaglibDTD)) {
1293 sb.append("<taglib>");
1294 sb.append("<taglib-uri>http:
1295 sb.append("<taglib-location>");
1296 sb.append("/WEB-INF/tld/liferay-ui.tld");
1297 sb.append("</taglib-location>");
1298 sb.append("</taglib>");
1299 }
1300
1301 if (Validator.isNotNull(utilTaglibDTD)) {
1302 sb.append("<taglib>");
1303 sb.append("<taglib-uri>http:
1304 sb.append("<taglib-location>");
1305 sb.append("/WEB-INF/tld/liferay-util.tld");
1306 sb.append("</taglib-location>");
1307 sb.append("</taglib>");
1308 }
1309
1310 if (hasTaglib && (webXmlVersion > 2.3)) {
1311 sb.append("</jsp-config>");
1312 }
1313
1314 return sb.toString();
1315 }
1316
1317 public String getExtraFiltersContent(double webXmlVersion, File srcFile)
1318 throws Exception {
1319
1320 return getSessionFiltersContent();
1321 }
1322
1323 public String getIgnoreFiltersContent(File srcFile) throws Exception {
1324 boolean ignoreFiltersEnabled = true;
1325
1326 Properties properties = getPluginPackageProperties(srcFile);
1327
1328 if (properties != null) {
1329 ignoreFiltersEnabled = GetterUtil.getBoolean(
1330 properties.getProperty("ignore-filters-enabled"), true);
1331 }
1332
1333 if (ignoreFiltersEnabled) {
1334 String ignoreFiltersContent = FileUtil.read(
1335 DeployUtil.getResourcePath("ignore-filters-web.xml"));
1336
1337 return ignoreFiltersContent;
1338 }
1339 else {
1340 return StringPool.BLANK;
1341 }
1342 }
1343
1344 public String getInvokerFilterContent() {
1345 StringBundler sb = new StringBundler(4);
1346
1347 sb.append(getInvokerFilterContent("ERROR"));
1348 sb.append(getInvokerFilterContent("FORWARD"));
1349 sb.append(getInvokerFilterContent("INCLUDE"));
1350 sb.append(getInvokerFilterContent("REQUEST"));
1351
1352 return sb.toString();
1353 }
1354
1355 public String getInvokerFilterContent(String dispatcher) {
1356 StringBundler sb = new StringBundler(23);
1357
1358 sb.append("<filter>");
1359 sb.append("<filter-name>Invoker Filter - ");
1360 sb.append(dispatcher);
1361 sb.append("</filter-name>");
1362 sb.append("<filter-class>");
1363 sb.append(InvokerFilter.class.getName());
1364 sb.append("</filter-class>");
1365 sb.append("<init-param>");
1366 sb.append("<param-name>dispatcher</param-name>");
1367 sb.append("<param-value>");
1368 sb.append(dispatcher);
1369 sb.append("</param-value>");
1370 sb.append("</init-param>");
1371 sb.append("</filter>");
1372
1373 sb.append("<filter-mapping>");
1374 sb.append("<filter-name>Invoker Filter - ");
1375 sb.append(dispatcher);
1376 sb.append("</filter-name>");
1377 sb.append("<url-pattern>