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