/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can * obtain a copy of the License at * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html * or packager/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at packager/legal/LICENSE.txt. * * GPL Classpath Exception: * Oracle designates this particular file as subject to the "Classpath" * exception as provided by Oracle in the GPL Version 2 section of the License * file that accompanied this code. * * Modifications: * If applicable, add the following below the License Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyright [year] [name of copyright owner]" * * Contributor(s): * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */ package org.glassfish.deployapi; import com.sun.enterprise.util.HostAndPort; import com.sun.enterprise.util.StringUtils; import com.sun.enterprise.module.ModulesRegistry; import org.jvnet.hk2.component.Habitat; import com.sun.hk2.component.ExistingSingletonInhabitant; import com.sun.enterprise.module.single.StaticModulesRegistry; import com.sun.enterprise.module.bootstrap.StartupContext; import org.glassfish.api.admin.ProcessEnvironment; import org.glassfish.api.admin.ProcessEnvironment.ProcessType; import org.glassfish.deployapi.config.SunDeploymentConfiguration; import org.glassfish.deployment.client.DeploymentFacility; import org.glassfish.deployment.client.DeploymentFacilityFactory; import org.glassfish.deployment.client.ServerConnectionEnvironment; import org.glassfish.deployment.client.ServerConnectionIdentifier; import org.glassfish.api.deployment.archive.ReadableArchive; import org.glassfish.api.deployment.archive.Archive; import com.sun.enterprise.deploy.shared.ArchiveFactory; import com.sun.enterprise.deployment.deploy.shared.InputJarArchive; import com.sun.enterprise.deployment.deploy.shared.MemoryMappedArchive; import org.glassfish.deployment.client.DFDeploymentProperties; import com.sun.enterprise.util.LocalStringManagerImpl; import com.sun.enterprise.util.Print; import java.io.File; import java.io.InputStream; import java.io.IOException; import java.net.URL; import java.net.MalformedURLException; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import java.net.URI; import javax.enterprise.deploy.spi.DeploymentManager; import javax.enterprise.deploy.model.DeployableObject; 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.exceptions.ConfigurationException; 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.ProgressObject; import javax.enterprise.deploy.spi.status.ProgressEvent; import javax.enterprise.deploy.spi.status.DeploymentStatus; import javax.enterprise.deploy.spi.Target; import javax.enterprise.deploy.spi.TargetModuleID; /** * * @author Jerome Dochez * @author Tim Quinn */ public class SunDeploymentManager implements DeploymentManager { // store ID to server connection private ServerConnectionIdentifier serverId = null; /** cached reference to a connected DeploymentFacility */ private DeploymentFacility deploymentFacility = null; private static LocalStringManagerImpl localStrings = new LocalStringManagerImpl(SunDeploymentManager.class); private static Locale defaultLocale = Locale.US; private Locale currentLocale = defaultLocale; private static Locale[] supportedLocales = { Locale.US }; private String disconnectedMessage = localStrings.getLocalString( "enterprise.deployapi.spi.disconnectedDM", // NOI18N "Illegal operation for a disconnected DeploymentManager");// NOI18N private static final String ENABLED_ATTRIBUTE_NAME = "Enabled"; // NOI18N private Habitat habitat; /** Creates a new instance of DeploymentManager */ public SunDeploymentManager() { } /** Creates a new instance of DeploymentManager */ public SunDeploymentManager(ServerConnectionIdentifier sci) { deploymentFacility = DeploymentFacilityFactory.getDeploymentFacility(); deploymentFacility.connect(sci); prepareHabitat(); } /** * Set additional env vars for the jmx https connector, provided * by the client. This method is expected to be called right after * the client retrieves the DeploymentManager, before * the client makes any calls on the DM that requires MBean Server * connection. */ public void setServerConnectionEnvironment(ServerConnectionEnvironment env) { serverId.setConnectionEnvironment(env); } /** * Retrieve the list of deployment targets supported by * this DeploymentManager. *
* @throws IllegalStateException is thrown when there is a problem getting
* Connection Source
* @return A list of deployment Target designators the
* user may select for application deployment or 'null'
* if there are none.
*/
public Target[] getTargets() throws IllegalStateException {
verifyConnected();
try {
return deploymentFacility.listTargets();
} catch (Throwable e) {
IllegalStateException ex = new IllegalStateException(e.getMessage());
ex.initCause(e);
throw ex;
}
}
/**
* Retrieve the list of J2EE application modules distributed
* to the identified targets and that are currently running
* on the associated server or servers.
*
* @param moduleType A predefined designator for a J2EE
* module type.
*
* @param targetList A list of deployment Target designators
* the user wants checked for module run
* status.
*
* @return An array of TargetModuleID objects representing
* the running modules or 'null' if there
* are none.
*
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @throws TargetException An invalid Target designator
* encountered.
*/
public TargetModuleID[] getRunningModules(ModuleType moduleType,
Target[] targetList) throws TargetException, IllegalStateException {
return getModules(moduleType, targetList, DFDeploymentProperties.RUNNING);
}
/**
* Retrieve the list of J2EE application modules distributed
* to the identified targets and that are currently not
* running on the associated server or servers.
*
* @param moduleType A predefined designator for a J2EE
* module type.
*
* @param targetList A list of deployment Target designators
* the user wants checked for module not
* running status.
*
* @return An array of TargetModuleID objects representing
* the non-running modules or 'null' if
* there are none.
*
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @throws TargetException An invalid Target designator
* encountered.
*/
public TargetModuleID[] getNonRunningModules(ModuleType moduleType,
Target[] targetList) throws TargetException, IllegalStateException {
return getModules(moduleType, targetList, DFDeploymentProperties.NON_RUNNING);
}
/**
* Retrieve the list of all J2EE application modules running
* or not running on the identified targets.
*
* @param moduleType A predefined designator for a J2EE
* module type.
*
* @param targetList A list of deployment Target designators
* the user wants checked for module not
* running status.
*
* @return An array of TargetModuleID objects representing
* all deployed modules running or not or
* 'null' if there are no deployed modules.
*
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @throws TargetException An invalid Target designator
* encountered.
*/
public TargetModuleID[] getAvailableModules(ModuleType moduleType,
Target[] targetList) throws TargetException,
IllegalStateException {
return getModules(moduleType, targetList, DFDeploymentProperties.ALL);
}
/**
*Single method used by several public methods to make sure the deployment manager is
*connected and, if not, throw the IllegalStateException.
*
*@throws IllegalStateException if the deployment manager is not connected.
*/
private void verifyConnected() {
if(isDisconnected()) {
throw new IllegalStateException(disconnectedMessage);
}
}
/**
*Report whether the deployment manager is currently disconnected from the DAS.
*@returns whether the deployment manager is disconnected from the DAS
*/
private boolean isDisconnected(){
if (deploymentFacility == null) {
return true;
}
return (!deploymentFacility.isConnected());
}
/**
*Get all modules in the specified state from the targets specified in the
argument list.
*@param moduleType which returned modules must match
*@param array of Target indicating which targets should be searched for matching modules
*@param state state of the modules
*have for the indicated attribute to be matched
*@exception TargetException if a target was improperly formed
*@exception IllegalStateException if the method is called after release was called
*/
private TargetModuleID[] getModules(ModuleType moduleType, Target[] targetList, String state) throws TargetException, IllegalStateException {
verifyConnected();
if (moduleType==null) {
return null;
}
try {
Vector resultingTMIDs = new Vector();
for (int i = 0; i < targetList.length; i++) {
TargetImpl aTarget = (TargetImpl) targetList[i];
TargetModuleID[] tmids = deploymentFacility._listAppRefs(new Target[] {aTarget}, state, getTypeFromModuleType(moduleType));
addToTargetModuleIDs(tmids, moduleType, aTarget, resultingTMIDs);
}
/*
*Return an array of runtime type TargetModuleIDImpl [].
*/
TargetModuleID [] answer = (TargetModuleID []) resultingTMIDs.toArray(new TargetModuleIDImpl[0]);
return answer;
} catch(Exception e){
TargetException tg = new TargetException(localStrings.getLocalString(
"enterprise.deployapi.spi.errorgetreqmods",
"Error getting required modules"
));
tg.initCause(e);
throw tg;
}
}
private String getTypeFromModuleType(ModuleType moduleType) {
if (moduleType.equals(ModuleType.WAR)) {
return "web";
} else if (moduleType.equals(ModuleType.EJB)) {
return "ejb";
} else if (moduleType.equals(ModuleType.CAR)) {
return "appclient";
} else if (moduleType.equals(ModuleType.RAR)) {
return "connector";
} else if (moduleType.equals(ModuleType.EAR)) {
return "ear";
}
return null;
}
private ModuleType getModuleTypeFromType(String type) {
if (type.equals("war")) {
return ModuleType.WAR;
} else if (type.equals("ejb")) {
return ModuleType.EJB;
} else if (type.equals("car")) {
return ModuleType.CAR;
} else if (type.equals("rar")) {
return ModuleType.RAR;
} else if (type.equals("ear")) {
return ModuleType.EAR;
}
return null;
}
/**
*Augments a Collection of TargetModuleIDs with new entries for target module IDs of a given module type on the specified target.
*@param tmids array of TargetModuleIDs
*@param type the ModuleType of interest
*@param targetImpl the TargetImpl from which to retrieve modules of the selected type
*@param resultingTMIDs pre-instantiated List to which TargetModuleIDs will be added
*/
private void addToTargetModuleIDs(TargetModuleID[] tmids, ModuleType type, TargetImpl targetImpl, Collection resultingTMIDs) throws IOException {
for (int j = 0;j< tmids.length;j++) {
// Get the host name and port where the application was deployed
HostAndPort webHost = deploymentFacility.getHostAndPort(targetImpl.getName(), tmids[j].getModuleID(), false);
if (tmids[j] instanceof TargetModuleIDImpl) {
((TargetModuleIDImpl)tmids[j]).setModuleType(type);
}
resultingTMIDs.add(tmids[j]);
/*
*Set additional information on the target module ID, depending on what type of
*module this is. For J2EE apps, this includes constructing sub TargetModuleIDs.
*/
try {
if (type.equals(ModuleType.EAR)) {
setJ2EEApplicationTargetModuleIDInfo(tmids[j], webHost);
} else if (type.equals(ModuleType.WAR)) {
setWebApplicationTargetModuleIDInfo(tmids[j], webHost);
}
}
catch(Exception exp){
Logger.getAnonymousLogger().log(Level.WARNING, exp.getLocalizedMessage(), exp);
}
}
}
/**
*Attach child target module IDs to a J2EE application target module ID.
*@param tmid the target module ID for the J2EE application.
*@param targetImpl the target identifying which installation of this module is of interest
*@param webHost the host and port for this target
*/
private void setJ2EEApplicationTargetModuleIDInfo(TargetModuleID tmid,
HostAndPort hostAndPort) throws MalformedURLException, IOException {
TargetImpl targetImpl = (TargetImpl) tmid.getTarget();
try {
List Only the TargetModuleIDs which represent a root module
* are valid for being started. A root TargetModuleID has no parent.
* A TargetModuleID with a parent can not be individually started.
* A root TargetModuleID module and all its child modules will be
* started.
*
* @param moduleIDList A array of TargetModuleID objects
* representing the modules to be started.
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @return ProgressObject an object that tracks and reports the
* status of the start operation.
*/
public ProgressObject start(TargetModuleID[] moduleIDList)
throws IllegalStateException
{
return executeCommandUsingFacility(CommandType.START, moduleIDList);
}
/**
* Stop the application running.
*
* Only the TargetModuleIDs which represent a root module
* are valid for being stopped. A root TargetModuleID has no parent.
* A TargetModuleID with a parent can not be individually stopped.
* A root TargetModuleID module and all its child modules will be
* stopped.
*
* @param moduleIDList A array of TargetModuleID objects
* representing the modules to be stopped.
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @return ProgressObject an object that tracks and reports the
* status of the stop operation.
*/
public ProgressObject stop(TargetModuleID [] moduleIDList)
throws IllegalStateException
{
return executeCommandUsingFacility(CommandType.STOP, moduleIDList);
}
/**
* Remove the application from the target server.
*
* Only the TargetModuleIDs which represent a root module
* are valid for undeployment. A root TargetModuleID has no parent.
* A TargetModuleID with a parent can not be undeployed. A root
* TargetModuleID module and all its child modules will be undeployed.
* The root TargetModuleID module and all its child modules must
* stopped before they can be undeployed.
*
* @param moduleIDList An array of TargetModuleID objects representing
* the root modules to be stopped.
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @return ProgressObject an object that tracks and reports the
* status of the stop operation.
*/
public ProgressObject undeploy(TargetModuleID[] moduleIDList)
throws IllegalStateException
{
return executeCommandUsingFacility(CommandType.UNDEPLOY, moduleIDList);
}
/**
* This method designates whether this platform vendor provides
* application redeployment functionality. A value of true means
* it is supported. False means it is not.
*
* @return A value of true means redeployment is supported by this
* vendor's DeploymentManager. False means it
* is not.
*/
public boolean isRedeploySupported() {
return true;
}
/**
* (optional)
* The redeploy method provides a means for updating currently
* deployed J2EE applications. This is an optional method for
* vendor implementation.
*
* Redeploy replaces a currently deployed application with an
* updated version. The runtime configuration information for
* the updated application must remain identical to the application
* it is updating.
*
* When an application update is redeployed, all existing client
* connections to the original running application must not be disrupted;
* new clients will connect to the application update.
*
* This operation is valid for TargetModuleIDs that represent a
* root module. A root TargetModuleID has no parent. A root
* TargetModuleID module and all its child modules will be redeployed.
* A child TargetModuleID module cannot be individually redeployed.
* The redeploy operation is complete only when this action for
* all the modules has completed.
*
* @param moduleIDList An array of designators of the applications
* to be updated.
* @param moduleArchive The file name of the application archive
* to be disrtibuted.
* @param deploymentPlan The deployment configuration information
* associated with this application archive.
* @return ProgressObject an object that tracks and reports the
* status of the redeploy operation.
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @throws UnsupportedOperationException this optional command
* is not supported by this implementation.
*/
public ProgressObject redeploy(TargetModuleID[] moduleIDList,
File moduleArchive, File deploymentPlan)
throws UnsupportedOperationException, IllegalStateException
{
try {
/*
*To support multiple different modules in the module ID list, use a TargetModuleIDCollection to
*organize them and work on each module one at a time.
*/
TargetModuleIDCollection coll = new TargetModuleIDCollection(moduleIDList);
for (Iterator it = coll.iterator(); it.hasNext();) {
/*
*The iterator returns one work instance for each module present in the collection.
*/
DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) it.next();
/*
*Set the name in the properties according to the moduleID. The module is the same for all the
*targets represented by this single work object.
*/
ProgressObject po = deploy(work.targets(), moduleArchive, deploymentPlan, getRedeployOptions(work.getModuleID()));
/*
*The work instance needs to know about its own progress object, and the
*aggregate progress object needs to also.
*/
work.setProgressObject(po);
coll.getProgressObjectSink().sinkProgressObject(po);
}
return coll.getProgressObjectSink();
} catch (Throwable e) {
return prepareErrorProgressObject(CommandType.REDEPLOY, e);
}
}
/**
* (optional)
* The redeploy method provides a means for updating currently
* deployed J2EE applications. This is an optional method for
* vendor implementation.
*
* Redeploy replaces a currently deployed application with an
* updated version. The runtime configuration information for
* the updated application must remain identical to the application
* it is updating.
*
* When an application update is redeployed, all existing client
* connections to the original running application must not be disrupted;
* new clients will connect to the application update.
*
* This operation is valid for TargetModuleIDs that represent a
* root module. A root TargetModuleID has no parent. A root
* TargetModuleID module and all its child modules will be redeployed.
* A child TargetModuleID module cannot be individually redeployed.
* The redeploy operation is complete only when this action for
* all the modules has completed.
*
* @param moduleIDList An array of designators of the applications
* to be updated.
* @param moduleArchive The input stream containing the application
* archive to be disrtibuted.
* @param deploymentPlan The input stream containing the runtime
* configuration information associated with
* this application archive.
* @return ProgressObject an object that tracks and reports the
* status of the redeploy operation.
* @throws IllegalStateException is thrown when the method is
* called when running in disconnected mode.
* @throws UnsupportedOperationException this optional command
* is not supported by this implementation.
*/
public ProgressObject redeploy(TargetModuleID[] moduleIDList,
InputStream moduleArchive, InputStream deploymentPlan)
throws UnsupportedOperationException, IllegalStateException
{
try {
/*
*To support multiple different modules in the module ID list, use a TargetModuleIDCollection to
*organize them and work on each module one at a time.
*/
TargetModuleIDCollection coll = new TargetModuleIDCollection(moduleIDList);
for (Iterator it = coll.iterator(); it.hasNext();) {
/*
*The iterator returns one work instance for each module present in the collection.
*/
DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) it.next();
/*
*Set the name in the properties according to the moduleID. The module is the same for all the
*targets represented by this single work object.
*/
DFDeploymentProperties dProps = getRedeployOptions(work.getModuleID());
// type is not needed for v3 server code now
// dProps.setType(deploymentFacility.getModuleType(work.getModuleID()));
ProgressObject po = deploy(work.targets(), moduleArchive, deploymentPlan, dProps);
/*
*The work instance needs to know about its own progress object, and the
*aggregate progress object needs to also.
*/
work.setProgressObject(po);
coll.getProgressObjectSink().sinkProgressObject(po);
}
return coll.getProgressObjectSink();
} catch (Throwable e) {
return prepareErrorProgressObject(CommandType.REDEPLOY, e);
}
}
/**
* 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() {
/*
*Make sure multiple releases are handled gracefully.
*/
if ( ! isDisconnected() ) {
deploymentFacility = null;
}
}
/**
* Returns the default locale supported by this implementation of
* javax.enterprise.deploy.spi subpackages.
*
* @return Locale the default locale for this implementation.
*/
public Locale getDefaultLocale() {
return defaultLocale;
}
/**
* Returns the active locale this implementation of
* javax.enterprise.deploy.spi subpackages is running.
*
* @return Locale the active locale of this implementation.
*/
public Locale getCurrentLocale() {
return currentLocale;
}
/**
* Set the active locale for this implementation of
* javax.enterprise.deploy.spi subpackages to run.
*
* @throws UnsupportedOperationException the provide locale is
* not supported.
*/
public void setLocale(Locale locale) throws UnsupportedOperationException {
for (int i=0;i
*Several methods in the JSR88 DeploymentManager interface accept a list of TargetModuleID values,
*and these lists can refer to multiple module IDs and multiple targets.
*Each invocation of a DeploymentFacility method, on the other hand, can work on only a single module
*although with perhaps multiple targets. This class provides a central way of organizing the
*target module IDs as passed from the JSR88 client and making the information for a single
*module ID readily available.
*
*Typically, a client will use three methods:
*
*
*/
protected static class TargetModuleIDCollection {
/* Maps the module ID to that module's instance of DeploymentFacilityModuleWork. */
private HashMap moduleIDToInfoMap = new HashMap();
/* Collects together the individual progress objects into a single aggregate one. */
ProgressObjectSink progressObjectSink = null;
/**
*Create a new instance of TargetModuleIDCollection.
*Accept the array of targetModuleIDs as passed by the JSR88 client and set up the
*internal data structures.
*@param targetModuleIDs array of {@link javax.deployment.api.TargetModuleID TargetModuleID} provided from the calling JSR88 client
*/
public TargetModuleIDCollection(TargetModuleID [] targetModuleIDs) throws IllegalArgumentException {
for (int i = 0; i < targetModuleIDs.length; i++) {
/*
*Make sure that this target module ID has a target that is a TargetImpl and was created by this DM.
*/
Target candidateTarget = targetModuleIDs[i].getTarget();
if ( ! (candidateTarget instanceof TargetImpl)) {
throw new IllegalArgumentException(
localStrings.getLocalString("enterprise.deployapi.spi.nott", //NOI18N
"Expected TargetImpl instance but found instance of {0}", new Object[] {candidateTarget.getClass().getName() } )); //NOI18N
}
String moduleID = targetModuleIDs[i].getModuleID();
/*
*Look for the entry in the hash map for this module.
*/
DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) moduleIDToInfoMap.get(moduleID);
if (work == null) {
/*
*This module ID is not yet in the map. Add a work instance for it with the module ID as the key.
*/
work = new DeploymentFacilityModuleWork(moduleID);
moduleIDToInfoMap.put(moduleID, work);
}
/*
*Either the entry already exists or one has been created.
*In either case, add the target to the work to be done with this module.
*/
work.addTarget(candidateTarget);
}
}
/**
*Provides an Iterator over the module work items in the collection.
*The iterator provides one element for each distinct module that appeared in the original
*array of TargetModuleIDs.
*
*@return Iterator over the DeploymentFacilityModuleWork elements in the collection
*/
public Iterator iterator() {
return moduleIDToInfoMap.values().iterator();
}
/**
*Reports the number of elements in the collection.
*This is also a measure of the number of distinct module IDs specified in the TargetModuleID array
*passed to the constructor of the collection.
*@return the number of DeploymentFacilityModuleWork elements contained in the collection
*/
public int size() {
return moduleIDToInfoMap.size();
}
/**
*Returns the aggregate progress object for the collection.
*Creates a new ProgressObjectSink if needed.
*@return ProgressObjectSink
*/
public ProgressObjectSink getProgressObjectSink() {
if (progressObjectSink == null) {
progressObjectSink = new ProgressObjectSink();
}
return progressObjectSink;
}
}
/**
*Encapsulates information used with a single invocation of a DeploymentFacility method--
*that is, one item of "work" the DeploymentFacility is being asked to perform.
*This includes the single target ID of interest (because the DF methods operate on a
*single module), a collection of all the targets to be included in the operation on that
*module, and the progress object resulting from the DF method invocation.
*/
protected static class DeploymentFacilityModuleWork {
/** The module ID this work handles */
private String moduleID = null;
/** The targets this work should affect. */
private Collection targets = new Vector();
/** The ProgressObject for this work returned by the DeploymentFacility method invocation. */
private ProgressObject progressObject = null;
/**
*Creates a new instance of DeploymentFacilityModuleWork.
*@param the module ID common to all work recorded in this instance
*/
public DeploymentFacilityModuleWork(String moduleID) {
this.moduleID = moduleID;
}
/**
*Adds a target to the collection of targets for the work to be done for this distinct module.
*@param the {@link javax.enterprise.deploy.spi.Target Target} to be added for this module
*/
public void addTarget(Target target) {
if ( ! (target instanceof TargetImpl) ) {
throw new IllegalArgumentException(localStrings.getLocalString(
"enterprise.deployapi.spi.unexptargettyp",
"Target must be of type TargetImpl but encountered {0}",
new Object [] {target.getClass().getName()}
));
}
targets.add(target);
}
/**
*Returns an array of {@link javax.enterprise.deploy.spi.Target Target} instances recorded for
*this module. Note the return of an array of runtime type TargetImpl[].
*@return array of Target
*/
public Target [] targets() {
return (Target []) targets.toArray(new TargetImpl[] {});
}
/**
*Returns the {@link javax.enterprise.deploy.spi.status.ProgressObject ProgressObject} that the
*DeploymentFacility method returned when it was invoked.
*@return the ProgressObject
*/
public ProgressObject getProgressObject() {
return this.progressObject;
}
/**
*Records the {@link javax.enterprise.deploy.spi.status.ProgressObject ProgressObject} that the
*DeploymentFacility returned when its method was invoked.
*@param the ProgressObject provided by the DeploymentFacility
*method
*/
public void setProgressObject (ProgressObject progressObject) {
this.progressObject = progressObject;
}
/**
*Reports the module ID for this instance of DeploymentFacilityModuleWork
*@return the module ID
*/
public String getModuleID() {
return this.moduleID;
}
}
}