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