KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > deployapi > SunDeploymentManager


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.deployapi;
25
26 import com.sun.appserv.management.base.AMX;
27 import com.sun.appserv.management.base.XTypes;
28 import com.sun.appserv.management.client.AppserverConnectionSource;
29 import com.sun.appserv.management.client.ConnectionSource;
30 import com.sun.appserv.management.client.ProxyFactory;
31 import com.sun.appserv.management.client.TLSParams;
32 import com.sun.appserv.management.config.ClusterConfig;
33 import com.sun.appserv.management.config.DeployedItemRefConfig;
34 import com.sun.appserv.management.config.DomainConfig;
35 import com.sun.appserv.management.config.HTTPListenerConfig;
36 import com.sun.appserv.management.config.StandaloneServerConfig;
37 import com.sun.appserv.management.config.TemplateResolver;
38 import com.sun.appserv.management.config.WebModuleConfig;
39 import com.sun.appserv.management.DomainRoot;
40 import com.sun.appserv.management.helper.DeployedItemHelper;
41 import com.sun.enterprise.admin.jmx.remote.DefaultConfiguration;
42 import com.sun.enterprise.admin.util.HostAndPort;
43 import com.sun.enterprise.deployapi.config.SunDeploymentConfiguration;
44 import com.sun.enterprise.deployapi.ProgressObjectImpl;
45 import com.sun.enterprise.deployapi.ProgressObjectSink;
46 import com.sun.enterprise.deployment.client.DeploymentClientUtils;
47 import com.sun.enterprise.deployment.client.DeploymentFacility;
48 import com.sun.enterprise.deployment.client.DeploymentFacilityFactory;
49 import com.sun.enterprise.deployment.client.ServerConnectionEnvironment;
50 import com.sun.enterprise.deployment.client.ServerConnectionIdentifier;
51 import com.sun.enterprise.deployment.client.TargetType;
52 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
53 import com.sun.enterprise.deployment.deploy.shared.AbstractArchiveFactory;
54 import com.sun.enterprise.deployment.deploy.shared.Archive;
55 import com.sun.enterprise.deployment.deploy.shared.ArchiveFactory;
56 import com.sun.enterprise.deployment.deploy.shared.InputJarArchive;
57 import com.sun.enterprise.deployment.deploy.shared.JarArchiveFactory;
58 import com.sun.enterprise.deployment.deploy.shared.MemoryMappedArchive;
59 import com.sun.enterprise.deployment.deploy.shared.WritableArchive;
60 import com.sun.enterprise.deployment.deploy.spi.DeploymentManager;
61 import com.sun.enterprise.deployment.util.DeploymentProperties;
62 import com.sun.enterprise.util.LocalStringManagerImpl;
63 import com.sun.enterprise.util.Print;
64
65 import java.io.File JavaDoc;
66 import java.io.InputStream JavaDoc;
67 import java.io.IOException JavaDoc;
68
69 import java.net.InetAddress JavaDoc;
70 import java.net.MalformedURLException JavaDoc;
71 import java.net.UnknownHostException JavaDoc;
72 import java.net.URI JavaDoc;
73 import java.net.URISyntaxException JavaDoc;
74 import java.net.URL JavaDoc;
75
76 import java.util.Collection JavaDoc;
77 import java.util.HashMap JavaDoc;
78 import java.util.Iterator JavaDoc;
79 import java.util.List JavaDoc;
80 import java.util.Locale JavaDoc;
81 import java.util.Map JavaDoc;
82 import java.util.Properties JavaDoc;
83 import java.util.Set JavaDoc;
84 import java.util.Vector JavaDoc;
85
86 import javax.enterprise.deploy.model.DeployableObject JavaDoc;
87 import javax.enterprise.deploy.shared.CommandType JavaDoc;
88 import javax.enterprise.deploy.shared.DConfigBeanVersionType JavaDoc;
89 import javax.enterprise.deploy.shared.ModuleType JavaDoc;
90 import javax.enterprise.deploy.shared.StateType JavaDoc;
91 import javax.enterprise.deploy.spi.DeploymentConfiguration JavaDoc;
92 import javax.enterprise.deploy.spi.exceptions.ConfigurationException JavaDoc;
93 import javax.enterprise.deploy.spi.exceptions.DConfigBeanVersionUnsupportedException JavaDoc;
94 import javax.enterprise.deploy.spi.exceptions.InvalidModuleException JavaDoc;
95 import javax.enterprise.deploy.spi.exceptions.TargetException JavaDoc;
96 import javax.enterprise.deploy.spi.status.ProgressObject JavaDoc;
97 import javax.enterprise.deploy.spi.status.ProgressEvent JavaDoc;
98 import javax.enterprise.deploy.spi.status.DeploymentStatus JavaDoc;
99 import javax.enterprise.deploy.spi.Target JavaDoc;
100 import javax.enterprise.deploy.spi.TargetModuleID JavaDoc;
101
102 import javax.management.AttributeNotFoundException JavaDoc;
103 import javax.management.InstanceNotFoundException JavaDoc;
104 import javax.management.MalformedObjectNameException JavaDoc;
105 import javax.management.MBeanException JavaDoc;
106 import javax.management.MBeanInfo JavaDoc;
107 import javax.management.MBeanServerConnection JavaDoc;
108 import javax.management.ObjectName JavaDoc;
109 import javax.management.ReflectionException JavaDoc;
110
111 import javax.net.ssl.X509TrustManager;
112
113 /**
114  *
115  * @author Jerome Dochez
116  * @author Tim Quinn
117  */

118 public class SunDeploymentManager implements DeploymentManager {
119     
120     // my domain admin server
121
private SunTarget target=null;
122
123     // save reference to ConnectionSource & domain-root proxy here
124
private ConnectionSource dasConnection = null;
125     private DomainRoot rootProxy = null;
126     
127     // other cached references
128
private DomainConfig domainConfigProxy = null;
129     private ProxyFactory proxyFactory = null;
130         
131     // store ID to server connection
132
private ServerConnectionIdentifier serverId = null;
133     
134     /** cached reference to a connected DeploymentFacility */
135     private DeploymentFacility deploymentFacility = null;
136     private static final String JavaDoc applicationsMBeanName =
137             "com.sun.appserv:type=applications,category=config"; // NOI18N
138

139     private static LocalStringManagerImpl localStrings =
140         new LocalStringManagerImpl(SunDeploymentManager.class);
141     
142     private static Locale JavaDoc defaultLocale = Locale.US;
143     private Locale JavaDoc currentLocale = defaultLocale;
144     private static Locale JavaDoc[] supportedLocales = { Locale.US };
145     private String JavaDoc disconnectedMessage = localStrings.getLocalString(
146             "enterprise.deployapi.spi.disconnectedDM", // NOI18N
147
"Illegal operation for a disconnected DeploymentManager");// NOI18N
148

149     private static final String JavaDoc ENABLED_ATTRIBUTE_NAME = "Enabled"; // NOI18N
150

151     /** Creates a new instance of DeploymentManager */
152     public SunDeploymentManager() {
153     }
154     
155     /** Creates a new instance of DeploymentManager */
156     public SunDeploymentManager(ServerConnectionIdentifier sci) {
157         this.target = new SunTarget(sci);
158         serverId = sci;
159     }
160
161     /**
162      * Set additional env vars for the jmx https connector, provided
163      * by the client. This method is expected to be called right after
164      * the client retrieves the DeploymentManager, before
165      * the client makes any calls on the DM that requires MBean Server
166      * connection.
167      */

168     public void setServerConnectionEnvironment(ServerConnectionEnvironment env) {
169         serverId.setConnectionEnvironment(env);
170     }
171     
172    /**
173     * Retrieve the list of deployment targets supported by
174     * this DeploymentManager.
175     *<p>
176     * @throws IllegalStateException is thrown when there is a problem getting
177     * Connection Source
178     * @return A list of deployment Target designators the
179     * user may select for application deployment or 'null'
180     * if there are none.
181     */

182     public Target JavaDoc[] getTargets() throws IllegalStateException JavaDoc {
183         verifyConnected();
184         Target JavaDoc[] result = null;
185         try {
186             DomainConfig domainCfg = getDomainConfigProxy();
187             /*
188              *There is no single proxy that "owns" both clusters and stand-alone instances, the
189              *two types of targets. So
190              *visit the two mgr proxies to retrieve the names of all targets of either type.
191              *From there on, the names can be treated the same regardless of which config mgr proxy
192              *each came from.
193              */

194             final Map JavaDoc standaloneServers =
195                     domainCfg.getStandaloneServerConfigMap();
196             final Map JavaDoc clusters = domainCfg.getClusterConfigMap();
197             /*
198              *Build a single result containing SunTarget instances for either kind of target.
199              */

200             Vector JavaDoc targets = new Vector JavaDoc();
201             
202             for (Iterator JavaDoc it = standaloneServers.keySet().iterator(); it.hasNext(); ) {
203                 targets.add(createSunTarget(target, (String JavaDoc)it.next(),
204                             TargetType.STAND_ALONE_SERVER));
205             }
206             for (Iterator JavaDoc it = clusters.keySet().iterator(); it.hasNext(); ) {
207                 targets.add(createSunTarget(target, (String JavaDoc)it.next(), TargetType.CLUSTER));
208             }
209             
210             /*
211              *Convert the vector into a Target array with runtime type SunTarget [].
212              */

213             result = (Target JavaDoc []) targets.toArray(new SunTarget[0]);
214         } catch (Throwable JavaDoc e) {
215             IllegalStateException JavaDoc ex = new IllegalStateException JavaDoc(e.getMessage());
216             ex.initCause(e);
217             throw ex;
218         }
219         return result;
220     }
221
222     /**
223      *Initialize a new SunTarget with the original target plus added info.
224      *@param the original Target
225      *@param the name for this SunTarget
226      *@param the target type
227      *@return SunTarget newly-initialized SunTarget object
228      *@throws IOException in case of problems retrieving the connection to the MBean server
229      */

230     private SunTarget createSunTarget(SunTarget target, String JavaDoc name, String JavaDoc type) throws IOException JavaDoc {
231         SunTarget aTarget = new SunTarget(target);
232         aTarget.setAppServerInstance(name);
233         aTarget.setConnectionSource(getDasConnection());
234         aTarget.setTargetType(type);
235         return aTarget;
236     }
237
238    /**
239     * Retrieve the list of J2EE application modules distributed
240     * to the identified targets and that are currently running
241     * on the associated server or servers.
242     *
243     * @param moduleType A predefined designator for a J2EE
244     * module type.
245     *
246     * @param targetList A list of deployment Target designators
247     * the user wants checked for module run
248     * status.
249     *
250     * @return An array of TargetModuleID objects representing
251     * the running modules or 'null' if there
252     * are none.
253     *
254     * @throws IllegalStateException is thrown when the method is
255     * called when running in disconnected mode.
256     * @throws TargetException An invalid Target designator
257     * encountered.
258     */

259     public TargetModuleID JavaDoc[] getRunningModules(ModuleType JavaDoc moduleType,
260         Target JavaDoc[] targetList) throws TargetException JavaDoc, IllegalStateException JavaDoc {
261
262         return getModules(moduleType, targetList, ENABLED_ATTRIBUTE_NAME, Boolean.TRUE);
263     }
264
265    /**
266     * Retrieve the list of J2EE application modules distributed
267     * to the identified targets and that are currently not
268     * running on the associated server or servers.
269     *
270     * @param moduleType A predefined designator for a J2EE
271     * module type.
272     *
273     * @param targetList A list of deployment Target designators
274     * the user wants checked for module not
275     * running status.
276     *
277     * @return An array of TargetModuleID objects representing
278     * the non-running modules or 'null' if
279     * there are none.
280     *
281     * @throws IllegalStateException is thrown when the method is
282     * called when running in disconnected mode.
283     * @throws TargetException An invalid Target designator
284     * encountered.
285     */

286     public TargetModuleID JavaDoc[] getNonRunningModules(ModuleType JavaDoc moduleType,
287             Target JavaDoc[] targetList) throws TargetException JavaDoc, IllegalStateException JavaDoc {
288         return getModules(moduleType, targetList, ENABLED_ATTRIBUTE_NAME, Boolean.FALSE);
289     }
290     
291    /**
292     * Retrieve the list of all J2EE application modules running
293     * or not running on the identified targets.
294     *
295     * @param moduleType A predefined designator for a J2EE
296     * module type.
297     *
298     * @param targetList A list of deployment Target designators
299     * the user wants checked for module not
300     * running status.
301     *
302     * @return An array of TargetModuleID objects representing
303     * all deployed modules running or not or
304     * 'null' if there are no deployed modules.
305     *
306     * @throws IllegalStateException is thrown when the method is
307     * called when running in disconnected mode.
308     * @throws TargetException An invalid Target designator
309     * encountered.
310     */

311     public TargetModuleID JavaDoc[] getAvailableModules(ModuleType JavaDoc moduleType,
312             Target JavaDoc[] targetList) throws TargetException JavaDoc,
313             IllegalStateException JavaDoc {
314
315         return getModules(moduleType, targetList, null, null);
316     }
317
318     /**
319      *Single method used by several public methods to make sure the deployment manager is
320      *connected and, if not, throw the IllegalStateException.
321      *
322      *@throws IllegalStateException if the deployment manager is not connected.
323      */

324     private void verifyConnected() {
325         if(isDisconnected()) {
326             throw new IllegalStateException JavaDoc(disconnectedMessage);
327         }
328     }
329
330     /**
331      *Report whether the deployment manager is currently disconnected from the DAS.
332      *@returns whether the deployment manager is disconnected from the DAS
333      */

334     private boolean isDisconnected(){
335         return target == null;
336     }
337
338     
339     /**
340      *Get all modules in the specified state from the targets specified in the
341      argument list.
342      *@param moduleType which returned modules must match
343      *@param array of Target indicating which targets should be searched for matching modules
344      *@param attribute name (optional) to be checked on each candidate module to see if it matches
345      *@param desired value (should be specified if attribute name specified) candidate module should
346      *have for the indicated attribute to be matched
347      *@exception TargetException if a target was improperly formed
348      *@exception IllegalStateException if the method is called after release was called
349      */

350     private TargetModuleID JavaDoc[] getModules(ModuleType JavaDoc moduleType, Target JavaDoc[] targetList,
351                                 String JavaDoc attribute, Object JavaDoc status) throws TargetException JavaDoc, IllegalStateException JavaDoc {
352
353         verifyConnected();
354         if (moduleType==null) {
355             return null;
356         }
357
358         try {
359             Vector JavaDoc resultingTMIDs = new Vector JavaDoc();
360             for (int i = 0; i < targetList.length; i++) {
361                 SunTarget aTarget = (SunTarget) targetList[i];
362             
363                 /*
364                  *For each target, get names of all modules of expected state.
365                  */

366                 String JavaDoc[] moduleNames = getModulesOnATarget(aTarget, moduleType, attribute, status);
367                 
368                 /*
369                  *Create the module ID and add it to the collection to be returned.
370                  */

371                 addToTargetModuleIDs(moduleNames, moduleType, aTarget, resultingTMIDs);
372             }
373
374             /*
375              *Return an array of runtime type SunTargetModuleID [].
376              */

377             TargetModuleID JavaDoc [] answer = (TargetModuleID JavaDoc []) resultingTMIDs.toArray(new SunTargetModuleID[0]);
378             return answer;
379         } catch(Exception JavaDoc e){
380             TargetException JavaDoc tg = new TargetException JavaDoc(localStrings.getLocalString(
381                 "enterprise.deployapi.spi.errorgetreqmods",
382                 "Error getting required modules"
383                 ));
384             tg.initCause(e);
385             throw tg;
386         }
387     }
388
389     /*
390      * Given a target, type and (optionally expected status), get all modules
391      */

392     private String JavaDoc[] getModulesOnATarget(SunTarget aTarget, ModuleType JavaDoc requiredType, String JavaDoc attribute,
393                                                             Object JavaDoc status) throws IOException JavaDoc {
394         Set JavaDoc modules = null;
395         
396         // Get all deployed items in the given target
397
DeployedItemHelper helper = new DeployedItemHelper(getRootProxy());
398         if( ! aTarget.getTargetType().equals(TargetType.CLUSTER)) {
399             modules = helper.queryStandaloneServerDeployedItemObjectNames(aTarget.getName());
400         } else {
401             modules = helper.queryClusterDeployedItemObjectNames(aTarget.getName());
402         }
403         
404         // if required to get only enabled / disabled modules, filter the received modules Set
405
if(attribute != null) {
406             modules = helper.filterByAttributeValue(modules, attribute, status);
407         }
408         
409         // Now from this filtered set, get the modules of the required type
410
Vector JavaDoc modulesMatchingType = new Vector JavaDoc();
411         final String JavaDoc xtype = getXType(requiredType);
412         for(Iterator JavaDoc it = modules.iterator(); it.hasNext(); ) {
413             
414             ObjectName JavaDoc objectName = (ObjectName JavaDoc) it.next();
415             String JavaDoc modId = objectName.getKeyProperty("name"); // NOI18N
416
AMX proxy = (AMX)getDomainConfigProxy().
417                     getContainee(xtype, modId);
418             
419             if (null != proxy) {
420                 modulesMatchingType.add(modId);
421             }
422         }
423         String JavaDoc[] actualModules = null;
424         actualModules = (String JavaDoc []) modulesMatchingType.toArray(new String JavaDoc[0]);
425         return actualModules;
426     }
427
428     private String JavaDoc getXType(ModuleType JavaDoc moduleType) {
429         String JavaDoc result = DeploymentClientUtils.mapModuleTypeToXType(moduleType);
430         return result;
431     }
432     
433     /**
434      *Augments a Collection of TargetModuleIDs with new entries for target module IDs of a given module type on the specified target.
435      *@param moduleIDs array of String for the modules of interest
436      *@param type the ModuleType of interest
437      *@param sunTarget the SunTarget from which to retrieve modules of the selected type
438      *@param resultingTMIDs pre-instantiated List to which TargetModuleIDs will be added
439      */

440     private void addToTargetModuleIDs(String JavaDoc[] moduleIDs, ModuleType JavaDoc type, SunTarget sunTarget, Collection JavaDoc resultingTMIDs) throws IOException JavaDoc {
441
442         for (int j = 0;j < moduleIDs.length;j++) {
443             
444             // Get the host name and port where the application was deployed
445
HostAndPort webHost = getHostPort(moduleIDs[j], sunTarget);
446
447             /*
448              *Prepare a new target module ID object, initialize it, and add it to the result list.
449              */

450             SunTargetModuleID tmid = new SunTargetModuleID(moduleIDs[j], sunTarget);
451             tmid.setModuleType(type);
452             resultingTMIDs.add((TargetModuleID JavaDoc) tmid);
453             
454             /*
455              *Set additional information on the target module ID, depending on what type of
456              *module this is. For J2EE apps, this includes constructing sub TargetModuleIDs.
457              */

458             try {
459                 if (type.equals(ModuleType.EAR)) {
460                     setJ2EEApplicationTargetModuleIDInfo(tmid, moduleIDs[j], webHost);
461                 } else if (type.equals(ModuleType.WAR)) {
462                     setWebApplicationTargetModuleIDInfo(tmid, moduleIDs[j], webHost);
463                 }
464             }
465             catch(Exception JavaDoc exp){
466                 Print.dprintStackTrace(exp.getLocalizedMessage(), exp);
467                 Print.dprint("***Exception occured while "+ // NOI18N
468
"navigating or accessing admin proxies: Keep continuing\n"); // NOI18N
469
}
470         }
471     }
472
473     /**
474      *Attach child target module IDs to a J2EE application target module ID.
475      *@param tmid the target module ID for the J2EE application.
476      *@param sunTarget the target identifying which installation of this module is of interest
477      *@param moduleID name of the module
478      *@param webHost the host and port for this target
479      */

480     private void setJ2EEApplicationTargetModuleIDInfo(SunTargetModuleID tmid, String JavaDoc moduleID, HostAndPort hostAndPort) throws AttributeNotFoundException JavaDoc, MalformedURLException JavaDoc, IOException JavaDoc {
481         
482         /*
483          *Only one of the following invocations is needed. As of this writing, we are
484          *choosing to use the "old" MBeans until the "new" MBean proxies offer the
485          *equivalent access.
486          */

487         addChildTargetModuleIDsToJ2EEUsingMBeans(tmid, moduleID, hostAndPort);
488     }
489     
490     /**
491      *Set additional type-specific information on the target module ID.
492      *@param tmid the target module ID for the Web app
493      *@param sunTarget the target identifying which installation of this module is of interest
494      *@param moduleID name of the module
495      *@param webHost the host and port for this target
496      */

497     private void setWebApplicationTargetModuleIDInfo(SunTargetModuleID tmid, String JavaDoc moduleID, HostAndPort webHost) throws MalformedURLException JavaDoc, IOException JavaDoc {
498
499         SunTarget sunTarget = (SunTarget) tmid.getTarget();
500         /*
501          *Navigate to the Web app's proxy.
502          */

503         WebModuleConfig webProxy = (WebModuleConfig)getDomainConfigProxy().
504             getContainee(XTypes.WEB_MODULE_CONFIG, moduleID);
505         
506         String JavaDoc path = webProxy.getContextRoot();
507         if (!path.startsWith("/")) { //NOI18N
508
path = "/" + path; //NOI18N
509
}
510         
511         // Patchup code for fixing netbeans issue 6221411; Need to find a good solution for this and WSDL publishing
512
String JavaDoc host;
513         if(isPE()) {
514             host = tmid.getConnectionInfo().getHostName();
515         } else {
516             host = webHost.getHost();
517         }
518         URL JavaDoc webURL = new URL JavaDoc("http", host, webHost.getPort(), path); //NOI18N
519
tmid.setWebURL(webURL.toExternalForm());
520     }
521     
522     /**
523      * For a given moduleID on a given Target, get Host and Port information
524      *@param moduleID the module ID of interest
525      *@param aTarget a SunTarget instance for the target of interest
526      */

527     private HostAndPort getHostPort(String JavaDoc moduleID, SunTarget aTarget) throws IOException JavaDoc {
528
529         /*
530          *Navigate the proxies using either the stand-along server proxy or the cluster proxy, depending
531          *on the type of the target.
532          */

533         DeployedItemRefConfig cfg = null;
534         
535         /*
536          *In doing proxy-based template resolution, we'll locate a resolver - such as a stand-alone server config proxy -
537          *that can translate templates if we encounter any.
538          */

539         TemplateResolver resolver = null;
540         
541         if( ! aTarget.getTargetType().equals(TargetType.CLUSTER)) {
542             StandaloneServerConfig svrProxy =
543                     (StandaloneServerConfig)getDomainConfigProxy().
544                         getContainee(XTypes.STANDALONE_SERVER_CONFIG,
545                                 aTarget.getName());
546             cfg = (DeployedItemRefConfig)svrProxy.getContainee(
547                     XTypes.DEPLOYED_ITEM_REF_CONFIG, moduleID);
548             resolver = svrProxy;
549         } else {
550             ClusterConfig clProxy = (ClusterConfig)getDomainConfigProxy().
551                     getContainee(XTypes.CLUSTER_CONFIG, aTarget.getName());
552             cfg = (DeployedItemRefConfig)clProxy.getContainee(
553                     XTypes.DEPLOYED_ITEM_REF_CONFIG, moduleID);
554             /*
555              *We cannot assign the resolver yet because the cluster config proxy itself cannot resolve templates.
556              */

557             resolver = null;
558         }
559
560         // Get the list of virtual servers from the application-Ref
561
String JavaDoc vServers = cfg.getVirtualServers();
562         
563         // if no virtual server configured, get default stuff
564
if(vServers == null) {
565             //FIXME - Need to assign resolver to something for cluster case to use proxy-based template resolution
566
return(getDefaultHostPort(resolver));
567         }
568
569         String JavaDoc [] vsList = vServers.split(" ,"); //NOI18N
570
if (vsList.length == 0) {
571             //FIXME - Need to assign resolver to something for cluster case to use proxy-based template resolution
572
return getDefaultHostPort(resolver);
573         }
574
575         /*
576          *Iterate through the available virtual servers. Stop when one has a legitimate
577          *(non-null) host and port value.
578          */

579         HostAndPort answer = null;
580         for (int i = 0; (i < vsList.length) && (answer == null); i++) {
581             /*
582              *FIXME - need to find the resolver for this virtual server and then pass it as the 2nd
583              *argument next in order to use proxy-based template resolution.
584              */

585             answer = getVirtualServerHostAndPort(vsList[i], resolver);
586         }
587         if (answer == null) {
588             answer = getDefaultHostPort(resolver);
589         }
590         return answer;
591     }
592
593     /**
594      *Return the HostAndPort for a specified virtual server, using either MBeans or proxies as indicated by
595      *the private instance setting.
596      *@param name of the virtual server
597      *@return HostAndPost for the virtual server
598      */

599     private HostAndPort getVirtualServerHostAndPort(String JavaDoc vs, TemplateResolver resolver) throws IOException JavaDoc {
600         try {
601             return getVirtualServerHostAndPortUsingMBeans(vs);
602         } catch (Throwable JavaDoc thr) {
603             IOException JavaDoc ioe = new IOException JavaDoc(localStrings.getLocalString(
604                 "enterprise.deployapi.spi.errretreivevirtualserverhostport",
605                 "Error retrieving virtual server host and port"
606             ));
607             ioe.initCause(thr);
608             throw ioe;
609         }
610     }
611     
612     /**
613      *Return the HostAndPort for the specified virtual server name.
614      *@param the virtual server name
615      *@return HostAndPort for the virtual server
616      */

617     private HostAndPort getVirtualServerHostAndPortUsingMBeans(String JavaDoc vs) throws IOException JavaDoc, MalformedObjectNameException JavaDoc, InstanceNotFoundException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc {
618         HostAndPort result = null;
619         
620         MBeanServerConnection JavaDoc mbsc = getMBeanServerConnection();
621
622         Object JavaDoc[] params = new Object JavaDoc[] {vs, Boolean.FALSE};
623         String JavaDoc[] signature = new String JavaDoc[]{ "java.lang.String", "boolean"}; //NOI18N
624
ObjectName JavaDoc applicationsMBean = new ObjectName JavaDoc(applicationsMBeanName);
625         result = (HostAndPort) mbsc.invoke(applicationsMBean, "getVirtualServerHostAndPort", params, signature); //NOI18N
626
return result;
627     }
628
629     private HostAndPort getDefaultHostPort(TemplateResolver resolver) throws IOException JavaDoc {
630         try {
631             return getDefaultHostPortUsingMBeans();
632         } catch (Throwable JavaDoc thr) {
633             IOException JavaDoc ioe = new IOException JavaDoc(localStrings.getLocalString(
634                 "enterprise.deployapi.spi.errretrievedefaulthostport",
635                 "Error retrieving default host and port"
636             ));
637             ioe.initCause(thr);
638             throw ioe;
639         }
640     }
641     
642     /** Return HostAndPort for first listener, using proxies for navigation.
643      *@return HostAndPort of the first listener with non-null host and port
644      */

645     private HostAndPort getDefaultHostPortUsingMBeans() throws IOException JavaDoc, MalformedObjectNameException JavaDoc, MBeanException JavaDoc, InstanceNotFoundException JavaDoc, ReflectionException JavaDoc {
646         MBeanServerConnection JavaDoc mbsc = getMBeanServerConnection();
647         HostAndPort result = null;
648         
649         Object JavaDoc[] params = new Object JavaDoc[] {Boolean.FALSE};
650         String JavaDoc[] signature = new String JavaDoc[]{ "boolean"};
651         ObjectName JavaDoc applicationsMBean = new ObjectName JavaDoc(applicationsMBeanName);
652         result = (HostAndPort) mbsc.invoke(applicationsMBean, "getHostAndPort", params, signature);
653         return result;
654     }
655     
656     private HostAndPort getHostPort(HTTPListenerConfig listenerProxy, TemplateResolver resolver) throws IOException JavaDoc {
657         String JavaDoc serverName = null;
658         int port = 0;
659         
660         // return if listener is not enabled
661
if(!listenerProxy.getEnabled()) {
662             return null;
663         }
664
665         // return if listener is meant for asadmin only
666
//com.sun.enterprise.web.WebContainer.ADMIN_VS
667
if("__asadmin".equals(listenerProxy.getDefaultVirtualServer())) {
668             return null;
669         }
670
671         if(!listenerProxy.getSecurityEnabled()) {
672             serverName = listenerProxy.getServerName();
673             if (serverName == null || serverName.trim().equals("")) {
674                 serverName = getDefaultHostName();
675             }
676             String JavaDoc portString = listenerProxy.getPort();
677             port = new Integer JavaDoc(getPropertyValueFromTemplate(portString, resolver)).intValue();
678             if(listenerProxy.getRedirectPort() != null) {
679                 port = new Integer JavaDoc(getPropertyValueFromTemplate(listenerProxy.getRedirectPort(), resolver)).intValue();
680             }
681         }
682         HostAndPort hostPort = new HostAndPort(serverName, port);
683         return hostPort;
684     }
685     
686     /**
687      * Checks if property got was a template (like ${listener-1});
688      * If so, gets the value from the specified template resolver.
689      */

690     private String JavaDoc getPropertyValueFromTemplate(String JavaDoc str, TemplateResolver resolver) throws IOException JavaDoc {
691         /*
692          *The resolver will tranlate the template if it can, returning the translation. It will return
693          *the input string unchanged if the string is not a template or if it is a template but the resolver
694          *cannot resolve it.
695          */

696         String JavaDoc result = resolver.resolveTemplateString(str);
697         return result;
698     }
699
700     private String JavaDoc getDefaultHostName() {
701         String JavaDoc defaultHostName = "localhost"; //NOI18N
702
try {
703             InetAddress JavaDoc host = InetAddress.getLocalHost();
704             defaultHostName = host.getCanonicalHostName();
705         } catch(UnknownHostException JavaDoc uhe) {
706         }
707         return defaultHostName;
708     }
709         
710    /**
711     * Retrieve the object that provides server-specific deployment
712     * configuration information for the J2EE deployable component.
713     *
714     * @param dObj An object representing a J2EE deployable component.
715     * @throws InvalidModuleException The DeployableObject is an
716     * unknown or unsupport component for this
717     * configuration tool.
718     */

719
720     public DeploymentConfiguration createConfiguration(DeployableObject JavaDoc dObj)
721             throws InvalidModuleException JavaDoc
722     {
723         try {
724             SunDeploymentConfiguration deploymentConfiguration = new SunDeploymentConfiguration(dObj);
725             deploymentConfiguration.setDeploymentManager(this);
726             return deploymentConfiguration;
727         } catch(ConfigurationException JavaDoc e) {
728             InvalidModuleException JavaDoc ime = new InvalidModuleException JavaDoc(e.getMessage());
729             ime.initCause(e);
730             throw ime;
731         }
732     }
733
734
735    /**
736     * The distribute method performs three tasks; it validates the
737     * deployment configuration data, generates all container specific
738     * classes and interfaces, and moves the fully baked archive to
739     * the designated deployment targets.
740     *
741     * @param targetList A list of server targets the user is specifying
742     * this application be deployed to.
743     * @param moduleArchive The file name of the application archive
744     * to be disrtibuted.
745     * @param deploymentPlan The XML file containing the runtime
746     * configuration information associated with
747     * this application archive.
748     * @throws IllegalStateException is thrown when the method is
749     * called when running in disconnected mode.
750     * @return ProgressObject an object that tracks and reports the
751     * status of the distribution process.
752     */

753
754     public ProgressObject JavaDoc distribute(Target JavaDoc[] targetList,
755            File JavaDoc moduleArchive, File JavaDoc deploymentPlan)
756            throws IllegalStateException JavaDoc
757     {
758         return deploy(targetList, moduleArchive, deploymentPlan, null /* presetOptions */);
759     }
760
761    /**
762     * The distribute method performs three tasks; it validates the
763     * deployment configuration data, generates all container specific
764     * classes and interfaces, and moves the fully baked archive to
765     * the designated deployment targets.
766     *
767     * @param targetList A list of server targets the user is specifying
768     * this application be deployed to.
769     * @param moduleArchive The input stream containing the application
770     * archive to be disrtibuted.
771     * @param deploymentPlan The input stream containing the deployment
772     * configuration information associated with
773     * this application archive.
774     * @throws IllegalStateException is thrown when the method is
775     * called when running in disconnected mode.
776     * @return ProgressObject an object that tracks and reports the
777     * status of the distribution process.
778     *
779     */

780     public ProgressObject JavaDoc distribute(Target JavaDoc[] targetList,
781            InputStream JavaDoc moduleArchive, InputStream JavaDoc deploymentPlan)
782            throws IllegalStateException JavaDoc
783     {
784         return deploy(targetList, moduleArchive, deploymentPlan, null /* presetOptions */);
785     }
786
787     /**
788      * The distribute method performs three tasks; it validates the
789      * deployment configuration data, generates all container specific
790      * classes and interfaces, and moves the fully baked archive to
791      * the designated deployment targets.
792      *
793      * @param targetList A list of server targets the user is specifying
794      * this application be deployed to.
795      * @param moduleType The module type of this application archive.
796      * @param moduleArchive The input stream containing the application
797      * archive to be disrtibuted.
798      * @param deploymentPlan The input stream containing the deployment
799      * configuration information associated with
800      * this application archive.
801      * @throws IllegalStateException is thrown when the method is
802      * called when running in disconnected mode.
803      * @return ProgressObject an object that tracks and reports the
804      * status of the distribution process.
805      *
806      */

807     
808     public ProgressObject JavaDoc distribute(Target JavaDoc[] targetList, ModuleType JavaDoc type,
809             InputStream JavaDoc moduleArchive, InputStream JavaDoc deploymentPlan)
810             throws IllegalStateException JavaDoc
811     {
812         DeploymentProperties dProps = new DeploymentProperties();
813         dProps.setType(type);
814         return deploy(targetList, moduleArchive, deploymentPlan, (Properties)dProps);
815     }
816
817    /**
818     * Start the application running.
819     *
820     * <p> Only the TargetModuleIDs which represent a root module
821     * are valid for being started. A root TargetModuleID has no parent.
822     * A TargetModuleID with a parent can not be individually started.
823     * A root TargetModuleID module and all its child modules will be
824     * started.
825     *
826     * @param moduleIDList A array of TargetModuleID objects
827     * representing the modules to be started.
828     * @throws IllegalStateException is thrown when the method is
829     * called when running in disconnected mode.
830     * @return ProgressObject an object that tracks and reports the
831     * status of the start operation.
832     */

833
834     public ProgressObject JavaDoc start(TargetModuleID JavaDoc[] moduleIDList)
835              throws IllegalStateException JavaDoc
836     {
837         return executeCommandUsingFacility(CommandType.START, moduleIDList);
838     }
839
840    /**
841     * Stop the application running.
842     *
843     * <p> Only the TargetModuleIDs which represent a root module
844     * are valid for being stopped. A root TargetModuleID has no parent.
845     * A TargetModuleID with a parent can not be individually stopped.
846     * A root TargetModuleID module and all its child modules will be
847     * stopped.
848     *
849     * @param moduleIDList A array of TargetModuleID objects
850     * representing the modules to be stopped.
851     * @throws IllegalStateException is thrown when the method is
852     * called when running in disconnected mode.
853     * @return ProgressObject an object that tracks and reports the
854     * status of the stop operation.
855     */

856
857     public ProgressObject JavaDoc stop(TargetModuleID JavaDoc [] moduleIDList)
858              throws IllegalStateException JavaDoc
859     {
860         return executeCommandUsingFacility(CommandType.STOP, moduleIDList);
861     }
862     
863
864    /**
865     * Remove the application from the target server.
866     *
867     * <p> Only the TargetModuleIDs which represent a root module
868     * are valid for undeployment. A root TargetModuleID has no parent.
869     * A TargetModuleID with a parent can not be undeployed. A root
870     * TargetModuleID module and all its child modules will be undeployed.
871     * The root TargetModuleID module and all its child modules must
872     * stopped before they can be undeployed.
873     *
874     * @param moduleIDList An array of TargetModuleID objects representing
875     * the root modules to be stopped.
876     * @throws IllegalStateException is thrown when the method is
877     * called when running in disconnected mode.
878     * @return ProgressObject an object that tracks and reports the
879     * status of the stop operation.
880     */

881
882     public ProgressObject JavaDoc undeploy(TargetModuleID JavaDoc[] moduleIDList)
883                throws IllegalStateException JavaDoc
884     {
885         return executeCommandUsingFacility(CommandType.UNDEPLOY, moduleIDList);
886     }
887          
888
889    /**
890     * This method designates whether this platform vendor provides
891     * application redeployment functionality. A value of true means
892     * it is supported. False means it is not.
893     *
894     * @return A value of true means redeployment is supported by this
895     * vendor's DeploymentManager. False means it
896     * is not.
897     */

898     public boolean isRedeploySupported() {
899         return true;
900     }
901
902    /**
903     * (optional)
904     * The redeploy method provides a means for updating currently
905     * deployed J2EE applications. This is an optional method for
906     * vendor implementation.
907     *
908     * Redeploy replaces a currently deployed application with an
909     * updated version. The runtime configuration information for
910     * the updated application must remain identical to the application
911     * it is updating.
912     *
913     * When an application update is redeployed, all existing client
914     * connections to the original running application must not be disrupted;
915     * new clients will connect to the application update.
916     *
917     * This operation is valid for TargetModuleIDs that represent a
918     * root module. A root TargetModuleID has no parent. A root
919     * TargetModuleID module and all its child modules will be redeployed.
920     * A child TargetModuleID module cannot be individually redeployed.
921     * The redeploy operation is complete only when this action for
922     * all the modules has completed.
923     *
924     * @param moduleIDList An array of designators of the applications
925     * to be updated.
926     * @param moduleArchive The file name of the application archive
927     * to be disrtibuted.
928     * @param deploymentPlan The deployment configuration information
929     * associated with this application archive.
930     * @return ProgressObject an object that tracks and reports the
931     * status of the redeploy operation.
932     * @throws IllegalStateException is thrown when the method is
933     * called when running in disconnected mode.
934     * @throws UnsupportedOperationException this optional command
935     * is not supported by this implementation.
936     */

937
938     public ProgressObject JavaDoc redeploy(TargetModuleID JavaDoc[] moduleIDList,
939            File JavaDoc moduleArchive, File JavaDoc deploymentPlan)
940            throws UnsupportedOperationException JavaDoc, IllegalStateException JavaDoc
941     {
942         try {
943             /*
944              *To support multiple different modules in the module ID list, use a TargetModuleIDCollection to
945              *organize them and work on each module one at a time.
946              */

947             TargetModuleIDCollection coll = new TargetModuleIDCollection(moduleIDList);
948             for (Iterator JavaDoc it = coll.iterator(); it.hasNext();) {
949                 /*
950                  *The iterator returns one work instance for each module present in the collection.
951                  */

952                 DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) it.next();
953                 /*
954                  *Set the name in the properties according to the moduleID. The module is the same for all the
955                  *targets represented by this single work object.
956                  */

957                 ProgressObject JavaDoc po = deploy(work.targets(), moduleArchive, deploymentPlan, getRedeployOptions(work.getModuleID()));
958
959                 /*
960                  *The work instance needs to know about its own progress object, and the
961                  *aggregate progress object needs to also.
962                  */

963                 work.setProgressObject(po);
964                 coll.getProgressObjectSink().sinkProgressObject(po);
965             }
966             return coll.getProgressObjectSink();
967         } catch (Throwable JavaDoc e) {
968             return prepareErrorProgressObject(CommandType.REDEPLOY, e);
969         }
970     }
971
972    /**
973     * (optional)
974     * The redeploy method provides a means for updating currently
975     * deployed J2EE applications. This is an optional method for
976     * vendor implementation.
977     *
978     * Redeploy replaces a currently deployed application with an
979     * updated version. The runtime configuration information for
980     * the updated application must remain identical to the application
981     * it is updating.
982     *
983     * When an application update is redeployed, all existing client
984     * connections to the original running application must not be disrupted;
985     * new clients will connect to the application update.
986     *
987     * This operation is valid for TargetModuleIDs that represent a
988     * root module. A root TargetModuleID has no parent. A root
989     * TargetModuleID module and all its child modules will be redeployed.
990     * A child TargetModuleID module cannot be individually redeployed.
991     * The redeploy operation is complete only when this action for
992     * all the modules has completed.
993     *
994     * @param moduleIDList An array of designators of the applications
995     * to be updated.
996     * @param moduleArchive The input stream containing the application
997     * archive to be disrtibuted.
998     * @param deploymentPlan The input stream containing the runtime
999     * configuration information associated with
1000    * this application archive.
1001    * @return ProgressObject an object that tracks and reports the
1002    * status of the redeploy operation.
1003    * @throws IllegalStateException is thrown when the method is
1004    * called when running in disconnected mode.
1005    * @throws UnsupportedOperationException this optional command
1006    * is not supported by this implementation.
1007    */

1008
1009    public ProgressObject JavaDoc redeploy(TargetModuleID JavaDoc[] moduleIDList,
1010           InputStream JavaDoc moduleArchive, InputStream JavaDoc deploymentPlan)
1011           throws UnsupportedOperationException JavaDoc, IllegalStateException JavaDoc
1012    {
1013        try {
1014            /*
1015             *To support multiple different modules in the module ID list, use a TargetModuleIDCollection to
1016             *organize them and work on each module one at a time.
1017             */

1018            TargetModuleIDCollection coll = new TargetModuleIDCollection(moduleIDList);
1019            for (Iterator JavaDoc it = coll.iterator(); it.hasNext();) {
1020                /*
1021                 *The iterator returns one work instance for each module present in the collection.
1022                 */

1023                DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) it.next();
1024                /*
1025                 *Set the name in the properties according to the moduleID. The module is the same for all the
1026                 *targets represented by this single work object.
1027                 */

1028                DeploymentProperties dProps = getRedeployOptions(work.getModuleID());
1029                dProps.setType(getModuleTypeFor(work.getModuleID()));
1030                ProgressObject JavaDoc po = deploy(work.targets(), moduleArchive, deploymentPlan, dProps);
1031
1032                /*
1033                 *The work instance needs to know about its own progress object, and the
1034                 *aggregate progress object needs to also.
1035                 */

1036                work.setProgressObject(po);
1037                coll.getProgressObjectSink().sinkProgressObject(po);
1038            }
1039            return coll.getProgressObjectSink();
1040        } catch (Throwable JavaDoc e) {
1041            return prepareErrorProgressObject(CommandType.REDEPLOY, e);
1042        }
1043    }
1044
1045   /**
1046    * The release method is the mechanism by which the tool signals
1047    * to the DeploymentManager that the tool does not need it to
1048    * continue running connected to the platform.
1049    *
1050    * The tool may be signaling it wants to run in a disconnected
1051    * mode or it is planning to shutdown.
1052    *
1053    * When release is called the DeploymentManager may close any
1054    * J2EE resource connections it had for deployment configuration
1055    * and perform other related resource cleanup. It should not
1056    * accept any new operation requests (i.e., distribute, start
1057    * stop, undeploy, redeploy. It should finish any operations
1058    * that are currently in process. Each ProgressObject associated
1059    * with a running operation should be marked as released (see
1060    * the ProgressObject).
1061    *
1062    */

1063
1064    public void release() {
1065        /*
1066         *Make sure multiple releases are handled gracefully.
1067         */

1068        if ( ! isDisconnected() ) {
1069            target.release();
1070            target = null;
1071        }
1072    }
1073
1074   /**
1075    * Returns the default locale supported by this implementation of
1076    * javax.enterprise.deploy.spi subpackages.
1077    *
1078    * @return Locale the default locale for this implementation.
1079    */

1080    public Locale JavaDoc getDefaultLocale() {
1081        return defaultLocale;
1082    }
1083
1084   /**
1085    * Returns the active locale this implementation of
1086    * javax.enterprise.deploy.spi subpackages is running.
1087    *
1088    * @return Locale the active locale of this implementation.
1089    */

1090    public Locale JavaDoc getCurrentLocale() {
1091        return currentLocale;
1092    }
1093
1094   /**
1095    * Set the active locale for this implementation of
1096    * javax.enterprise.deploy.spi subpackages to run.
1097    *
1098    * @throws UnsupportedOperationException the provide locale is
1099    * not supported.
1100    */

1101    public void setLocale(Locale JavaDoc locale) throws UnsupportedOperationException JavaDoc {
1102        for (int i=0;i<supportedLocales.length;i++) {
1103            if (supportedLocales[i] == locale) {
1104                currentLocale = locale;
1105                return;
1106            }
1107        }
1108        throw new UnsupportedOperationException JavaDoc(
1109            localStrings.getLocalString("enterprise.deployapi.spi.localnotsupported", //NOI18N
1110
"Locale {0} is not supported", new Object JavaDoc[] {locale})); //NOI18N
1111
}
1112
1113   /**
1114    * Returns an array of supported locales for this implementation.
1115    *
1116    * @return Locale[] the list of supported locales.
1117    */

1118    public Locale JavaDoc[] getSupportedLocales() {
1119        return supportedLocales;
1120    }
1121
1122   /**
1123    * Reports if this implementation supports the designated locale.
1124    *
1125    * @return A value of 'true' means it is support and 'false' it is
1126    * not.
1127    */

1128    public boolean isLocaleSupported(Locale JavaDoc locale) {
1129        Locale JavaDoc[] locales = getSupportedLocales();
1130        for (int i=0;i<locales.length;i++) {
1131            if (locales[i].equals(locale))
1132                return true;
1133        }
1134        return false;
1135    }
1136
1137   /**
1138    * Returns the J2EE platform version number for which the
1139    * configuration beans are provided. The beans must have
1140    * been compiled with the J2SE version required by the J2EE
1141    * platform.
1142    *
1143    * @return a DConfigBeanVersionType object representing the
1144    * platform version number for which these beans are provided.
1145    */

1146   public DConfigBeanVersionType JavaDoc getDConfigBeanVersion() {
1147       return DConfigBeanVersionType.V5;
1148   }
1149
1150   /**
1151    * Returns 'true' if the configuration beans support the J2EE platform
1152    * version specified. It returns 'false' if the version is
1153    * not supported.
1154    *
1155    * @param version a DConfigBeanVersionType object representing the
1156    * J2EE platform version for which support is requested.
1157    * @return 'true' if the version is supported and 'false if not.
1158    */

1159   public boolean isDConfigBeanVersionSupported(DConfigBeanVersionType JavaDoc version) {
1160       return version.getValue()==getDConfigBeanVersion().getValue();
1161   }
1162
1163   /**
1164    * Set the configuration beans to be used to the J2EE platform
1165    * version specificed.
1166    *
1167    * @param version a DConfigBeanVersionType object representing the
1168    * J2EE platform version for which support is requested.
1169    * @throws DConfigBeanVersionUnsupportedException when the
1170    * requested bean version is not supported.
1171    */

1172   public void setDConfigBeanVersion(DConfigBeanVersionType JavaDoc version) throws
1173            DConfigBeanVersionUnsupportedException JavaDoc {
1174                               
1175       if (!isDConfigBeanVersionSupported(version)) {
1176           throw new DConfigBeanVersionUnsupportedException JavaDoc(
1177            localStrings.getLocalString(
1178                "enterprise.deployapi.spi.dconfigbeanversionnotsupported", //NOI18N
1179
"DConfigBean version {0} is not supported", //NOI18N
1180
new Object JavaDoc[] {version.toString()}));
1181       }
1182   }
1183    
1184   /**
1185    *Return deployment options for the DeploymentFacility preset for the needs of redeployment.
1186    *These properties will be merged with and will override the options set for normal deployment.
1187    *@return Properties with the conventional preset properties for redeployment
1188    */

1189   private DeploymentProperties getRedeployOptions(String JavaDoc moduleID) {
1190        DeploymentProperties deplProps = new DeploymentProperties();
1191        deplProps.setForce(true);
1192        deplProps.setName(moduleID);
1193        return deplProps;
1194   }
1195   
1196   /**
1197    * @return the admin server manager managing hosts for us
1198    */

1199   private MBeanServerConnection JavaDoc getMBeanServerConnection() throws IllegalStateException JavaDoc {
1200        return getDasConnection().getExistingMBeanServerConnection();
1201   }
1202   
1203   
1204    /**
1205     *Deploy the specified module to the list of targets.
1206     *The deployment plan archive can be null.
1207     *@param Target[] the targets to which to deploy the module
1208     *@param File the archive stream to be deployed
1209     *@param File the (optional) deployment plan stream
1210     *@param options set by the caller to override and augment any settings made here
1211     *@return ProgressObject to communicate progress and results of the deployment
1212     *@exception IllegalStateException if the DeploymentManager has disconnected
1213     *@exception IOException if there are problems working with the input streams
1214     */

1215    private ProgressObject JavaDoc deploy(Target JavaDoc[] targetList,
1216           InputStream JavaDoc moduleStream, InputStream JavaDoc deploymentPlanStream, Properties presetOptions)
1217           throws IllegalStateException JavaDoc {
1218        
1219        /*
1220         *Create archives for the module's input stream and, if present, the deployment plan's
1221         *input stream, and then delegate to the variant of deploy that accepts archives as
1222         *arguments.
1223         */

1224        MemoryMappedArchive moduleArchive = null;
1225        MemoryMappedArchive deploymentPlanArchive = null;
1226        
1227        try {
1228            moduleArchive = new MemoryMappedArchive(moduleStream);
1229            if (deploymentPlanStream != null) {
1230                deploymentPlanArchive = new MemoryMappedArchive(deploymentPlanStream);
1231            }
1232            return deploy(targetList, moduleArchive, deploymentPlanArchive, presetOptions);
1233        } catch (Throwable JavaDoc e) {
1234            String JavaDoc msg = localStrings.getLocalString(
1235                "enterprise.deployapi.spi.errpreparearchstream",
1236                "Could not prepare archives for module and/or deployment plan input streams");
1237            IllegalArgumentException JavaDoc ex = new IllegalArgumentException JavaDoc(msg);
1238            ex.initCause(e);
1239            return prepareErrorProgressObject(CommandType.DISTRIBUTE, ex);
1240        }
1241    }
1242
1243    /**
1244     *Deploy the specified module to the list of targets.
1245     *The deployment plan archive can be null.
1246     *@param Target[] the targets to which to deploy the module
1247     *@param File the archive file to be deployed
1248     *@param File the (optional) deployment plan file
1249     *@param options set by the caller to override and augment any settings made here
1250     *@return ProgressObject to communicate progress and results of the deployment
1251     *@exception IllegalStateException if the DeploymentManager has disconnected
1252     *@exception IOException if there are problems opening the archive files
1253     */

1254    private ProgressObject JavaDoc deploy(Target JavaDoc[] targetList,
1255           File JavaDoc moduleArchive, File JavaDoc deploymentPlan, Properties presetOptions)
1256           throws IllegalStateException JavaDoc {
1257           
1258        /*
1259         *Create archives for the module file and, if present, the deployment plan file, and
1260         *then delegate to the variant of deploy that accepts archives as arguments.
1261         */

1262        AbstractArchive appArchive = null;
1263        AbstractArchive planArchive = null;
1264        ArchiveFactory archiveFactory = new ArchiveFactory();
1265        
1266        try {
1267            appArchive = archiveFactory.openArchive(toJarURI(moduleArchive));
1268        
1269            if(deploymentPlan != null && deploymentPlan.length() != 0) {
1270                planArchive = archiveFactory.openArchive(toJarURI(deploymentPlan));
1271                if (planArchive == null) {
1272                    throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
1273                        "enterprise.deployapi.spi.noarchivisthandlesplan",
1274                        "No archivist is able to handle the deployment plan {0}",
1275                        new Object JavaDoc [] {deploymentPlan.getAbsolutePath()}
1276                    ));
1277                }
1278            }
1279            
1280            ProgressObject JavaDoc po = deploy(targetList, appArchive, planArchive, presetOptions);
1281            return po;
1282        } catch (Exception JavaDoc se) {
1283            String JavaDoc msg = localStrings.getLocalString(
1284                "enterprise.deployapi.spi.errpreparearchfile",
1285                "Could not prepare archives for module and/or deployment plan files");
1286            IllegalArgumentException JavaDoc ex = new IllegalArgumentException JavaDoc(msg);
1287            ex.initCause(se);
1288            return prepareErrorProgressObject(CommandType.DISTRIBUTE, ex);
1289        } finally {
1290            closeArchives(CommandType.DISTRIBUTE, appArchive, moduleArchive.getAbsolutePath(), planArchive, (deploymentPlan != null) ? deploymentPlan.getAbsolutePath() : null);
1291        }
1292    }
1293
1294    /**
1295     *Deploy the specified module to the list of targets.
1296     *The deployment plan archive can be null.
1297     *@param Target[] the targets to which to deploy the module
1298     *@param AbstractArchive the archive to be deployed
1299     *@param AbstractArchive the (optional) deployment plan
1300     *@param options set by the caller to override and augment any settings made here
1301     *@return ProgressObject to communicate progress and results of the deployment
1302     *@exception IllegalStateException if the DeploymentManager has disconnected
1303     */

1304    private ProgressObject JavaDoc deploy(Target JavaDoc[] targetList,
1305           AbstractArchive moduleArchive, AbstractArchive planArchive, Properties presetOptions)
1306           throws IllegalStateException JavaDoc {
1307               
1308        verifyConnected();
1309        
1310        String JavaDoc moduleID = null;
1311        ProgressObject JavaDoc progressObj = null;
1312
1313        try {
1314            String JavaDoc UriPath = moduleArchive.getArchiveUri();
1315            moduleID = computeModuleID(moduleArchive);
1316            Properties options = getProperties(UriPath, moduleID);
1317
1318            /*
1319             *If any preset options were specified by the caller, use them to
1320             *override or augment the just-assigned set.
1321             */

1322            if (presetOptions != null) {
1323                options.putAll(presetOptions);
1324            }
1325            progressObj = getDeploymentFacility().deploy(targetList, moduleArchive, planArchive, options);
1326            
1327        } catch(Throwable JavaDoc e) {
1328            /*
1329             *Prepare a progress object with a deployment status "wrapper" around this exception.
1330             */

1331            progressObj = prepareErrorProgressObject(CommandType.DISTRIBUTE, e);
1332        }
1333        return progressObj;
1334    }
1335
1336    /**
1337     *Closes the module archive and the plan archive, if any, preparing a
1338     *ProgressObject if any error occurred.
1339     *@param commandType the CommandType in progress - used in preparing the progress object (if needed)
1340     *@param moduleArchive the main module archive to be closed
1341     *@param moduleArchiveSpec a String representation of the main module archive
1342     *@param planArchive the deployment plan archive (if any) to be closed
1343     *@param planArchiveSpec a String representation of the deployment plan archive (if any) to be closed
1344     *@return ProgressObject an error progress object if any error ocurred trying to close the archive(s)
1345     */

1346    private ProgressObject JavaDoc closeArchives(CommandType JavaDoc commandType, AbstractArchive moduleArchive, String JavaDoc moduleArchiveSpec, AbstractArchive planArchive, String JavaDoc planArchiveSpec) {
1347        ProgressObject JavaDoc errorPO = null;
1348        StringBuilder JavaDoc msg = new StringBuilder JavaDoc();
1349        
1350        IOException JavaDoc moduleIOE = closeArchive(moduleArchive);
1351        IOException JavaDoc planIOE = closeArchive(planArchive);
1352        
1353        IOException JavaDoc excForProgressObject = null;
1354        String JavaDoc errorMsg = null;
1355        /*
1356         *I the module could not be closed, record the IOException resulting from the attempt for
1357         *use in the error progress object returned to the caller.
1358         */

1359        if (moduleIOE != null) {
1360            excForProgressObject = moduleIOE;
1361            /*
1362             *If there was a problem with both the module archive and the plan archive,
1363             *compose an appropriate message that says both failed.
1364             */

1365            if (planIOE != null) {
1366                errorMsg = localStrings.getLocalString(
1367                        "enterprise.deployapi.spi.errclosearchs",
1368                        "Could not close module archive {0} or deployment plan archive {1}",
1369                        new Object JavaDoc[] {moduleArchiveSpec, planArchiveSpec}
1370                );
1371            } else {
1372                /*
1373                 *Either the plan was closed or there was no plan to close. To build
1374                 *a message about only the module archive.
1375                 */

1376                errorMsg = localStrings.getLocalString(
1377                        
1378                        "enterprise.deployapi.spi.errclosemodulearch",
1379                        "Could not close module archive {0}",
1380                        new Object JavaDoc[] {moduleArchiveSpec}
1381                );
1382            }
1383        } else if (planIOE != null) {
1384            /*
1385             *The module archive was closed fine. If the plan archive exists and
1386             *could not be closed, compose an error message to that effect and
1387             *record the IOException that occurred during the attempt to close the
1388             *deployment plan archive for use in the error progress object returned
1389             *to the caller.
1390             */

1391            excForProgressObject = planIOE;
1392            errorMsg = localStrings.getLocalString(
1393                    "enterprise.deployapi.spi.errcloseplanarch",
1394                    "Could not close deployment plan archive {0}",
1395                    new Object JavaDoc[] {planArchiveSpec}
1396            );
1397        }
1398        
1399        /**
1400         *If an error occurred trying to close either archive, build an error progress object
1401         *for return to the caller.
1402         */

1403        if (errorMsg != null) {
1404            IOException JavaDoc ioe = new IOException JavaDoc(errorMsg);
1405            ioe.initCause(excForProgressObject); // Only reflects the module exception if both occurred, but the msg describes both.
1406
errorPO = prepareErrorProgressObject(commandType, ioe);
1407        }
1408        
1409        return errorPO;
1410    }
1411    
1412    /**
1413     *Closes the specified archive, returning any IOException encountered in the process.
1414     *@param archive the archive to be closed
1415     *@return IOException describing any error; null if the close succeeded
1416     */

1417    private IOException JavaDoc closeArchive(AbstractArchive archive) {
1418        IOException JavaDoc errorIOE = null;
1419        if (archive != null) {
1420            try {
1421                archive.close();
1422            } catch (IOException JavaDoc ioe) {
1423                errorIOE = ioe;
1424            }
1425        }
1426        return errorIOE;
1427    }
1428    
1429    /**
1430     *Computes a module ID for use during deployment. We use the file
1431     *name as default. If the archive is not available, i.e. using InputStream
1432     *to deploy, we return null and delay the defining of moduleID (to server
1433     *side).
1434     *@param moduleArchive the archive of the module's archive
1435     *@return the derived module ID
1436     *@exception IOException
1437     */

1438    private String JavaDoc computeModuleID(AbstractArchive moduleArchive) throws Exception JavaDoc
1439    {
1440        /*
1441         *Prefer the archive's path.
1442         */

1443        String JavaDoc moduleID = null;
1444            
1445        String JavaDoc UriPath = moduleArchive.getArchiveUri();
1446        if ((UriPath != null) && (UriPath.length() > 0)) {
1447            /*
1448             *Use the archive path.
1449             */

1450            moduleID = pathExcludingType(UriPath);
1451
1452            //Additional processing of the moduleID
1453
moduleID = moduleID.replace(' ','_');
1454
1455            // This moduleID will be later used to construct file path,
1456
// replace the illegal characters in file name
1457
// \ / : * ? " < > | with _
1458
moduleID = moduleID.replace('\\', '_').replace('/', '_');
1459            moduleID = moduleID.replace(':', '_').replace('*', '_');
1460            moduleID = moduleID.replace('?', '_').replace('"', '_');
1461            moduleID = moduleID.replace('<', '_').replace('>', '_');
1462            moduleID = moduleID.replace('|', '_');
1463
1464            // This moduleID will also be used to construct an ObjectName
1465
// to register the module, so replace additional special
1466
// characters , = used in property parsing with -
1467
moduleID = moduleID.replace(',', '_').replace('=', '_');
1468        }
1469
1470        return moduleID;
1471    }
1472    
1473    /**
1474     *Perform the selected command on the DeploymentFacility using the specified target module IDs.
1475     *<p>
1476     *Several of the deployment facility methods have the same signature except for the name.
1477     *This method collects the pre- and post-processing around those method calls in one place, then
1478     *chooses which of the deployment facility methods to actually invoke based on the
1479     *command type provided as an argument.
1480     *
1481     *@param commandType selects which method should be invoked
1482     *@param moduleIDList array of TargetModuleID to be started
1483     *@exception IllegalArgumentException if the command type is not supported
1484     *@exception IllegalStateException if the deployment manager had been released previously
1485     */

1486     private ProgressObject JavaDoc executeCommandUsingFacility(
1487        CommandType JavaDoc commandType, TargetModuleID JavaDoc[] targetModuleIDList)
1488        throws IllegalStateException JavaDoc {
1489
1490         verifyConnected();
1491       try {
1492         DeploymentFacility df = getDeploymentFacility();
1493
1494        /*
1495         *Create a temporary collection based on the target module IDs to make it easier to deal
1496         *with the different modules and the set of targets.
1497         */

1498        TargetModuleIDCollection coll = new TargetModuleIDCollection(targetModuleIDList);
1499        
1500        /*
1501         *For each distinct module ID present in the list, ask the deployment facility to
1502         *operate on that module on all the relevant targets.
1503         */

1504        
1505        for (Iterator JavaDoc it = coll.iterator(); it.hasNext();) {
1506            /*
1507             *The iterator returns one work instance for each module present in the collection.
1508             *Each work instance reflects one invocation of a method on the DeploymentFacility.
1509             */

1510            DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) it.next();
1511            ProgressObject JavaDoc po = null;
1512            
1513            if (commandType.equals(CommandType.START)) {
1514                po = df.enable(work.targets(), work.getModuleID());
1515                
1516            } else if (commandType.equals(CommandType.STOP)) {
1517                po = df.disable(work.targets(), work.getModuleID());
1518                
1519            } else if (commandType.equals(CommandType.UNDEPLOY)) {
1520                po = df.undeploy(work.targets(), work.getModuleID());
1521
1522            } else {
1523                throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
1524                    "enterprise.deployapi.spi.unexpcommand",
1525                    "Received unexpected deployment facility command ${0}",
1526                    new Object JavaDoc [] {commandType.toString()}
1527                    ));
1528            }
1529            
1530            /*
1531             *The new work instance needs to know about its own progress object, and the
1532             *aggregate progress object needs to also.
1533             */

1534            work.setProgressObject(po);
1535            coll.getProgressObjectSink().sinkProgressObject(po);
1536        }
1537        
1538        /*
1539         *Return the single progress object to return to the caller.
1540         */

1541        return coll.getProgressObjectSink();
1542        
1543      } catch (Throwable JavaDoc thr) {
1544        return prepareErrorProgressObject(commandType, thr);
1545      }
1546    }
1547    
1548    /**
1549     *Prepare a ProgressObject that reflects an error, with a related Throwable cause.
1550     *@param commandType being processed at the time of the error
1551     *@param throwable that occurred
1552     *@return ProgressObject set to FAILED with linked cause reporting full error info
1553     */

1554    private ProgressObject JavaDoc prepareErrorProgressObject (CommandType JavaDoc commandType, Throwable JavaDoc thr) {
1555        DeploymentStatus JavaDoc ds = new DeploymentStatusImplWithError(CommandType.DISTRIBUTE, thr);
1556        SimpleProgressObjectImpl progressObj = new SimpleProgressObjectImpl(ds);
1557        ProgressEvent JavaDoc event = new ProgressEvent JavaDoc(progressObj, null /*targetModuleID */, ds);
1558        progressObj.fireProgressEvent(event);
1559        return progressObj;
1560    }
1561
1562    protected Properties getProperties(String JavaDoc archiveName, String JavaDoc moduleID) {
1563        DeploymentProperties dProps = new DeploymentProperties();
1564        dProps.setArchiveName(archiveName);
1565        dProps.setName(moduleID);
1566        dProps.setEnable(false);
1567        return (Properties)dProps;
1568    }
1569    
1570    /**
1571     *Extract the name part of the path except for any file type at the end, following the "dot" character.
1572     *@param path the path from which the leading path and type are to be excluded
1573     *@return the name with no file type
1574     */

1575    private String JavaDoc pathExcludingType(String JavaDoc path) {
1576        /*
1577         *Use the last part of the path up to but not including the archive type.
1578         */

1579        path = path.substring(path.lastIndexOf('/')+1);
1580        if (path.lastIndexOf('.')!=-1) {
1581            path = path.substring(0, path.lastIndexOf('.'));
1582        }
1583        return path;
1584    }
1585
1586    /**
1587     *Returns the cached DAS connection, creating it if needed.
1588     *This method should be called only if the SunDeploymentManager was instantiated using the
1589     *constructor that provides a target and a principal.
1590     *@return the DAS connection
1591     *@throws IllegalStateException if target and/or principal have not been set
1592     */

1593    private ConnectionSource getDasConnection() {
1594        if (dasConnection == null) {
1595            if (serverId == null) {
1596                throw new IllegalStateException JavaDoc(localStrings.getLocalString(
1597                    "enterprise.deployapi.spi.targetorprinnotset",
1598                    "Attempted to connect to DAS management interface but target and/or principal have not been set"
1599                    ));
1600            }
1601
1602            TLSParams tlsParams = null;
1603            if (serverId.isSecure()) {
1604                X509TrustManager trustManager =
1605                    (X509TrustManager)serverId.getConnectionEnvironment().
1606                    get(DefaultConfiguration.TRUST_MANAGER_PROPERTY_NAME);
1607                tlsParams = new TLSParams(trustManager, null);
1608            }
1609
1610            dasConnection = new AppserverConnectionSource(
1611                AppserverConnectionSource.PROTOCOL_HTTP,
1612                serverId.getHostName(), serverId.getHostPort(),
1613                serverId.getUserName(), serverId.getPassword(),
1614                tlsParams, null);
1615        }
1616        return dasConnection;
1617    }
1618
1619    /**
1620     *Returns the cached root proxy, creating it if needed.
1621     *@return the root proxy
1622     */

1623    private DomainRoot getRootProxy() throws IOException JavaDoc {
1624        if (rootProxy == null) {
1625            rootProxy = getProxyFactory().createDomainRoot();
1626        }
1627        rootProxy.waitAMXReady();
1628        return rootProxy;
1629    }
1630
1631    /**
1632     *Returns the cached domain config proxy for this SDM's domain, creating it if needed.
1633     *@return the proxy to the DomainConfig MBean
1634     */

1635    private DomainConfig getDomainConfigProxy() throws IOException JavaDoc {
1636        if (domainConfigProxy == null) {
1637            domainConfigProxy = getRootProxy().getDomainConfig();
1638        }
1639        return domainConfigProxy;
1640    }
1641
1642    /**
1643     *Returns the cached ProxyFactory, creating one if needed.
1644     *@return the proxy factory
1645     */

1646    private ProxyFactory getProxyFactory() {
1647        if (proxyFactory == null) {
1648            proxyFactory = ProxyFactory.getInstance(getDasConnection());
1649        }
1650        return proxyFactory;
1651    }
1652
1653   /**
1654    * The distribute method performs three tasks; it validates the
1655    * deployment configuration data, generates all container specific
1656    * classes and interfaces, and moves the fully baked archive to
1657    * the designated deployment targets.
1658    *
1659    * @param targetList A list of server targets the user is specifying
1660    * this application be deployed to.
1661    * @param moduleArchive The abstraction for the application
1662    * archive to be disrtibuted.
1663    * @param deploymentPlan The archive containing the deployment
1664    * configuration information associated with
1665    * this application archive.
1666    * @param deploymentOptions is a JavaBeans compliant component
1667    * containing all deployment options for this deployable
1668    * unit. This object must be created using the
1669    * BeanInfo instance returned by
1670    * DeploymentConfiguration.getDeploymentOptions
1671    * @throws IllegalStateException is thrown when the method is
1672    * called when running in disconnected mode.
1673    * @return ProgressObject an object that tracks and reports the
1674    * status of the distribution process.
1675    *
1676    */

1677    public ProgressObject JavaDoc distribute(Target JavaDoc[] targetList,
1678                                     Archive moduleArchive,
1679                                     Archive deploymentPlan,
1680                                     Object JavaDoc deploymentOptions)
1681            throws IllegalStateException JavaDoc {
1682        return null;
1683    }
1684
1685    /**
1686     * Creates a new instance of WritableArchive which can be used to
1687     * store application elements in a layout that can be directly used by
1688     * the application server. Implementation of this method should carefully
1689     * return the appropriate implementation of the interface that suits
1690     * the server needs and provide the fastest deployment time.
1691     * An archive may already exist at the location and elements may be
1692     * read but not changed or added depending on the underlying medium.
1693     * @param path the directory in which to create this archive if local
1694     * storage is a possibility.
1695     * @param name is the desired name for the archive
1696     * @return the writable archive instance
1697     */

1698    public WritableArchive getArchive(URI JavaDoc path, String JavaDoc name)
1699        throws IOException JavaDoc
1700    {
1701        
1702        if (path==null) {
1703            // no particular path was provided, using tmp jar file
1704
File JavaDoc root = File.createTempFile(name,".jar"); //NOI18N
1705
path = root.toURI();
1706        }
1707        ArchiveFactory factory = new ArchiveFactory();
1708        boolean exists = false;
1709        if ((path.getScheme().equals("file")) || //NOI18N
1710
(path.getScheme().equals("jar"))) { //NOI18N
1711

1712            File JavaDoc target = new File JavaDoc(path);
1713            exists = target.exists();
1714        } else {
1715            return null;
1716        }
1717        if (exists) {
1718            return factory.openArchive(path);
1719        } else {
1720            return factory.createArchive(path);
1721        }
1722    }
1723    
1724    /**
1725     *Organizes the target module IDs passed by a JSR88 client for easy processing one module ID
1726     *at a time.
1727     *<p>
1728     *Several methods in the JSR88 DeploymentManager interface accept a list of TargetModuleID values,
1729     *and these lists can refer to multiple module IDs and multiple targets.
1730     *Each invocation of a DeploymentFacility method, on the other hand, can work on only a single module
1731     *although with perhaps multiple targets. This class provides a central way of organizing the
1732     *target module IDs as passed from the JSR88 client and making the information for a single
1733     *module ID readily available.
1734     *<p>
1735     *Typically, a client will use three methods:
1736     *<ul>
1737     *<le>the constructor - pass a TargetModuleID array as supplied by a client
1738     *<le>the iterator() method, which the client uses to step through the DeploymentFacilityModuleWork
1739     *instances, each representing a single module and perhaps multiple targets.
1740     *<le>the getProgressObjectSink which returns the aggregator for the ProgressObjects
1741     *from each work element
1742     *</ul>
1743     */

1744    protected class TargetModuleIDCollection {
1745        /* Maps the module ID to that module's instance of DeploymentFacilityModuleWork. */
1746        private HashMap JavaDoc moduleIDToInfoMap = new HashMap JavaDoc();
1747        
1748        /* Collects together the individual progress objects into a single aggregate one. */
1749        ProgressObjectSink progressObjectSink = null;
1750        
1751        /**
1752         *Create a new instance of TargetModuleIDCollection.
1753         *Accept the array of targetModuleIDs as passed by the JSR88 client and set up the
1754         *internal data structures.
1755         *@param targetModuleIDs array of {@link javax.deployment.api.TargetModuleID TargetModuleID} provided from the calling JSR88 client
1756         */

1757        public TargetModuleIDCollection(TargetModuleID JavaDoc [] targetModuleIDs) throws IllegalArgumentException JavaDoc {
1758
1759            for (int i = 0; i < targetModuleIDs.length; i++) {
1760                /*
1761                 *Make sure that this target module ID has a target that is a SunTarget and was created by this DM.
1762                 */

1763                Target JavaDoc candidateTarget = targetModuleIDs[i].getTarget();
1764                if ( ! (candidateTarget instanceof SunTarget)) {
1765                    throw new IllegalArgumentException JavaDoc(
1766                    localStrings.getLocalString("enterprise.deployapi.spi.notSunTarget", //NOI18N
1767
"Expected SunTarget instance but found instance of {0}", new Object JavaDoc[] {candidateTarget.getClass().getName() } )); //NOI18N
1768
}
1769                SunTarget candidateSunTarget = (SunTarget) candidateTarget;
1770                String JavaDoc moduleID = targetModuleIDs[i].getModuleID();
1771                
1772                /*
1773                 *Look for the entry in the hash map for this module.
1774                 */

1775                DeploymentFacilityModuleWork work = (DeploymentFacilityModuleWork) moduleIDToInfoMap.get(moduleID);
1776                if (work == null) {
1777                    /*
1778                     *This module ID is not yet in the map. Add a work instance for it with the module ID as the key.
1779                     */

1780                    work = new DeploymentFacilityModuleWork(moduleID);
1781                    moduleIDToInfoMap.put(moduleID, work);
1782                }
1783                /*
1784                 *Either the entry already exists or one has been created.
1785                 *In either case, add the target to the work to be done with this module.
1786                 */

1787                work.addTarget(candidateTarget);
1788            }
1789        }
1790        
1791        /**
1792         *Provides an Iterator over the module work items in the collection.
1793         *The iterator provides one element for each distinct module that appeared in the original
1794         *array of TargetModuleIDs.
1795         *
1796         *@return Iterator over the DeploymentFacilityModuleWork elements in the collection
1797         */

1798        public Iterator JavaDoc iterator() {
1799            return moduleIDToInfoMap.values().iterator();
1800        }
1801
1802        /**
1803         *Reports the number of elements in the collection.
1804         *This is also a measure of the number of distinct module IDs specified in the TargetModuleID array
1805         *passed to the constructor of the collection.
1806         *@return the number of DeploymentFacilityModuleWork elements contained in the collection
1807         */

1808        public int size() {
1809            return moduleIDToInfoMap.size();
1810        }
1811        
1812        /**
1813         *Returns the aggregate progress object for the collection.
1814         *Creates a new ProgressObjectSink if needed.
1815         *@return ProgressObjectSink
1816         */

1817        public ProgressObjectSink getProgressObjectSink() {
1818            if (progressObjectSink == null) {
1819                progressObjectSink = new ProgressObjectSink();
1820            }
1821            return progressObjectSink;
1822        }
1823    }
1824    
1825    /**
1826     *Encapsulates information used with a single invocation of a DeploymentFacility method--
1827     *that is, one item of "work" the DeploymentFacility is being asked to perform.
1828     *This includes the single target ID of interest (because the DF methods operate on a
1829     *single module), a collection of all the targets to be included in the operation on that
1830     *module, and the progress object resulting from the DF method invocation.
1831     */

1832    protected class DeploymentFacilityModuleWork {
1833        
1834        /** The module ID this work handles */
1835        private String JavaDoc moduleID = null;
1836        
1837        /** The targets this work should affect. */
1838        private Collection JavaDoc targets = new Vector JavaDoc();
1839        
1840        /** The ProgressObject for this work returned by the DeploymentFacility method invocation. */
1841        private ProgressObject JavaDoc progressObject = null;
1842        
1843        /**
1844         *Creates a new instance of DeploymentFacilityModuleWork.
1845         *@param the module ID common to all work recorded in this instance
1846         */

1847        public DeploymentFacilityModuleWork(String JavaDoc moduleID) {
1848            this.moduleID = moduleID;
1849        }
1850        
1851        /**
1852         *Adds a target to the collection of targets for the work to be done for this distinct module.
1853         *@param the {@link javax.enterprise.deploy.spi.Target Target} to be added for this module
1854         */

1855        public void addTarget(Target JavaDoc target) {
1856            if ( ! (target instanceof SunTarget) ) {
1857                throw new IllegalArgumentException JavaDoc(localStrings.getLocalString(
1858                    "enterprise.deployapi.spi.unexptargettyp",
1859                    "Target must be of type SunTarget but encountered {0}",
1860                    new Object JavaDoc [] {target.getClass().getName()}
1861                ));
1862            }
1863            targets.add(target);
1864        }
1865        
1866        /**
1867         *Returns an array of {@link javax.enterprise.deploy.spi.Target Target} instances recorded for
1868         *this module. Note the return of an array of runtime type SunTarget[].
1869         *@return array of Target
1870         */

1871        public Target JavaDoc [] targets() {
1872            return (Target JavaDoc []) targets.toArray(new SunTarget[] {});
1873        }
1874        
1875        /**
1876         *Returns the {@link javax.enterprise.deploy.spi.status.ProgressObject ProgressObject} that the
1877         *DeploymentFacility method returned when it was invoked.
1878         *@return the ProgressObject
1879         */

1880        public ProgressObject JavaDoc getProgressObject() {
1881            return this.progressObject;
1882        }
1883        
1884        /**
1885         *Records the {@link javax.enterprise.deploy.spi.status.ProgressObject ProgressObject} that the
1886         *DeploymentFacility returned when its method was invoked.
1887         *@param the ProgressObject provided by the DeploymentFacility
1888         *method
1889         */

1890        public void setProgressObject (ProgressObject JavaDoc progressObject) {
1891            this.progressObject = progressObject;
1892        }
1893        
1894        /**
1895         *Reports the module ID for this instance of DeploymentFacilityModuleWork
1896         *@return the module ID
1897         */

1898        public String JavaDoc getModuleID() {
1899            return this.moduleID;
1900        }
1901    }
1902
1903    /**
1904     *Convert a file spec into a jar URI.
1905     *This creates a URI acceptable to the rest of the processing. Using File.toURI alone omits the
1906     *authority from the result which causes problems later on. Plus, the scheme needs to be jar
1907     *for archive files; otherwise a URI with "file:" triggers deployment directory behavior.
1908     *@param filePath to be converted into a URI
1909     *@return URI with scheme=jar for the file
1910     */

1911    private URI JavaDoc toJarURI(File JavaDoc archiveFile) throws URISyntaxException JavaDoc {
1912        URI JavaDoc archiveFileURI = archiveFile.toURI();
1913        URI JavaDoc answer = new URI JavaDoc("jar", "" /* authority */, archiveFileURI.getSchemeSpecificPart(), null, null); //NOI18N
1914
return answer;
1915    }
1916
1917    /**
1918     *Return a reference to a connected DeploymentFacility object. Instantiates and connects
1919     *one if needed.
1920     *@return DeploymentFacility
1921     */

1922    private DeploymentFacility getDeploymentFacility() {
1923        if (this.deploymentFacility == null) {
1924            this.deploymentFacility = DeploymentFacilityFactory.getDeploymentFacility();
1925            this.deploymentFacility.connect(serverId);
1926        }
1927        return this.deploymentFacility;
1928    }
1929
1930    /**
1931     *Append child TargetModuleIDs to the J2EE module's TargetModuleID, navigating MBeans to do so.
1932     *<p>
1933     *Note that the result of this method is to add child IDs to the sunTargetModuleID. There is
1934     *no return value.
1935     *@param sunTargetModuleID the TMID of the J2EE app to which child entries should be appended
1936     *@param moduleID the module ID for which child entries are of interest
1937     *
1938     */

1939    private void addChildTargetModuleIDsToJ2EEUsingMBeans(SunTargetModuleID sunTargetModuleID, String JavaDoc moduleID, HostAndPort hostAndPort) {
1940        SunTarget sunTarget = (SunTarget) sunTargetModuleID.getTarget();
1941        try {
1942            MBeanServerConnection JavaDoc mbsc = getMBeanServerConnection();
1943            /*
1944             *Use the MBean to retrieve the ObjectNames of all children of this module on this target.
1945             */

1946            ObjectName JavaDoc query = new ObjectName JavaDoc("com.sun.appserv:category=runtime,name=" + moduleID + ",J2EEServer=" + sunTarget.getAppServerInstance() + ",*");
1947            Set JavaDoc mbeans = mbsc.queryNames(query, null);
1948            
1949            /*
1950             *Work through the child ObjectNames, adding appropriately-constructed SunTargetModuleIDs
1951             *as children of the SunTargetModuleID of the parent J2EE module.
1952             */

1953            for (Iterator JavaDoc itr = mbeans.iterator();itr.hasNext();) {
1954
1955                ObjectName JavaDoc module = (ObjectName JavaDoc) itr.next();
1956
1957                /*
1958                 *Retrieve the list of child module names of the module's ObjectName.
1959                 */

1960                String JavaDoc subModules[] = (String JavaDoc[]) mbsc.getAttribute(module, "modules");
1961                for (int i = 0; i < subModules.length; i++) {
1962                    Set JavaDoc subModuleObjectNames = mbsc.queryNames(new ObjectName JavaDoc(subModules[i]), null);
1963                    if (subModuleObjectNames != null) {
1964                        /*
1965                         *The MBean returned some children, so iterate through them and prepare a sub TMID.
1966                         */

1967                        for (Iterator JavaDoc subItr = subModuleObjectNames.iterator(); subItr.hasNext(); ) {
1968                            ObjectName JavaDoc aSubModule = (ObjectName JavaDoc) subItr.next();
1969                            SunTargetModuleID childTmid;
1970                            String JavaDoc aSubModuleName = aSubModule.toString();
1971                            if (aSubModuleName.indexOf("WebModule")!=-1) {
1972                                String JavaDoc id = (String JavaDoc) mbsc.getAttribute(aSubModule, "iD");
1973                                String JavaDoc path = (String JavaDoc) mbsc.getAttribute(aSubModule, "path");
1974                                childTmid = prepareWebChildTargetModuleID(id, sunTarget, hostAndPort, path);
1975                            } else {
1976                                String JavaDoc name = (String JavaDoc) mbsc.getAttribute(aSubModule, "name");
1977                                ModuleType JavaDoc moduleType = deriveModuleTypeFromModuleName(aSubModuleName);
1978                                childTmid = prepareNonWebChildTargetModuleID(moduleID, sunTarget, name, moduleType);
1979                            }
1980                            
1981                            sunTargetModuleID.addChildTargetModuleID(childTmid);
1982                            childTmid.setParentTargetModuleID(sunTargetModuleID);
1983                        }
1984                    }
1985                }
1986            }
1987        }
1988        catch(Exception JavaDoc exp){
1989            Print.dprintStackTrace(exp.getLocalizedMessage(), exp);
1990            Print.dprint("***Exception occured while "+
1991            "accessing mbean details: Keep continuing\n");
1992        }
1993    }
1994
1995    private SunTargetModuleID prepareWebChildTargetModuleID(String JavaDoc id, SunTarget sunTarget, HostAndPort hostAndPort, String JavaDoc path) throws MalformedURLException JavaDoc {
1996        id = id.replace(':','#');
1997        SunTargetModuleID childTmid = new SunTargetModuleID(id, sunTarget);
1998        
1999        // Patchup code for fixing netbeans issue 6221411; Need to find a good solution for this and WSDL publishing
2000
String JavaDoc host;
2001        if(isPE()) {
2002            host = childTmid.getConnectionInfo().getHostName();
2003        } else {
2004            host = hostAndPort.getHost();
2005        }
2006
2007        // get the web url
2008
URL JavaDoc webURL = new URL JavaDoc("http", host, hostAndPort.getPort(), path);
2009        childTmid.setWebURL(webURL.toExternalForm());
2010        childTmid.setModuleType(ModuleType.WAR);
2011        return childTmid;
2012    }
2013
2014    private SunTargetModuleID prepareNonWebChildTargetModuleID(String JavaDoc id, SunTarget sunTarget, String JavaDoc subModuleName, ModuleType JavaDoc moduleType) {
2015        String JavaDoc moduleID = id + "#" + subModuleName;
2016        SunTargetModuleID childTmid = new SunTargetModuleID(moduleID, sunTarget);
2017        childTmid.setModuleType(moduleType);
2018        return childTmid;
2019    }
2020    
2021    private ModuleType JavaDoc deriveModuleTypeFromModuleName(String JavaDoc moduleName) {
2022        ModuleType JavaDoc moduleType = null;
2023        if (moduleName.indexOf("EJBModule")!=-1) {
2024            moduleType = ModuleType.EJB;
2025        } else if (moduleName.indexOf("AppClientModule")!=-1) {
2026            moduleType = ModuleType.CAR;
2027        } else {
2028            moduleType = ModuleType.RAR;
2029        }
2030        return moduleType;
2031    }
2032
2033    /**
2034     *Identifies the DAS to which the DeploymentManager is connected as a PE (as opposed to SE/EE) one.
2035     *@return boolean indicating whether the DAS is a PE DAS
2036     */

2037    public boolean isPE() {
2038        boolean result;
2039        try {
2040            result = applicationsConfigMBeanIsPE();
2041            return result;
2042        } catch (Throwable JavaDoc thr) {
2043            throw new RuntimeException JavaDoc(localStrings.getLocalString(
2044                        "enterprise.deployapi.spi.errcheckingtype",
2045                        "Error checking type of DAS"), thr); //NOI18N
2046
}
2047    }
2048
2049    private boolean applicationsConfigMBeanIsPE() throws
2050                    javax.management.MalformedObjectNameException JavaDoc,
2051                    javax.management.InstanceNotFoundException JavaDoc,
2052                    javax.management.IntrospectionException JavaDoc,
2053                    javax.management.ReflectionException JavaDoc,
2054                    IOException JavaDoc {
2055        boolean result;
2056        MBeanServerConnection JavaDoc mbsc = getMBeanServerConnection();
2057        ObjectName JavaDoc applicationsMBean = new ObjectName JavaDoc(applicationsMBeanName);
2058        MBeanInfo JavaDoc info = mbsc.getMBeanInfo(applicationsMBean);
2059        String JavaDoc className = info.getClassName();
2060        result = ! className.endsWith(EE_APPLICATIONS_CONFIG_MBEAN_SUFFIX);
2061        return result;
2062    }
2063
2064    private ModuleType JavaDoc getModuleTypeFor(String JavaDoc moduleID) throws Exception JavaDoc {
2065        MBeanServerConnection JavaDoc mbsc = getMBeanServerConnection();
2066        ObjectName JavaDoc applicationsMBean = new ObjectName JavaDoc(applicationsMBeanName);
2067        String JavaDoc[] signature = new String JavaDoc[] {"java.lang.String"};
2068        Object JavaDoc[] params = new Object JavaDoc[] {moduleID};
2069        Integer JavaDoc result = (Integer JavaDoc)
2070            mbsc.invoke(applicationsMBean, "getModuleType", params, signature);
2071        if (result == null) {
2072            String JavaDoc msg = localStrings.getLocalString(
2073                "enterprise.deployapi.spi.redeploy.modulenotfound",
2074                "Module " + moduleID + " not found");
2075            throw new IllegalArgumentException JavaDoc(msg);
2076        }
2077        return ModuleType.getModuleType(result.intValue());
2078    }
2079
2080    private static final String JavaDoc EE_APPLICATIONS_CONFIG_MBEAN_SUFFIX = ".EEApplicationsConfigMBean";
2081}
2082
Popular Tags