1
14
15 package com.liferay.portal.tools.deploy;
16
17 import com.liferay.portal.deploy.DeployUtil;
18 import com.liferay.portal.kernel.deploy.Deployer;
19 import com.liferay.portal.kernel.deploy.auto.AutoDeployException;
20 import com.liferay.portal.kernel.log.Log;
21 import com.liferay.portal.kernel.log.LogFactoryUtil;
22 import com.liferay.portal.kernel.plugin.License;
23 import com.liferay.portal.kernel.plugin.PluginPackage;
24 import com.liferay.portal.kernel.util.FileUtil;
25 import com.liferay.portal.kernel.util.GetterUtil;
26 import com.liferay.portal.kernel.util.HttpUtil;
27 import com.liferay.portal.kernel.util.PropertiesUtil;
28 import com.liferay.portal.kernel.util.PropsKeys;
29 import com.liferay.portal.kernel.util.ServerDetector;
30 import com.liferay.portal.kernel.util.StringBundler;
31 import com.liferay.portal.kernel.util.StringPool;
32 import com.liferay.portal.kernel.util.StringUtil;
33 import com.liferay.portal.kernel.util.Time;
34 import com.liferay.portal.kernel.util.Validator;
35 import com.liferay.portal.kernel.xml.Document;
36 import com.liferay.portal.kernel.xml.Element;
37 import com.liferay.portal.kernel.xml.SAXReaderUtil;
38 import com.liferay.portal.plugin.PluginPackageUtil;
39 import com.liferay.portal.tools.WebXMLBuilder;
40 import com.liferay.portal.util.ExtRegistry;
41 import com.liferay.portal.util.InitUtil;
42 import com.liferay.portal.util.PortalUtil;
43 import com.liferay.portal.util.PrefsPropsUtil;
44 import com.liferay.portal.util.PropsUtil;
45 import com.liferay.portal.util.PropsValues;
46 import com.liferay.util.SystemProperties;
47 import com.liferay.util.ant.CopyTask;
48 import com.liferay.util.ant.DeleteTask;
49 import com.liferay.util.ant.ExpandTask;
50 import com.liferay.util.ant.UpToDateTask;
51 import com.liferay.util.ant.WarTask;
52 import com.liferay.util.xml.XMLFormatter;
53
54 import java.io.File;
55 import java.io.FileInputStream;
56 import java.io.IOException;
57 import java.io.InputStream;
58
59 import java.util.ArrayList;
60 import java.util.List;
61 import java.util.Map;
62 import java.util.Properties;
63 import java.util.Set;
64 import java.util.zip.ZipEntry;
65 import java.util.zip.ZipFile;
66
67 import org.apache.oro.io.GlobFilenameFilter;
68
69
75 public class BaseDeployer implements Deployer {
76
77 public static final String DEPLOY_TO_PREFIX = "DEPLOY_TO__";
78
79 public static void main(String[] args) {
80 InitUtil.initWithSpring();
81
82 List<String> wars = new ArrayList<String>();
83 List<String> jars = new ArrayList<String>();
84
85 for (String arg : args) {
86 String fileName = arg.toLowerCase();
87
88 if (fileName.endsWith(".war")) {
89 wars.add(arg);
90 }
91 else if (fileName.endsWith(".jar")) {
92 jars.add(arg);
93 }
94 }
95
96 new BaseDeployer(wars, jars);
97 }
98
99 public BaseDeployer() {
100 }
101
102 public BaseDeployer(List<String> wars, List<String> jars) {
103 baseDir = System.getProperty("deployer.base.dir");
104 destDir = System.getProperty("deployer.dest.dir");
105 appServerType = System.getProperty("deployer.app.server.type");
106 portletTaglibDTD = System.getProperty("deployer.portlet.taglib.dtd");
107 portletExtTaglibDTD = System.getProperty(
108 "deployer.portlet.ext.taglib.dtd");
109 securityTaglibDTD = System.getProperty("deployer.security.taglib.dtd");
110 themeTaglibDTD = System.getProperty("deployer.theme.taglib.dtd");
111 uiTaglibDTD = System.getProperty("deployer.ui.taglib.dtd");
112 utilTaglibDTD = System.getProperty("deployer.util.taglib.dtd");
113 unpackWar = GetterUtil.getBoolean(
114 System.getProperty("deployer.unpack.war"), true);
115 filePattern = System.getProperty("deployer.file.pattern");
116 jbossPrefix = GetterUtil.getString(
117 System.getProperty("deployer.jboss.prefix"));
118 tomcatLibDir = System.getProperty("deployer.tomcat.lib.dir");
119 this.wars = wars;
120 this.jars = jars;
121
122 checkArguments();
123
124 try {
125 deploy();
126 }
127 catch (Exception e) {
128 e.printStackTrace();
129 }
130 }
131
132 public void addExtJar(List<String> jars, String resource)
133 throws Exception {
134
135 Set<String> servletContextNames = ExtRegistry.getServletContextNames();
136
137 for (String servletContextName : servletContextNames) {
138 String extResource =
139 "ext-" + servletContextName + resource.substring(3);
140
141 String path = DeployUtil.getResourcePath(extResource);
142
143 if (_log.isDebugEnabled()) {
144 if (path == null) {
145 _log.debug("Resource " + extResource + " is not available");
146 }
147 else {
148 _log.debug(
149 "Resource " + extResource + " is available at " + path);
150 }
151 }
152
153 if (path != null) {
154 jars.add(path);
155 }
156 }
157 }
158
159 public void addRequiredJar(List<String> jars, String resource)
160 throws Exception {
161
162 String path = DeployUtil.getResourcePath(resource);
163
164 if (path == null) {
165 throw new RuntimeException(
166 "Resource " + resource + " does not exist");
167 }
168
169 if (_log.isDebugEnabled()) {
170 _log.debug("Resource " + resource + " is available at " + path);
171 }
172
173 jars.add(path);
174 }
175
176 public void checkArguments() {
177 if (Validator.isNull(baseDir)) {
178 throw new IllegalArgumentException(
179 "The system property deployer.base.dir is not set");
180 }
181
182 if (Validator.isNull(destDir)) {
183 throw new IllegalArgumentException(
184 "The system property deployer.dest.dir is not set");
185 }
186
187 if (Validator.isNull(appServerType)) {
188 throw new IllegalArgumentException(
189 "The system property deployer.app.server.type is not set");
190 }
191
192 if (!appServerType.startsWith(ServerDetector.GERONIMO_ID) &&
193 !appServerType.startsWith(ServerDetector.GLASSFISH_ID) &&
194 !appServerType.startsWith(ServerDetector.JBOSS_ID) &&
195 !appServerType.startsWith(ServerDetector.JONAS_ID) &&
196 !appServerType.equals(ServerDetector.JETTY_ID) &&
197 !appServerType.equals(ServerDetector.OC4J_ID) &&
198 !appServerType.equals(ServerDetector.RESIN_ID) &&
199 !appServerType.equals(ServerDetector.TOMCAT_ID) &&
200 !appServerType.equals(ServerDetector.WEBLOGIC_ID) &&
201 !appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
202
203 throw new IllegalArgumentException(
204 appServerType + " is not a valid application server type");
205 }
206
207 if (appServerType.startsWith(ServerDetector.GLASSFISH_ID) ||
208 appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
209
210 unpackWar = false;
211 }
212
213 if (Validator.isNotNull(jbossPrefix) &&
214 !Validator.isNumber(jbossPrefix)) {
215
216 jbossPrefix = "1";
217 }
218 }
219
220 public void copyDependencyXml(String fileName, String targetDir)
221 throws Exception {
222
223 copyDependencyXml(fileName, targetDir, null);
224 }
225
226 public void copyDependencyXml(
227 String fileName, String targetDir, Map<String, String> filterMap)
228 throws Exception {
229
230 copyDependencyXml(fileName, targetDir, filterMap, false);
231 }
232
233 public void copyDependencyXml(
234 String fileName, String targetDir, Map<String, String> filterMap,
235 boolean overwrite)
236 throws Exception {
237
238 File file = new File(DeployUtil.getResourcePath(fileName));
239 File targetFile = new File(targetDir + "/" + fileName);
240
241 if (!targetFile.exists()) {
242 CopyTask.copyFile(
243 file, new File(targetDir), filterMap, overwrite, true);
244 }
245 }
246
247 public void copyJars(File srcFile, PluginPackage pluginPackage)
248 throws Exception {
249
250 for (int i = 0; i < jars.size(); i++) {
251 String jarFullName = jars.get(i);
252
253 String jarName = jarFullName.substring(
254 jarFullName.lastIndexOf("/") + 1, jarFullName.length());
255
256 if ((!appServerType.equals(ServerDetector.TOMCAT_ID)) ||
257 (appServerType.equals(ServerDetector.TOMCAT_ID) &&
258 !jarFullName.equals("util-java.jar"))) {
259
260 FileUtil.copyFile(
261 jarFullName, srcFile + "/WEB-INF/lib/" + jarName, true);
262 }
263 }
264
265 FileUtil.delete(srcFile + "/WEB-INF/lib/util-jsf.jar");
266 }
267
268 public void copyPortalDependencies(File srcFile) throws Exception {
269 Properties properties = getPluginPackageProperties(srcFile);
270
271 if (properties == null) {
272 return;
273 }
274
275
277 String[] portalJars = StringUtil.split(
278 properties.getProperty(
279 "portal-dependency-jars",
280 properties.getProperty("portal.dependency.jars")));
281
282 for (int i = 0; i < portalJars.length; i++) {
283 String portalJar = portalJars[i].trim();
284
285 if (_log.isDebugEnabled()) {
286 _log.debug("Copy portal JAR " + portalJar);
287 }
288
289 try {
290 String portalJarPath = PortalUtil.getPortalLibDir() + portalJar;
291
292 FileUtil.copyFile(
293 portalJarPath, srcFile + "/WEB-INF/lib/" + portalJar, true);
294 }
295 catch (Exception e) {
296 _log.error("Unable to copy portal JAR " + portalJar, e);
297 }
298 }
299
300
302 String[] portalTlds = StringUtil.split(
303 properties.getProperty(
304 "portal-dependency-tlds",
305 properties.getProperty("portal.dependency.tlds")));
306
307 for (int i = 0; i < portalTlds.length; i++) {
308 String portalTld = portalTlds[i].trim();
309
310 if (_log.isDebugEnabled()) {
311 _log.debug("Copy portal TLD " + portalTld);
312 }
313
314 try {
315 String portalTldPath = DeployUtil.getResourcePath(portalTld);
316
317 FileUtil.copyFile(
318 portalTldPath, srcFile + "/WEB-INF/tld/" + portalTld, true);
319 }
320 catch (Exception e) {
321 _log.error("Unable to copy portal TLD " + portalTld, e);
322 }
323 }
324
325
327 File pluginLibDir = new File(srcFile + "/WEB-INF/lib/");
328
329 String[] commonsLoggingJars = pluginLibDir.list(
330 new GlobFilenameFilter("commons-logging*.jar"));
331
332 if ((commonsLoggingJars == null) || (commonsLoggingJars.length == 0)) {
333 String portalJarPath =
334 PortalUtil.getPortalLibDir() + "commons-logging.jar";
335
336 FileUtil.copyFile(
337 portalJarPath, srcFile + "/WEB-INF/lib/commons-logging.jar",
338 true);
339 }
340
341
343 String[] log4jJars = pluginLibDir.list(
344 new GlobFilenameFilter("log4j*.jar"));
345
346 if ((log4jJars == null) || (log4jJars.length == 0)) {
347 String portalJarPath = PortalUtil.getPortalLibDir() + "log4j.jar";
348
349 FileUtil.copyFile(
350 portalJarPath, srcFile + "/WEB-INF/lib/log4j.jar", true);
351 }
352 }
353
354 public void copyProperties(File srcFile, PluginPackage pluginPackage)
355 throws Exception {
356
357 copyDependencyXml("log4j.properties", srcFile + "/WEB-INF/classes");
358 copyDependencyXml("logging.properties", srcFile + "/WEB-INF/classes");
359 }
360
361 public void copyTlds(File srcFile, PluginPackage pluginPackage)
362 throws Exception {
363
364 if (Validator.isNotNull(portletTaglibDTD)) {
365 FileUtil.copyFile(
366 portletTaglibDTD, srcFile + "/WEB-INF/tld/liferay-portlet.tld",
367 true);
368 }
369
370 if (Validator.isNotNull(portletExtTaglibDTD)) {
371 FileUtil.copyFile(
372 portletExtTaglibDTD,
373 srcFile + "/WEB-INF/tld/liferay-portlet-ext.tld", true);
374 }
375
376 if (Validator.isNotNull(securityTaglibDTD)) {
377 FileUtil.copyFile(
378 securityTaglibDTD,
379 srcFile + "/WEB-INF/tld/liferay-security.tld", true);
380 }
381
382 if (Validator.isNotNull(themeTaglibDTD)) {
383 FileUtil.copyFile(
384 themeTaglibDTD, srcFile + "/WEB-INF/tld/liferay-theme.tld",
385 true);
386 }
387
388 if (Validator.isNotNull(uiTaglibDTD)) {
389 FileUtil.copyFile(
390 uiTaglibDTD, srcFile + "/WEB-INF/tld/liferay-ui.tld", true);
391 }
392
393 if (Validator.isNotNull(utilTaglibDTD)) {
394 FileUtil.copyFile(
395 utilTaglibDTD, srcFile + "/WEB-INF/tld/liferay-util.tld", true);
396 }
397 }
398
399 public void copyXmls(
400 File srcFile, String displayName, PluginPackage pluginPackage)
401 throws Exception {
402
403 if (appServerType.startsWith(ServerDetector.GERONIMO_ID)) {
404 copyDependencyXml("geronimo-web.xml", srcFile + "/WEB-INF");
405 }
406 else if (appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
407 copyDependencyXml("weblogic.xml", srcFile + "/WEB-INF");
408 }
409 else if (appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
410 copyDependencyXml("ibm-web-ext.xmi", srcFile + "/WEB-INF");
411 }
412
413 copyDependencyXml("web.xml", srcFile + "/WEB-INF");
414 }
415
416 public void deploy() throws Exception {
417 try {
418 File baseDirFile = new File(baseDir);
419
420 File[] files = baseDirFile.listFiles();
421
422 if (files == null) {
423 return;
424 }
425
426 files = FileUtil.sortFiles(files);
427
428 for (int i = 0; i < files.length; i++) {
429 File srcFile = files[i];
430
431 String fileName = srcFile.getName().toLowerCase();
432
433 boolean deploy = false;
434
435 if (fileName.endsWith(".war") || fileName.endsWith(".zip")) {
436 deploy = true;
437
438 if (wars.size() > 0) {
439 if (!wars.contains(srcFile.getName())) {
440 deploy = false;
441 }
442 }
443 else if (Validator.isNotNull(filePattern)) {
444 if (!StringUtil.matches(fileName, filePattern)) {
445 deploy = false;
446 }
447 }
448 }
449
450 if (deploy) {
451 deployFile(srcFile);
452 }
453 }
454 }
455 catch (Exception e) {
456 e.printStackTrace();
457 }
458 }
459
460 public void deployDirectory(
461 File srcFile, String displayName, boolean override,
462 PluginPackage pluginPackage)
463 throws Exception {
464
465 deployDirectory(
466 srcFile, null, null, displayName, override, pluginPackage);
467 }
468
469 public void deployDirectory(
470 File srcFile, File mergeDir, File deployDir, String displayName,
471 boolean overwrite, PluginPackage pluginPackage)
472 throws Exception {
473
474 rewriteFiles(srcFile);
475
476 mergeDirectory(mergeDir, srcFile);
477
478 processPluginPackageProperties(srcFile, displayName, pluginPackage);
479
480 copyJars(srcFile, pluginPackage);
481 copyProperties(srcFile, pluginPackage);
482 copyTlds(srcFile, pluginPackage);
483 copyXmls(srcFile, displayName, pluginPackage);
484 copyPortalDependencies(srcFile);
485
486 updateGeronimoWebXml(srcFile, displayName, pluginPackage);
487
488 File webXml = new File(srcFile + "/WEB-INF/web.xml");
489
490 updateWebXml(webXml, srcFile, displayName, pluginPackage);
491
492 File extLibGlobalDir = new File(
493 srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/global");
494
495 if (extLibGlobalDir.exists()) {
496 File globalLibDir = new File(PortalUtil.getGlobalLibDir());
497
498 CopyTask.copyDirectory(
499 extLibGlobalDir, globalLibDir, "*.jar", StringPool.BLANK,
500 overwrite, true);
501 }
502
503 File extLibPortalDir = new File(
504 srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/portal");
505
506 if (extLibPortalDir.exists()) {
507 File portalLibDir = new File(PortalUtil.getPortalLibDir());
508
509 CopyTask.copyDirectory(
510 extLibPortalDir, portalLibDir, "*.jar", StringPool.BLANK,
511 overwrite, true);
512 }
513
514 if ((deployDir == null) || baseDir.equals(destDir)) {
515 return;
516 }
517
518 updateDeployDirectory(srcFile);
519
520 String excludes = StringPool.BLANK;
521
522 if (appServerType.startsWith("jboss")) {
523 excludes += "**/WEB-INF/lib/log4j.jar,";
524 }
525 else if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
526 String[] libs = FileUtil.listFiles(tomcatLibDir);
527
528 for (int i = 0; i < libs.length; i++) {
529 excludes += "**/WEB-INF/lib/" + libs[i] + ",";
530 }
531
532 File contextXml = new File(srcFile + "/META-INF/context.xml");
533
534 if (contextXml.exists()) {
535 String content = FileUtil.read(contextXml);
536
537 if (content.indexOf(_PORTAL_CLASS_LOADER) != -1) {
538 excludes += "**/WEB-INF/lib/util-bridges.jar,";
539 excludes += "**/WEB-INF/lib/util-java.jar,";
540 excludes += "**/WEB-INF/lib/util-taglib.jar,";
541 }
542 }
543
544 try {
545
546
548 Class.forName("javax.el.ELContext");
549
550 excludes += "**/WEB-INF/lib/el-api.jar,";
551 }
552 catch (ClassNotFoundException cnfe) {
553 }
554 }
555
556 if (!unpackWar || appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
557 File tempDir = new File(
558 SystemProperties.get(SystemProperties.TMP_DIR) +
559 File.separator + Time.getTimestamp());
560
561 WarTask.war(srcFile, tempDir, "WEB-INF/web.xml", webXml);
562
563 if (isJEEDeploymentEnabled()) {
564 File tempWarDir = new File(
565 tempDir.getParent(), deployDir.getName());
566
567 if (tempWarDir.exists()) {
568 tempWarDir.delete();
569 }
570
571 if (!tempDir.renameTo(tempWarDir)) {
572 tempWarDir = tempDir;
573 }
574
575 DeploymentHandler deploymentHandler = getDeploymentHandler();
576
577 deploymentHandler.deploy(tempWarDir, displayName);
578
579 deploymentHandler.releaseDeploymentManager();
580
581 DeleteTask.deleteDirectory(tempWarDir);
582 }
583 else {
584 if (!tempDir.renameTo(deployDir)) {
585 WarTask.war(srcFile, deployDir, "WEB-INF/web.xml", webXml);
586 }
587
588 DeleteTask.deleteDirectory(tempDir);
589 }
590 }
591 else {
592
593
599 excludes += "**/WEB-INF/web.xml";
600
601 CopyTask.copyDirectory(
602 srcFile, deployDir, StringPool.BLANK, excludes, overwrite,
603 true);
604
605 CopyTask.copyDirectory(
606 srcFile, deployDir, "**/WEB-INF/web.xml", StringPool.BLANK,
607 true, false);
608
609 if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
610
611
615 File deployWebXml = new File(deployDir + "/WEB-INF/web.xml");
616
617 deployWebXml.setLastModified(
618 System.currentTimeMillis() + (Time.SECOND * 6));
619 }
620 }
621 }
622
623 public void deployFile(File srcFile) throws Exception {
624 PluginPackage pluginPackage = readPluginPackage(srcFile);
625
626 if (_log.isInfoEnabled()) {
627 _log.info("Deploying " + srcFile.getName());
628 }
629
630 String deployDir = null;
631 String displayName = null;
632 boolean overwrite = false;
633 String preliminaryContext = null;
634
635
638 if (srcFile.getName().startsWith(DEPLOY_TO_PREFIX)) {
639 displayName = srcFile.getName().substring(
640 DEPLOY_TO_PREFIX.length(), srcFile.getName().length() - 4);
641
642 overwrite = true;
643 preliminaryContext = displayName;
644 }
645
646 if (preliminaryContext == null) {
647 preliminaryContext = getDisplayName(srcFile);
648 }
649
650 if (pluginPackage != null) {
651 if (!PluginPackageUtil.isCurrentVersionSupported(
652 pluginPackage.getLiferayVersions())) {
653
654 throw new AutoDeployException(
655 srcFile.getName() +
656 " does not support this version of Liferay");
657 }
658
659 if (displayName == null) {
660 displayName = pluginPackage.getRecommendedDeploymentContext();
661 }
662
663 if (Validator.isNull(displayName)) {
664 displayName = getDisplayName(srcFile);
665 }
666
667 pluginPackage.setContext(displayName);
668
669 PluginPackageUtil.updateInstallingPluginPackage(
670 preliminaryContext, pluginPackage);
671 }
672
673 if (Validator.isNotNull(displayName)) {
674 deployDir = displayName + ".war";
675 }
676 else {
677 deployDir = srcFile.getName();
678 displayName = getDisplayName(srcFile);
679 }
680
681 if (appServerType.startsWith(ServerDetector.JBOSS_ID)) {
682 deployDir = jbossPrefix + deployDir;
683 }
684 else if (appServerType.equals(ServerDetector.JETTY_ID) ||
685 appServerType.equals(ServerDetector.OC4J_ID) ||
686 appServerType.equals(ServerDetector.RESIN_ID) ||
687 appServerType.equals(ServerDetector.TOMCAT_ID)) {
688
689 if (unpackWar) {
690 deployDir = deployDir.substring(0, deployDir.length() - 4);
691 }
692 }
693
694 deployDir = destDir + "/" + deployDir;
695
696 File deployDirFile = new File(deployDir);
697
698 try {
699 PluginPackage previousPluginPackage =
700 readPluginPackage(deployDirFile);
701
702 if ((pluginPackage != null) && (previousPluginPackage != null)) {
703 if (_log.isInfoEnabled()) {
704 String name = pluginPackage.getName();
705 String previousVersion = previousPluginPackage.getVersion();
706 String version = pluginPackage.getVersion();
707
708 _log.info(
709 "Updating " + name + " from version " +
710 previousVersion + " to version " + version);
711 }
712
713 if (pluginPackage.isLaterVersionThan(
714 previousPluginPackage)) {
715
716 overwrite = true;
717 }
718 }
719
720 File mergeDirFile = new File(
721 srcFile.getParent() + "/merge/" + srcFile.getName());
722
723 if (srcFile.isDirectory()) {
724 deployDirectory(
725 srcFile, mergeDirFile, deployDirFile, displayName,
726 overwrite, pluginPackage);
727 }
728 else {
729 boolean deployed = deployFile(
730 srcFile, mergeDirFile, deployDirFile, displayName,
731 overwrite, pluginPackage);
732
733 if (!deployed) {
734 String context = preliminaryContext;
735
736 if (pluginPackage != null) {
737 context = pluginPackage.getContext();
738 }
739
740 PluginPackageUtil.endPluginPackageInstallation(context);
741 }
742 }
743 }
744 catch (Exception e) {
745 if (pluginPackage != null) {
746 PluginPackageUtil.endPluginPackageInstallation(
747 pluginPackage.getContext());
748 }
749
750 throw e;
751 }
752 }
753
754 public boolean deployFile(
755 File srcFile, File mergeDir, File deployDir, String displayName,
756 boolean overwrite, PluginPackage pluginPackage)
757 throws Exception {
758
759 boolean undeployOnRedeploy = false;
760
761 try {
762 undeployOnRedeploy = PrefsPropsUtil.getBoolean(
763 PropsKeys.HOT_UNDEPLOY_ON_REDEPLOY,
764 PropsValues.HOT_UNDEPLOY_ON_REDEPLOY);
765 }
766 catch (Exception e) {
767
768
772 }
773
774 if (undeployOnRedeploy) {
775 DeployUtil.undeploy(appServerType, deployDir);
776 }
777
778 if (!overwrite && UpToDateTask.isUpToDate(srcFile, deployDir)) {
779 if (_log.isInfoEnabled()) {
780 _log.info(deployDir + " is already up to date");
781 }
782
783 return false;
784 }
785
786 File tempDir = new File(
787 SystemProperties.get(SystemProperties.TMP_DIR) + File.separator +
788 Time.getTimestamp());
789
790 ExpandTask.expand(srcFile, tempDir);
791
792 deployDirectory(
793 tempDir, mergeDir, deployDir, displayName, overwrite,
794 pluginPackage);
795
796 DeleteTask.deleteDirectory(tempDir);
797
798 return true;
799 }
800
801 public String downloadJar(String jar) throws Exception {
802 String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
803
804 File file = new File(
805 tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" +
806 jar);
807
808 if (!file.exists()) {
809 synchronized (this) {
810 String url = PropsUtil.get(
811 PropsKeys.LIBRARY_DOWNLOAD_URL + jar);
812
813 if (_log.isInfoEnabled()) {
814 _log.info("Downloading library from " + url);
815 }
816
817 byte[] bytes = HttpUtil.URLtoByteArray(url);
818
819 FileUtil.write(file, bytes);
820 }
821 }
822
823 return FileUtil.getAbsolutePath(file);
824 }
825
826 public String getDisplayName(File srcFile) {
827 String displayName = srcFile.getName();
828
829 if (StringUtil.endsWith(displayName, ".war") ||
830 StringUtil.endsWith(displayName, ".xml")) {
831
832 displayName = displayName.substring(0, displayName.length() - 4);
833 }
834
835 if (appServerType.startsWith("jboss") &&
836 Validator.isNotNull(jbossPrefix) &&
837 displayName.startsWith(jbossPrefix)) {
838
839 displayName = displayName.substring(1, displayName.length());
840 }
841
842 return displayName;
843 }
844
845 public DeploymentHandler getDeploymentHandler() {
846 String prefix = "auto.deploy." + ServerDetector.getServerId() + ".jee.";
847
848 String dmId = PropsUtil.get(prefix + "dm.id");
849 String dmUser = PropsUtil.get(prefix + "dm.user");
850 String dmPassword = PropsUtil.get(prefix + "dm.passwd");
851 String dfClassName = PropsUtil.get(prefix + "df.classname");
852
853 return new DeploymentHandler(dmId, dmUser, dmPassword, dfClassName);
854 }
855
856 public String getExtraContent(
857 double webXmlVersion, File srcFile, String displayName)
858 throws Exception {
859
860 StringBundler sb = new StringBundler();
861
862 sb.append("<display-name>");
863 sb.append(displayName);
864 sb.append("</display-name>");
865
866 sb.append("<listener>");
867 sb.append("<listener-class>");
868 sb.append("com.liferay.portal.kernel.servlet.");
869 sb.append("SerializableSessionAttributeListener");
870 sb.append("</listener-class>");
871 sb.append("</listener>");
872
873 File serviceXml = new File(srcFile + "/WEB-INF/service.xml");
874
875 if (serviceXml.exists()) {
876 sb.append("<listener>");
877 sb.append("<listener-class>");
878 sb.append("com.liferay.portal.kernel.spring.context.");
879 sb.append("PortletContextLoaderListener");
880 sb.append("</listener-class>");
881 sb.append("</listener>");
882 }
883
884 File serverConfigWsdd = new File(
885 srcFile + "/WEB-INF/server-config.wsdd");
886
887 if (serverConfigWsdd.exists()) {
888 File webXml = new File(srcFile + "/WEB-INF/web.xml");
889
890 String content = FileUtil.read(webXml);
891
892 if (!content.contains("axis.servicesPath")) {
893 String remotingContent = FileUtil.read(
894 DeployUtil.getResourcePath("remoting-web.xml"));
895
896 sb.append(remotingContent);
897 }
898 }
899
900 boolean hasTaglib = false;
901
902 if (Validator.isNotNull(portletTaglibDTD) ||
903 Validator.isNotNull(portletExtTaglibDTD) ||
904 Validator.isNotNull(securityTaglibDTD) ||
905 Validator.isNotNull(themeTaglibDTD) ||
906 Validator.isNotNull(uiTaglibDTD) ||
907 Validator.isNotNull(utilTaglibDTD)) {
908
909 hasTaglib = true;
910 }
911
912 if (hasTaglib && (webXmlVersion > 2.3)) {
913 sb.append("<jsp-config>");
914 }
915
916 if (Validator.isNotNull(portletTaglibDTD)) {
917 sb.append("<taglib>");
918 sb.append(
919 "<taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>");
920 sb.append("<taglib-location>");
921 sb.append("/WEB-INF/tld/liferay-portlet.tld");
922 sb.append("</taglib-location>");
923 sb.append("</taglib>");
924 }
925
926 if (Validator.isNotNull(portletExtTaglibDTD)) {
927 sb.append("<taglib>");
928 sb.append("<taglib-uri>");
929 sb.append("http://liferay.com/tld/portlet");
930 sb.append("</taglib-uri>");
931 sb.append("<taglib-location>");
932 sb.append("/WEB-INF/tld/liferay-portlet-ext.tld");
933 sb.append("</taglib-location>");
934 sb.append("</taglib>");
935 }
936
937 if (Validator.isNotNull(securityTaglibDTD)) {
938 sb.append("<taglib>");
939 sb.append("<taglib-uri>");
940 sb.append("http://liferay.com/tld/security");
941 sb.append("</taglib-uri>");
942 sb.append("<taglib-location>");
943 sb.append("/WEB-INF/tld/liferay-security.tld");
944 sb.append("</taglib-location>");
945 sb.append("</taglib>");
946 }
947
948 if (Validator.isNotNull(themeTaglibDTD)) {
949 sb.append("<taglib>");
950 sb.append("<taglib-uri>http://liferay.com/tld/theme</taglib-uri>");
951 sb.append("<taglib-location>");
952 sb.append("/WEB-INF/tld/liferay-theme.tld");
953 sb.append("</taglib-location>");
954 sb.append("</taglib>");
955 }
956
957 if (Validator.isNotNull(uiTaglibDTD)) {
958 sb.append("<taglib>");
959 sb.append("<taglib-uri>http://liferay.com/tld/ui</taglib-uri>");
960 sb.append("<taglib-location>");
961 sb.append("/WEB-INF/tld/liferay-ui.tld");
962 sb.append("</taglib-location>");
963 sb.append("</taglib>");
964 }
965
966 if (Validator.isNotNull(utilTaglibDTD)) {
967 sb.append("<taglib>");
968 sb.append("<taglib-uri>http://liferay.com/tld/util</taglib-uri>");
969 sb.append("<taglib-location>");
970 sb.append("/WEB-INF/tld/liferay-util.tld");
971 sb.append("</taglib-location>");
972 sb.append("</taglib>");
973 }
974
975 if (hasTaglib && (webXmlVersion > 2.3)) {
976 sb.append("</jsp-config>");
977 }
978
979 return sb.toString();
980 }
981
982 public String getIgnoreFiltersContent(File srcFile) throws Exception {
983 boolean ignoreFiltersEnabled = true;
984
985 Properties properties = getPluginPackageProperties(srcFile);
986
987 if (properties != null) {
988 ignoreFiltersEnabled = GetterUtil.getBoolean(
989 properties.getProperty("ignore-filters-enabled"), true);
990 }
991
992 if (ignoreFiltersEnabled) {
993 String ignoreFiltersContent = FileUtil.read(
994 DeployUtil.getResourcePath("ignore-filters-web.xml"));
995
996 return ignoreFiltersContent;
997 }
998 else {
999 return StringPool.BLANK;
1000 }
1001 }
1002
1003 public String getPluginPackageLicensesXml(List<License> licenses) {
1004 if (licenses.isEmpty()) {
1005 return StringPool.BLANK;
1006 }
1007
1008 StringBundler sb = new StringBundler(5 * licenses.size() + 2);
1009
1010 for (int i = 0; i < licenses.size(); i++) {
1011 License license = licenses.get(i);
1012
1013 if (i == 0) {
1014 sb.append("\r\n");
1015 }
1016
1017 sb.append("\t\t<license osi-approved=\"");
1018 sb.append(license.isOsiApproved());
1019 sb.append("\">");
1020 sb.append(license.getName());
1021 sb.append("</license>\r\n");
1022
1023 if ((i + 1) == licenses.size()) {
1024 sb.append("\t");
1025 }
1026 }
1027
1028 return sb.toString();
1029 }
1030
1031 public String getPluginPackageLiferayVersionsXml(
1032 List<String> liferayVersions) {
1033
1034 if (liferayVersions.isEmpty()) {
1035 return StringPool.BLANK;
1036 }
1037
1038 StringBundler sb = new StringBundler(liferayVersions.size() * 3 + 2);
1039
1040 for (int i = 0; i < liferayVersions.size(); i++) {
1041 String liferayVersion = liferayVersions.get(i);
1042
1043 if (i == 0) {
1044 sb.append("\r\n");
1045 }
1046
1047 sb.append("\t\t<liferay-version>");
1048 sb.append(liferayVersion);
1049 sb.append("</liferay-version>\r\n");
1050
1051 if ((i + 1) == liferayVersions.size()) {
1052 sb.append("\t");
1053 }
1054 }
1055
1056 return sb.toString();
1057 }
1058
1059 public Properties getPluginPackageProperties(File srcFile)
1060 throws Exception {
1061
1062 File propertiesFile = new File(
1063 srcFile + "/WEB-INF/liferay-plugin-package.properties");
1064
1065 if (!propertiesFile.exists()) {
1066 return null;
1067 }
1068
1069 String propertiesString = FileUtil.read(propertiesFile);
1070
1071 return PropertiesUtil.load(propertiesString);
1072 }
1073
1074 public String getPluginPackageTagsXml(List<String> tags) {
1075 if (tags.isEmpty()) {
1076 return StringPool.BLANK;
1077 }
1078
1079 StringBundler sb = new StringBundler(tags.size() * 3 + 2);
1080
1081 for (int i = 0; i < tags.size(); i++) {
1082 String tag = tags.get(i);
1083
1084 if (i == 0) {
1085 sb.append("\r\n");
1086 }
1087
1088 sb.append("\t\t<tag>");
1089 sb.append(tag);
1090 sb.append("</tag>\r\n");
1091
1092 if ((i + 1) == tags.size()) {
1093 sb.append("\t");
1094 }
1095 }
1096
1097 return sb.toString();
1098 }
1099
1100 public String getSpeedFiltersContent(File srcFile) throws Exception {
1101 boolean speedFiltersEnabled = true;
1102
1103 Properties properties = getPluginPackageProperties(srcFile);
1104
1105 if (properties != null) {
1106 speedFiltersEnabled = GetterUtil.getBoolean(
1107 properties.getProperty("speed-filters-enabled"), true);
1108 }
1109
1110 if (speedFiltersEnabled) {
1111 String speedFiltersContent = FileUtil.read(
1112 DeployUtil.getResourcePath("speed-filters-web.xml"));
1113
1114 return speedFiltersContent;
1115 }
1116 else {
1117 return StringPool.BLANK;
1118 }
1119 }
1120
1121 public boolean isJEEDeploymentEnabled() {
1122 return GetterUtil.getBoolean(PropsUtil.get(
1123 "auto.deploy." + ServerDetector.getServerId() +
1124 ".jee.deployment.enabled"));
1125 }
1126
1127 public void mergeDirectory(File mergeDir, File targetDir) {
1128 if ((mergeDir == null) || (!mergeDir.exists())) {
1129 return;
1130 }
1131
1132 CopyTask.copyDirectory(mergeDir, targetDir, null, null, true, false);
1133 }
1134
1135 public void processPluginPackageProperties(
1136 File srcFile, String displayName, PluginPackage pluginPackage)
1137 throws Exception {
1138 }
1139
1140 public PluginPackage readPluginPackage(File file) {
1141 if (!file.exists()) {
1142 return null;
1143 }
1144
1145 InputStream is = null;
1146 ZipFile zipFile = null;
1147
1148 try {
1149 boolean parseProps = false;
1150
1151 if (file.isDirectory()) {
1152 String path = file.getPath();
1153
1154 File pluginPackageXmlFile = new File(
1155 file.getParent() + "/merge/" + file.getName() +
1156 "/WEB-INF/liferay-plugin-package.xml");
1157
1158 if (pluginPackageXmlFile.exists()) {
1159 is = new FileInputStream(pluginPackageXmlFile);
1160 }
1161 else {
1162 pluginPackageXmlFile = new File(
1163 path + "/WEB-INF/liferay-plugin-package.xml");
1164
1165 if (pluginPackageXmlFile.exists()) {
1166 is = new FileInputStream(pluginPackageXmlFile);
1167 }
1168 }
1169
1170 File pluginPackagePropsFile = new File(
1171 file.getParent() + "/merge/" + file.getName() +
1172 "/WEB-INF/liferay-plugin-package.properties");
1173
1174 if ((is == null) && pluginPackagePropsFile.exists()) {
1175 is = new FileInputStream(pluginPackagePropsFile);
1176
1177 parseProps = true;
1178 }
1179 else {
1180 pluginPackagePropsFile = new File(
1181 path + "/WEB-INF/liferay-plugin-package.properties");
1182
1183 if ((is == null) && pluginPackagePropsFile.exists()) {
1184 is = new FileInputStream(pluginPackagePropsFile);
1185
1186 parseProps = true;
1187 }
1188 }
1189 }
1190 else {
1191 zipFile = new ZipFile(file);
1192
1193 File pluginPackageXmlFile = new File(
1194 file.getParent() + "/merge/" + file.getName() +
1195 "/WEB-INF/liferay-plugin-package.xml");
1196
1197 if (pluginPackageXmlFile.exists()) {
1198 is = new FileInputStream(pluginPackageXmlFile);
1199 }
1200 else {
1201 ZipEntry zipEntry = zipFile.getEntry(
1202 "WEB-INF/liferay-plugin-package.xml");
1203
1204 if (zipEntry != null) {
1205 is = zipFile.getInputStream(zipEntry);
1206 }
1207 }
1208
1209 File pluginPackagePropsFile = new File(
1210 file.getParent() + "/merge/" + file.getName() +
1211 "/WEB-INF/liferay-plugin-package.properties");
1212
1213 if ((is == null) && pluginPackagePropsFile.exists()) {
1214 is = new FileInputStream(pluginPackagePropsFile);
1215
1216 parseProps = true;
1217 }
1218 else {
1219 ZipEntry zipEntry = zipFile.getEntry(
1220 "WEB-INF/liferay-plugin-package.properties");
1221
1222 if ((is == null) && (zipEntry != null)) {
1223 is = zipFile.getInputStream(zipEntry);
1224
1225 parseProps = true;
1226 }
1227 }
1228 }
1229
1230 if (is == null) {
1231 if (_log.isInfoEnabled()) {
1232 _log.info(
1233 file.getPath() + " does not have a " +
1234 "WEB-INF/liferay-plugin-package.xml or " +
1235 "WEB-INF/liferay-plugin-package.properties");
1236 }
1237
1238 return null;
1239 }
1240
1241 if (parseProps) {
1242 String displayName = getDisplayName(file);
1243
1244 String propertiesString = StringUtil.read(is);
1245
1246 Properties properties = PropertiesUtil.load(propertiesString);
1247
1248 return PluginPackageUtil.readPluginPackageProperties(
1249 displayName, properties);
1250 }
1251 else {
1252 String xml = StringUtil.read(is);
1253
1254 xml = XMLFormatter.fixProlog(xml);
1255
1256 return PluginPackageUtil.readPluginPackageXml(xml);
1257 }
1258 }
1259 catch (Exception e) {
1260 _log.error(file.getPath() + ": " + e.toString());
1261 }
1262 finally {
1263 if (is != null) {
1264 try {
1265 is.close();
1266 }
1267 catch (IOException ioe) {
1268 }
1269 }
1270
1271 if (zipFile != null) {
1272 try {
1273 zipFile.close();
1274 }
1275 catch (IOException ioe) {
1276 }
1277 }
1278 }
1279
1280 return null;
1281 }
1282
1283 public void rewriteFiles(File srcDir) throws Exception {
1284 String[] files = FileUtil.listFiles(srcDir + "/WEB-INF/");
1285
1286 for (int i = 0; i < files.length; i++) {
1287 String fileName = GetterUtil.getString(
1288 FileUtil.getShortFileName(files[i]));
1289
1290
1292 if (fileName.equalsIgnoreCase("mule-config.xml")) {
1293 continue;
1294 }
1295
1296 String ext = GetterUtil.getString(FileUtil.getExtension(files[i]));
1297
1298 if (!ext.equalsIgnoreCase("xml")) {
1299 continue;
1300 }
1301
1302
1305 File file = new File(srcDir + "/WEB-INF/" + files[i]);
1306
1307 try {
1308 Document doc = SAXReaderUtil.read(file);
1309
1310 String content = doc.formattedString(StringPool.TAB, true);
1311
1312 FileUtil.write(file, content);
1313 }
1314 catch (Exception e) {
1315 if (_log.isWarnEnabled()) {
1316 _log.warn(
1317 "Unable to format " + file + ": " + e.getMessage());
1318 }
1319 }
1320 }
1321 }
1322
1323 public void updateDeployDirectory(File srcFile) throws Exception {
1324 }
1325
1326 public void updateGeronimoWebXml(
1327 File srcFile, String displayName, PluginPackage pluginPackage)
1328 throws Exception {
1329
1330 if (!appServerType.startsWith(ServerDetector.GERONIMO_ID)) {
1331 return;
1332 }
1333
1334 File geronimoWebXml = new File(srcFile + "/WEB-INF/geronimo-web.xml");
1335
1336 Document doc = SAXReaderUtil.read(geronimoWebXml);
1337
1338 Element root = doc.getRootElement();
1339
1340 Element environmentEl = root.element("environment");
1341
1342 Element moduleIdEl = environmentEl.element("moduleId");
1343
1344 Element artifactIdEl = moduleIdEl.element("artifactId");
1345
1346 String artifactIdText = GetterUtil.getString(artifactIdEl.getText());
1347
1348 if (!artifactIdText.equals(displayName)) {
1349 artifactIdEl.setText(displayName);
1350
1351 String content = doc.formattedString();
1352
1353 FileUtil.write(geronimoWebXml, content);
1354
1355 if (_log.isInfoEnabled()) {
1356 _log.info("Modifying Geronimo " + geronimoWebXml);
1357 }
1358 }
1359 }
1360
1361 public void updateWebXml(
1362 File webXml, File srcFile, String displayName,
1363 PluginPackage pluginPackage)
1364 throws Exception {
1365
1366 String content = FileUtil.read(webXml);
1367
1368 int x = content.indexOf("<display-name>");
1369
1370 if (x != -1) {
1371 int y = content.indexOf("</display-name>", x);
1372
1373 y = content.indexOf(">", y) + 1;
1374
1375 content = content.substring(0, x) + content.substring(y);
1376 }
1377
1378 double webXmlVersion = 2.3;
1379
1380 Document webXmlDoc = SAXReaderUtil.read(content);
1381
1382 Element webXmlRoot = webXmlDoc.getRootElement();
1383
1384 webXmlVersion = GetterUtil.getDouble(
1385 webXmlRoot.attributeValue("version"), webXmlVersion);
1386
1387
1389 String extraContent = getExtraContent(
1390 webXmlVersion, srcFile, displayName);
1391
1392 if (webXmlVersion > 2.3) {
1393 while (true) {
1394 int pos = extraContent.indexOf(
1395 "<param-name>servlet-2.4-dispatcher</param-name>");
1396
1397 if (pos == -1) {
1398 break;
1399 }
1400
1401 x = extraContent.lastIndexOf("<init-param>", pos);
1402 int y = extraContent.indexOf("</init-param>", pos);
1403
1404 extraContent =
1405 extraContent.substring(0, x) +
1406 extraContent.substring(y + 13);
1407 }
1408 }
1409
1410 int pos = content.indexOf("</web-app>");
1411
1412 String newContent =
1413 content.substring(0, pos) + extraContent +
1414 content.substring(pos, content.length());
1415
1416
1418 newContent = StringUtil.replace(
1419 newContent, "com.liferay.portal.shared.",
1420 "com.liferay.portal.kernel.");
1421
1422 newContent = WebXMLBuilder.organizeWebXML(newContent);
1423
1424 FileUtil.write(webXml, newContent, true);
1425
1426 if (_log.isInfoEnabled()) {
1427 _log.info("Modifying Servlet " + webXmlVersion + " " + webXml);
1428 }
1429 }
1430
1431 protected String baseDir;
1432 protected String destDir;
1433 protected String appServerType;
1434 protected String portletTaglibDTD;
1435 protected String portletExtTaglibDTD;
1436 protected String securityTaglibDTD;
1437 protected String themeTaglibDTD;
1438 protected String uiTaglibDTD;
1439 protected String utilTaglibDTD;
1440 protected boolean unpackWar;
1441 protected String filePattern;
1442 protected String jbossPrefix;
1443 protected String tomcatLibDir;
1444 protected List<String> wars;
1445 protected List<String> jars;
1446
1447 private static final String _PORTAL_CLASS_LOADER =
1448 "com.liferay.support.tomcat.loader.PortalClassLoader";
1449
1450 private static Log _log = LogFactoryUtil.getLog(BaseDeployer.class);
1451
1452}