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 File serverConfigWsdd = new File(
878 srcFile + "/WEB-INF/server-config.wsdd");
879
880 if (serverConfigWsdd.exists()) {
881 File webXml = new File(srcFile + "/WEB-INF/web.xml");
882
883 String content = FileUtil.read(webXml);
884
885 if (!content.contains("axis.servicesPath")) {
886 String remotingContent = FileUtil.read(
887 DeployUtil.getResourcePath("remoting-web.xml"));
888
889 sb.append(remotingContent);
890 }
891 }
892
893 boolean hasTaglib = false;
894
895 if (Validator.isNotNull(auiTaglibDTD) ||
896 Validator.isNotNull(portletTaglibDTD) ||
897 Validator.isNotNull(portletExtTaglibDTD) ||
898 Validator.isNotNull(securityTaglibDTD) ||
899 Validator.isNotNull(themeTaglibDTD) ||
900 Validator.isNotNull(uiTaglibDTD) ||
901 Validator.isNotNull(utilTaglibDTD)) {
902
903 hasTaglib = true;
904 }
905
906 if (hasTaglib && (webXmlVersion > 2.3)) {
907 sb.append("<jsp-config>");
908 }
909
910 if (Validator.isNotNull(auiTaglibDTD)) {
911 sb.append("<taglib>");
912 sb.append("<taglib-uri>http://liferay.com/tld/aui</taglib-uri>");
913 sb.append("<taglib-location>");
914 sb.append("/WEB-INF/tld/liferay-aui.tld");
915 sb.append("</taglib-location>");
916 sb.append("</taglib>");
917 }
918
919 if (Validator.isNotNull(portletTaglibDTD)) {
920 sb.append("<taglib>");
921 sb.append(
922 "<taglib-uri>http://java.sun.com/portlet_2_0</taglib-uri>");
923 sb.append("<taglib-location>");
924 sb.append("/WEB-INF/tld/liferay-portlet.tld");
925 sb.append("</taglib-location>");
926 sb.append("</taglib>");
927 }
928
929 if (Validator.isNotNull(portletExtTaglibDTD)) {
930 sb.append("<taglib>");
931 sb.append("<taglib-uri>");
932 sb.append("http://liferay.com/tld/portlet");
933 sb.append("</taglib-uri>");
934 sb.append("<taglib-location>");
935 sb.append("/WEB-INF/tld/liferay-portlet-ext.tld");
936 sb.append("</taglib-location>");
937 sb.append("</taglib>");
938 }
939
940 if (Validator.isNotNull(securityTaglibDTD)) {
941 sb.append("<taglib>");
942 sb.append("<taglib-uri>");
943 sb.append("http://liferay.com/tld/security");
944 sb.append("</taglib-uri>");
945 sb.append("<taglib-location>");
946 sb.append("/WEB-INF/tld/liferay-security.tld");
947 sb.append("</taglib-location>");
948 sb.append("</taglib>");
949 }
950
951 if (Validator.isNotNull(themeTaglibDTD)) {
952 sb.append("<taglib>");
953 sb.append("<taglib-uri>http://liferay.com/tld/theme</taglib-uri>");
954 sb.append("<taglib-location>");
955 sb.append("/WEB-INF/tld/liferay-theme.tld");
956 sb.append("</taglib-location>");
957 sb.append("</taglib>");
958 }
959
960 if (Validator.isNotNull(uiTaglibDTD)) {
961 sb.append("<taglib>");
962 sb.append("<taglib-uri>http://liferay.com/tld/ui</taglib-uri>");
963 sb.append("<taglib-location>");
964 sb.append("/WEB-INF/tld/liferay-ui.tld");
965 sb.append("</taglib-location>");
966 sb.append("</taglib>");
967 }
968
969 if (Validator.isNotNull(utilTaglibDTD)) {
970 sb.append("<taglib>");
971 sb.append("<taglib-uri>http://liferay.com/tld/util</taglib-uri>");
972 sb.append("<taglib-location>");
973 sb.append("/WEB-INF/tld/liferay-util.tld");
974 sb.append("</taglib-location>");
975 sb.append("</taglib>");
976 }
977
978 if (hasTaglib && (webXmlVersion > 2.3)) {
979 sb.append("</jsp-config>");
980 }
981
982 return sb.toString();
983 }
984
985 protected String getPluginPackageLicensesXml(List<License> licenses) {
986 if (licenses.isEmpty()) {
987 return StringPool.BLANK;
988 }
989
990 StringBundler sb = new StringBundler(5 * licenses.size() + 2);
991
992 for (int i = 0; i < licenses.size(); i++) {
993 License license = licenses.get(i);
994
995 if (i == 0) {
996 sb.append("\r\n");
997 }
998
999 sb.append("\t\t<license osi-approved=\"");
1000 sb.append(license.isOsiApproved());
1001 sb.append("\">");
1002 sb.append(license.getName());
1003 sb.append("</license>\r\n");
1004
1005 if ((i + 1) == licenses.size()) {
1006 sb.append("\t");
1007 }
1008 }
1009
1010 return sb.toString();
1011 }
1012
1013 protected String getPluginPackageLiferayVersionsXml(
1014 List<String> liferayVersions) {
1015
1016 if (liferayVersions.isEmpty()) {
1017 return StringPool.BLANK;
1018 }
1019
1020 StringBundler sb = new StringBundler(liferayVersions.size() * 3 + 2);
1021
1022 for (int i = 0; i < liferayVersions.size(); i++) {
1023 String liferayVersion = liferayVersions.get(i);
1024
1025 if (i == 0) {
1026 sb.append("\r\n");
1027 }
1028
1029 sb.append("\t\t<liferay-version>");
1030 sb.append(liferayVersion);
1031 sb.append("</liferay-version>\r\n");
1032
1033 if ((i + 1) == liferayVersions.size()) {
1034 sb.append("\t");
1035 }
1036 }
1037
1038 return sb.toString();
1039 }
1040
1041 protected Properties getPluginPackageProperties(File srcFile)
1042 throws Exception {
1043
1044 File propertiesFile = new File(
1045 srcFile + "/WEB-INF/liferay-plugin-package.properties");
1046
1047 if (!propertiesFile.exists()) {
1048 return null;
1049 }
1050
1051 String propertiesString = FileUtil.read(propertiesFile);
1052
1053 return PropertiesUtil.load(propertiesString);
1054 }
1055
1056 protected String getPluginPackageTagsXml(List<String> tags) {
1057 if (tags.isEmpty()) {
1058 return StringPool.BLANK;
1059 }
1060
1061 StringBundler sb = new StringBundler(tags.size() * 3 + 2);
1062
1063 for (int i = 0; i < tags.size(); i++) {
1064 String tag = tags.get(i);
1065
1066 if (i == 0) {
1067 sb.append("\r\n");
1068 }
1069
1070 sb.append("\t\t<tag>");
1071 sb.append(tag);
1072 sb.append("</tag>\r\n");
1073
1074 if ((i + 1) == tags.size()) {
1075 sb.append("\t");
1076 }
1077 }
1078
1079 return sb.toString();
1080 }
1081
1082 protected String getSpeedFiltersContent(File srcFile) throws Exception {
1083 boolean speedFiltersEnabled = true;
1084
1085 Properties properties = getPluginPackageProperties(srcFile);
1086
1087 if (properties != null) {
1088 speedFiltersEnabled = GetterUtil.getBoolean(
1089 properties.getProperty("speed-filters-enabled"), true);
1090 }
1091
1092 if (speedFiltersEnabled) {
1093 String speedFiltersContent = FileUtil.read(
1094 DeployUtil.getResourcePath("speed-filters-web.xml"));
1095
1096 return speedFiltersContent;
1097 }
1098 else {
1099 return StringPool.BLANK;
1100 }
1101 }
1102
1103 protected boolean isJEEDeploymentEnabled() {
1104 return GetterUtil.getBoolean(PropsUtil.get(
1105 "auto.deploy." + ServerDetector.getServerId() +
1106 ".jee.deployment.enabled"));
1107 }
1108
1109 protected void mergeDirectory(File mergeDir, File targetDir) {
1110 if ((mergeDir == null) || (!mergeDir.exists())) {
1111 return;
1112 }
1113
1114 CopyTask.copyDirectory(mergeDir, targetDir, null, null, true, false);
1115 }
1116
1117 protected void processPluginPackageProperties(
1118 File srcFile, String displayName, PluginPackage pluginPackage)
1119 throws Exception {
1120 }
1121
1122 protected PluginPackage readPluginPackage(File file) {
1123 if (!file.exists()) {
1124 return null;
1125 }
1126
1127 InputStream is = null;
1128 ZipFile zipFile = null;
1129
1130 try {
1131 boolean parseProps = false;
1132
1133 if (file.isDirectory()) {
1134 String path = file.getPath();
1135
1136 File pluginPackageXmlFile = new File(
1137 file.getParent() + "/merge/" + file.getName() +
1138 "/WEB-INF/liferay-plugin-package.xml");
1139
1140 if (pluginPackageXmlFile.exists()) {
1141 is = new FileInputStream(pluginPackageXmlFile);
1142 }
1143 else {
1144 pluginPackageXmlFile = new File(
1145 path + "/WEB-INF/liferay-plugin-package.xml");
1146
1147 if (pluginPackageXmlFile.exists()) {
1148 is = new FileInputStream(pluginPackageXmlFile);
1149 }
1150 }
1151
1152 File pluginPackagePropsFile = new File(
1153 file.getParent() + "/merge/" + file.getName() +
1154 "/WEB-INF/liferay-plugin-package.properties");
1155
1156 if ((is == null) && pluginPackagePropsFile.exists()) {
1157 is = new FileInputStream(pluginPackagePropsFile);
1158
1159 parseProps = true;
1160 }
1161 else {
1162 pluginPackagePropsFile = new File(
1163 path + "/WEB-INF/liferay-plugin-package.properties");
1164
1165 if ((is == null) && pluginPackagePropsFile.exists()) {
1166 is = new FileInputStream(pluginPackagePropsFile);
1167
1168 parseProps = true;
1169 }
1170 }
1171 }
1172 else {
1173 zipFile = new ZipFile(file);
1174
1175 File pluginPackageXmlFile = new File(
1176 file.getParent() + "/merge/" + file.getName() +
1177 "/WEB-INF/liferay-plugin-package.xml");
1178
1179 if (pluginPackageXmlFile.exists()) {
1180 is = new FileInputStream(pluginPackageXmlFile);
1181 }
1182 else {
1183 ZipEntry zipEntry = zipFile.getEntry(
1184 "WEB-INF/liferay-plugin-package.xml");
1185
1186 if (zipEntry != null) {
1187 is = zipFile.getInputStream(zipEntry);
1188 }
1189 }
1190
1191 File pluginPackagePropsFile = new File(
1192 file.getParent() + "/merge/" + file.getName() +
1193 "/WEB-INF/liferay-plugin-package.properties");
1194
1195 if ((is == null) && pluginPackagePropsFile.exists()) {
1196 is = new FileInputStream(pluginPackagePropsFile);
1197
1198 parseProps = true;
1199 }
1200 else {
1201 ZipEntry zipEntry = zipFile.getEntry(
1202 "WEB-INF/liferay-plugin-package.properties");
1203
1204 if ((is == null) && (zipEntry != null)) {
1205 is = zipFile.getInputStream(zipEntry);
1206
1207 parseProps = true;
1208 }
1209 }
1210 }
1211
1212 if (is == null) {
1213 if (_log.isInfoEnabled()) {
1214 _log.info(
1215 file.getPath() + " does not have a " +
1216 "WEB-INF/liferay-plugin-package.xml or " +
1217 "WEB-INF/liferay-plugin-package.properties");
1218 }
1219
1220 return null;
1221 }
1222
1223 if (parseProps) {
1224 String displayName = getDisplayName(file);
1225
1226 String propertiesString = StringUtil.read(is);
1227
1228 Properties properties = PropertiesUtil.load(propertiesString);
1229
1230 return PluginPackageUtil.readPluginPackageProperties(
1231 displayName, properties);
1232 }
1233 else {
1234 String xml = StringUtil.read(is);
1235
1236 xml = XMLFormatter.fixProlog(xml);
1237
1238 return PluginPackageUtil.readPluginPackageXml(xml);
1239 }
1240 }
1241 catch (Exception e) {
1242 _log.error(file.getPath() + ": " + e.toString());
1243 }
1244 finally {
1245 if (is != null) {
1246 try {
1247 is.close();
1248 }
1249 catch (IOException ioe) {
1250 }
1251 }
1252
1253 if (zipFile != null) {
1254 try {
1255 zipFile.close();
1256 }
1257 catch (IOException ioe) {
1258 }
1259 }
1260 }
1261
1262 return null;
1263 }
1264
1265 protected void rewriteFiles(File srcDir) throws Exception {
1266 String[] files = FileUtil.listFiles(srcDir + "/WEB-INF/");
1267
1268 for (int i = 0; i < files.length; i++) {
1269 String fileName = GetterUtil.getString(
1270 FileUtil.getShortFileName(files[i]));
1271
1272
1274 if (fileName.equalsIgnoreCase("mule-config.xml")) {
1275 continue;
1276 }
1277
1278 String ext = GetterUtil.getString(FileUtil.getExtension(files[i]));
1279
1280 if (!ext.equalsIgnoreCase("xml")) {
1281 continue;
1282 }
1283
1284
1287 File file = new File(srcDir + "/WEB-INF/" + files[i]);
1288
1289 try {
1290 Document doc = SAXReaderUtil.read(file);
1291
1292 String content = doc.formattedString(StringPool.TAB, true);
1293
1294 FileUtil.write(file, content);
1295 }
1296 catch (Exception e) {
1297 if (_log.isWarnEnabled()) {
1298 _log.warn(
1299 "Unable to format " + file + ": " + e.getMessage());
1300 }
1301 }
1302 }
1303 }
1304
1305 protected void updateDeployDirectory(File srcFile) throws Exception {
1306 }
1307
1308 protected void updateGeronimoWebXml(
1309 File srcFile, String displayName, PluginPackage pluginPackage)
1310 throws Exception {
1311
1312 if (!appServerType.equals(ServerDetector.GERONIMO_ID)) {
1313 return;
1314 }
1315
1316 File geronimoWebXml = new File(srcFile + "/WEB-INF/geronimo-web.xml");
1317
1318 Document doc = SAXReaderUtil.read(geronimoWebXml);
1319
1320 Element root = doc.getRootElement();
1321
1322 Element environmentEl = root.element("environment");
1323
1324 Element moduleIdEl = environmentEl.element("moduleId");
1325
1326 Element artifactIdEl = moduleIdEl.element("artifactId");
1327
1328 String artifactIdText = GetterUtil.getString(artifactIdEl.getText());
1329
1330 if (!artifactIdText.equals(displayName)) {
1331 artifactIdEl.setText(displayName);
1332
1333 String content = doc.formattedString();
1334
1335 FileUtil.write(geronimoWebXml, content);
1336
1337 if (_log.isInfoEnabled()) {
1338 _log.info("Modifying Geronimo " + geronimoWebXml);
1339 }
1340 }
1341 }
1342
1343 protected void updateWebXml(
1344 File webXml, File srcFile, String displayName,
1345 PluginPackage pluginPackage)
1346 throws Exception {
1347
1348 String content = FileUtil.read(webXml);
1349
1350 int x = content.indexOf("<display-name>");
1351
1352 if (x != -1) {
1353 int y = content.indexOf("</display-name>", x);
1354
1355 y = content.indexOf(">", y) + 1;
1356
1357 content = content.substring(0, x) + content.substring(y);
1358 }
1359
1360 double webXmlVersion = 2.3;
1361
1362 Document webXmlDoc = SAXReaderUtil.read(content);
1363
1364 Element webXmlRoot = webXmlDoc.getRootElement();
1365
1366 webXmlVersion = GetterUtil.getDouble(
1367 webXmlRoot.attributeValue("version"), webXmlVersion);
1368
1369
1371 String extraContent = getExtraContent(
1372 webXmlVersion, srcFile, displayName);
1373
1374 if (webXmlVersion > 2.3) {
1375 while (true) {
1376 int pos = extraContent.indexOf(
1377 "<param-name>servlet-2.4-dispatcher</param-name>");
1378
1379 if (pos == -1) {
1380 break;
1381 }
1382
1383 x = extraContent.lastIndexOf("<init-param>", pos);
1384 int y = extraContent.indexOf("</init-param>", pos);
1385
1386 extraContent =
1387 extraContent.substring(0, x) +
1388 extraContent.substring(y + 13);
1389 }
1390 }
1391
1392 int pos = content.indexOf("</web-app>");
1393
1394 String newContent =
1395 content.substring(0, pos) + extraContent +
1396 content.substring(pos, content.length());
1397
1398
1400 newContent = StringUtil.replace(
1401 newContent, "com.liferay.portal.shared.",
1402 "com.liferay.portal.kernel.");
1403
1404 newContent = WebXMLBuilder.organizeWebXML(newContent);
1405
1406 FileUtil.write(webXml, newContent, true);
1407
1408 if (_log.isInfoEnabled()) {
1409 _log.info("Modifying Servlet " + webXmlVersion + " " + webXml);
1410 }
1411 }
1412
1413 protected String baseDir;
1414 protected String destDir;
1415 protected String appServerType;
1416 protected String auiTaglibDTD;
1417 protected String portletTaglibDTD;
1418 protected String portletExtTaglibDTD;
1419 protected String securityTaglibDTD;
1420 protected String themeTaglibDTD;
1421 protected String uiTaglibDTD;
1422 protected String utilTaglibDTD;
1423 protected boolean unpackWar;
1424 protected String filePattern;
1425 protected String jbossPrefix;
1426 protected String tomcatLibDir;
1427 protected List<String> wars;
1428 protected List<String> jars;
1429
1430 private static final String _PORTAL_CLASS_LOADER =
1431 "com.liferay.support.tomcat.loader.PortalClassLoader";
1432
1433 private static Log _log = LogFactoryUtil.getLog(BaseDeployer.class);
1434
1435}