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