/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.deployment.spi;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import javax.enterprise.deploy.model.DeployableObject;
import javax.enterprise.deploy.shared.ActionType;
import javax.enterprise.deploy.shared.CommandType;
import javax.enterprise.deploy.shared.DConfigBeanVersionType;
import javax.enterprise.deploy.shared.ModuleType;
import javax.enterprise.deploy.shared.StateType;
import javax.enterprise.deploy.spi.DeploymentConfiguration;
import javax.enterprise.deploy.spi.DeploymentManager;
import javax.enterprise.deploy.spi.Target;
import javax.enterprise.deploy.spi.TargetModuleID;
import javax.enterprise.deploy.spi.exceptions.DConfigBeanVersionUnsupportedException;
import javax.enterprise.deploy.spi.exceptions.InvalidModuleException;
import javax.enterprise.deploy.spi.exceptions.TargetException;
import javax.enterprise.deploy.spi.status.DeploymentStatus;
import javax.enterprise.deploy.spi.status.ProgressObject;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.jboss.deployment.remoting.StreamingTarget;
import org.jboss.deployment.spi.configurations.WarConfiguration;
import org.jboss.deployment.spi.status.DeploymentStatusImpl;
import org.jboss.deployment.spi.status.ProgressObjectImpl;
import org.jboss.logging.Logger;
import org.jboss.util.xml.JBossEntityResolver;
/**
* The DeploymentManager object provides the core set of functions a J2EE
* platform must provide for J2EE application deployment. It provides server
* related information, such as, a list of deployment targets, and vendor unique
* runtime configuration information.
* @author thomas.diesler@jboss.org
* @version $Revision: 81011 $
*/
public class DeploymentManagerImpl implements DeploymentManager
{
// deployment logging
private static final Logger log = Logger.getLogger(DeploymentManagerImpl.class);
/** The URI deployment factory recoginzes: http://org.jboss.deployment/jsr88 */
public static final String DEPLOYER_URI = "http://org.jboss.deployment/jsr88";
// available deployment targets
private Target[] targets;
// maps the DD to the archives
private HashMap mapDeploymentPlan;
private DeploymentMetaData metaData;
private List tmpFiles = new ArrayList();
private URI deployURI;
private boolean isConnected;
/**
* Create a deployment manager for the given URL and connected mode.
*
* @param deployURI
* @param isConnected
*/
public DeploymentManagerImpl(URI deployURI, boolean isConnected)
{
this(deployURI, isConnected, null, null);
}
/**
* Create a deployment manager for the given URL and connected mode, username
* and password.
*
* @param deployURI
* @param isConnected
* @param username
* @param password
*/
public DeploymentManagerImpl(URI deployURI, boolean isConnected, String username, String password)
{
this.deployURI = deployURI;
this.isConnected = isConnected;
this.targets = null;
}
/**
* Get the available targets. This is determined by parsing the deployURI
* and looking at the targetType query parameter if the URI is not
* opaque. Supported targetTypes are:
* jmx = JMXTarget
* remote = StreamingTarget
* LocalhostTarget is the target type used if the URI is opaque.
*
* @return the available targets
* @throws IllegalStateException when the manager is disconnected
*/
public Target[] getTargets()
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
if (targets == null)
{
if (deployURI.isOpaque())
{
log.debug("Opaque URI seen, defaulting to LocalhostTarget");
targets = new Target[] { new LocalhostTarget() };
}
else
{
log.debug("Non-Opaque URI seen, checking query for targetType");
// Check the query parameters
String query = deployURI.getQuery();
String[] params = {};
if( query != null )
{
params = query.split("&|=");
}
String targetType = "jmx";
for(int n = 0; n < params.length; n += 2)
{
String key = params[n];
String value = params[n+1];
if( key.endsWith("targetType") )
targetType = value;
}
if( targetType.equals("remote") )
targets = new Target[] { new StreamingTarget(deployURI) };
else
targets = new Target[] { new JMXTarget(deployURI) };
}
}
return targets;
}
/**
* Get the running modules
*
* @param moduleType the module type
* @param targets the targets
* @return the target modules
* @throws javax.enterprise.deploy.spi.exceptions.TargetException
* an invalid target
* @throws IllegalStateException when the manager is disconnected
*/
public TargetModuleID[] getRunningModules(ModuleType moduleType, Target[] targets) throws TargetException
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
log.debug("getRunningModules [type=" + moduleType + ",targets=" + Arrays.asList(targets) + "]");
// get running modules
Set moduleSet = new HashSet();
TargetModuleID[] availableModules = getAvailableModules(moduleType, targets);
if (availableModules == null)
{
log.debug("No modules available");
return null;
}
for (int i = 0; i < availableModules.length; i++)
{
TargetModuleIDImpl moduleID = (TargetModuleIDImpl)availableModules[i];
if (moduleID.isRunning())
{
moduleSet.add(moduleID);
}
}
log.debug("Found [" + moduleSet.size() + "] running modules");
// convert set to array
TargetModuleID[] idarr = new TargetModuleID[moduleSet.size()];
moduleSet.toArray(idarr);
return idarr;
}
/**
* Get the non running modules
*
* @param moduleType the module type
* @param targets the targets
* @return the target modules
* @throws javax.enterprise.deploy.spi.exceptions.TargetException
* an invalid target
* @throws IllegalStateException when the manager is disconnected
*/
public TargetModuleID[] getNonRunningModules(ModuleType moduleType, Target[] targets) throws TargetException
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
log.debug("getNonRunningModules [type=" + moduleType + ",targets=" + Arrays.asList(targets) + "]");
// get non running modules
Set moduleSet = new HashSet();
TargetModuleID[] availableModules = getAvailableModules(moduleType, targets);
if (availableModules == null)
{
log.debug("No modules available");
return null;
}
for (int i = 0; i < availableModules.length; i++)
{
TargetModuleIDImpl moduleID = (TargetModuleIDImpl)availableModules[i];
if (moduleID.isRunning() == false)
{
moduleSet.add(moduleID);
}
}
log.debug("Found [" + moduleSet.size() + "] non running modules");
// convert set to array
TargetModuleID[] idarr = new TargetModuleID[moduleSet.size()];
moduleSet.toArray(idarr);
return idarr;
}
/**
* Retrieve the list of all J2EE application modules running or not running on the identified targets.
*
* @param moduleType the module type
* @param targets the targets
* @return the target modules
* @throws javax.enterprise.deploy.spi.exceptions.TargetException
* an invalid target
* @throws IllegalStateException when the manager is disconnected
*/
public TargetModuleID[] getAvailableModules(ModuleType moduleType, Target[] targets) throws TargetException
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
log.debug("getAvailableModules [type=" + moduleType + ",targets=" + Arrays.asList(targets) + "]");
// get non running modules
List targetModules = new ArrayList();
for (int i = 0; i < targets.length; i++)
{
JBossTarget target = (JBossTarget)targets[i];
TargetModuleID[] tmids = target.getAvailableModules(moduleType);
targetModules.addAll(Arrays.asList(tmids));
}
log.debug("Found [" + targetModules.size() + "] available modules");
// convert set to array
if (targetModules.size() > 0)
{
TargetModuleID[] idarr = new TargetModuleID[targetModules.size()];
targetModules.toArray(idarr);
return idarr;
}
// according to the spec, we have to return null
return null;
}
/**
* Retrieve server specific configuration for a component
*
* @param obj the deployable component
* @return the configuration
* @throws javax.enterprise.deploy.spi.exceptions.InvalidModuleException
* when the module does not exist or is not supported
*/
public DeploymentConfiguration createConfiguration(DeployableObject obj) throws InvalidModuleException
{
// do some stuff to figure out what kind of config to return.
if (obj.getType().equals(ModuleType.WAR))
return new WarConfiguration(obj);
throw new InvalidModuleException("CreateConfiguration: Module type not yet supported");
}
/**
* Validates the configuration, generates all container specific classes and moves the archive
* to the targets
*
* @param targets the targets
* @param moduleArchive the module archive
* @param deploymentPlan the runtime configuration
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
*/
public ProgressObject distribute(Target[] targets, File moduleArchive, File deploymentPlan)
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
InputStream isModuleArchive = null;
InputStream isDeploymentPlan = null;
try
{
isModuleArchive = new FileInputStream(moduleArchive);
isDeploymentPlan = new FileInputStream(deploymentPlan);
return distribute(targets, isModuleArchive, isDeploymentPlan);
}
catch (FileNotFoundException e)
{
String message = "Cannot find deployment file" + e.getMessage();
log.error(message, e);
DeploymentStatus status = new DeploymentStatusImpl(StateType.FAILED, CommandType.DISTRIBUTE, ActionType.EXECUTE, message);
return new ProgressObjectImpl(status, null);
}
}
/**
* Validates the configuration, generates all container specific classes and moves the archive
* to the targets
*
* @param targets the targets
* @param moduleArchive the module archive
* @param deploymentPlan the runtime configuration
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
*/
public ProgressObject distribute(Target[] targets, InputStream moduleArchive, InputStream deploymentPlan)
{
return doDistribute(targets, null, moduleArchive, deploymentPlan);
}
/**
* The distribute method performs three tasks; it validates the deployment configuration
* data, generates all container specific classes and interfaces, and moves the fully
* baked archive to the designated deployment targets.
*
* @param targets the targets
* @param moduleArchive the module archive
* @param deploymentPlan the runtime configuration
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
*/
public ProgressObject distribute(Target[] targets, ModuleType type,
InputStream moduleArchive, InputStream deploymentPlan)
throws IllegalStateException
{
return doDistribute(targets, type, moduleArchive, deploymentPlan);
}
private ProgressObject doDistribute(Target[] targets, ModuleType type,
InputStream moduleArchive, InputStream deploymentPlan)
throws IllegalStateException
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
TargetModuleID[] targetModuleIDs = new TargetModuleID[targets.length];
try
{
// create for each entry in the deploymentPlan a temp file
mapDeploymentPlan = unpackDeploymentPlan(deploymentPlan);
initDeploymentMetaData();
// create the temp file that contains the deployment
TargetModuleInfo moduleInfo = createDeployment(moduleArchive, metaData.getDeploymentName());
URL deployment = moduleInfo.getModuleID();
if( type == null )
type = moduleInfo.getModuleType();
// create the target module ids
for (int i = 0; i < targets.length; i++)
{
JBossTarget target = (JBossTarget)targets[i];
String moduleID = deployment.toExternalForm();
targetModuleIDs[i] = new TargetModuleIDImpl(target, moduleID, null, false, type);
}
// delete all temp files, except the depoyment
for (int i = 0; i < tmpFiles.size(); i++)
{
File file = (File)tmpFiles.get(i);
if (file.equals(deployment) == false)
file.delete();
}
}
catch (IOException e)
{
String message = "Exception during deployment validation";
log.error(message, e);
DeploymentStatus status = new DeploymentStatusImpl(StateType.FAILED, CommandType.DISTRIBUTE, ActionType.EXECUTE, message);
return new ProgressObjectImpl(status, targetModuleIDs);
}
// start the deployment process
DeploymentStatus status = new DeploymentStatusImpl(StateType.RUNNING, CommandType.DISTRIBUTE, ActionType.EXECUTE, null);
ProgressObject progress = new ProgressObjectImpl(status, targetModuleIDs);
DeploymentWorker worker = new DeploymentWorker(progress);
worker.start();
return progress;
}
/**
* Initialize the deployment meta data
*/
private void initDeploymentMetaData() throws IOException
{
File metaTmpFile = (File)mapDeploymentPlan.get(DeploymentMetaData.ENTRY_NAME);
if (metaTmpFile == null)
throw new IOException("Deployment plan does not contain an entry: " + DeploymentMetaData.ENTRY_NAME);
try
{
SAXReader reader = new SAXReader();
reader.setEntityResolver(new JBossEntityResolver());
Document metaDoc = reader.read(metaTmpFile);
metaData = new DeploymentMetaData(metaDoc);
log.debug(DeploymentMetaData.ENTRY_NAME + "\n" + metaData.toXMLString());
}
catch (Exception e)
{
log.error("Cannot obtain meta data: " + e);
}
}
/**
* Create the JBoss deployment, by enhancing the content of the module
* archive with the entries in the deployment plan.
*/
private TargetModuleInfo createDeployment(InputStream moduleArchive, String moduleName) throws IOException
{
File tmpFile = File.createTempFile("jboss_deployment_", ".zip");
log.debug("temporary deployment file: " + tmpFile);
JarInputStream jis = new JarInputStream(moduleArchive);
// make sure we don't loose the manifest when creating a new JarOutputStream
JarOutputStream jos = null;
FileOutputStream fos = new FileOutputStream(tmpFile);
Manifest manifest = jis.getManifest();
if (manifest != null)
jos = new JarOutputStream(fos, manifest);
else jos = new JarOutputStream(fos);
// process all modules
TargetModuleInfo moduleInfo = new TargetModuleInfo();
ModuleType moduleType = null;
JarEntry entry = jis.getNextJarEntry();
while (entry != null)
{
String entryName = entry.getName();
// only process file entries
if (entryName.endsWith("/") == false)
{
if (entryName.endsWith("/application.xml"))
{
moduleType = ModuleType.EAR;
}
else if (entryName.endsWith("/application-client.xml"))
{
moduleType = ModuleType.CAR;
}
else if (entryName.endsWith("/ra.xml"))
{
moduleType = ModuleType.RAR;
}
else if (entryName.endsWith("/web.xml"))
{
moduleType = ModuleType.WAR;
}
else if (entryName.endsWith("/ejb-jar.xml"))
{
moduleType = ModuleType.EJB;
}
// process a sub module
if (entryName.endsWith(".jar") || entryName.endsWith(".war"))
{
File tmpSubModule = processSubModule(entryName, jis);
FileInputStream fis = new FileInputStream(tmpSubModule);
JarUtils.addJarEntry(jos, entryName, fis);
fis.close();
}
else
{
if (mapDeploymentPlan.get("!/" + entryName) == null)
JarUtils.addJarEntry(jos, entryName, jis);
else log.debug("Skip entry found in deployment plan: " + entryName);
}
}
entry = jis.getNextJarEntry();
}
if (moduleType == null)
{
if (moduleName.endsWith(ModuleType.EAR.getModuleExtension()))
moduleType = ModuleType.EAR;
else
throw new RuntimeException("cannot obtain module type");
}
moduleInfo.setModuleType(moduleType);
// there may be top level deployment plan entries, add them
addDeploymentPlanEntry(jos, null);
jos.close();
// rename the deployment
String deploymentName = tmpFile.getParent() + File.separator + metaData.getDeploymentName();
File deployment = new File(deploymentName);
if (deployment.exists() && deployment.delete() == false)
throw new IOException("Cannot delete existing deployment: " + deployment);
tmpFile.renameTo(deployment);
moduleInfo.setModuleID(deployment.toURL());
return moduleInfo;
}
public ProgressObject redeploy(TargetModuleID[] targetModuleIDs, File file, File file1) throws UnsupportedOperationException, IllegalStateException
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
throw new UnsupportedOperationException("redeploy");
}
public ProgressObject redeploy(TargetModuleID[] targetModuleIDs, InputStream inputStream, InputStream inputStream1) throws UnsupportedOperationException,
IllegalStateException
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
throw new UnsupportedOperationException("redeploy");
}
/**
* Start the modules
*
* @param targetModuleIDs the list of modules
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
*/
public ProgressObject start(TargetModuleID[] targetModuleIDs)
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
log.debug("start " + Arrays.asList(targetModuleIDs));
// start the deployment process
DeploymentStatus status = new DeploymentStatusImpl(StateType.RUNNING, CommandType.START, ActionType.EXECUTE, null);
ProgressObject progress = new ProgressObjectImpl(status, targetModuleIDs);
DeploymentWorker worker = new DeploymentWorker(progress);
worker.start();
return progress;
}
/**
* Stop the modules
*
* @param targetModuleIDs the list of modules
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
*/
public ProgressObject stop(TargetModuleID[] targetModuleIDs)
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
log.debug("stop " + Arrays.asList(targetModuleIDs));
DeploymentStatus status = new DeploymentStatusImpl(StateType.RUNNING, CommandType.STOP, ActionType.EXECUTE, null);
ProgressObject progress = new ProgressObjectImpl(status, targetModuleIDs);
DeploymentWorker worker = new DeploymentWorker(progress);
worker.start();
return progress;
}
/**
* Removes the modules
*
* @param targetModuleIDs the list of modules
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
*/
public ProgressObject undeploy(TargetModuleID[] targetModuleIDs)
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
log.debug("undeploy " + Arrays.asList(targetModuleIDs));
// start the deployment process
DeploymentStatus status = new DeploymentStatusImpl(StateType.RUNNING, CommandType.UNDEPLOY, ActionType.EXECUTE, null);
ProgressObject progress = new ProgressObjectImpl(status, targetModuleIDs);
DeploymentWorker worker = new DeploymentWorker(progress);
worker.start();
return progress;
}
/**
* Is redeploy supported
*
* @return true when redeploy is supported, false otherwise
*/
public boolean isRedeploySupported()
{
return false;
}
/**
* Redeploys the modules
*
* @param moduleIDList the list of modules
* @return the progress object
* @throws IllegalStateException when the manager is disconnected
* @throws UnsupportedOperationException when redeploy is not supported
*/
public ProgressObject redeploy(TargetModuleID[] moduleIDList)
{
if (isConnected == false)
throw new IllegalStateException("DeploymentManager is not connected");
throw new UnsupportedOperationException("redeploy");
}
/**
* The release method is the mechanism by which the tool signals to the DeploymentManager that the tool does not need
* it to continue running connected to the platform. The tool may be signaling it wants to run in a
* disconnected mode or it is planning to shutdown.
* When release is called the DeploymentManager may close any J2EE resource connections it had for deployment
* configuration and perform other related resource cleanup.
* It should not accept any new operation requests (i.e., distribute, start stop, undeploy, redeploy.
* It should finish any operations that are currently in process.
* Each ProgressObject associated with a running operation should be marked as released (see the ProgressObject).
*/
public void release()
{
isConnected = false;
}
/**
* Get the default locale
*
* @return the default locale
*/
public Locale getDefaultLocale()
{
return Locale.getDefault();
}
/**
* Currently we only support the default locale
*/
public Locale getCurrentLocale()
{
return Locale.getDefault();
}
/**
* Currently we only support the default locale
*/
public void setLocale(Locale locale)
{
throw new UnsupportedOperationException("setLocale");
}
/**
* Currently we only support the default locale
*/
public boolean isLocaleSupported(Locale locale)
{
return Locale.getDefault().equals(locale);
}
/**
* Currently we only support the default locale
*
* @return the supported locales
*/
public Locale[] getSupportedLocales()
{
return new Locale[] { Locale.getDefault() };
}
/**
* Get the J2EE platform version
*
* @return the version
*/
public DConfigBeanVersionType getDConfigBeanVersion()
{
return DConfigBeanVersionType.V1_4;
}
public void setDConfigBeanVersion(DConfigBeanVersionType dConfigBeanVersionType) throws DConfigBeanVersionUnsupportedException
{
throw new UnsupportedOperationException("setDConfigBeanVersion");
}
public boolean isDConfigBeanVersionSupported(DConfigBeanVersionType dConfigBeanVersionType)
{
return dConfigBeanVersionType == DConfigBeanVersionType.V1_4;
}
/**
* Test whether the version is supported
*
* @param version the version
* @return true when supported, false otherwise
*/
public boolean isDConfigBeanVersionTypeSupported(DConfigBeanVersionType version)
{
return version == DConfigBeanVersionType.V1_4;
}
/**
* Set the J2EE version
*
* @param version the version
* @throws UnsupportedOperationException when the version is not supported
*/
public void setDConfigBeanVersionType(DConfigBeanVersionType version)
{
throw new UnsupportedOperationException("setDConfigBeanVersionType");
}
/**
* Process a potential sub module, adding descriptors from the deployment plan
*/
private File processSubModule(String entryName, JarInputStream jis) throws IOException
{
// first copy te entry as is to a temp file
File tmpModule = getTempFile(entryName);
tmpFiles.add(tmpModule);
FileOutputStream fos = new FileOutputStream(tmpModule);
JarUtils.copyStream(fos, jis);
fos.close();
// now open the copy we just made and copy again entry by entry
JarInputStream jisModule = new JarInputStream(new FileInputStream(tmpModule));
File tmpJBossModule = getTempFile("jboss_" + entryName);
tmpFiles.add(tmpJBossModule);
JarOutputStream jos = null;
fos = new FileOutputStream(tmpJBossModule);
Manifest manifest = jisModule.getManifest();
if (manifest != null)
jos = new JarOutputStream(fos, manifest);
else jos = new JarOutputStream(fos);
// now copy entry by entry
JarEntry entry = jisModule.getNextJarEntry();
while (entry != null)
{
String subEntryName = entry.getName();
if (mapDeploymentPlan.get(entryName + "!/" + subEntryName) == null)
JarUtils.addJarEntry(jos, subEntryName, jisModule);
else log.debug("Skip entry found in deployment plan: " + subEntryName);
entry = jisModule.getNextJarEntry();
}
jisModule.close();
addDeploymentPlanEntry(jos, entryName);
jos.close();
return tmpJBossModule;
}
/**
* Add an entry from the deployment plan, if found
* @param moduleName entries will be added for that module, null indicates top level
*/
private void addDeploymentPlanEntry(JarOutputStream jos, String moduleName) throws IOException
{
if (moduleName == null)
moduleName = "";
// ignore deployment plan entries that do not start like this
String moduleKey = moduleName + "!/";
Iterator it = mapDeploymentPlan.keySet().iterator();
while (it.hasNext())
{
String key = (String)it.next();
if (key.startsWith(moduleKey))
{
String dpName = key.substring(moduleKey.length());
log.debug("found deployment plan entry: " + dpName);
File dpFile = (File)mapDeploymentPlan.get(key);
FileInputStream dpin = new FileInputStream(dpFile);
JarUtils.addJarEntry(jos, dpName, dpin);
dpin.close();
}
}
}
/**
* Create a temp file for every entry in the deployment plan
*/
private HashMap unpackDeploymentPlan(InputStream deploymentPlan) throws IOException
{
HashMap dpMap = new HashMap();
if (deploymentPlan == null)
return dpMap;
// process the deployment plan
try
{
JarInputStream jarDeploymentPlan = new JarInputStream(deploymentPlan);
JarEntry entry = jarDeploymentPlan.getNextJarEntry();
while (entry != null)
{
String entryName = entry.getName();
log.debug("unpack deployment plan entry: " + entryName);
File tempFile = getTempFile(entryName);
dpMap.put(entryName, tempFile);
FileOutputStream out = new FileOutputStream(tempFile);
JarUtils.copyStream(out, jarDeploymentPlan);
out.close();
entry = jarDeploymentPlan.getNextJarEntry();
}
}
finally
{
deploymentPlan.close();
}
return dpMap;
}
/**
* Get a temp file for an jar entry name
*/
private File getTempFile(String entryName) throws IOException
{
entryName = entryName.replace('/', '_');
int index = entryName.lastIndexOf(".");
String prefix = entryName.substring(0, index);
String suffix = entryName.substring(index);
File tempFile = File.createTempFile(prefix, suffix);
tmpFiles.add(tempFile);
return tempFile;
}
static private class TargetModuleInfo
{
URL moduleID = null;
ModuleType moduleType = null;
public URL getModuleID()
{
return moduleID;
}
public void setModuleID(URL url)
{
moduleID = url;
}
public ModuleType getModuleType()
{
return moduleType;
}
public void setModuleType(ModuleType type)
{
moduleType = type;
}
}
}