一、前言
这边通过分析cargo源码包(0.6)中关于常用的应用服务器容器(jboss、tomcat)部署基于ear、war的项目实施方案org.codehaus.cargo.container.deployable包路径部分分析说明,分别定义统一部署定义org.codehaus.cargo.container.deployable.Deployable接口,并定义都是基于WAR包项目通用实现部署接口实现类org.codehaus.cargo.container.deployable.WAR,再分别对JBossWAR、TomcatWAR差异化区分实现,具体参见如下源码。
二、源码说明
1.Deployable、Monitorable接口
package org.codehaus.cargo.container.deployable;@b@@b@import java.io.File;@b@import org.codehaus.cargo.util.monitor.Monitorable;@b@@b@public abstract interface Deployable extends Monitorable@b@{@b@ public abstract File getFile();@b@}
package org.codehaus.cargo.util.monitor;@b@@b@public abstract interface Monitorable@b@{@b@ public abstract void setMonitor(Monitor paramMonitor);@b@@b@ public abstract Monitor getMonitor();@b@}
2.WAR、EAR实现类、DeployableType类型
package org.codehaus.cargo.container.deployable;@b@@b@import java.io.File;@b@import org.codehaus.cargo.util.monitor.Monitor;@b@import org.codehaus.cargo.util.monitor.MonitoredObject;@b@@b@public class WAR extends MonitoredObject@b@ implements Deployable@b@{@b@ private File war;@b@ private String context;@b@@b@ public WAR(String war)@b@ {@b@ this.war = new File(war);@b@ }@b@@b@ public synchronized void setContext(String context)@b@ {@b@ this.context = context;@b@ }@b@@b@ private void parseContext()@b@ {@b@ if (this.context == null)@b@ {@b@ String ctx = getFile().getName();@b@ int warIndex = ctx.toLowerCase().lastIndexOf(".war");@b@ if (warIndex >= 0)@b@ {@b@ ctx = ctx.substring(0, warIndex);@b@ }@b@@b@ getMonitor().debug("Parsed web context = [" + ctx + "]", getClass().getName());@b@@b@ setContext(ctx);@b@ }@b@ }@b@@b@ public synchronized String getContext()@b@ {@b@ parseContext();@b@ return this.context;@b@ }@b@@b@ public File getFile()@b@ {@b@ return this.war;@b@ }@b@@b@ public boolean isExpandedWar()@b@ {@b@ return getFile().isDirectory();@b@ }@b@}
package org.codehaus.cargo.container.deployable;@b@@b@import java.io.File;@b@import java.util.HashMap;@b@import java.util.Iterator;@b@import java.util.Map;@b@import java.util.Set;@b@import org.codehaus.cargo.container.ContainerException;@b@import org.codehaus.cargo.module.application.ApplicationXml;@b@import org.codehaus.cargo.module.application.DefaultEarArchive;@b@import org.codehaus.cargo.module.application.EarArchive;@b@import org.codehaus.cargo.util.monitor.Monitor;@b@import org.codehaus.cargo.util.monitor.MonitoredObject;@b@@b@public class EAR extends MonitoredObject@b@ implements Deployable@b@{@b@ private File ear;@b@ private String name;@b@ private Map webapps;@b@@b@ public EAR(String ear)@b@ {@b@ this.ear = new File(ear);@b@ }@b@@b@ private void parseName()@b@ {@b@ if (this.name == null)@b@ {@b@ String name = getFile().getName();@b@ int nameIndex = name.toLowerCase().lastIndexOf(".ear");@b@ if (nameIndex >= 0)@b@ {@b@ name = name.substring(0, nameIndex);@b@ }@b@@b@ getMonitor().debug("Parsed EAR name = [" + name + "]", getClass().getName());@b@@b@ setName(name);@b@ }@b@ }@b@@b@ private void parseWebApps()@b@ {@b@ if (this.webapps == null)@b@ {@b@ ApplicationXml applicationXml;@b@ Iterator it;@b@ Map webapps = new HashMap();@b@ try@b@ {@b@ EarArchive ear = new DefaultEarArchive(getFile());@b@ applicationXml = ear.getApplicationXml();@b@ for (it = applicationXml.getWebModuleUris(); it.hasNext(); )@b@ {@b@ String webUri = (String)it.next();@b@@b@ String context = applicationXml.getWebModuleContextRoot(webUri);@b@@b@ if (context == null)@b@ {@b@ throw new ContainerException("Your application.xml must define a <context-root> element in the <web> module definition.");@b@ }@b@@b@ if (context.startsWith("/"))@b@ {@b@ context = context.substring(1);@b@ }@b@@b@ getMonitor().debug("Found Web URI [" + webUri + "], context [" + context + "]", getClass().getName());@b@@b@ webapps.put(context, webUri);@b@ }@b@ }@b@ catch (Exception e)@b@ {@b@ throw new ContainerException("Failed to parse webapps from [" + getFile() + "] EAR.", e);@b@ }@b@@b@ this.webapps = webapps;@b@ }@b@ }@b@@b@ public File getFile()@b@ {@b@ return this.ear;@b@ }@b@@b@ public synchronized void setName(String name)@b@ {@b@ this.name = name;@b@ }@b@@b@ public synchronized String getName()@b@ {@b@ parseName();@b@ return this.name;@b@ }@b@@b@ public synchronized Iterator getWebContexts()@b@ {@b@ parseWebApps();@b@ return this.webapps.keySet().iterator();@b@ }@b@@b@ public synchronized String getWebUri(String context)@b@ {@b@ parseWebApps();@b@ return ((String)this.webapps.get(context));@b@ }@b@}
package org.codehaus.cargo.generic.deployable;@b@@b@public final class DeployableType@b@{@b@ public static final DeployableType WAR = new DeployableType("war");@b@ public static final DeployableType EAR = new DeployableType("ear");@b@ private String id;@b@@b@ private DeployableType(String id)@b@ {@b@ this.id = id;@b@ }@b@@b@ public boolean equals(Object object)@b@ {@b@ boolean result = false;@b@ if (object instanceof DeployableType)@b@ {@b@ DeployableType type = (DeployableType)object;@b@ if (type.id.equalsIgnoreCase(this.id))@b@ {@b@ result = true;@b@ }@b@ }@b@ return result;@b@ }@b@@b@ public int hashCode()@b@ {@b@ return this.id.hashCode();@b@ }@b@}
3.应用容器差异化实现类JBossWAR、TomcatWAR
package org.codehaus.cargo.container.deployable.jboss;@b@@b@import org.codehaus.cargo.container.ContainerException;@b@import org.codehaus.cargo.container.deployable.WAR;@b@import org.codehaus.cargo.module.webapp.jboss.JBossWarArchive;@b@import org.codehaus.cargo.module.webapp.jboss.JBossWebXml;@b@@b@public class JBossWAR extends WAR@b@{@b@ private JBossWarArchive warArchive;@b@@b@ public JBossWAR(String war)@b@ {@b@ super(war);@b@ try@b@ {@b@ this.warArchive = new JBossWarArchive(getFile());@b@ }@b@ catch (Exception e)@b@ {@b@ throw new ContainerException("Failed to parse JBoss WAR file in [" + getFile() + "]", e);@b@ }@b@ }@b@@b@ public synchronized String getContext()@b@ {@b@ String result = parseJbossWebXml();@b@ if (result == null)@b@ {@b@ result = super.getContext();@b@ }@b@@b@ return result;@b@ }@b@@b@ private String parseJbossWebXml()@b@ {@b@ String context = null;@b@@b@ if (this.warArchive.getJBossWebXml() != null)@b@ {@b@ context = this.warArchive.getJBossWebXml().getContextRoot();@b@ }@b@@b@ return context;@b@ }@b@@b@ public boolean containsJBossWebFile()@b@ {@b@ return (this.warArchive.getJBossWebXml() != null);@b@ }@b@}
package org.codehaus.cargo.container.deployable.tomcat;@b@@b@import org.codehaus.cargo.container.ContainerException;@b@import org.codehaus.cargo.container.deployable.WAR;@b@import org.codehaus.cargo.module.webapp.tomcat.TomcatContextXml;@b@import org.codehaus.cargo.module.webapp.tomcat.TomcatWarArchive;@b@@b@public class TomcatWAR extends WAR@b@{@b@ private TomcatWarArchive warArchive;@b@@b@ public TomcatWAR(String war)@b@ {@b@ super(war);@b@ try@b@ {@b@ this.warArchive = new TomcatWarArchive(getFile());@b@ }@b@ catch (Exception e)@b@ {@b@ throw new ContainerException("Failed to parse Tomcat WAR file in [" + getFile() + "]", e);@b@ }@b@ }@b@@b@ public synchronized String getContext()@b@ {@b@ String result = parseTomcatContextXml();@b@ if (result == null)@b@ {@b@ result = super.getContext();@b@ }@b@@b@ return result;@b@ }@b@@b@ private String parseTomcatContextXml()@b@ {@b@ String context = null;@b@@b@ if (this.warArchive.getTomcatContextXml() != null)@b@ {@b@ context = this.warArchive.getTomcatContextXml().getPath();@b@ }@b@@b@ return context;@b@ }@b@@b@ public boolean containsContextFile()@b@ {@b@ return (this.warArchive.getTomcatContextXml() != null);@b@ }@b@}
4.部署实例化工厂DeployableFactory接口及实现类DefaultDeployableFactory
package org.codehaus.cargo.generic.deployable;@b@@b@import org.codehaus.cargo.container.deployable.Deployable;@b@@b@public abstract interface DeployableFactory@b@{@b@ public abstract Deployable createDeployable(String paramString1, String paramString2, DeployableType paramDeployableType);@b@}
package org.codehaus.cargo.generic.deployable;@b@@b@import java.lang.reflect.Constructor;@b@import java.util.HashMap;@b@import java.util.Map;@b@import org.codehaus.cargo.container.deployable.Deployable;@b@import org.codehaus.cargo.container.deployable.EAR;@b@import org.codehaus.cargo.container.deployable.WAR;@b@import org.codehaus.cargo.container.deployable.tomcat.TomcatWAR;@b@import org.codehaus.cargo.util.CargoException;@b@@b@public class DefaultDeployableFactory@b@ implements DeployableFactory@b@{@b@ private Map defaultMappings;@b@ private Map specificMappings;@b@@b@ public DefaultDeployableFactory()@b@ {@b@ this.defaultMappings = new HashMap();@b@ this.defaultMappings.put(DeployableType.WAR, WAR.class);@b@ this.defaultMappings.put(DeployableType.EAR, EAR.class);@b@@b@ this.specificMappings = new HashMap();@b@@b@ Map tomcat5xMappings = new HashMap();@b@ tomcat5xMappings.put(DeployableType.WAR, TomcatWAR.class);@b@ registerImplementation("tomcat5x", tomcat5xMappings);@b@ }@b@@b@ public void registerImplementation(String containerId, Map deployableTypeMappings)@b@ {@b@ this.specificMappings.put(containerId, deployableTypeMappings);@b@ }@b@@b@ public Deployable createDeployable(String containerId, String deployableLocation, DeployableType type)@b@ {@b@ Deployable deployable;@b@ if (this.specificMappings.containsKey(containerId))@b@ {@b@ Map mapping = (Map)this.specificMappings.get(containerId);@b@@b@ if (mapping.containsKey(type))@b@ {@b@ deployable = createDeployableInstance((Class)mapping.get(type), deployableLocation);@b@ }@b@ else@b@ {@b@ deployable = createDeployableInstance((Class)this.defaultMappings.get(type), deployableLocation);@b@ }@b@@b@ }@b@ else@b@ {@b@ deployable = createDeployableInstance((Class)this.defaultMappings.get(type), deployableLocation);@b@ }@b@@b@ return deployable;@b@ }@b@@b@ private Deployable createDeployableInstance(Class deployableClass, String deployableLocation)@b@ {@b@ Deployable deployable;@b@ try@b@ {@b@ Constructor constructor = deployableClass.getConstructor(new Class[] { String.class });@b@ deployable = (Deployable)constructor.newInstance(new Object[] { deployableLocation });@b@ }@b@ catch (Exception e)@b@ {@b@ throw new CargoException("Failed to create deployable [" + deployableClass.getName() + "] for [" + deployableLocation + "]", e);@b@ }@b@@b@ return deployable;@b@ }@b@}