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 if ((deployDir == null) || baseDir.equals(destDir)) {
496 return;
497 }
498
499 updateDeployDirectory(srcFile);
500
501 String excludes = StringPool.BLANK;
502
503 if (appServerType.equals(ServerDetector.JBOSS_ID)) {
504 excludes += "**/WEB-INF/lib/log4j.jar,";
505 }
506 else if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
507 String[] libs = FileUtil.listFiles(tomcatLibDir);
508
509 for (int i = 0; i < libs.length; i++) {
510 excludes += "**/WEB-INF/lib/" + libs[i] + ",";
511 }
512
513 File contextXml = new File(srcFile + "/META-INF/context.xml");
514
515 if (contextXml.exists()) {
516 String content = FileUtil.read(contextXml);
517
518 if (content.indexOf(_PORTAL_CLASS_LOADER) != -1) {
519 excludes += "**/WEB-INF/lib/util-bridges.jar,";
520 excludes += "**/WEB-INF/lib/util-java.jar,";
521 excludes += "**/WEB-INF/lib/util-taglib.jar,";
522 }
523 }
524
525 try {
526
527
528
529 Class.forName("javax.el.ELContext");
530
531 excludes += "**/WEB-INF/lib/el-api.jar,";
532 }
533 catch (ClassNotFoundException cnfe) {
534 }
535 }
536
537
538
539 Properties properties = getPluginPackageProperties(srcFile);
540
541 if (properties != null) {
542 String deployExcludes = properties.getProperty("deploy-excludes");
543
544 if (deployExcludes != null) {
545 excludes += deployExcludes.trim();
546
547 if (!excludes.endsWith(",")) {
548 excludes += ",";
549 }
550 }
551
552 deployExcludes = properties.getProperty(
553 "deploy-excludes-" + appServerType);
554
555 if (deployExcludes != null) {
556 excludes += deployExcludes.trim();
557
558 if (!excludes.endsWith(",")) {
559 excludes += ",";
560 }
561 }
562 }
563
564 if (_log.isDebugEnabled()) {
565 _log.debug("Excludes " + excludes);
566 }
567
568 if (!unpackWar || appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
569 File tempDir = new File(
570 SystemProperties.get(SystemProperties.TMP_DIR) +
571 File.separator + Time.getTimestamp());
572
573 WarTask.war(srcFile, tempDir, "WEB-INF/web.xml", webXml);
574
575 if (isJEEDeploymentEnabled()) {
576 File tempWarDir = new File(
577 tempDir.getParent(), deployDir.getName());
578
579 if (tempWarDir.exists()) {
580 tempWarDir.delete();
581 }
582
583 if (!tempDir.renameTo(tempWarDir)) {
584 tempWarDir = tempDir;
585 }
586
587 DeploymentHandler deploymentHandler = getDeploymentHandler();
588
589 deploymentHandler.deploy(tempWarDir, displayName);
590
591 deploymentHandler.releaseDeploymentManager();
592
593 DeleteTask.deleteDirectory(tempWarDir);
594 }
595 else {
596 if (!tempDir.renameTo(deployDir)) {
597 WarTask.war(srcFile, deployDir, "WEB-INF/web.xml", webXml);
598 }
599
600 DeleteTask.deleteDirectory(tempDir);
601 }
602 }
603 else {
604 File extLibGlobalDir = new File(
605 srcFile.getAbsolutePath() + "/WEB-INF/ext-lib/global");
606
607 if (extLibGlobalDir.exists()) {
608 File globalLibDir = new File(PortalUtil.getGlobalLibDir());
609
610 CopyTask.copyDirectory(
611 extLibGlobalDir, globalLibDir, "*.jar", StringPool.BLANK,
612 overwrite, true);
613 }
614
615
616
617
618
619
620
621 excludes += "**/WEB-INF/web.xml";
622
623 CopyTask.copyDirectory(
624 srcFile, deployDir, StringPool.BLANK, excludes, overwrite,
625 true);
626
627 CopyTask.copyDirectory(
628 srcFile, deployDir, "**/WEB-INF/web.xml", StringPool.BLANK,
629 true, false);
630
631 if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
632
633
634
635
636
637 File deployWebXml = new File(deployDir + "/WEB-INF/web.xml");
638
639 deployWebXml.setLastModified(
640 System.currentTimeMillis() + (Time.SECOND * 6));
641 }
642 }
643 }
644
645 protected void deployFile(File srcFile) throws Exception {
646 PluginPackage pluginPackage = readPluginPackage(srcFile);
647
648 if (_log.isInfoEnabled()) {
649 _log.info("Deploying " + srcFile.getName());
650 }
651
652 String deployDir = null;
653 String displayName = null;
654 boolean overwrite = false;
655 String preliminaryContext = null;
656
657
658
659
660 if (srcFile.getName().startsWith(DEPLOY_TO_PREFIX)) {
661 displayName = srcFile.getName().substring(
662 DEPLOY_TO_PREFIX.length(), srcFile.getName().length() - 4);
663
664 overwrite = true;
665 preliminaryContext = displayName;
666 }
667
668 if (preliminaryContext == null) {
669 preliminaryContext = getDisplayName(srcFile);
670 }
671
672 if (pluginPackage != null) {
673 if (!PluginPackageUtil.isCurrentVersionSupported(
674 pluginPackage.getLiferayVersions())) {
675
676 throw new AutoDeployException(
677 srcFile.getName() +
678 " does not support this version of Liferay");
679 }
680
681 if (displayName == null) {
682 displayName = pluginPackage.getRecommendedDeploymentContext();
683 }
684
685 if (Validator.isNull(displayName)) {
686 displayName = getDisplayName(srcFile);
687 }
688
689 pluginPackage.setContext(displayName);
690
691 PluginPackageUtil.updateInstallingPluginPackage(
692 preliminaryContext, pluginPackage);
693 }
694
695 if (Validator.isNotNull(displayName)) {
696 deployDir = displayName + ".war";
697 }
698 else {
699 deployDir = srcFile.getName();
700 displayName = getDisplayName(srcFile);
701 }
702
703 if (appServerType.equals(ServerDetector.JBOSS_ID)) {
704 deployDir = jbossPrefix + deployDir;
705 }
706 else if (appServerType.equals(ServerDetector.JETTY_ID) ||
707 appServerType.equals(ServerDetector.OC4J_ID) ||
708 appServerType.equals(ServerDetector.RESIN_ID) ||
709 appServerType.equals(ServerDetector.TOMCAT_ID)) {
710
711 if (unpackWar) {
712 deployDir = deployDir.substring(0, deployDir.length() - 4);
713 }
714 }
715
716 deployDir = destDir + "/" + deployDir;
717
718 File deployDirFile = new File(deployDir);
719
720 try {
721 PluginPackage previousPluginPackage =
722 readPluginPackage(deployDirFile);
723
724 if ((pluginPackage != null) && (previousPluginPackage != null)) {
725 if (_log.isInfoEnabled()) {
726 String name = pluginPackage.getName();
727 String previousVersion = previousPluginPackage.getVersion();
728 String version = pluginPackage.getVersion();
729
730 _log.info(
731 "Updating " + name + " from version " +
732 previousVersion + " to version " + version);
733 }
734
735 if (pluginPackage.isLaterVersionThan(
736 previousPluginPackage)) {
737
738 overwrite = true;
739 }
740 }
741
742 File mergeDirFile = new File(
743 srcFile.getParent() + "/merge/" + srcFile.getName());
744
745 if (srcFile.isDirectory()) {
746 deployDirectory(
747 srcFile, mergeDirFile, deployDirFile, displayName,
748 overwrite, pluginPackage);
749 }
750 else {
751 boolean deployed = deployFile(
752 srcFile, mergeDirFile, deployDirFile, displayName,
753 overwrite, pluginPackage);
754
755 if (!deployed) {
756 String context = preliminaryContext;
757
758 if (pluginPackage != null) {
759 context = pluginPackage.getContext();
760 }
761
762 PluginPackageUtil.endPluginPackageInstallation(context);
763 }
764 }
765 }
766 catch (Exception e) {
767 if (pluginPackage != null) {
768 PluginPackageUtil.endPluginPackageInstallation(
769 pluginPackage.getContext());
770 }
771
772 throw e;
773 }
774 }
775
776 protected boolean deployFile(
777 File srcFile, File mergeDir, File deployDir, String displayName,
778 boolean overwrite, PluginPackage pluginPackage)
779 throws Exception {
780
781 boolean undeployOnRedeploy = false;
782
783 try {
784 undeployOnRedeploy = PrefsPropsUtil.getBoolean(
785 PropsKeys.HOT_UNDEPLOY_ON_REDEPLOY,
786 PropsValues.HOT_UNDEPLOY_ON_REDEPLOY);
787 }
788 catch (Exception e) {
789
790
791
792
793
794 }
795
796 if (undeployOnRedeploy) {
797 DeployUtil.undeploy(appServerType, deployDir);
798 }
799
800 if (!overwrite && UpToDateTask.isUpToDate(srcFile, deployDir)) {
801 if (_log.isInfoEnabled()) {
802 _log.info(deployDir + " is already up to date");
803 }
804
805 return false;
806 }
807
808 File tempDir = new File(
809 SystemProperties.get(SystemProperties.TMP_DIR) + File.separator +
810 Time.getTimestamp());
811
812 ExpandTask.expand(srcFile, tempDir);
813
814 deployDirectory(
815 tempDir, mergeDir, deployDir, displayName, overwrite,
816 pluginPackage);
817
818 DeleteTask.deleteDirectory(tempDir);
819
820 return true;
821 }
822
823 protected String downloadJar(String jar) throws Exception {
824 String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
825
826 File file = new File(
827 tmpDir + "/liferay/com/liferay/portal/deploy/dependencies/" +
828 jar);
829
830 if (!file.exists()) {
831 synchronized (this) {
832 String url = PropsUtil.get(
833 PropsKeys.LIBRARY_DOWNLOAD_URL + jar);
834
835 if (_log.isInfoEnabled()) {
836 _log.info("Downloading library from " + url);
837 }
838
839 byte[] bytes = HttpUtil.URLtoByteArray(url);
840
841 FileUtil.write(file, bytes);
842 }
843 }
844
845 return FileUtil.getAbsolutePath(file);
846 }
847
848 protected String getDisplayName(File srcFile) {
849 String displayName = srcFile.getName();
850
851 if (StringUtil.endsWith(displayName, ".war") ||
852 StringUtil.endsWith(displayName, ".xml")) {
853
854 displayName = displayName.substring(0, displayName.length() - 4);
855 }
856
857 if (appServerType.equals(ServerDetector.JBOSS_ID) &&
858 Validator.isNotNull(jbossPrefix) &&
859 displayName.startsWith(jbossPrefix)) {
860
861 displayName = displayName.substring(1, displayName.length());
862 }
863
864 return displayName;
865 }
866
867 protected DeploymentHandler getDeploymentHandler() {
868 String prefix = "auto.deploy." + ServerDetector.getServerId() + ".jee.";
869
870 String dmId = PropsUtil.get(prefix + "dm.id");
871 String dmUser = PropsUtil.get(prefix + "dm.user");
872 String dmPassword = PropsUtil.get(prefix + "dm.passwd");
873 String dfClassName = PropsUtil.get(prefix + "df.classname");
874
875 return new DeploymentHandler(dmId, dmUser, dmPassword, dfClassName);
876 }
877
878 protected String getExtraContent(
879 double webXmlVersion, File srcFile, String displayName)
880 throws Exception {
881
882 StringBundler sb = new StringBundler();
883
884 sb.append("<display-name>");
885 sb.append(displayName);
886 sb.append("</display-name>");
887
888 sb.append("<listener>");
889 sb.append("<listener-class>");
890 sb.append("com.liferay.portal.kernel.servlet.");
891 sb.append("SerializableSessionAttributeListener");
892 sb.append("</listener-class>");
893 sb.append("</listener>");
894
895 File serviceXml = new File(srcFile + "/WEB-INF/service.xml");
896
897 if (serviceXml.exists()) {
898 sb.append("<listener>");
899 sb.append("<listener-class>");
900 sb.append("com.liferay.portal.kernel.spring.context.");
901 sb.append("PortletContextLoaderListener");
902 sb.append("</listener-class>");
903 sb.append("</listener>");
904 }
905
906 File serverConfigWsdd = new File(
907 srcFile + "/WEB-INF/server-config.wsdd");
908
909 if (serverConfigWsdd.exists()) {
910 File webXml = new File(srcFile + "/WEB-INF/web.xml");
911
912 String content = FileUtil.read(webXml);
913
914 if (!content.contains("axis.servicesPath")) {
915 String remotingContent = FileUtil.read(
916 DeployUtil.getResourcePath("remoting-web.xml"));
917
918 sb.append(remotingContent);
919 }
920 }
921
922 boolean hasTaglib = false;
923
924 if (Validator.isNotNull(auiTaglibDTD) ||
925 Validator.isNotNull(portletTaglibDTD) ||
926 Validator.isNotNull(portletExtTaglibDTD) ||
927 Validator.isNotNull(securityTaglibDTD) ||
928 Validator.isNotNull(themeTaglibDTD) ||
929 Validator.isNotNull(uiTaglibDTD) ||
930 Validator.isNotNull(utilTaglibDTD)) {
931
932 hasTaglib = true;
933 }
934
935 if (hasTaglib && (webXmlVersion > 2.3)) {
936 sb.append("<jsp-config>");
937 }
938
939 if (Validator.isNotNull(auiTaglibDTD)) {
940 sb.append("<taglib>");
941 sb.append("<taglib-uri>http:
942 sb.append("<taglib-location>");
943 sb.append("/WEB-INF/tld/liferay-aui.tld");
944 sb.append("</taglib-location>");
945 sb.append("</taglib>");
946 }
947
948 if (Validator.isNotNull(portletTaglibDTD)) {
949 sb.append("<taglib>");
950 sb.append(
951 "<taglib-uri>http:
952 sb.append("<taglib-location>");
953 sb.append("/WEB-INF/tld/liferay-portlet.tld");
954 sb.append("</taglib-location>");
955 sb.append("</taglib>");
956 }
957
958 if (Validator.isNotNull(portletExtTaglibDTD)) {
959 sb.append("<taglib>");
960 sb.append("<taglib-uri>");
961 sb.append("http:
962 sb.append("</taglib-uri>");
963 sb.append("<taglib-location>");
964 sb.append("/WEB-INF/tld/liferay-portlet-ext.tld");
965 sb.append("</taglib-location>");
966 sb.append("</taglib>");
967 }
968
969 if (Validator.isNotNull(securityTaglibDTD)) {
970 sb.append("<taglib>");
971 sb.append("<taglib-uri>");
972 sb.append("http:
973 sb.append("</taglib-uri>");
974 sb.append("<taglib-location>");
975 sb.append("/WEB-INF/tld/liferay-security.tld");
976 sb.append("</taglib-location>");
977 sb.append("</taglib>");
978 }
979
980 if (Validator.isNotNull(themeTaglibDTD)) {
981 sb.append("<taglib>");
982 sb.append("<taglib-uri>http:
983 sb.append("<taglib-location>");
984 sb.append("/WEB-INF/tld/liferay-theme.tld");
985 sb.append("</taglib-location>");
986 sb.append("</taglib>");
987 }
988
989 if (Validator.isNotNull(uiTaglibDTD)) {
990 sb.append("<taglib>");
991 sb.append("<taglib-uri>http:
992 sb.append("<taglib-location>");
993 sb.append("/WEB-INF/tld/liferay-ui.tld");
994 sb.append("</taglib-location>");
995 sb.append("</taglib>");
996 }
997
998 if (Validator.isNotNull(utilTaglibDTD)) {
999 sb.append("<taglib>");
1000 sb.append("<taglib-uri>http:
1001 sb.append("<taglib-location>");
1002 sb.append("/WEB-INF/tld/liferay-util.tld");
1003 sb.append("</taglib-location>");
1004 sb.append("</taglib>");
1005 }
1006
1007 if (hasTaglib && (webXmlVersion > 2.3)) {
1008 sb.append("</jsp-config>");
1009 }
1010
1011 return sb.toString();
1012 }
1013
1014 protected String getPluginPackageLicensesXml(List<License> licenses) {
1015 if (licenses.isEmpty()) {
1016 return StringPool.BLANK;
1017 }
1018
1019 StringBundler sb = new StringBundler(5 * licenses.size() + 2);
1020
1021 for (int i = 0; i < licenses.size(); i++) {
1022 License license = licenses.get(i);
1023
1024 if (i == 0) {
1025 sb.append("\r\n");
1026 }
1027
1028 sb.append("\t\t<license osi-approved=\"");
1029 sb.append(license.isOsiApproved());
1030 sb.append("\">");
1031 sb.append(license.getName());
1032 sb.append("</license>\r\n");
1033
1034 if ((i + 1) == licenses.size()) {
1035 sb.append("\t");
1036 }
1037 }
1038
1039 return sb.toString();
1040 }
1041
1042 protected String getPluginPackageLiferayVersionsXml(
1043 List<String> liferayVersions) {
1044
1045 if (liferayVersions.isEmpty()) {
1046 return StringPool.BLANK;
1047 }
1048
1049 StringBundler sb = new StringBundler(liferayVersions.size() * 3 + 2);
1050
1051 for (int i = 0; i < liferayVersions.size(); i++) {
1052 String liferayVersion = liferayVersions.get(i);
1053
1054 if (i == 0) {
1055 sb.append("\r\n");
1056 }
1057
1058 sb.append("\t\t<liferay-version>");
1059 sb.append(liferayVersion);
1060 sb.append("</liferay-version>\r\n");
1061
1062 if ((i + 1) == liferayVersions.size()) {
1063 sb.append("\t");
1064 }
1065 }
1066
1067 return sb.toString();
1068 }
1069
1070 protected Properties getPluginPackageProperties(File srcFile)
1071 throws Exception {
1072
1073 File propertiesFile = new File(
1074 srcFile + "/WEB-INF/liferay-plugin-package.properties");
1075
1076 if (!propertiesFile.exists()) {
1077 return null;
1078 }
1079
1080 String propertiesString = FileUtil.read(propertiesFile);
1081
1082 return PropertiesUtil.load(propertiesString);
1083 }
1084
1085 protected String getPluginPackageTagsXml(List<String> tags) {
1086 if (tags.isEmpty()) {
1087 return StringPool.BLANK;
1088 }
1089
1090 StringBundler sb = new StringBundler(tags.size() * 3 + 2);
1091
1092 for (int i = 0; i < tags.size(); i++) {
1093 String tag = tags.get(i);
1094
1095 if (i == 0) {
1096 sb.append("\r\n");
1097 }
1098
1099 sb.append("\t\t<tag>");
1100 sb.append(tag);
1101 sb.append("</tag>\r\n");
1102
1103 if ((i + 1) == tags.size()) {
1104 sb.append("\t");
1105 }
1106 }
1107
1108 return sb.toString();
1109 }
1110
1111 protected String getSpeedFiltersContent(File srcFile) throws Exception {
1112 boolean speedFiltersEnabled = true;
1113
1114 Properties properties = getPluginPackageProperties(srcFile);
1115
1116 if (properties != null) {
1117 speedFiltersEnabled = GetterUtil.getBoolean(
1118 properties.getProperty("speed-filters-enabled"), true);
1119 }
1120
1121 if (speedFiltersEnabled) {
1122 String speedFiltersContent = FileUtil.read(
1123 DeployUtil.getResourcePath("speed-filters-web.xml"));
1124
1125 return speedFiltersContent;
1126 }
1127 else {
1128 return StringPool.BLANK;
1129 }
1130 }
1131
1132 protected boolean isJEEDeploymentEnabled() {
1133 return GetterUtil.getBoolean(PropsUtil.get(
1134 "auto.deploy." + ServerDetector.getServerId() +
1135 ".jee.deployment.enabled"));
1136 }
1137
1138 protected void mergeDirectory(File mergeDir, File targetDir) {
1139 if ((mergeDir == null) || (!mergeDir.exists())) {
1140 return;
1141 }
1142
1143 CopyTask.copyDirectory(mergeDir, targetDir, null, null, true, false);
1144 }
1145
1146 protected void processPluginPackageProperties(
1147 File srcFile, String displayName, PluginPackage pluginPackage)
1148 throws Exception {
1149 }
1150
1151 protected PluginPackage readPluginPackage(File file) {
1152 if (!file.exists()) {
1153 return null;
1154 }
1155
1156 InputStream is = null;
1157 ZipFile zipFile = null;
1158
1159 try {
1160 boolean parseProps = false;
1161
1162 if (file.isDirectory()) {
1163 String path = file.getPath();
1164
1165 File pluginPackageXmlFile = new File(
1166 file.getParent() + "/merge/" + file.getName() +
1167 "/WEB-INF/liferay-plugin-package.xml");
1168
1169 if (pluginPackageXmlFile.exists()) {
1170 is = new FileInputStream(pluginPackageXmlFile);
1171 }
1172 else {
1173 pluginPackageXmlFile = new File(
1174 path + "/WEB-INF/liferay-plugin-package.xml");
1175
1176 if (pluginPackageXmlFile.exists()) {
1177 is = new FileInputStream(pluginPackageXmlFile);
1178 }
1179 }
1180
1181 File pluginPackagePropsFile = new File(
1182 file.getParent() + "/merge/" + file.getName() +
1183 "/WEB-INF/liferay-plugin-package.properties");
1184
1185 if ((is == null) && pluginPackagePropsFile.exists()) {
1186 is = new FileInputStream(pluginPackagePropsFile);
1187
1188 parseProps = true;
1189 }
1190 else {
1191 pluginPackagePropsFile = new File(
1192 path + "/WEB-INF/liferay-plugin-package.properties");
1193
1194 if ((is == null) && pluginPackagePropsFile.exists()) {
1195 is = new FileInputStream(pluginPackagePropsFile);
1196
1197 parseProps = true;
1198 }
1199 }
1200 }
1201 else {
1202 zipFile = new ZipFile(file);
1203
1204 File pluginPackageXmlFile = new File(
1205 file.getParent() + "/merge/" + file.getName() +
1206 "/WEB-INF/liferay-plugin-package.xml");
1207
1208 if (pluginPackageXmlFile.exists()) {
1209 is = new FileInputStream(pluginPackageXmlFile);
1210 }
1211 else {
1212 ZipEntry zipEntry = zipFile.getEntry(
1213 "WEB-INF/liferay-plugin-package.xml");
1214
1215 if (zipEntry != null) {
1216 is = zipFile.getInputStream(zipEntry);
1217 }
1218 }
1219
1220 File pluginPackagePropsFile = new File(
1221 file.getParent() + "/merge/" + file.getName() +
1222 "/WEB-INF/liferay-plugin-package.properties");
1223
1224 if ((is == null) && pluginPackagePropsFile.exists()) {
1225 is = new FileInputStream(pluginPackagePropsFile);
1226
1227 parseProps = true;
1228 }
1229 else {
1230 ZipEntry zipEntry = zipFile.getEntry(
1231 "WEB-INF/liferay-plugin-package.properties");
1232
1233 if ((is == null) && (zipEntry != null)) {
1234 is = zipFile.getInputStream(zipEntry);
1235
1236 parseProps = true;
1237 }
1238 }
1239 }
1240
1241 if (is == null) {
1242 if (_log.isInfoEnabled()) {
1243 _log.info(
1244 file.getPath() + " does not have a " +
1245 "WEB-INF/liferay-plugin-package.xml or " +
1246 "WEB-INF/liferay-plugin-package.properties");
1247 }
1248
1249 return null;
1250 }
1251
1252 if (parseProps) {
1253 String displayName = getDisplayName(file);
1254
1255 String propertiesString = StringUtil.read(is);
1256
1257 Properties properties = PropertiesUtil.load(propertiesString);
1258
1259 return PluginPackageUtil.readPluginPackageProperties(
1260 displayName, properties);
1261 }
1262 else {
1263 String xml = StringUtil.read(is);
1264
1265 xml = XMLFormatter.fixProlog(xml);
1266
1267 return PluginPackageUtil.readPluginPackageXml(xml);
1268 }
1269 }
1270 catch (Exception e) {
1271 _log.error(file.getPath() + ": " + e.toString());
1272 }
1273 finally {
1274 if (is != null) {
1275 try {
1276 is.close();
1277 }
1278 catch (IOException ioe) {
1279 }
1280 }
1281
1282 if (zipFile != null) {
1283 try {
1284 zipFile.close();
1285 }
1286 catch (IOException ioe) {
1287 }
1288 }
1289 }
1290
1291 return null;
1292 }
1293
1294 protected void rewriteFiles(File srcDir) throws Exception {
1295 String[] files = FileUtil.listFiles(srcDir + "/WEB-INF/");
1296
1297 for (int i = 0; i < files.length; i++) {
1298 String fileName = GetterUtil.getString(
1299 FileUtil.getShortFileName(files[i]));
1300
1301
1302
1303 if (fileName.equalsIgnoreCase("mule-config.xml")) {
1304 continue;
1305 }
1306
1307 String ext = GetterUtil.getString(FileUtil.getExtension(files[i]));
1308
1309 if (!ext.equalsIgnoreCase("xml")) {
1310 continue;
1311 }
1312
1313
1314
1315
1316 File file = new File(srcDir + "/WEB-INF/" + files[i]);
1317
1318 try {
1319 Document doc = SAXReaderUtil.read(file);
1320
1321 String content = doc.formattedString(StringPool.TAB, true);
1322
1323 FileUtil.write(file, content);
1324 }
1325 catch (Exception e) {
1326 if (_log.isWarnEnabled()) {
1327 _log.warn(
1328 "Unable to format " + file + ": " + e.getMessage());
1329 }
1330 }
1331 }
1332 }
1333
1334 protected void updateDeployDirectory(File srcFile) throws Exception {
1335 }
1336
1337 protected void updateGeronimoWebXml(
1338 File srcFile, String displayName, PluginPackage pluginPackage)
1339 throws Exception {
1340
1341 if (!appServerType.equals(ServerDetector.GERONIMO_ID)) {
1342 return;
1343 }
1344
1345 File geronimoWebXml = new File(srcFile + "/WEB-INF/geronimo-web.xml");
1346
1347 Document doc = SAXReaderUtil.read(geronimoWebXml);
1348
1349 Element root = doc.getRootElement();
1350
1351 Element environmentEl = root.element("environment");
1352
1353 Element moduleIdEl = environmentEl.element("moduleId");
1354
1355 Element artifactIdEl = moduleIdEl.element("artifactId");
1356
1357 artifactIdEl.setText(displayName);
1358
1359 Element versionEl = moduleIdEl.element("version");
1360
1361 versionEl.setText(pluginPackage.getVersion());
1362
1363 String content = doc.formattedString();
1364
1365 FileUtil.write(geronimoWebXml, content);
1366
1367 if (_log.isInfoEnabled()) {
1368 _log.info("Modifying Geronimo " + geronimoWebXml);
1369 }
1370 }
1371
1372 protected void updateWebXml(
1373 File webXml, File srcFile, String displayName,
1374 PluginPackage pluginPackage)
1375 throws Exception {
1376
1377 String content = FileUtil.read(webXml);
1378
1379 int x = content.indexOf("<display-name>");
1380
1381 if (x != -1) {
1382 int y = content.indexOf("</display-name>", x);
1383
1384 y = content.indexOf(">", y) + 1;
1385
1386 content = content.substring(0, x) + content.substring(y);
1387 }
1388
1389 double webXmlVersion = 2.3;
1390
1391 Document webXmlDoc = SAXReaderUtil.read(content);
1392
1393 Element webXmlRoot = webXmlDoc.getRootElement();
1394
1395 webXmlVersion = GetterUtil.getDouble(
1396 webXmlRoot.attributeValue("version"), webXmlVersion);
1397
1398
1399
1400 String extraContent = getExtraContent(
1401 webXmlVersion, srcFile, displayName);
1402
1403 if (webXmlVersion > 2.3) {
1404 while (true) {
1405 int pos = extraContent.indexOf(
1406 "<param-name>servlet-2.4-dispatcher</param-name>");
1407
1408 if (pos == -1) {
1409 break;
1410 }
1411
1412 x = extraContent.lastIndexOf("<init-param>", pos);
1413 int y = extraContent.indexOf("</init-param>", pos);
1414
1415 extraContent =
1416 extraContent.substring(0, x) +
1417 extraContent.substring(y + 13);
1418 }
1419 }
1420
1421 int pos = content.indexOf("</web-app>");
1422
1423 String newContent =
1424 content.substring(0, pos) + extraContent +
1425 content.substring(pos, content.length());
1426
1427
1428
1429 newContent = StringUtil.replace(
1430 newContent, "com.liferay.portal.shared.",
1431 "com.liferay.portal.kernel.");
1432
1433 newContent = WebXMLBuilder.organizeWebXML(newContent);
1434
1435 FileUtil.write(webXml, newContent, true);
1436
1437 if (_log.isInfoEnabled()) {
1438 _log.info("Modifying Servlet " + webXmlVersion + " " + webXml);
1439 }
1440 }
1441
1442 protected String baseDir;
1443 protected String destDir;
1444 protected String appServerType;
1445 protected String auiTaglibDTD;
1446 protected String portletTaglibDTD;
1447 protected String portletExtTaglibDTD;
1448 protected String securityTaglibDTD;
1449 protected String themeTaglibDTD;
1450 protected String uiTaglibDTD;
1451 protected String utilTaglibDTD;
1452 protected boolean unpackWar;
1453 protected String filePattern;
1454 protected String jbossPrefix;
1455 protected String tomcatLibDir;
1456 protected List<String> wars;
1457 protected List<String> jars;
1458
1459 private static final String _PORTAL_CLASS_LOADER =
1460 "com.liferay.support.tomcat.loader.PortalClassLoader";
1461
1462 private static Log _log = LogFactoryUtil.getLog(BaseDeployer.class);
1463
1464 }