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 getIgnoreFiltersContent(File srcFile) throws Exception {
1029 boolean ignoreFiltersEnabled = true;
1030
1031 Properties properties = getPluginPackageProperties(srcFile);
1032
1033 if (properties != null) {
1034 ignoreFiltersEnabled = GetterUtil.getBoolean(
1035 properties.getProperty("ignore-filters-enabled"), true);
1036 }
1037
1038 if (ignoreFiltersEnabled) {
1039 String ignoreFiltersContent = FileUtil.read(
1040 DeployUtil.getResourcePath("ignore-filters-web.xml"));
1041
1042 return ignoreFiltersContent;
1043 }
1044 else {
1045 return StringPool.BLANK;
1046 }
1047 }
1048
1049 protected String getPluginPackageLicensesXml(List<License> licenses) {
1050 if (licenses.isEmpty()) {
1051 return StringPool.BLANK;
1052 }
1053
1054 StringBundler sb = new StringBundler(5 * licenses.size() + 2);
1055
1056 for (int i = 0; i < licenses.size(); i++) {
1057 License license = licenses.get(i);
1058
1059 if (i == 0) {
1060 sb.append("\r\n");
1061 }
1062
1063 sb.append("\t\t<license osi-approved=\"");
1064 sb.append(license.isOsiApproved());
1065 sb.append("\">");
1066 sb.append(license.getName());
1067 sb.append("</license>\r\n");
1068
1069 if ((i + 1) == licenses.size()) {
1070 sb.append("\t");
1071 }
1072 }
1073
1074 return sb.toString();
1075 }
1076
1077 protected String getPluginPackageLiferayVersionsXml(
1078 List<String> liferayVersions) {
1079
1080 if (liferayVersions.isEmpty()) {
1081 return StringPool.BLANK;
1082 }
1083
1084 StringBundler sb = new StringBundler(liferayVersions.size() * 3 + 2);
1085
1086 for (int i = 0; i < liferayVersions.size(); i++) {
1087 String liferayVersion = liferayVersions.get(i);
1088
1089 if (i == 0) {
1090 sb.append("\r\n");
1091 }
1092
1093 sb.append("\t\t<liferay-version>");
1094 sb.append(liferayVersion);
1095 sb.append("</liferay-version>\r\n");
1096
1097 if ((i + 1) == liferayVersions.size()) {
1098 sb.append("\t");
1099 }
1100 }
1101
1102 return sb.toString();
1103 }
1104
1105 protected Properties getPluginPackageProperties(File srcFile)
1106 throws Exception {
1107
1108 File propertiesFile = new File(
1109 srcFile + "/WEB-INF/liferay-plugin-package.properties");
1110
1111 if (!propertiesFile.exists()) {
1112 return null;
1113 }
1114
1115 String propertiesString = FileUtil.read(propertiesFile);
1116
1117 return PropertiesUtil.load(propertiesString);
1118 }
1119
1120 protected String getPluginPackageTagsXml(List<String> tags) {
1121 if (tags.isEmpty()) {
1122 return StringPool.BLANK;
1123 }
1124
1125 StringBundler sb = new StringBundler(tags.size() * 3 + 2);
1126
1127 for (int i = 0; i < tags.size(); i++) {
1128 String tag = tags.get(i);
1129
1130 if (i == 0) {
1131 sb.append("\r\n");
1132 }
1133
1134 sb.append("\t\t<tag>");
1135 sb.append(tag);
1136 sb.append("</tag>\r\n");
1137
1138 if ((i + 1) == tags.size()) {
1139 sb.append("\t");
1140 }
1141 }
1142
1143 return sb.toString();
1144 }
1145
1146 protected String getSpeedFiltersContent(File srcFile) throws Exception {
1147 boolean speedFiltersEnabled = true;
1148
1149 Properties properties = getPluginPackageProperties(srcFile);
1150
1151 if (properties != null) {
1152 speedFiltersEnabled = GetterUtil.getBoolean(
1153 properties.getProperty("speed-filters-enabled"), true);
1154 }
1155
1156 if (speedFiltersEnabled) {
1157 String speedFiltersContent = FileUtil.read(
1158 DeployUtil.getResourcePath("speed-filters-web.xml"));
1159
1160 return speedFiltersContent;
1161 }
1162 else {
1163 return StringPool.BLANK;
1164 }
1165 }
1166
1167 protected boolean isJEEDeploymentEnabled() {
1168 return GetterUtil.getBoolean(PropsUtil.get(
1169 "auto.deploy." + ServerDetector.getServerId() +
1170 ".jee.deployment.enabled"));
1171 }
1172
1173 protected void mergeDirectory(File mergeDir, File targetDir) {
1174 if ((mergeDir == null) || (!mergeDir.exists())) {
1175 return;
1176 }
1177
1178 CopyTask.copyDirectory(mergeDir, targetDir, null, null, true, false);
1179 }
1180
1181 protected void processPluginPackageProperties(
1182 File srcFile, String displayName, PluginPackage pluginPackage)
1183 throws Exception {
1184 }
1185
1186 protected PluginPackage readPluginPackage(File file) {
1187 if (!file.exists()) {
1188 return null;
1189 }
1190
1191 InputStream is = null;
1192 ZipFile zipFile = null;
1193
1194 try {
1195 boolean parseProps = false;
1196
1197 if (file.isDirectory()) {
1198 String path = file.getPath();
1199
1200 File pluginPackageXmlFile = new File(
1201 file.getParent() + "/merge/" + file.getName() +
1202 "/WEB-INF/liferay-plugin-package.xml");
1203
1204 if (pluginPackageXmlFile.exists()) {
1205 is = new FileInputStream(pluginPackageXmlFile);
1206 }
1207 else {
1208 pluginPackageXmlFile = new File(
1209 path + "/WEB-INF/liferay-plugin-package.xml");
1210
1211 if (pluginPackageXmlFile.exists()) {
1212 is = new FileInputStream(pluginPackageXmlFile);
1213 }
1214 }
1215
1216 File pluginPackagePropsFile = new File(
1217 file.getParent() + "/merge/" + file.getName() +
1218 "/WEB-INF/liferay-plugin-package.properties");
1219
1220 if ((is == null) && pluginPackagePropsFile.exists()) {
1221 is = new FileInputStream(pluginPackagePropsFile);
1222
1223 parseProps = true;
1224 }
1225 else {
1226 pluginPackagePropsFile = new File(
1227 path + "/WEB-INF/liferay-plugin-package.properties");
1228
1229 if ((is == null) && pluginPackagePropsFile.exists()) {
1230 is = new FileInputStream(pluginPackagePropsFile);
1231
1232 parseProps = true;
1233 }
1234 }
1235 }
1236 else {
1237 zipFile = new ZipFile(file);
1238
1239 File pluginPackageXmlFile = new File(
1240 file.getParent() + "/merge/" + file.getName() +
1241 "/WEB-INF/liferay-plugin-package.xml");
1242
1243 if (pluginPackageXmlFile.exists()) {
1244 is = new FileInputStream(pluginPackageXmlFile);
1245 }
1246 else {
1247 ZipEntry zipEntry = zipFile.getEntry(
1248 "WEB-INF/liferay-plugin-package.xml");
1249
1250 if (zipEntry != null) {
1251 is = zipFile.getInputStream(zipEntry);
1252 }
1253 }
1254
1255 File pluginPackagePropsFile = new File(
1256 file.getParent() + "/merge/" + file.getName() +
1257 "/WEB-INF/liferay-plugin-package.properties");
1258
1259 if ((is == null) && pluginPackagePropsFile.exists()) {
1260 is = new FileInputStream(pluginPackagePropsFile);
1261
1262 parseProps = true;
1263 }
1264 else {
1265 ZipEntry zipEntry = zipFile.getEntry(
1266 "WEB-INF/liferay-plugin-package.properties");
1267
1268 if ((is == null) && (zipEntry != null)) {
1269 is = zipFile.getInputStream(zipEntry);
1270
1271 parseProps = true;
1272 }
1273 }
1274 }
1275
1276 if (is == null) {
1277 if (_log.isInfoEnabled()) {
1278 _log.info(
1279 file.getPath() + " does not have a " +
1280 "WEB-INF/liferay-plugin-package.xml or " +
1281 "WEB-INF/liferay-plugin-package.properties");
1282 }
1283
1284 return null;
1285 }
1286
1287 if (parseProps) {
1288 String displayName = getDisplayName(file);
1289
1290 String propertiesString = StringUtil.read(is);
1291
1292 Properties properties = PropertiesUtil.load(propertiesString);
1293
1294 return PluginPackageUtil.readPluginPackageProperties(
1295 displayName, properties);
1296 }
1297 else {
1298 String xml = StringUtil.read(is);
1299
1300 xml = XMLFormatter.fixProlog(xml);
1301
1302 return PluginPackageUtil.readPluginPackageXml(xml);
1303 }
1304 }
1305 catch (Exception e) {
1306 _log.error(file.getPath() + ": " + e.toString());
1307 }
1308 finally {
1309 if (is != null) {
1310 try {
1311 is.close();
1312 }
1313 catch (IOException ioe) {
1314 }
1315 }
1316
1317 if (zipFile != null) {
1318 try {
1319 zipFile.close();
1320 }
1321 catch (IOException ioe) {
1322 }
1323 }
1324 }
1325
1326 return null;
1327 }
1328
1329 protected void rewriteFiles(File srcDir) throws Exception {
1330 String[] files = FileUtil.listFiles(srcDir + "/WEB-INF/");
1331
1332 for (int i = 0; i < files.length; i++) {
1333 String fileName = GetterUtil.getString(
1334 FileUtil.getShortFileName(files[i]));
1335
1336
1337
1338 if (fileName.equalsIgnoreCase("mule-config.xml")) {
1339 continue;
1340 }
1341
1342 String ext = GetterUtil.getString(FileUtil.getExtension(files[i]));
1343
1344 if (!ext.equalsIgnoreCase("xml")) {
1345 continue;
1346 }
1347
1348
1349
1350
1351 File file = new File(srcDir + "/WEB-INF/" + files[i]);
1352
1353 try {
1354 Document doc = SAXReaderUtil.read(file);
1355
1356 String content = doc.formattedString(StringPool.TAB, true);
1357
1358 FileUtil.write(file, content);
1359 }
1360 catch (Exception e) {
1361 if (_log.isWarnEnabled()) {
1362 _log.warn(
1363 "Unable to format " + file + ": " + e.getMessage());
1364 }
1365 }
1366 }
1367 }
1368
1369 protected void updateDeployDirectory(File srcFile) throws Exception {
1370 }
1371
1372 protected void updateGeronimoWebXml(
1373 File srcFile, String displayName, PluginPackage pluginPackage)
1374 throws Exception {
1375
1376 if (!appServerType.equals(ServerDetector.GERONIMO_ID)) {
1377 return;
1378 }
1379
1380 File geronimoWebXml = new File(srcFile + "/WEB-INF/geronimo-web.xml");
1381
1382 Document doc = SAXReaderUtil.read(geronimoWebXml);
1383
1384 Element root = doc.getRootElement();
1385
1386 Element environmentEl = root.element("environment");
1387
1388 Element moduleIdEl = environmentEl.element("moduleId");
1389
1390 Element artifactIdEl = moduleIdEl.element("artifactId");
1391
1392 artifactIdEl.setText(displayName);
1393
1394 Element versionEl = moduleIdEl.element("version");
1395
1396 versionEl.setText(pluginPackage.getVersion());
1397
1398 String content = doc.formattedString();
1399
1400 FileUtil.write(geronimoWebXml, content);
1401
1402 if (_log.isInfoEnabled()) {
1403 _log.info("Modifying Geronimo " + geronimoWebXml);
1404 }
1405 }
1406
1407 protected void updateWebXml(
1408 File webXml, File srcFile, String displayName,
1409 PluginPackage pluginPackage)
1410 throws Exception {
1411
1412 String content = FileUtil.read(webXml);
1413
1414 int x = content.indexOf("<display-name>");
1415
1416 if (x != -1) {
1417 int y = content.indexOf("</display-name>", x);
1418
1419 y = content.indexOf(">", y) + 1;
1420
1421 content = content.substring(0, x) + content.substring(y);
1422 }
1423
1424 double webXmlVersion = 2.3;
1425
1426 Document webXmlDoc = SAXReaderUtil.read(content);
1427
1428 Element webXmlRoot = webXmlDoc.getRootElement();
1429
1430 webXmlVersion = GetterUtil.getDouble(
1431 webXmlRoot.attributeValue("version"), webXmlVersion);
1432
1433
1434
1435 String extraContent = getExtraContent(
1436 webXmlVersion, srcFile, displayName);
1437
1438 if (webXmlVersion > 2.3) {
1439 while (true) {
1440 int pos = extraContent.indexOf(
1441 "<param-name>servlet-2.4-dispatcher</param-name>");
1442
1443 if (pos == -1) {
1444 break;
1445 }
1446
1447 x = extraContent.lastIndexOf("<init-param>", pos);
1448 int y = extraContent.indexOf("</init-param>", pos);
1449
1450 extraContent =
1451 extraContent.substring(0, x) +
1452 extraContent.substring(y + 13);
1453 }
1454 }
1455
1456 int pos = content.indexOf("</web-app>");
1457
1458 String newContent =
1459 content.substring(0, pos) + extraContent +
1460 content.substring(pos, content.length());
1461
1462
1463
1464 newContent = StringUtil.replace(
1465 newContent, "com.liferay.portal.shared.",
1466 "com.liferay.portal.kernel.");
1467
1468 newContent = WebXMLBuilder.organizeWebXML(newContent);
1469
1470 FileUtil.write(webXml, newContent, true);
1471
1472 if (_log.isInfoEnabled()) {
1473 _log.info("Modifying Servlet " + webXmlVersion + " " + webXml);
1474 }
1475 }
1476
1477 protected String baseDir;
1478 protected String destDir;
1479 protected String appServerType;
1480 protected String auiTaglibDTD;
1481 protected String portletTaglibDTD;
1482 protected String portletExtTaglibDTD;
1483 protected String securityTaglibDTD;
1484 protected String themeTaglibDTD;
1485 protected String uiTaglibDTD;
1486 protected String utilTaglibDTD;
1487 protected boolean unpackWar;
1488 protected String filePattern;
1489 protected String jbossPrefix;
1490 protected String tomcatLibDir;
1491 protected List<String> wars;
1492 protected List<String> jars;
1493
1494 private static final String _PORTAL_CLASS_LOADER =
1495 "com.liferay.support.tomcat.loader.PortalClassLoader";
1496
1497 private static Log _log = LogFactoryUtil.getLog(BaseDeployer.class);
1498
1499 }