0001: /**
0002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
0003: *
0004: * Permission is hereby granted, free of charge, to any person obtaining a copy
0005: * of this software and associated documentation files (the "Software"), to deal
0006: * in the Software without restriction, including without limitation the rights
0007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0008: * copies of the Software, and to permit persons to whom the Software is
0009: * furnished to do so, subject to the following conditions:
0010: *
0011: * The above copyright notice and this permission notice shall be included in
0012: * all copies or substantial portions of the Software.
0013: *
0014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0020: * SOFTWARE.
0021: */package com.liferay.portal.tools;
0022:
0023: import com.liferay.portal.deploy.DeployUtil;
0024: import com.liferay.portal.kernel.deploy.auto.AutoDeployException;
0025: import com.liferay.portal.kernel.plugin.PluginPackage;
0026: import com.liferay.portal.kernel.util.GetterUtil;
0027: import com.liferay.portal.kernel.util.PropertiesUtil;
0028: import com.liferay.portal.kernel.util.ServerDetector;
0029: import com.liferay.portal.kernel.util.StringMaker;
0030: import com.liferay.portal.kernel.util.StringPool;
0031: import com.liferay.portal.kernel.util.StringUtil;
0032: import com.liferay.portal.kernel.util.Validator;
0033: import com.liferay.portal.plugin.PluginPackageUtil;
0034: import com.liferay.portal.util.PortalUtil;
0035: import com.liferay.portal.util.PropsUtil;
0036: import com.liferay.util.FileUtil;
0037: import com.liferay.util.Http;
0038: import com.liferay.util.License;
0039: import com.liferay.util.SystemProperties;
0040: import com.liferay.util.Time;
0041: import com.liferay.util.ant.CopyTask;
0042: import com.liferay.util.ant.DeleteTask;
0043: import com.liferay.util.ant.ExpandTask;
0044: import com.liferay.util.ant.UpToDateTask;
0045: import com.liferay.util.ant.WarTask;
0046: import com.liferay.util.xml.XMLFormatter;
0047:
0048: import java.io.File;
0049: import java.io.FileInputStream;
0050: import java.io.IOException;
0051: import java.io.InputStream;
0052:
0053: import java.util.ArrayList;
0054: import java.util.List;
0055: import java.util.Map;
0056: import java.util.Properties;
0057: import java.util.zip.ZipEntry;
0058: import java.util.zip.ZipFile;
0059:
0060: import org.apache.commons.logging.Log;
0061: import org.apache.commons.logging.LogFactory;
0062: import org.apache.oro.io.GlobFilenameFilter;
0063:
0064: import org.dom4j.Document;
0065: import org.dom4j.Element;
0066:
0067: /**
0068: * <a href="BaseDeployer.java.html"><b><i>View Source</i></b></a>
0069: *
0070: * @author Brian Wing Shun Chan
0071: *
0072: */
0073: public class BaseDeployer {
0074:
0075: public static final String DEPLOY_TO_PREFIX = "DEPLOY_TO__";
0076:
0077: public static void main(String[] args) {
0078: List wars = new ArrayList();
0079: List jars = new ArrayList();
0080:
0081: for (int i = 0; i < args.length; i++) {
0082: String fileName = args[i].toLowerCase();
0083:
0084: if (fileName.endsWith(".war")) {
0085: wars.add(args[i]);
0086: } else if (fileName.endsWith(".jar")) {
0087: jars.add(args[i]);
0088: }
0089: }
0090:
0091: new BaseDeployer(wars, jars);
0092: }
0093:
0094: protected BaseDeployer() {
0095: }
0096:
0097: protected BaseDeployer(List wars, List jars) {
0098: baseDir = System.getProperty("deployer.base.dir");
0099: destDir = System.getProperty("deployer.dest.dir");
0100: appServerType = System.getProperty("deployer.app.server.type");
0101: portletTaglibDTD = System
0102: .getProperty("deployer.portlet.taglib.dtd");
0103: portletExtTaglibDTD = System
0104: .getProperty("deployer.portlet.ext.taglib.dtd");
0105: securityTaglibDTD = System
0106: .getProperty("deployer.security.taglib.dtd");
0107: themeTaglibDTD = System
0108: .getProperty("deployer.theme.taglib.dtd");
0109: uiTaglibDTD = System.getProperty("deployer.ui.taglib.dtd");
0110: utilTaglibDTD = System.getProperty("deployer.util.taglib.dtd");
0111: unpackWar = GetterUtil.getBoolean(System
0112: .getProperty("deployer.unpack.war"), true);
0113: jbossPrefix = GetterUtil.getString(System
0114: .getProperty("deployer.jboss.prefix"));
0115: tomcatLibDir = System.getProperty("deployer.tomcat.lib.dir");
0116: this .wars = wars;
0117: this .jars = jars;
0118:
0119: checkArguments();
0120:
0121: try {
0122: deploy();
0123: } catch (Exception e) {
0124: e.printStackTrace();
0125: }
0126: }
0127:
0128: protected void checkArguments() {
0129: if (Validator.isNull(baseDir)) {
0130: throw new IllegalArgumentException(
0131: "The system property deployer.base.dir is not set");
0132: }
0133:
0134: if (Validator.isNull(destDir)) {
0135: throw new IllegalArgumentException(
0136: "The system property deployer.dest.dir is not set");
0137: }
0138:
0139: if (Validator.isNull(appServerType)) {
0140: throw new IllegalArgumentException(
0141: "The system property deployer.app.server.type is not set");
0142: }
0143:
0144: if (!appServerType.startsWith(ServerDetector.GERONIMO_ID)
0145: && !appServerType
0146: .startsWith(ServerDetector.GLASSFISH_ID)
0147: && !appServerType.startsWith(ServerDetector.JBOSS_ID)
0148: && !appServerType.startsWith(ServerDetector.JONAS_ID)
0149: && !appServerType.equals(ServerDetector.JETTY_ID)
0150: && !appServerType.equals(ServerDetector.OC4J_ID)
0151: && !appServerType.equals(ServerDetector.ORION_ID)
0152: && !appServerType.equals(ServerDetector.PRAMATI_ID)
0153: && !appServerType.equals(ServerDetector.RESIN_ID)
0154: && !appServerType.equals(ServerDetector.TOMCAT_ID)
0155: && !appServerType.equals(ServerDetector.WEBLOGIC_ID)
0156: && !appServerType.equals(ServerDetector.WEBSPHERE_ID)) {
0157:
0158: throw new IllegalArgumentException(appServerType
0159: + " is not a valid application server type");
0160: }
0161:
0162: if (appServerType.startsWith(ServerDetector.GLASSFISH_ID)
0163: || appServerType.equals(ServerDetector.PRAMATI_ID)
0164: || appServerType.equals(ServerDetector.WEBLOGIC_ID)) {
0165:
0166: unpackWar = false;
0167: }
0168:
0169: if (Validator.isNotNull(jbossPrefix)
0170: && !Validator.isNumber(jbossPrefix)) {
0171:
0172: jbossPrefix = "1";
0173: }
0174: }
0175:
0176: protected void copyDependencyXml(String fileName, String targetDir)
0177: throws Exception {
0178:
0179: copyDependencyXml(fileName, targetDir, null);
0180: }
0181:
0182: protected void copyDependencyXml(String fileName, String targetDir,
0183: Map filterMap) throws Exception {
0184:
0185: copyDependencyXml(fileName, targetDir, filterMap, false);
0186: }
0187:
0188: protected void copyDependencyXml(String fileName, String targetDir,
0189: Map filterMap, boolean overwrite) throws Exception {
0190:
0191: File file = new File(DeployUtil.getResourcePath(fileName));
0192: File targetFile = new File(targetDir + "/" + fileName);
0193:
0194: if (!targetFile.exists()) {
0195: CopyTask.copyFile(file, new File(targetDir), filterMap,
0196: overwrite, true);
0197: }
0198: }
0199:
0200: protected void copyJars(File srcFile, PluginPackage pluginPackage)
0201: throws Exception {
0202:
0203: for (int i = 0; i < jars.size(); i++) {
0204: String jarFullName = (String) jars.get(i);
0205: String jarName = jarFullName.substring(jarFullName
0206: .lastIndexOf("/") + 1, jarFullName.length());
0207:
0208: if ((!appServerType.equals(ServerDetector.TOMCAT_ID))
0209: || (appServerType.equals(ServerDetector.TOMCAT_ID) && !jarFullName
0210: .equals("util-java.jar"))) {
0211:
0212: FileUtil.copyFile(jarFullName, srcFile
0213: + "/WEB-INF/lib/" + jarName, true);
0214: }
0215: }
0216:
0217: FileUtil.delete(srcFile + "/WEB-INF/lib/util-jsf.jar");
0218: }
0219:
0220: protected void copyPortalDependencies(File srcFile)
0221: throws Exception {
0222: Properties props = getPluginPackageProperties(srcFile);
0223:
0224: if (props == null) {
0225: return;
0226: }
0227:
0228: // jars
0229:
0230: String[] portalJars = StringUtil.split(props
0231: .getProperty("portal.dependency.jars"));
0232:
0233: for (int i = 0; i < portalJars.length; i++) {
0234: String portalJar = portalJars[i].trim();
0235:
0236: if (_log.isDebugEnabled()) {
0237: _log.debug("Copy portal JAR " + portalJar);
0238: }
0239:
0240: try {
0241: String portalJarPath = PortalUtil.getPortalLibDir()
0242: + portalJar;
0243:
0244: FileUtil.copyFile(portalJarPath, srcFile
0245: + "/WEB-INF/lib/" + portalJar, true);
0246: } catch (Exception e) {
0247: _log.error("Unable to copy portal JAR " + portalJar, e);
0248: }
0249: }
0250:
0251: // tlds
0252:
0253: String[] portalTlds = StringUtil.split(props
0254: .getProperty("portal.dependency.tlds"));
0255:
0256: for (int i = 0; i < portalTlds.length; i++) {
0257: String portalTld = portalTlds[i].trim();
0258:
0259: if (_log.isDebugEnabled()) {
0260: _log.debug("Copy portal TLD " + portalTld);
0261: }
0262:
0263: try {
0264: String portalTldPath = DeployUtil
0265: .getResourcePath(portalTld);
0266:
0267: FileUtil.copyFile(portalTldPath, srcFile
0268: + "/WEB-INF/tld/" + portalTld, true);
0269: } catch (Exception e) {
0270: _log.error("Unable to copy portal TLD " + portalTld, e);
0271: }
0272: }
0273:
0274: // commons-logging*.jar
0275:
0276: File pluginLibDir = new File(srcFile + "/WEB-INF/lib/");
0277:
0278: String[] commonsLoggingJars = pluginLibDir
0279: .list(new GlobFilenameFilter("commons-logging*.jar"));
0280:
0281: if ((commonsLoggingJars == null)
0282: || (commonsLoggingJars.length == 0)) {
0283: String portalJarPath = PortalUtil.getPortalLibDir()
0284: + "commons-logging.jar";
0285:
0286: FileUtil.copyFile(portalJarPath, srcFile
0287: + "/WEB-INF/lib/commons-logging.jar", true);
0288: }
0289:
0290: // log4j*.jar
0291:
0292: String[] log4jJars = pluginLibDir.list(new GlobFilenameFilter(
0293: "log4j*.jar"));
0294:
0295: if ((log4jJars == null) || (log4jJars.length == 0)) {
0296: String portalJarPath = PortalUtil.getPortalLibDir()
0297: + "log4j.jar";
0298:
0299: FileUtil.copyFile(portalJarPath, srcFile
0300: + "/WEB-INF/lib/log4j.jar", true);
0301: }
0302: }
0303:
0304: protected void copyTlds(File srcFile, PluginPackage pluginPackage)
0305: throws Exception {
0306:
0307: if (Validator.isNotNull(portletTaglibDTD)) {
0308: FileUtil.copyFile(portletTaglibDTD, srcFile
0309: + "/WEB-INF/tld/liferay-portlet.tld", true);
0310: }
0311:
0312: if (Validator.isNotNull(themeTaglibDTD)) {
0313: FileUtil.copyFile(themeTaglibDTD, srcFile
0314: + "/WEB-INF/tld/liferay-theme.tld", true);
0315: }
0316:
0317: if (Validator.isNotNull(utilTaglibDTD)) {
0318: FileUtil.copyFile(utilTaglibDTD, srcFile
0319: + "/WEB-INF/tld/liferay-util.tld", true);
0320: }
0321: }
0322:
0323: protected void copyXmls(File srcFile, String displayName,
0324: PluginPackage pluginPackage) throws Exception {
0325:
0326: copyDependencyXml("geronimo-web.xml", srcFile + "/WEB-INF");
0327: copyDependencyXml("web.xml", srcFile + "/WEB-INF");
0328: }
0329:
0330: protected void deploy() throws Exception {
0331: try {
0332: File baseDirFile = new File(baseDir);
0333:
0334: File[] files = baseDirFile.listFiles();
0335:
0336: if (files == null) {
0337: return;
0338: }
0339:
0340: files = FileUtil.sortFiles(files);
0341:
0342: for (int i = 0; i < files.length; i++) {
0343: File srcFile = files[i];
0344:
0345: String fileName = srcFile.getName().toLowerCase();
0346:
0347: boolean deploy = false;
0348:
0349: if (fileName.endsWith(".war")
0350: || fileName.endsWith(".zip")) {
0351: deploy = true;
0352:
0353: if ((wars.size() > 0)
0354: && (!wars.contains(srcFile.getName()))) {
0355:
0356: deploy = false;
0357: }
0358: }
0359:
0360: if (deploy) {
0361: deployFile(srcFile);
0362: }
0363: }
0364: } catch (Exception e) {
0365: e.printStackTrace();
0366: }
0367: }
0368:
0369: protected void deployDirectory(File srcFile, String displayName,
0370: boolean override, PluginPackage pluginPackage)
0371: throws Exception {
0372:
0373: deployDirectory(srcFile, null, null, displayName, override,
0374: pluginPackage);
0375: }
0376:
0377: protected void deployDirectory(File srcFile, File mergeDir,
0378: File deployDir, String displayName, boolean overwrite,
0379: PluginPackage pluginPackage) throws Exception {
0380:
0381: rewriteFiles(srcFile);
0382:
0383: mergeDirectory(mergeDir, srcFile);
0384:
0385: processPluginPackageProperties(srcFile, displayName,
0386: pluginPackage);
0387:
0388: copyJars(srcFile, pluginPackage);
0389: copyTlds(srcFile, pluginPackage);
0390: copyXmls(srcFile, displayName, pluginPackage);
0391: copyPortalDependencies(srcFile);
0392:
0393: updateGeronimoWebXml(srcFile, displayName, pluginPackage);
0394:
0395: File webXml = new File(srcFile + "/WEB-INF/web.xml");
0396:
0397: updateWebXml(webXml, srcFile, displayName, pluginPackage);
0398:
0399: if ((deployDir != null) && !baseDir.equals(destDir)) {
0400: updateDeployDirectory(srcFile);
0401:
0402: String excludes = StringPool.BLANK;
0403:
0404: if (appServerType.startsWith("jboss")) {
0405: excludes += "**/WEB-INF/lib/log4j.jar,";
0406: } else if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
0407: String[] libs = FileUtil.listFiles(tomcatLibDir);
0408:
0409: for (int i = 0; i < libs.length; i++) {
0410: excludes += "**/WEB-INF/lib/" + libs[i] + ",";
0411: }
0412:
0413: File contextXml = new File(srcFile
0414: + "/META-INF/context.xml");
0415:
0416: if (contextXml.exists()) {
0417: String content = FileUtil.read(contextXml);
0418:
0419: if (content.indexOf(_PORTAL_CLASS_LOADER) != -1) {
0420: excludes += "**/WEB-INF/lib/util-bridges.jar,";
0421: excludes += "**/WEB-INF/lib/util-java.jar,";
0422: excludes += "**/WEB-INF/lib/util-taglib.jar,";
0423: }
0424: }
0425:
0426: try {
0427:
0428: // LEP-2990
0429:
0430: Class.forName("javax.el.ELContext");
0431:
0432: excludes += "**/WEB-INF/lib/el-api.jar,";
0433: } catch (ClassNotFoundException cnfe) {
0434: }
0435: }
0436:
0437: if (!unpackWar || appServerType.equals("websphere")) {
0438: File tempDir = new File(SystemProperties
0439: .get(SystemProperties.TMP_DIR)
0440: + File.separator + Time.getTimestamp());
0441:
0442: WarTask
0443: .war(srcFile, tempDir, "WEB-INF/web.xml",
0444: webXml);
0445:
0446: if (!tempDir.renameTo(deployDir)) {
0447: WarTask.war(srcFile, deployDir, "WEB-INF/web.xml",
0448: webXml);
0449: }
0450:
0451: DeleteTask.deleteDirectory(tempDir);
0452: } else {
0453:
0454: // The deployer might only copy files that have been modified.
0455: // However, the deployer always copies and overwrites web.xml
0456: // after the other files have been copied because application
0457: // servers usually detect that a WAR has been modified based on
0458: // the web.xml time stamp.
0459:
0460: excludes += "**/WEB-INF/web.xml";
0461:
0462: CopyTask.copyDirectory(srcFile, deployDir,
0463: StringPool.BLANK, excludes, overwrite, true);
0464:
0465: CopyTask.copyDirectory(srcFile, deployDir,
0466: "**/WEB-INF/web.xml", StringPool.BLANK, true,
0467: false);
0468:
0469: if (appServerType.equals(ServerDetector.TOMCAT_ID)) {
0470:
0471: // See org.apache.catalina.startup.HostConfig to see how
0472: // Tomcat checks to make sure that web.xml was modified 5
0473: // seconds after WEB-INF
0474:
0475: File deployWebXml = new File(deployDir
0476: + "/WEB-INF/web.xml");
0477:
0478: deployWebXml.setLastModified(System
0479: .currentTimeMillis()
0480: + (Time.SECOND * 6));
0481: }
0482: }
0483: }
0484: }
0485:
0486: protected void deployFile(File srcFile) throws Exception {
0487: PluginPackage pluginPackage = readPluginPackage(srcFile);
0488:
0489: if (_log.isInfoEnabled()) {
0490: _log.info("Deploying " + srcFile.getName());
0491: }
0492:
0493: String deployDir = null;
0494: String displayName = null;
0495: boolean overwrite = false;
0496: String preliminaryContext = null;
0497:
0498: // File names starting with DEPLOY_TO_PREFIX should use the filename
0499: // after the prefix as the deployment context
0500:
0501: if (srcFile.getName().startsWith(DEPLOY_TO_PREFIX)) {
0502: displayName = srcFile.getName().substring(
0503: DEPLOY_TO_PREFIX.length(),
0504: srcFile.getName().length() - 4);
0505:
0506: overwrite = true;
0507: preliminaryContext = displayName;
0508: }
0509:
0510: if (preliminaryContext == null) {
0511: preliminaryContext = getDisplayName(srcFile);
0512: }
0513:
0514: if (pluginPackage != null) {
0515: if (!PluginPackageUtil
0516: .isCurrentVersionSupported(pluginPackage
0517: .getLiferayVersions())) {
0518:
0519: throw new AutoDeployException(srcFile.getName()
0520: + " does not support this version of Liferay");
0521: }
0522:
0523: if (displayName == null) {
0524: displayName = pluginPackage
0525: .getRecommendedDeploymentContext();
0526: }
0527:
0528: if (Validator.isNull(displayName)) {
0529: displayName = getDisplayName(srcFile);
0530: }
0531:
0532: pluginPackage.setContext(displayName);
0533:
0534: PluginPackageUtil.updateInstallingPluginPackage(
0535: preliminaryContext, pluginPackage);
0536: }
0537:
0538: if (Validator.isNotNull(displayName)) {
0539: deployDir = displayName + ".war";
0540: } else {
0541: deployDir = srcFile.getName();
0542: displayName = getDisplayName(srcFile);
0543: }
0544:
0545: if (appServerType.startsWith(ServerDetector.JBOSS_ID)) {
0546: deployDir = jbossPrefix + deployDir;
0547: } else if (appServerType.equals(ServerDetector.JETTY_ID)
0548: || appServerType.equals(ServerDetector.OC4J_ID)
0549: || appServerType.equals(ServerDetector.ORION_ID)
0550: || appServerType.equals(ServerDetector.RESIN_ID)
0551: || appServerType.equals(ServerDetector.TOMCAT_ID)) {
0552:
0553: if (unpackWar) {
0554: deployDir = deployDir.substring(0,
0555: deployDir.length() - 4);
0556: }
0557: }
0558:
0559: deployDir = destDir + "/" + deployDir;
0560:
0561: File deployDirFile = new File(deployDir);
0562:
0563: try {
0564: PluginPackage previousPluginPackage = readPluginPackage(deployDirFile);
0565:
0566: if ((pluginPackage != null)
0567: && (previousPluginPackage != null)) {
0568: if (_log.isInfoEnabled()) {
0569: String name = pluginPackage.getName();
0570: String previousVersion = previousPluginPackage
0571: .getVersion();
0572: String version = pluginPackage.getVersion();
0573:
0574: _log.info("Updating " + name + " from version "
0575: + previousVersion + " to version "
0576: + version);
0577: }
0578:
0579: if (pluginPackage
0580: .isLaterVersionThan(previousPluginPackage)) {
0581:
0582: overwrite = true;
0583: }
0584: }
0585:
0586: File mergeDirFile = new File(srcFile.getParent()
0587: + "/merge/" + srcFile.getName());
0588:
0589: if (srcFile.isDirectory()) {
0590: deployDirectory(srcFile, mergeDirFile, deployDirFile,
0591: displayName, overwrite, pluginPackage);
0592: } else {
0593: boolean deployed = deployFile(srcFile, mergeDirFile,
0594: deployDirFile, displayName, overwrite,
0595: pluginPackage);
0596:
0597: if (!deployed) {
0598: String context = preliminaryContext;
0599:
0600: if (pluginPackage != null) {
0601: context = pluginPackage.getContext();
0602: }
0603:
0604: PluginPackageUtil
0605: .endPluginPackageInstallation(context);
0606: }
0607: }
0608: } catch (Exception e) {
0609: if (pluginPackage != null) {
0610: PluginPackageUtil
0611: .endPluginPackageInstallation(pluginPackage
0612: .getContext());
0613: }
0614:
0615: throw e;
0616: }
0617: }
0618:
0619: protected boolean deployFile(File srcFile, File mergeDir,
0620: File deployDir, String displayName, boolean overwrite,
0621: PluginPackage pluginPackage) throws Exception {
0622:
0623: if (!overwrite && UpToDateTask.isUpToDate(srcFile, deployDir)) {
0624: if (_log.isInfoEnabled()) {
0625: _log.info(deployDir + " is already up to date");
0626: }
0627:
0628: return false;
0629: }
0630:
0631: // Don't delete the deploy directory because it can cause problems in
0632: // certain application servers
0633:
0634: //DeleteTask.deleteDirectory(deployDir);
0635:
0636: File tempDir = new File(SystemProperties
0637: .get(SystemProperties.TMP_DIR)
0638: + File.separator + Time.getTimestamp());
0639:
0640: ExpandTask.expand(srcFile, tempDir);
0641:
0642: deployDirectory(tempDir, mergeDir, deployDir, displayName,
0643: overwrite, pluginPackage);
0644:
0645: DeleteTask.deleteDirectory(tempDir);
0646:
0647: return true;
0648: }
0649:
0650: protected String downloadJar(String jar) throws Exception {
0651: String tmpDir = SystemProperties.get(SystemProperties.TMP_DIR);
0652:
0653: File file = new File(tmpDir
0654: + "/liferay/com/liferay/portal/deploy/dependencies/"
0655: + jar);
0656:
0657: if (!file.exists()) {
0658: synchronized (this ) {
0659: String url = PropsUtil
0660: .get(PropsUtil.LIBRARY_DOWNLOAD_URL + jar);
0661:
0662: if (_log.isInfoEnabled()) {
0663: _log.info("Downloading library from " + url);
0664: }
0665:
0666: byte[] bytes = Http.URLtoByteArray(url);
0667:
0668: FileUtil.write(file, bytes);
0669: }
0670: }
0671:
0672: return FileUtil.getAbsolutePath(file);
0673: }
0674:
0675: protected String getDisplayName(File srcFile) {
0676: String displayName = srcFile.getName();
0677:
0678: displayName = displayName
0679: .substring(0, displayName.length() - 4);
0680:
0681: if (appServerType.startsWith("jboss")
0682: && Validator.isNotNull(jbossPrefix)
0683: && displayName.startsWith(jbossPrefix)) {
0684:
0685: displayName = displayName
0686: .substring(1, displayName.length());
0687: }
0688:
0689: return displayName;
0690: }
0691:
0692: protected String getExtraContent(double webXmlVersion,
0693: File srcFile, String displayName) throws Exception {
0694:
0695: StringMaker sm = new StringMaker();
0696:
0697: sm.append("<display-name>");
0698: sm.append(displayName);
0699: sm.append("</display-name>");
0700:
0701: boolean hasTaglib = false;
0702:
0703: if (Validator.isNotNull(portletTaglibDTD)
0704: || Validator.isNotNull(portletExtTaglibDTD)
0705: || Validator.isNotNull(securityTaglibDTD)
0706: || Validator.isNotNull(themeTaglibDTD)
0707: || Validator.isNotNull(uiTaglibDTD)
0708: || Validator.isNotNull(utilTaglibDTD)) {
0709:
0710: hasTaglib = true;
0711: }
0712:
0713: if (hasTaglib && (webXmlVersion > 2.3)) {
0714: sm.append("<jsp-config>");
0715: }
0716:
0717: if (Validator.isNotNull(portletTaglibDTD)) {
0718: sm.append("<taglib>");
0719: sm
0720: .append("<taglib-uri>http://java.sun.com/portlet</taglib-uri>");
0721: sm.append("<taglib-location>");
0722: sm.append("/WEB-INF/tld/liferay-portlet.tld");
0723: sm.append("</taglib-location>");
0724: sm.append("</taglib>");
0725: }
0726:
0727: if (Validator.isNotNull(portletExtTaglibDTD)) {
0728: sm.append("<taglib>");
0729: sm.append("<taglib-uri>");
0730: sm.append("http://liferay.com/tld/portlet");
0731: sm.append("</taglib-uri>");
0732: sm.append("<taglib-location>");
0733: sm.append("/WEB-INF/tld/liferay-portlet-ext.tld");
0734: sm.append("</taglib-location>");
0735: sm.append("</taglib>");
0736: }
0737:
0738: if (Validator.isNotNull(securityTaglibDTD)) {
0739: sm.append("<taglib>");
0740: sm.append("<taglib-uri>");
0741: sm.append("http://liferay.com/tld/security");
0742: sm.append("</taglib-uri>");
0743: sm.append("<taglib-location>");
0744: sm.append("/WEB-INF/tld/liferay-security.tld");
0745: sm.append("</taglib-location>");
0746: sm.append("</taglib>");
0747: }
0748:
0749: if (Validator.isNotNull(themeTaglibDTD)) {
0750: sm.append("<taglib>");
0751: sm
0752: .append("<taglib-uri>http://liferay.com/tld/theme</taglib-uri>");
0753: sm.append("<taglib-location>");
0754: sm.append("/WEB-INF/tld/liferay-theme.tld");
0755: sm.append("</taglib-location>");
0756: sm.append("</taglib>");
0757: }
0758:
0759: if (Validator.isNotNull(uiTaglibDTD)) {
0760: sm.append("<taglib>");
0761: sm
0762: .append("<taglib-uri>http://liferay.com/tld/ui</taglib-uri>");
0763: sm.append("<taglib-location>");
0764: sm.append("/WEB-INF/tld/liferay-ui.tld");
0765: sm.append("</taglib-location>");
0766: sm.append("</taglib>");
0767: }
0768:
0769: if (Validator.isNotNull(utilTaglibDTD)) {
0770: sm.append("<taglib>");
0771: sm
0772: .append("<taglib-uri>http://liferay.com/tld/util</taglib-uri>");
0773: sm.append("<taglib-location>");
0774: sm.append("/WEB-INF/tld/liferay-util.tld");
0775: sm.append("</taglib-location>");
0776: sm.append("</taglib>");
0777: }
0778:
0779: if (hasTaglib && (webXmlVersion > 2.3)) {
0780: sm.append("</jsp-config>");
0781: }
0782:
0783: return sm.toString();
0784: }
0785:
0786: protected String getPluginPackageLicensesXml(List licenses) {
0787: StringMaker sm = new StringMaker();
0788:
0789: for (int i = 0; i < licenses.size(); i++) {
0790: License license = (License) licenses.get(i);
0791:
0792: if (i == 0) {
0793: sm.append("\r\n");
0794: }
0795:
0796: sm.append("\t\t<license osi-approved=\"");
0797: sm.append(license.isOsiApproved());
0798: sm.append("\">");
0799: sm.append(license.getName());
0800: sm.append("</license>\r\n");
0801:
0802: if ((i + 1) == licenses.size()) {
0803: sm.append("\t");
0804: }
0805: }
0806:
0807: return sm.toString();
0808: }
0809:
0810: protected String getPluginPackageLiferayVersionsXml(
0811: List liferayVersions) {
0812: StringMaker sm = new StringMaker();
0813:
0814: for (int i = 0; i < liferayVersions.size(); i++) {
0815: String liferayVersion = (String) liferayVersions.get(i);
0816:
0817: if (i == 0) {
0818: sm.append("\r\n");
0819: }
0820:
0821: sm.append("\t\t<liferay-version>");
0822: sm.append(liferayVersion);
0823: sm.append("</liferay-version>\r\n");
0824:
0825: if ((i + 1) == liferayVersions.size()) {
0826: sm.append("\t");
0827: }
0828: }
0829:
0830: return sm.toString();
0831: }
0832:
0833: protected Properties getPluginPackageProperties(File srcFile)
0834: throws Exception {
0835:
0836: File propsFile = new File(srcFile
0837: + "/WEB-INF/liferay-plugin-package.properties");
0838:
0839: if (!propsFile.exists()) {
0840: return null;
0841: }
0842:
0843: String propsString = FileUtil.read(propsFile);
0844:
0845: return PropertiesUtil.load(propsString);
0846: }
0847:
0848: protected String getPluginPackageTagsXml(List tags) {
0849: StringMaker sm = new StringMaker();
0850:
0851: for (int i = 0; i < tags.size(); i++) {
0852: String tag = (String) tags.get(i);
0853:
0854: if (i == 0) {
0855: sm.append("\r\n");
0856: }
0857:
0858: sm.append("\t\t<tag>");
0859: sm.append(tag);
0860: sm.append("</tag>\r\n");
0861:
0862: if ((i + 1) == tags.size()) {
0863: sm.append("\t");
0864: }
0865: }
0866:
0867: return sm.toString();
0868: }
0869:
0870: protected void mergeDirectory(File mergeDir, File targetDir) {
0871: if ((mergeDir == null) || (!mergeDir.exists())) {
0872: return;
0873: }
0874:
0875: CopyTask.copyDirectory(mergeDir, targetDir, null, null, true,
0876: false);
0877: }
0878:
0879: protected void processPluginPackageProperties(File srcFile,
0880: String displayName, PluginPackage pluginPackage)
0881: throws Exception {
0882: }
0883:
0884: protected PluginPackage readPluginPackage(File file) {
0885: if (!file.exists()) {
0886: return null;
0887: }
0888:
0889: InputStream is = null;
0890: ZipFile zipFile = null;
0891:
0892: try {
0893: boolean parseProps = false;
0894:
0895: if (file.isDirectory()) {
0896: String path = file.getPath();
0897:
0898: File pluginPackageXmlFile = new File(file.getParent()
0899: + "/merge/" + file.getName()
0900: + "/WEB-INF/liferay-plugin-package.xml");
0901:
0902: if (pluginPackageXmlFile.exists()) {
0903: is = new FileInputStream(pluginPackageXmlFile);
0904: } else {
0905: pluginPackageXmlFile = new File(path
0906: + "/WEB-INF/liferay-plugin-package.xml");
0907:
0908: if (pluginPackageXmlFile.exists()) {
0909: is = new FileInputStream(pluginPackageXmlFile);
0910: }
0911: }
0912:
0913: File pluginPackagePropsFile = new File(file.getParent()
0914: + "/merge/" + file.getName()
0915: + "/WEB-INF/liferay-plugin-package.properties");
0916:
0917: if (pluginPackagePropsFile.exists()) {
0918: is = new FileInputStream(pluginPackagePropsFile);
0919:
0920: parseProps = true;
0921: } else {
0922: pluginPackagePropsFile = new File(
0923: path
0924: + "/WEB-INF/liferay-plugin-package.properties");
0925:
0926: if (pluginPackagePropsFile.exists()) {
0927: is = new FileInputStream(pluginPackagePropsFile);
0928:
0929: parseProps = true;
0930: }
0931: }
0932: } else {
0933: zipFile = new ZipFile(file);
0934:
0935: File pluginPackageXmlFile = new File(file.getParent()
0936: + "/merge/" + file.getName()
0937: + "/WEB-INF/liferay-plugin-package.xml");
0938:
0939: if (pluginPackageXmlFile.exists()) {
0940: is = new FileInputStream(pluginPackageXmlFile);
0941: } else {
0942: ZipEntry zipEntry = zipFile
0943: .getEntry("WEB-INF/liferay-plugin-package.xml");
0944:
0945: if (zipEntry != null) {
0946: is = zipFile.getInputStream(zipEntry);
0947: }
0948: }
0949:
0950: File pluginPackagePropsFile = new File(file.getParent()
0951: + "/merge/" + file.getName()
0952: + "/WEB-INF/liferay-plugin-package.properties");
0953:
0954: if (pluginPackagePropsFile.exists()) {
0955: is = new FileInputStream(pluginPackagePropsFile);
0956:
0957: parseProps = true;
0958: } else {
0959: ZipEntry zipEntry = zipFile
0960: .getEntry("WEB-INF/liferay-plugin-package.properties");
0961:
0962: if (zipEntry != null) {
0963: is = zipFile.getInputStream(zipEntry);
0964:
0965: parseProps = true;
0966: }
0967: }
0968: }
0969:
0970: if (is == null) {
0971: if (_log.isInfoEnabled()) {
0972: _log
0973: .info(file.getPath()
0974: + " does not have a "
0975: + "WEB-INF/liferay-plugin-package.xml or "
0976: + "WEB-INF/liferay-plugin-package.properties");
0977: }
0978:
0979: return null;
0980: }
0981:
0982: if (parseProps) {
0983: String displayName = getDisplayName(file);
0984:
0985: String propsString = StringUtil.read(is);
0986:
0987: Properties props = PropertiesUtil.load(propsString);
0988:
0989: return PluginPackageUtil.readPluginPackageProps(
0990: displayName, props);
0991: } else {
0992: String xml = StringUtil.read(is);
0993:
0994: xml = XMLFormatter.fixProlog(xml);
0995:
0996: return PluginPackageUtil.readPluginPackageXml(xml);
0997: }
0998: } catch (Exception e) {
0999: _log.error(file.getPath() + ": " + e.toString());
1000: } finally {
1001: if (is != null) {
1002: try {
1003: is.close();
1004: } catch (IOException ioe) {
1005: }
1006: }
1007:
1008: if (zipFile != null) {
1009: try {
1010: zipFile.close();
1011: } catch (IOException ioe) {
1012: }
1013: }
1014: }
1015:
1016: return null;
1017: }
1018:
1019: protected void rewriteFiles(File srcDir) throws Exception {
1020: String[] files = FileUtil.listFiles(srcDir + "/WEB-INF/");
1021:
1022: for (int i = 0; i < files.length; i++) {
1023: String ext = FileUtil.getExtension(files[i]);
1024:
1025: if (ext.equalsIgnoreCase("xml")) {
1026:
1027: // Make sure to rewrite any XML files to include external
1028: // entities into same file. See LEP-3142.
1029:
1030: File file = new File(srcDir + "/WEB-INF/" + files[i]);
1031:
1032: try {
1033: Document doc = PortalUtil
1034: .readDocumentFromFile(file);
1035:
1036: String content = XMLFormatter.toString(doc,
1037: XMLFormatter.INDENT, true);
1038:
1039: FileUtil.write(file, content);
1040: } catch (Exception e) {
1041: if (_log.isWarnEnabled()) {
1042: _log.warn("Unable to format " + file + ": "
1043: + e.getMessage());
1044: }
1045: }
1046: }
1047: }
1048: }
1049:
1050: protected void updateDeployDirectory(File srcFile) throws Exception {
1051: }
1052:
1053: protected void updateGeronimoWebXml(File srcFile,
1054: String displayName, PluginPackage pluginPackage)
1055: throws Exception {
1056:
1057: if (!appServerType.startsWith(ServerDetector.GERONIMO_ID)) {
1058: return;
1059: }
1060:
1061: File geronimoWebXml = new File(srcFile
1062: + "/WEB-INF/geronimo-web.xml");
1063:
1064: Document doc = PortalUtil.readDocumentFromFile(geronimoWebXml);
1065:
1066: Element root = doc.getRootElement();
1067:
1068: Element environmentEl = root.element("environment");
1069:
1070: Element moduleIdEl = environmentEl.element("moduleId");
1071:
1072: Element artifactIdEl = moduleIdEl.element("artifactId");
1073:
1074: String artifactIdText = GetterUtil.getString(artifactIdEl
1075: .getText());
1076:
1077: if (!artifactIdText.equals(displayName)) {
1078: artifactIdEl.setText(displayName);
1079:
1080: String content = XMLFormatter.toString(doc);
1081:
1082: FileUtil.write(geronimoWebXml, content);
1083:
1084: if (_log.isInfoEnabled()) {
1085: _log.info("Modifying Geronimo " + geronimoWebXml);
1086: }
1087: }
1088: }
1089:
1090: protected void updateWebXml(File webXml, File srcFile,
1091: String displayName, PluginPackage pluginPackage)
1092: throws Exception {
1093:
1094: String content = FileUtil.read(webXml);
1095:
1096: int pos = content.indexOf("</web-app>");
1097:
1098: double webXmlVersion = 2.3;
1099:
1100: Document webXmlDoc = PortalUtil.readDocumentFromXML(content);
1101:
1102: Element webXmlRoot = webXmlDoc.getRootElement();
1103:
1104: webXmlVersion = GetterUtil.getDouble(webXmlRoot
1105: .attributeValue("version"), webXmlVersion);
1106:
1107: // Merge extra content
1108:
1109: String extraContent = getExtraContent(webXmlVersion, srcFile,
1110: displayName);
1111:
1112: String newContent = content.substring(0, pos) + extraContent
1113: + content.substring(pos, content.length());
1114:
1115: // Replace old package names
1116:
1117: newContent = StringUtil.replace(newContent,
1118: "com.liferay.portal.shared.",
1119: "com.liferay.portal.kernel.");
1120:
1121: newContent = WebXMLBuilder.organizeWebXML(newContent);
1122:
1123: FileUtil.write(webXml, newContent, true);
1124:
1125: if (_log.isInfoEnabled()) {
1126: _log.info("Modifying Servlet " + webXmlVersion + " "
1127: + webXml);
1128: }
1129: }
1130:
1131: protected String baseDir;
1132: protected String destDir;
1133: protected String appServerType;
1134: protected String portletTaglibDTD;
1135: protected String portletExtTaglibDTD;
1136: protected String securityTaglibDTD;
1137: protected String themeTaglibDTD;
1138: protected String uiTaglibDTD;
1139: protected String utilTaglibDTD;
1140: protected boolean unpackWar;
1141: protected String jbossPrefix;
1142: protected String tomcatLibDir;
1143: protected List wars;
1144: protected List jars;
1145:
1146: private static final String _PORTAL_CLASS_LOADER = "com.liferay.support.tomcat.loader.PortalClassLoader";
1147:
1148: private static Log _log = LogFactory.getLog(BaseDeployer.class);
1149:
1150: }
|