KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > appclient > jws > AppclientJWSSupportInfo


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.appclient.jws;
25
26 import com.sun.enterprise.appclient.AppClientInfo;
27 import com.sun.enterprise.appclient.Main;
28 import com.sun.enterprise.appclient.MainWithModuleSupport;
29 import com.sun.enterprise.config.ConfigException;
30 import com.sun.enterprise.deployment.Application;
31 import com.sun.enterprise.deployment.ApplicationClientDescriptor;
32 import com.sun.enterprise.deployment.Descriptor;
33 import com.sun.enterprise.deployment.deploy.shared.AbstractArchive;
34 import com.sun.enterprise.deployment.deploy.shared.ArchiveFactory;
35 import com.sun.enterprise.deployment.interfaces.DeploymentImplConstants;
36 import com.sun.enterprise.deployment.runtime.JavaWebStartAccessDescriptor;
37 import com.sun.enterprise.deployment.util.ModuleDescriptor;
38 import com.sun.enterprise.instance.AppclientModulesManager;
39 import com.sun.enterprise.instance.AppsManager;
40 import com.sun.enterprise.instance.BaseManager;
41 import com.sun.enterprise.instance.InstanceEnvironment;
42 import com.sun.enterprise.loader.EJBClassPathUtils;
43 import com.sun.enterprise.server.ApplicationServer;
44 import com.sun.enterprise.server.ServerContext;
45 import com.sun.enterprise.util.ExecException;
46 import com.sun.enterprise.util.ORBManager;
47 import com.sun.enterprise.util.ProcessExecutor;
48 import com.sun.enterprise.util.SystemPropertyConstants;
49 import com.sun.enterprise.util.io.FileUtils;
50 import com.sun.enterprise.util.i18n.StringManager;
51 import com.sun.enterprise.util.net.NetUtils;
52 import com.sun.enterprise.web.WebContainer;
53 import com.sun.logging.LogDomains;
54 import java.io.BufferedReader JavaDoc;
55 import java.io.File JavaDoc;
56 import java.io.FileInputStream JavaDoc;
57 import java.io.FileNotFoundException JavaDoc;
58 import java.io.IOException JavaDoc;
59 import java.io.InputStream JavaDoc;
60 import java.io.InputStreamReader JavaDoc;
61 import java.net.URI JavaDoc;
62 import java.net.URISyntaxException JavaDoc;
63 import java.util.Collections JavaDoc;
64 import java.util.Date JavaDoc;
65 import java.util.Enumeration JavaDoc;
66 import java.util.HashMap JavaDoc;
67 import java.util.List JavaDoc;
68 import java.util.Map JavaDoc;
69 import java.util.Properties JavaDoc;
70 import java.util.Set JavaDoc;
71 import java.util.Vector JavaDoc;
72 import java.util.jar.Attributes JavaDoc;
73 import java.util.jar.JarEntry JavaDoc;
74 import java.util.jar.JarFile JavaDoc;
75 import java.util.jar.Manifest JavaDoc;
76 import java.util.logging.Level JavaDoc;
77 import java.util.logging.Logger JavaDoc;
78 import java.util.regex.Matcher JavaDoc;
79 import java.util.regex.Pattern JavaDoc;
80 import javax.enterprise.deploy.shared.ModuleType JavaDoc;
81 import javax.servlet.http.HttpServletRequest JavaDoc;
82 import org.xml.sax.SAXParseException JavaDoc;
83
84 import org.omg.CORBA.ORB JavaDoc;
85 import com.sun.corba.ee.spi.folb.ClusterInstanceInfo;
86 import com.sun.corba.ee.spi.folb.GroupInfoService;
87 import com.sun.corba.ee.spi.folb.SocketInfo;
88 import com.sun.corba.ee.impl.orbutil.ORBConstants;
89 import org.omg.CORBA.ORBPackage.InvalidName JavaDoc;
90
91 /**
92  *Records and provides access to information about app clients that need
93  *Java Web Start support.
94  *<p>
95  *The basic purpose of this class is to map between the "virtual" location of
96  *files as will be specified by incoming HTTP requests and the content to be returned
97  *as the responses to those requests. The
98  *content itself can be dynamic (created based on information about the
99  *particular app client or the particular HTTP request) or static (a file
100  *that resides somewhere in the file system).
101  *<p>
102  *This information is updated as modules are loaded and unloaded in the
103  *server instance and as the administrator enables or disables modules
104  *for Java Web Start access to their app clients. The information is used
105  *by the system web application that responds to Java Web Start's requests
106  *for content related to the app clients.
107  *<p>
108  *This class is a singleton.
109  *
110  * @author tjquinn
111  */

112 public class AppclientJWSSupportInfo {
113
114     /** MIME types for dynamic documents */
115     private static final String JavaDoc JNLP_MIME_TYPE = "application/x-java-jnlp-file";
116     private static final String JavaDoc HTML_MIME_TYPE = "text/html";
117     private static final String JavaDoc XML_MIME_TYPE = "application/xml";
118
119     /** the singleton instance for this class */
120     private static AppclientJWSSupportInfo instance = null;
121
122     /**
123      * pattern string describing the format of the pathInfo of incoming requests;
124      * includes capture of useful portions as separate groups
125      *
126      *The format is: <category>/<subcategory>/<rest-of-path>
127      *
128      *where category must be appclient, application, or appserver. The
129      *exact meaning of the subcategory can vary, depending on the category.
130      *The /<rest-of-path> part can be empty, and will be for requests for
131      *the main JNLP document.
132      *
133      *If the pattern is changed, then the int definitions just below may also
134      *need to be changed to reflect the correct positions in the pattern.
135      */

136     private static final String JavaDoc REQUEST_PATH_INFO_PATTERN = "/(" +
137             NamingConventions.APPCLIENT_CATEGORY + "|" +
138             NamingConventions.APPLICATION_CATEGORY + "|" +
139             NamingConventions.APPSERVER_CATEGORY + "|" +
140             ")/(.*?)(?:/(.*(?:$|\\z)))?";
141     
142     /*
143      *These group numbers are used in retrieving "captured" parts of matched
144      *strings.
145      */

146     private static final int PATTERN_CATEGORY_GROUP_NUMBER = 1;
147     private static final int PATTERN_REGNAME_GROUP_NUMBER = 2;
148     private static final int PATTERN_RELATIVEPATH_GROUP_NUMBER = 3;
149     
150     /** pattern used for processing incoming request pathInfo strings */
151     private static final Pattern JavaDoc requestPathInfoPattern = Pattern.compile(REQUEST_PATH_INFO_PATTERN);
152     
153     /*
154      *Property settable on the server side to retain temp files on the client.
155      *Use the same property name on both sides for clarity.
156      */

157     private static final String JavaDoc SERVER_RETAIN_TEMP_FILES_PROPERTYNAME = MainWithModuleSupport.APPCLIENT_RETAIN_TEMP_FILES_PROPERTYNAME;
158     
159     /*
160      * Defines the type prefix that indicates a IIOP socket info object that should
161      * NOT be included in the list of IIOP endpoints sent to the client for
162      * failover. Eventually the IIOP classes may provide this constant in
163      * one place.
164      */

165     private static final String JavaDoc IIOP_ENDPOINT_TYPE_PREFIX_IGNORE = "SSL";
166     
167     /** Property name used to create request for elevated permissions in the JNLP document */
168     private static final String JavaDoc APPCLIENT_JAR_SECURITY_ELEMENT_PROPERTYNAME = "appclient.jar.security.setting";
169     
170     /** local strings manager */
171     private StringManager localStrings = StringManager.getManager(getClass());
172     
173     /*
174      *Two key concepts in the implementation are "content" - information that
175      *must be served back to Java Web Start on the requesting client - and
176      *"origin" of content - such as an app client, an application, or one of
177      *several groupings of content from the app server itself.
178      *
179      *The following Maps relate each app client registration name, J2EE app reg. name,
180      *and app server content grouping (lib, imq, etc.) to the corresponding "origin" of
181      *the content. In particular, by keeping separate collections for the signed
182      *vs. unsigned appserver origins, it is easier to create the two JNLP documents
183      *that list the files. Each list of files must appear in a separate JNLP
184      *document so each file can have different security settings.
185      */

186     
187     private Map JavaDoc<String JavaDoc,ContentOrigin> appclients;
188     private Map JavaDoc<String JavaDoc,ContentOrigin> applications;
189     private Map JavaDoc<String JavaDoc,ContentOrigin> appserverOrigins;
190     private Map JavaDoc<String JavaDoc,ContentOrigin> signedAppserverOrigins;
191     private Map JavaDoc<String JavaDoc,ContentOrigin> extJarAppserverOrigins;
192     
193     /*
194      *The following map relates strings representing pathInfo values to the
195      *corresponding Content. All content available from the Java Web Start
196      *system servlet is entered in this map.
197      */

198     private Map JavaDoc<String JavaDoc,Content> contentMap;
199     
200
201     /** maps the category name to the particular map of key to content */
202     private Map JavaDoc<String JavaDoc,Map JavaDoc<String JavaDoc,ContentOrigin>> originTypes;
203     
204     /*
205      *Several app server-provided objects are used for looking up apps,
206      *app clients, and getting information about the server.
207      */

208     /** the app server instance server context */
209     protected ServerContext appServerContext;
210     
211     /** the app server instance environment */
212     protected InstanceEnvironment instEnv;
213     
214     /** the instance's J2EE applications manager */
215     protected AppsManager appsManager;
216     
217     /** the instance's app client modules manager */
218     protected AppclientModulesManager appclientModulesManager;
219     
220     private static final String JavaDoc lineSep = System.getProperty("line.separator");
221
222     private Logger JavaDoc _logger=LogDomains.getLogger(NamingConventions.JWS_LOGGER);
223     
224     /** Cache for the templates, bundled and retrieved from the jar file that contains this class. */
225     private TemplateCache templateCache;
226     
227     /** URI to the app server's installation root directory */
228     private URI JavaDoc installRootURI;
229     
230     /** File pointing to the app server's root directory */
231     private File JavaDoc installRootDir;
232     
233     /** File pointing to the app server's installed lib directory */
234     private File JavaDoc libRoot;
235     
236     /** File pointing to the temporary app client jar directory */
237     private File JavaDoc tempJarDirectory;
238     
239     /** File pointing to the instance's j2ee-modules directory */
240     private File JavaDoc j2eeModulesDir;
241     
242     /** File pointing to the instance's j2ee-apps directory */
243     private File JavaDoc j2eeApplicationsDir;
244
245     /** manages extension jar files */
246     private ExtensionFileManager extensionFileManager;
247
248     private String JavaDoc UNSIGNED_JWSACC_JARFILE_NAME = "appserv-jwsacc.jar";
249
250     private String JavaDoc SIGNED_JWSACC_JARFILE_NAME = "appserv-jwsacc-signed.jar";
251     
252     /**
253      *Returns the single instance of the class.
254      *@return the singleton AppclientJWSSupportInfo
255      */

256     public static AppclientJWSSupportInfo getInstance() throws IOException JavaDoc, Exception JavaDoc {
257         if (instance == null) {
258             instance = new AppclientJWSSupportInfo();
259             
260             /*
261              *Make sure the manager is instantiated so it can register for
262              *events. No reference to the object needs to be kept here;
263              *just make sure the manager has been set up.
264              */

265              AppclientJWSSupportManager.getInstance();
266         }
267         return instance;
268     }
269
270     /**
271      *Creates a new instance of AppclientJWSSupportInfo.
272      *The constructor is private to prevent other objects from creating a new
273      *instance except through getInstance().
274      */

275     private AppclientJWSSupportInfo() throws IOException JavaDoc, Exception JavaDoc {
276         
277         extensionFileManager = new ExtensionFileManager();
278         
279         /*
280          *Create the collections of content origins (such as the app server itself,
281          *app clients, and applications that contain embedded app clients.
282          */

283         appclients = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc,ContentOrigin>());
284         applications = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc,ContentOrigin>());
285         appserverOrigins = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc,ContentOrigin>());
286         signedAppserverOrigins = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc,ContentOrigin>());
287         extJarAppserverOrigins = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc,ContentOrigin>());
288         
289         contentMap = Collections.synchronizedMap(new HashMap JavaDoc<String JavaDoc,Content>());
290         
291         /*
292          *Add these maps to the map of maps (!).
293          */

294         originTypes = new HashMap JavaDoc<String JavaDoc,Map JavaDoc<String JavaDoc,ContentOrigin>>();
295         originTypes.put(NamingConventions.APPCLIENT_CATEGORY, appclients);
296         originTypes.put(NamingConventions.APPLICATION_CATEGORY, applications);
297         originTypes.put(NamingConventions.APPSERVER_CATEGORY, appserverOrigins);
298         originTypes.put(NamingConventions.APPSERVER_CATEGORY, signedAppserverOrigins);
299         originTypes.put(NamingConventions.APPSERVER_EXTJAR_FILES, extJarAppserverOrigins);
300         
301         /*
302          *Get references to useful app server objects.
303          */

304         findAppServerObjects();
305
306         /*
307          *On Windows, the user may have entered the installation path with
308          *different case compared to how the directories are actually spelled.
309          *(For example, the directory might be on the disk as MyDir but the
310          *user could have entered mydir.) Windows is okay with this, but
311          *a File object using mydir will yield a different URI than one
312          *with MyDir. Using the canonical path for the installation directory
313          *makes sure the installRootURI is formatted consistently with the
314          *ones for which we construct relative paths later on.
315          */

316         String JavaDoc installRootDirSpec = System.getProperty("com.sun.aas.installRoot");
317         installRootDir = new File JavaDoc(installRootDirSpec).getCanonicalFile();
318         installRootURI = installRootDir.toURI();
319         
320         /*
321          *Create the template cache.
322          */

323         templateCache = new TemplateCache();
324         
325         /*
326          *Set up the File objects for the app server's lib directory. It is
327          *used in setting up the content objects for the app server jars served
328          *back to the client.
329          */

330         String JavaDoc instanceRootDirSpec = instEnv.getInstancesRoot();
331         File JavaDoc instanceRootDir = new File JavaDoc(instanceRootDirSpec);
332         libRoot = new File JavaDoc(installRootDir, "lib");
333
334         /*
335          *Load the map with app server-provided files. Do this now, because these
336          *are the same for all applications or app clients.
337          */

338         preloadAppserverContent();
339     }
340     
341     /**
342      *Starts Java Web Start services for a stand-alone app client module.
343      *
344      *@param the Application object for this app client
345      *@param the ModuleDescriptor for the app client
346      */

347     public void startJWSServicesForAppclient(Application application, ModuleDescriptor moduleDescr)
348         throws IOException JavaDoc, URISyntaxException JavaDoc, ConfigException, SAXParseException JavaDoc, ConfigException, Exception JavaDoc {
349         String JavaDoc regName = application.getRegistrationName();
350         
351         if ( ! appclientModulesManager.isRegistered(regName)) {
352             findAppServerObjects();
353             if ( ! appclientModulesManager.isRegistered(regName)) {
354                 throw new ConfigException("Cannot locate config information for app client " + regName);
355             }
356         }
357
358         /*
359          *Make sure we don't already have services going for this app client.
360          */

361         String JavaDoc appclientMapKey = NamingConventions.TopLevelAppclient.actualContextRoot(application);
362         AppclientContentOrigin origin = findAppclient(appclientMapKey);
363         
364         if (origin != null) {
365             _logger.warning("Attempted to start Java Web Start services for stand-alone app client " + regName + " when they were already started; ignoring the duplicate request");
366             return;
367         }
368
369         _logger.fine("Starting Java Web Start services for stand-alone app client " + application.getRegistrationName());
370         
371         /*
372          *There is no pre-existing origin for this app client, so create one and
373          *start Java Web Start services for it.
374          */

375         origin = prepareTopLevelAppclient(application, moduleDescr);
376         if (origin != null) {
377             startJWSServices(origin);
378
379             appclients.put(appclientMapKey, origin);
380
381             String JavaDoc logOutput = (_logger.isLoggable(Level.FINE) ? origin.toLongString() : origin.toString());
382             _logger.info("Java Web Start services started for stand-alone app client " + logOutput);
383         }
384     }
385     
386     /**
387      *Ends Java Web Start support for a stand-alone app client that is being
388      *unloaded from the server.
389      *
390      *@param the application for the app client
391      *@param the module descriptor for the app client
392      */

393     public void endJWSServicesForAppclient(Application application, ModuleDescriptor moduleDescr) {
394         _logger.fine("Ending Java Web Start services for stand-alone app client " + application.getRegistrationName());
395         
396         String JavaDoc appclientMapKey = NamingConventions.TopLevelAppclient.actualContextRoot(application);
397         AppclientContentOrigin origin = findAppclient(appclientMapKey);
398         if (origin != null) {
399             endJWSServices(origin);
400             appclients.remove(appclientMapKey);
401
402             _logger.info("Java Web Start services ended for stand-alone app client " + origin);
403         }
404     }
405     
406     /**
407      *Starts Java Web Start services for an application that contains nested
408      *app clients which need Java Web Start support.
409      *@param the application's registration ID
410      *@param the module descriptors for child app clients eligible for Java Web Start access
411      *@exception IOException during any retrieval of template for dynamic content
412      */

413     public void startJWSServicesForApplication(Application application, ModuleDescriptor [] moduleDescriptors)
414             throws IOException JavaDoc, URISyntaxException JavaDoc, SAXParseException JavaDoc, ConfigException, Exception JavaDoc {
415         String JavaDoc applicationMapKey = NamingConventions.TopLevelApplication.contextRoot(application);
416         String JavaDoc regName = application.getRegistrationName();
417         if ( ! appsManager.isRegistered(regName)) {
418             findAppServerObjects();
419             if ( ! appsManager.isRegistered(regName)) {
420                 throw new ConfigException("Cannot locate config information for application " + regName);
421             }
422         }
423         _logger.fine("Starting Java Web Start services for application " + regName);
424
425         /*
426          *Make sure we don't have services running already for this application.
427          */

428         ApplicationContentOrigin origin = findApplication(applicationMapKey);
429         if (origin != null) {
430             _logger.warning("Attempt to start Java Web Start services for application " + regName + " when they were already started; ignoring the duplicate request");
431             return;
432         }
433         
434         /*
435          *Preparing the application also includes preparing its child
436          *app clients, which is the real goal.
437          */

438         origin = prepareApplication(application, moduleDescriptors);
439
440         startJWSServices(origin);
441
442         /*
443          *Add the origin to the collection.
444          */

445         applications.put(applicationMapKey, origin);
446
447         String JavaDoc logOutput = (_logger.isLoggable(Level.FINE) ? origin.toLongString() : origin.toString());
448         _logger.info("Java Web Start services started for application " + logOutput);
449     }
450     
451     /**
452      *Ends Java Web Start services for an application that may contain embedded app clients.
453      *
454      *@param the application object for the application
455      *@param the module descriptor for the application
456      */

457      public void endJWSServicesForApplication(Application application, ModuleDescriptor[] moduleDescrs) {
458          String JavaDoc applicationMapKey = NamingConventions.TopLevelApplication.contextRoot(application);
459          ApplicationContentOrigin origin = findApplication(applicationMapKey);
460          if (origin != null) {
461              _logger.fine("Ending Java Web Start services for application " + origin.getTopLevelRegistrationName());
462              endJWSServices(origin);
463              _logger.info("Java Web Start services ended for application: " + origin);
464
465              /*
466               *Finally, remove the application's origin from the collection.
467               */

468              applications.remove(applicationMapKey);
469          }
470      }
471
472       /**
473       *Returns whether the specified origin is currently enabled for Java Web
474       *Start access or not.
475       *@param origin the UserContentOrigin to check
476       *@return boolean indicating whether the app client origin is enabled for JWS access
477       */

478       public boolean isEnabled(UserContentOrigin origin){
479           boolean result = false;
480           String JavaDoc regName = origin.getApplication().getRegistrationName();
481           try {
482               if (origin instanceof ApplicationContentOrigin) {
483                   result = appsManager.isJavaWebStartEnabled(regName);
484               } else {
485                   result = appclientModulesManager.isJavaWebStartEnabled(regName);
486               }
487               return result;
488           } catch (ConfigException ce) {
489               _logger.log(Level.SEVERE, "Error checking if Java Web Start access enabled for app client " + origin.getApplication().getRegistrationName(), ce);
490               return false;
491           }
492       }
493        
494       /**
495       *Returns whether the specified origin is currently enabled for Java Web
496       *Start access or not.
497       *@param origin the ApplicationContentOrigin to check
498       *@return boolean indicating whether the app client origin is enabled for JWS access
499       */

500       public boolean isEnabled(ApplicationContentOrigin origin) {
501           try {
502              return appsManager.isJavaWebStartEnabled(origin.getApplication().getRegistrationName());
503           } catch (ConfigException ce) {
504               _logger.log(Level.SEVERE, "Error checking if Java Web Start access enabled for application " + origin.getApplication().getRegistrationName(), ce);
505               return false;
506           }
507       }
508     /**
509      *Returns the Content object corresponding to the path info in the HTTP
510      *request.
511      *@param the HTTP request asking for the content
512      *@return Content object representing the desired content; returns null if no
513      *content matches the HTTP request's information
514      */

515     public Content getContent(HttpServletRequest JavaDoc request) {
516         
517         String JavaDoc pathInfo = request.getPathInfo();
518         
519         /*
520          *Adjust the request's pathInfo - for instance, this removes the
521          *context-root of the web app if the web app is nested inside an ear.
522          */

523         String JavaDoc contentKey = NamingConventions.pathToContentKey(pathInfo);
524
525         /*
526          *Even though each origin tracks its own content as well, the single
527          *contentMap allows a single look-up to find any content, regardless
528          *of its origin.
529          */

530         Content result = contentMap.get(contentKey);
531
532         /*
533          *Make sure the origin for this content is currently enabled for Java
534          *Web Start access.
535          */

536          if (result != null) {
537              ContentOrigin origin = result.getOrigin();
538              if ( ! origin.isEnabled()) {
539                  if (_logger.isLoggable(Level.FINE)) {
540                      _logger.fine("Located requested document with content key " + contentKey + " but reporting 'not found' because the administrator has disabled Java Web Start access for the application or app client");
541                  }
542                  result = null;
543              }
544          } else if (_logger.isLoggable(Level.WARNING) && (result == null) ) {
545              /*
546               *Almost every request that reaches our system servlet results from
547               *information we generated into the JNLP documents. So we should not
548               *receive requests for content we do not have. If the look-up failed
549               *to find the content, report it.
550               */

551               _logger.warning("Attempt failed to find Java Web Start content at path " + pathInfo + "; content is available at these paths:" + contentMap.keySet());
552           }
553         
554         return result;
555     }
556
557      /**
558       *Register all deployed appclients with JWS service. This will be called by
559       *OnDemand initialization framework, when webcontainer starts.
560       */

561      public void startJWSServicesForDeployedAppclients() {
562          for (ContentOrigin origin : appclients.values()) {
563              AppclientContentOrigin acOrigin = (AppclientContentOrigin) origin;
564              if (acOrigin.isAdhocPathRegistered() == false) {
565                  startJWSServices(acOrigin);
566              }
567          }
568
569          for (ContentOrigin origin : applications.values()) {
570              ApplicationContentOrigin aOrigin = (ApplicationContentOrigin) origin;
571              if (aOrigin.isAdhocPathRegistered() == false) {
572                  startJWSServices(aOrigin);
573              }
574          }
575      }
576     
577      /**
578       *Returns the AppclientContentOrigin corresponding to the app client with the
579       *specified registration name.
580       *@param the reg name of the app client
581       *@return the AppclientContentOrigin object for that app client; null if there is none
582       */

583      private AppclientContentOrigin findAppclient(String JavaDoc regName) {
584          AppclientContentOrigin result = (AppclientContentOrigin) appclients.get(regName);
585         return result;
586      }
587      
588      /**
589      *Returns the AppclientContentOrigin that corresponds to the specified Application and ModuleDescriptor.
590      *@param the Application object for the app client
591      *@param the ModuleDescriptor object for the app client
592      *@return the corresponding AppclientOrigin; null if no matching AppclientOrigin is found
593      */

594     private AppclientContentOrigin findAppclient(Application application, ModuleDescriptor moduleDescr) {
595         return findAppclient(application.getRegistrationName());
596     }
597
598     /**
599      *Returns the ApplicationContentOrigin corresponding to the specified Application and ModuleDescriptor
600      *@param the registration name for the application
601      *@return the corresponding AppclientOrigin; null if no matching AppclientOrigin is found
602      */

603     private ApplicationContentOrigin findApplication(String JavaDoc regName) {
604         ApplicationContentOrigin result = (ApplicationContentOrigin) applications.get(regName);
605         return result;
606     }
607     /**
608      *Returns the ApplicationContentOrigin corresponding to the specified Application and ModuleDescriptor
609      *@param the Application object for the app client
610      *@return the corresponding AppclientOrigin; null if no matching AppclientOrigin is found
611      */

612     private ApplicationContentOrigin findApplication(Application application) {
613         return findApplication(application.getRegistrationName());
614     }
615
616     /**
617      *Does the work to start Java Web Start services for an app client.
618      *@param the appclientOrigin for which to begin JWS services
619      */

620     private void startJWSServices(AppclientContentOrigin origin) {
621         
622         WebContainer container = WebContainer.getInstance();
623         if (container != null) { // Make sure that webcontainer is up.
624

625             /*
626              *Ask the web container to route requests for the app client's context-root to
627              *our ad hoc servlet using the appropriate target path for this origin.
628              */

629             String JavaDoc targetPathString = origin.getTargetPath();
630             WebPath targetPath = new WebPath(targetPathString);
631             JWSAdHocServletInfo info = new JWSAdHocServletInfo(targetPath.path(), targetPath.contextRoot());
632
633             String JavaDoc virtualContextRoot = origin.getVirtualPath();
634             WebPath virtualPath = new WebPath(virtualContextRoot);
635             _logger.info("Registering ad hoc servlet: " + virtualPath);
636             container.registerAdHocPath(virtualPath.path(),
637                                         virtualPath.contextRoot(),
638                                         origin.getTopLevelRegistrationName(),
639                                         info);
640             origin.adhocPathRegistered();
641         }
642     }
643     
644     /**
645      *Does the work to end Java Web Start support for the specified app client.
646      *@param the app client for which Java Web Start is no longer needed
647      */

648     private void endJWSServices(AppclientContentOrigin origin) {
649         
650         for (Content c : origin.getContents()) {
651             contentMap.remove(c.getContentKey());
652         }
653         
654         WebPath path = new WebPath(origin.getVirtualPath());
655         _logger.fine("Unregistering ad hoc servlet: " + path);
656
657         WebContainer container = WebContainer.getInstance();
658         if (container != null) {
659             container.unregisterAdHocPath(path.path(), path.contextRoot());
660         }
661     }
662
663     /**
664      *Does the work to start Java Web Start services for app clients
665      *nested within an application.
666      *@param the applicationOrigin for which to begin JWS services
667      */

668     private void startJWSServices(ApplicationContentOrigin origin) {
669         
670         WebContainer container = WebContainer.getInstance();
671         if (container != null) { // Make sure that webcontainer is up.
672
/*
673              *Start services for each of the child app clients.
674              */

675             for (AppclientContentOrigin appclient : origin.getAppclientOrigins()) {
676                 startJWSServices(appclient);
677             }
678             origin.adhocPathRegistered();
679         }
680     }
681     
682     /**
683      *Does the work to end Java Web Start support for the app clients
684      *within the specified parent application content origin.
685      *@param the app client for which Java Web Start is no longer needed
686      */

687     private void endJWSServices(ApplicationContentOrigin origin) {
688
689         for (AppclientContentOrigin appclient : origin.getAppclientOrigins()) {
690             endJWSServices(appclient);
691         }
692         
693         for (Content c : origin.getContents()) {
694             contentMap.remove(c.getContentKey());
695         }
696     }
697     
698     /**
699      *Loads several app server objects for retrieving useful information
700      *about the app server instance and applications deployed on it.
701      *@throws IllegalStateException reporting any error retrieving the references
702      */

703     private void findAppServerObjects() throws IllegalStateException JavaDoc {
704         /*
705          *Build a string listing each failed attempt to locate a useful object.
706          */

707         StringBuilder JavaDoc failedObjects = new StringBuilder JavaDoc();
708         
709         Throwable JavaDoc relatedException = null;
710         if ((appServerContext = ApplicationServer.getServerContext()) == null) {
711             failedObjects.append(lineSep).append(" ApplicationServer.getServerContext()");
712         }
713         if ((instEnv = appServerContext.getInstanceEnvironment()) == null) {
714             failedObjects.append(lineSep).append(" appServerContext.getInstanceEnvironment()");
715         }
716         try {
717             appsManager = new AppsManager(instEnv, false);
718         } catch (ConfigException ce) {
719             relatedException = ce;
720             failedObjects.append(lineSep).append(" AppsManager(instEnv)");
721         }
722     
723         try {
724             appclientModulesManager = new AppclientModulesManager(instEnv, false);
725         } catch (ConfigException ce) {
726             relatedException = ce; // Might override earlier assignment; ok, since it'd be rare and both are config exc.
727
failedObjects.append(lineSep).append(" AppclientModulesManager(instEnv)");
728         } finally {
729             /*
730              *If there were any failures to find the objects, report them.
731              */

732             if (failedObjects.length() > 0) {
733                 if (relatedException == null) {
734                      relatedException = new IllegalStateException JavaDoc("Null returned");
735                 }
736                 throw new IllegalStateException JavaDoc("The following utility objects could not be initialized: " + failedObjects.toString(), relatedException);
737             }
738         }
739     }
740
741     /**
742      *Loads the appserver files map.
743      *<p>
744      *This method loads the app server file entries into the map. This map is
745      *also used to populate part of the JNLP documents that list app
746      *server files for Java Web Start. This method is then the only place that needs to change
747      *if the list of app server files needs to change.
748      *@exception IOException indicates problems loading a dynamic template
749      */

750     private void preloadAppserverContent() throws IOException JavaDoc, Exception JavaDoc {
751         
752         /*
753          *Build the collection of signed jar files as one content origin.
754          *
755          *Note that this may change so that the files listed below become part
756          *of the previous group instead with only a small bootstrap jar needing
757          *to be signed.
758          */

759         AppserverContentOrigin signedLibFilesOrigin = new AppserverContentOrigin(
760                 NamingConventions.APPSERVER_CATEGORY,
761                 NamingConventions.APPSERVER_LIB_FILES);
762
763         addJWSACCStaticContent(signedLibFilesOrigin);
764         
765         /*
766          *Add the app server lib files entry to the collection of app server entries.
767          */

768         signedAppserverOrigins.put(NamingConventions.APPSERVER_LIB_FILES, signedLibFilesOrigin);
769
770         AppserverContentOrigin libFilesOrigin = new AppserverContentOrigin(
771                 NamingConventions.APPSERVER_CATEGORY,
772                 NamingConventions.APPSERVER_LIB_FILES);
773
774         /*
775          *Add a new static content object for each unsigned app server lib file to the
776          *app server lib entry.
777          */

778         addAppserverStaticContent(libRoot, libFilesOrigin, false /* isMain */,
779                 "appserv-rt.jar",
780                 "appserv-cmp.jar",
781                 "appserv-admin.jar",
782                 "appserv-deployment-client.jar",
783                 "javaee.jar",
784                 "appserv-ext.jar",
785                 "mail.jar",
786                 "activation.jar",
787                 "appserv-ws.jar",
788                 "toplink-essentials.jar",
789                 "dbschema.jar"
790                 );
791
792         /*
793          *Add the app server lib files entry to the collection of app server origins.
794          */

795         appserverOrigins.put(NamingConventions.APPSERVER_LIB_FILES, libFilesOrigin);
796
797         /*
798          *Add the derby jar.
799          */

800         AppserverContentOrigin derbyLibFilesOrigin = new AppserverContentOrigin(
801                 NamingConventions.APPSERVER_CATEGORY,
802                 NamingConventions.APPSERVER_LIB_FILES);
803         File JavaDoc derbyRoot = new File JavaDoc(installRootDir, "javadb");
804         File JavaDoc derbyLib = new File JavaDoc(derbyRoot, "lib");
805         
806     addAppserverStaticContent(derbyLib, derbyLibFilesOrigin, false /* isMain */, "derbyclient.jar");
807         appserverOrigins.put(NamingConventions.APPSERVER_DERBY_FILES, derbyLibFilesOrigin);
808         
809         /*
810          *Add static content objects for the mq files needed on the client and add
811          *the origin to the appserver origins.
812          */

813         AppserverContentOrigin mqlibFilesOrigin = new AppserverContentOrigin(
814             NamingConventions.APPSERVER_CATEGORY,
815             NamingConventions.APPSERVER_LIB_FILES);
816
817         File JavaDoc mqRoot = new File JavaDoc(installRootDir, "imq");
818         File JavaDoc mqlibRoot = new File JavaDoc(mqRoot, "lib");
819         
820         addAppserverStaticContent(mqlibRoot, mqlibFilesOrigin, false /* isMain */, "fscontext.jar");
821         appserverOrigins.put(NamingConventions.APPSERVER_MQLIB_FILES, mqlibFilesOrigin);
822
823         /*
824          *Again, for the jms ra jar.
825          */

826         AppserverContentOrigin jmsraFilesOrigin = new AppserverContentOrigin(
827             NamingConventions.APPSERVER_CATEGORY,
828             NamingConventions.APPSERVER_LIB_FILES);
829         
830         File JavaDoc installRoot = new File JavaDoc(libRoot, "install");
831         File JavaDoc appsRoot = new File JavaDoc(installRoot, "applications");
832         File JavaDoc jmsraRoot = new File JavaDoc(appsRoot, "jmsra");
833         
834         addAppserverStaticContent(jmsraRoot, jmsraFilesOrigin, false /* isMain */, "imqjmsra.jar");
835         
836         appserverOrigins.put(NamingConventions.APPSERVER_JMSRALIB_FILES, jmsraFilesOrigin);
837         
838         /*
839          *Add static content for the extension jars.
840          */

841         AppserverContentOrigin extJarsOrigin = new AppserverContentOrigin(
842                 NamingConventions.APPSERVER_CATEGORY,
843                 NamingConventions.APPSERVER_LIB_FILES);
844         
845         Map JavaDoc<ExtensionFileManager.ExtensionKey,ExtensionFileManager.Extension> extFileInfo = extensionFileManager.getExtensionFileEntries();
846         
847         for (ExtensionFileManager.Extension e : extFileInfo.values()) {
848             File JavaDoc f = e.getFile();
849             String JavaDoc path = NamingConventions.extJarFilePath(e.getExtDirectoryNumber(), f);
850             String JavaDoc contentKey = extJarsOrigin.getContentKeyPrefix() + path;
851             AppserverStaticContent extContent = new AppserverStaticContent(
852                 extJarsOrigin,
853                 contentKey,
854                 path,
855                 f,
856                 installRootURI,
857                 false);
858                 
859             extJarsOrigin.pathToContent.put(extContent.getContentKey(), extContent);
860             contentMap.put(extContent.getContentKey(), extContent);
861         }
862         
863         extJarAppserverOrigins.put(NamingConventions.APPSERVER_EXTJAR_FILES, extJarsOrigin);
864     }
865
866     private void addJWSACCStaticContent(AppserverContentOrigin origin) throws Exception JavaDoc {
867
868         String JavaDoc signedJarFileName = NamingConventions.SignedJar.signedJarPath(UNSIGNED_JWSACC_JARFILE_NAME);
869         String JavaDoc path = "/" + signedJarFileName;
870         String JavaDoc contentKey = origin.getContentKeyPrefix() + path;
871         File JavaDoc unsignedJar = new File JavaDoc(installRootDir, "lib" + File.separator + UNSIGNED_JWSACC_JARFILE_NAME);
872         File JavaDoc signedJar = new File JavaDoc(instEnv.getJavaWebStartPath(), signedJarFileName);
873             
874         SignedStaticContent content = new SignedStaticContent(
875             origin,
876             contentKey,
877             path,
878             signedJar,
879             unsignedJar,
880             installRootURI,
881             localStrings,
882             true /* isMain */
883             );
884             
885         addAppserverStaticContent(origin, content);
886     }
887
888     /**
889      *Adds static content objects to an origin.
890      *
891      *@param prefix to use at the beginning of the URL path for these files
892      *@param the directory in which the files actually reside
893      *@param the appserver origin whose pathToContent map should contain mappings for these paths to the files
894      *@param list of file names
895      */

896     private void addAppserverStaticContent(File JavaDoc dir, AppserverContentOrigin origin, boolean isMain, String JavaDoc... fileName) {
897         for (String JavaDoc fn : fileName) {
898             String JavaDoc path = "/" + fn;
899             String JavaDoc contentKey = origin.getContentKeyPrefix() + path;
900             
901             AppserverStaticContent content = new AppserverStaticContent(
902                 origin,
903                 contentKey,
904                 path,
905                 new File JavaDoc(dir, fn),
906                 installRootURI,
907                 isMain);
908
909             /*
910              *Add the new content object both to the origin's map and also to
911              *the global content map.
912              */

913             addAppserverStaticContent(origin, content);
914         }
915     }
916
917     /**
918      *Adds static content objects to an origin.
919      *
920      *@param prefix to use at the beginning of the URL path for these files
921      *@param the directory in which the files actually reside
922      *@param the appserver origin whose pathToContent map should contain mappings for these paths to the files
923      *@param list of file names
924      */

925     private void addAppserverStaticContent(AppserverContentOrigin origin, StaticContent content) {
926         /*
927          *Add the new content object both to the origin's map and also to
928          *the global content map.
929          */

930         origin.pathToContent.put(content.getContentKey(), content);
931         contentMap.put(content.getContentKey(), content);
932     }
933
934     /**
935      *Creates Properties object containing names and values of placeholders
936      *known when an appclient or application is loaded. This excludes information
937      *available only when a request arrives. This Properties object is used
938      *to substitute the values for the names in the generated documents.
939      *<p>
940      *All properties are defined in a single Properties object, and that Properties
941      *instance is used in processing all dynamic documents before those dynamic
942      *documents are stored in the maps. At request-time, further substitution
943      *occurs with information available only then.
944      *@param the origin for which values are to be assigned
945      *@param the app client's specified main class name
946      *@param the name of a class present in the generated app client jar file
947      *@return Properties object containing the token-to-value correspondence
948      *@throws IOException for errors getting information
949      */

950     protected Properties JavaDoc prepareInitPlaceholders(
951             AppclientContentOrigin origin,
952             String JavaDoc mainClassName
953                 ) {
954         String JavaDoc appclientRegName = origin.getTopLevelRegistrationName();
955
956         Properties JavaDoc answer = new Properties JavaDoc();
957
958         answer.setProperty("appserver.codebase.path", NamingConventions.appServerCodebasePath());
959         
960         answer.setProperty("appclient.codebase.path", NamingConventions.appclientCodebasePath(origin));
961         answer.setProperty("appclient.context-root", origin.getContextRoot());
962         String JavaDoc vendor = origin.getVendor();
963         answer.setProperty("appclient.vendor", (vendor == null || vendor.length() == 0) ? localStrings.getString("jws.defaultVendorName") : vendor);
964         answer.setProperty("appclient.client.jnlp.filename", NamingConventions.Client.JNLPFilename(appclientRegName));
965         answer.setProperty("appclient.client.html.filepath", NamingConventions.Client.HTMLPath(appclientRegName));
966         answer.setProperty("appclient.mainext.jnlp.filename", NamingConventions.Main.JNLPExtFilename(appclientRegName));
967         
968 // answer.setProperty("default.wss.client.config.path", NamingConventions.defaultWSSClientConfigPathInJNLP());
969
//
970
// answer.setProperty("default.sun.acc.xml.url.property.name", com.sun.enterprise.appclient.MainWithModuleSupport.DEFAULT_SUN_ACC_URL_PROPERTY);
971
// answer.setProperty("default.wss.client.config.xml.url.property.name", com.sun.enterprise.appclient.MainWithModuleSupport.DEFAULT_WSS_CONFIG_URL_PROPERTY);
972
//
973
// answer.setProperty("default.sun.acc.xml.path", NamingConventions.defaultSunACCPathInJNLP());
974
// answer.setProperty("security.config.file.property.name", com.sun.enterprise.appclient.MainWithModuleSupport.SUN_ACC_SECURITY_CONFIG_PROPERTY);
975

976         prepareIIOPProperties(answer);
977         
978         /*
979          *The Java Web Start ACC creates temporary files that are marked for deletion on exit.
980          *For diagnostic purposes, administrators can set a property on the server to
981          *ask that these files be retained on the client. The property value is sent to
982          *each client when the user requests the main JNLP document.
983          */

984         boolean retainTempFiles = Boolean.getBoolean(SERVER_RETAIN_TEMP_FILES_PROPERTYNAME);
985         answer.setProperty("appclient.retainTempFiles.propertyName", MainWithModuleSupport.APPCLIENT_RETAIN_TEMP_FILES_PROPERTYNAME);
986         answer.setProperty("appclient.retainTempFiles", String.valueOf(retainTempFiles));
987         
988         /*
989          *Set the JNLP information title to the app client module's display name,
990          *if one is present.
991          */

992         String JavaDoc displayName = origin.getDisplayName();
993         String JavaDoc jnlpInformationTitle = (displayName != null && displayName.length() > 0) ? displayName : "Application Client " + appclientRegName;
994         answer.setProperty("appclient.information.title", jnlpInformationTitle);
995         
996         /*
997          *Set the file part of the homepage URL.
998          */

999         String JavaDoc jnlpInformationHomepageFilepath = NamingConventions.Main.HTMLPath(appclientRegName);
1000        answer.setProperty("appclient.information.homepage.filepath", jnlpInformationHomepageFilepath);
1001        
1002        /*
1003         *Set the one-line description the same as the title for now.
1004         */

1005        answer.setProperty("appclient.information.description.one-line", jnlpInformationTitle);
1006        
1007        /*
1008         *Set the short description to the description from the descriptor, if any.
1009         */

1010        String JavaDoc description = origin.getDescription();
1011        String JavaDoc jnlpInformationShortDescription = (description != null && description.length() > 0) ? description : jnlpInformationTitle;
1012        answer.setProperty("appclient.information.description.short", jnlpInformationShortDescription);
1013        
1014        /*
1015         *Set up variables used for populating descriptive information in the
1016         *JNLP document that lists app server jars. Although this document is
1017         *generated for each separate app client that is loaded, it's content
1018         *is basically the same for all since all app clients rely on the same
1019         *app server jars.
1020         */

1021        prepareAppserverPlaceholders(answer);
1022        
1023        /*
1024         *If a main class is specified in the manifest, use it to specify the
1025         *main class argument to ACC. Otherwise, do not emit the mainclass
1026         *argument into the JNLP document and let the app client container
1027         *process any user-supplied mainclass or name argument.
1028         */

1029        String JavaDoc mainClassArgsValue = "";
1030        if ((mainClassName != null) && ( ! mainClassName.equals("")) ) {
1031            mainClassArgsValue = " <argument>-mainclass</argument>" + lineSep +
1032                    " <argument>" + mainClassName + "</argument>";
1033        }
1034        answer.setProperty(
1035            "appclient.main.class.arguments", mainClassArgsValue);
1036
1037        /*
1038         *Set a property that indicates to the app client container that it is
1039         *running under Java Web Start and what the download host name is.
1040         */

1041        answer.setProperty("appclient.isJWS.propertyName", MainWithModuleSupport.APPCLIENT_ISJWS_PROPERTYNAME);
1042        answer.setProperty("appclient.download.host.propertyName", MainWithModuleSupport.APPCLIENT_DOWNLOAD_HOST_PROPERTYNAME);
1043        answer.setProperty("appclient.user.code.is.signed.propertyName", AppClientInfo.USER_CODE_IS_SIGNED_PROPERTYNAME);
1044        return answer;
1045    }
1046    
1047    /**
1048     *Prepares property value assignments for IIOP connectitivy.
1049     */

1050    private void prepareIIOPProperties(Properties JavaDoc props) {
1051        /*
1052         *Set the default IIOP information for the app client based on this server. The template
1053         *uses the host retrieved from the incoming request as the default host value. Note that
1054         *because this code and the app client container Main both must use the same property names
1055         *for this to work, those names are defined as constants in Main and the constants are used
1056         *both there and here.
1057         */

1058        props.setProperty("appclient.iiop.defaultHost.propertyName", MainWithModuleSupport.APPCLIENT_IIOP_DEFAULTHOST_PROPERTYNAME);
1059        props.setProperty("appclient.iiop.defaultPort.propertyName", MainWithModuleSupport.APPCLIENT_IIOP_DEFAULTPORT_PROPERTYNAME);
1060        props.setProperty("appclient.iiop.defaultPort", String.valueOf(ORBManager.getORBInitialPort()));
1061        
1062        /*
1063         *If this instance participates in a failover group, prepare the property
1064         *that the JWS-aware ACC will recognize.
1065         */

1066        String JavaDoc failoverEndpoints = getIIOPEndpoints();
1067        String JavaDoc failoverEndpointsSetting = "";
1068        if (failoverEndpoints != null) {
1069            failoverEndpointsSetting = "<property name=\"" + MainWithModuleSupport.APPCLIENT_IIOP_FAILOVER_ENDPOINTS_PROPERTYNAME + "\" value=\"" + failoverEndpoints + "\"/>";
1070        }
1071        props.setProperty("appclient.iiop.failover.endpoints", failoverEndpointsSetting);
1072    }
1073    
1074    /**
1075     *Returns the IIOP endpoints in the cluster in which the current instance
1076     *participates.
1077     *@return String suitable for use in defining the IIOP property for endpoints; null if this instance is not in a cluster
1078     */

1079    private String JavaDoc getIIOPEndpoints() {
1080        String JavaDoc result = null;
1081    /*
1082     * Unfortunately we cannot use this in general, because
1083     * is starts up the ORB, and the lazy initialization does not
1084     * want the ORB to start at this point. We need to fix this
1085     * before 9.0ee beta, but for now I am disabling this code.
1086     * See bug 6364861.
1087
1088        try {
1089            // Thanks to Harold for the following logic.
1090            StringBuilder endpoints = new StringBuilder();
1091            GroupInfoService gis = (GroupInfoService)
1092                ORBManager.getORB().resolve_initial_references(
1093                    ORBConstants.FOLB_SERVER_GROUP_INFO_SERVICE);
1094            List<ClusterInstanceInfo> lcii = gis.getClusterInstanceInfo(null);
1095            if (lcii != null) {
1096                // EE static and dynamic case
1097                for (ClusterInstanceInfo cii : lcii) {
1098                    // Get cluster addresses
1099                    if (cii.endpoints != null) {
1100                        for (SocketInfo si : cii.endpoints) {
1101                            // Include only socket info objects with a type that
1102                            // does NOT start with SSL.
1103                            if ( ! si.type.startsWith(IIOP_ENDPOINT_TYPE_PREFIX_IGNORE)) {
1104                                if (endpoints.length() > 0) {
1105                                    endpoints.append(",");
1106                                }
1107                                endpoints.append(si.host + ":" + si.port);
1108                            }
1109                        }
1110                    }
1111                }
1112            }
1113            if (endpoints.length() > 0) {
1114                result = endpoints.toString();
1115            }
1116        } catch (InvalidName invName) {
1117        }
1118    */

1119        return result;
1120    }
1121
1122    /**
1123     *Adds values for placeholders used in the generated JNLP document that
1124     *lists app server jars. These values do not depend on the particular app
1125     *client but are retrieved from the local strings bundle.
1126     *@param p the Properties holding placeholders and their values
1127     */

1128    private void prepareAppserverPlaceholders(Properties JavaDoc p) {
1129        p.setProperty(
1130                "appserver.information.title",
1131                localStrings.getString("jws.appserver.information.title"));
1132        p.setProperty(
1133                "appserver.information.vendor",
1134                localStrings.getString("jws.appserver.information.vendor"));
1135        p.setProperty(
1136                "appserver.information.description.one-line",
1137                localStrings.getString("jws.appserver.information.description.one-line"));
1138        p.setProperty(
1139                "appserver.information.description.short",
1140                localStrings.getString("jws.appserver.information.description.short"));
1141    }
1142    
1143    /**
1144     *Prepares the document entries for an application's nested app clients.
1145     */

1146    private ApplicationContentOrigin prepareApplication(Application application, ModuleDescriptor [] moduleDescrs)
1147        throws IOException JavaDoc, URISyntaxException JavaDoc, SAXParseException JavaDoc, ConfigException, Exception JavaDoc {
1148        
1149        refreshConfigContextForManagers();
1150        
1151        ApplicationContentOrigin result = new ApplicationContentOrigin(application);
1152        
1153        /*
1154         *Add a static content instance for the single combined client jar file
1155         *for all app clients in this module.
1156         */

1157        SignedStaticContent jarFileContent = addAppclientJarContent(result);
1158
1159        String JavaDoc jarHrefs = jarFileContent.asJNLPJarElement();
1160        
1161        String JavaDoc earDirectory = appsManager.getLocation(application.getRegistrationName());
1162        
1163        /**
1164         *Each module descriptor in the array represents an app client that is eligible
1165         *for Java Web Start services. For each, create a nested app client content
1166         *origin and add it to the parent application content origin.
1167         */

1168        for (ModuleDescriptor md : moduleDescrs) {
1169            /*
1170             *Get the descriptor for the app client of interest.
1171             *The prepareAppClient method uses it to extract the main class for use as a command line argument.
1172             */

1173            Manifest JavaDoc mf = getManifest(earDirectory, md);
1174            Attributes JavaDoc mainAttrs = mf.getMainAttributes();
1175            String JavaDoc mainClassName = mainAttrs.getValue(Attributes.Name.MAIN_CLASS);
1176            String JavaDoc appclientJarURI = md.getArchiveUri();
1177
1178            /*
1179             *Extension libraries are not bundled into the generated jar file.
1180             *So any relevant extension library jar needs to be added as static
1181             *content for this appclient origin. An extension library could
1182             *be referenced from a jar that appears in the app client's
1183             *Class-Path expression. URIs there are relative to the directory
1184             *that contains the jar with the Class-Path. So we need the
1185             *directory that contains the developer's app client jar.
1186             */

1187            File JavaDoc appclientJar = new File JavaDoc(appclientJarURI);
1188            File JavaDoc appclientJarDir = appclientJar.getParentFile();
1189            
1190            if ( ! appclientJar.isAbsolute()) {
1191                appclientJar = new File JavaDoc(earDirectory, appclientJarURI);
1192            }
1193            
1194            /*
1195             *Create and add the nested origin.
1196             */

1197            NestedAppclientContentOrigin nestedAppclient = prepareNestedAppclient(
1198                    result,
1199                    md,
1200                    jarHrefs,
1201                    mainClassName,
1202                    mainAttrs,
1203                    appclientJar.getParent(),
1204                    jarFileContent);
1205            result.addNestedOrigin(nestedAppclient);
1206        }
1207        
1208        return result;
1209    }
1210    
1211    /**
1212     *Returns the manifest for the nested app client specified by the
1213     *module descriptor.
1214     *@param earDirectoryPath the directory into which the ear has been expanded
1215     *@param md the ModuleDescriptor for the embedded app client of interest
1216     */

1217    private Manifest JavaDoc getManifest(String JavaDoc earDirectoryPath, ModuleDescriptor md) {
1218        /*
1219         *Use the same logic that the J2EEModuleExploder uses to choose the
1220         *name for the embedded app client's subdirectory.
1221         */

1222        String JavaDoc submoduleDirSpec = FileUtils.makeFriendlyFileName(md.getArchiveUri());
1223        File JavaDoc submoduleDir = new File JavaDoc(earDirectoryPath, submoduleDirSpec);
1224        Manifest JavaDoc mf = EJBClassPathUtils.getManifest(submoduleDir.getAbsolutePath());
1225        return mf;
1226    }
1227    
1228    /**
1229     *Prepares the content origin for a top-level app client.
1230     *<p>
1231     *The object returned describes a single, identifiable origin for content pertinent
1232     *to a single app client.
1233     *@param the Application for the app client
1234     *@param the ModuleDescriptor describing the app client
1235     *@return the populated content origin object for the app client; null if there is a problem creating it
1236     *@throws IOException for errors reading the app client's manifest
1237     *@throws URISyntaxException for errors preparing URIs for static content
1238     *@throws ConfigException for errors finding the app client's generated JAR directory
1239     */

1240    private AppclientContentOrigin prepareTopLevelAppclient(Application application, ModuleDescriptor moduleDescr)
1241        throws IOException JavaDoc, URISyntaxException JavaDoc, ConfigException, FileNotFoundException JavaDoc, SAXParseException JavaDoc, Exception JavaDoc {
1242        refreshConfigContextForManagers();
1243        
1244        String JavaDoc contextRoot = NamingConventions.TopLevelAppclient.defaultVirtualContextRoot(application);
1245
1246        AppclientContentOrigin result = new AppclientContentOrigin(application, moduleDescr, contextRoot);
1247        String JavaDoc regName = result.getTopLevelRegistrationName();
1248        
1249        /*
1250         *Potentially, there could be multiple jar files needed by this app client.
1251         *Currently, only the generated app client jar is needed. Build the
1252         *string containing <jar href...> elements for insertion into the
1253         *client JNLP document.
1254         */

1255        
1256        String JavaDoc appclientJarPath = result.getAppclientJarPath();
1257        
1258        /*
1259         *Add a static content instance for the single combined client jar file
1260         *for all app clients in this module.
1261         */

1262        StaticContent jarFileContent = addAppclientJarContent(result);
1263
1264        String JavaDoc jarHrefs = jarFileContent.asJNLPJarElement();
1265
1266        String JavaDoc dirPath = appclientModulesManager.getLocation(regName);
1267        Manifest JavaDoc mf = EJBClassPathUtils.getManifest(dirPath);
1268        Attributes JavaDoc mainAttrs = mf.getMainAttributes();
1269        String JavaDoc mainClassName = mainAttrs.getValue(Attributes.Name.MAIN_CLASS);
1270        
1271        /*
1272         *Perform the rest of the initialization which is shared with nested app client origins.
1273         */

1274        prepareAppclient(result, application, moduleDescr, appclientModulesManager, jarHrefs, regName, mainClassName, mainAttrs, dirPath, jarFileContent);
1275        return result;
1276    }
1277    
1278    /**
1279     *Performs initialization that is common between top-level and nested app clients.
1280     *@param the app client origin object to be further set up
1281     *@param the Application for this app client
1282     *@param the ModuleDescriptor for this app client
1283     *@param the manager to be used for finding the directory holding the generated app client jar file
1284     *@param a string representing the module name to be used in constructing virtual file names
1285     *@param mainAttrs the main attributes for the client that may contain extension jar requirements
1286     *@param dirPath location of the jar file to be used in resolving relative Class-Path manifest entries
1287     *@param publishedAppclientJarContent the content object describing the app client jar to publish
1288     */

1289    private void prepareAppclient(
1290            AppclientContentOrigin origin,
1291            Application application,
1292            ModuleDescriptor moduleDescr,
1293            BaseManager mgr,
1294            String JavaDoc jarHRefs,
1295            String JavaDoc modName,
1296            String JavaDoc mainClassName,
1297            Attributes JavaDoc mainAttrs,
1298            String JavaDoc dirPathForRelativeClassPathEntries,
1299            StaticContent appclientJarContent)
1300                throws FileNotFoundException JavaDoc, IOException JavaDoc, URISyntaxException JavaDoc, ConfigException {
1301
1302        /*
1303         *Using information now available, assemble as much of the JNLP and HTML
1304         *documents as possible and store them with the content origin object
1305         *for this app client. As it handles specific incoming
1306         *requests, the JWS system servlet will do further substitutions.
1307         */

1308        Properties JavaDoc tokenValues = prepareInitPlaceholders(
1309                origin,
1310                mainClassName
1311                );
1312        
1313        /*
1314         *Prepare the main JNLP document.
1315         *
1316         *Build a string containing the <jar> elements for the app server files
1317         *that need to be listed in the main JNLP document. Add the placeholder
1318         *name and the resulting string to the token values.
1319         *
1320         *Get the template, merge with user content (future), and substitute for placeholders.
1321         *Then add the now partially-substituted main JNLP document template to
1322         *the content map.
1323         */

1324        
1325        StringBuilder JavaDoc appserverJarElements = buildJarElements(appserverOrigins);
1326        StringBuilder JavaDoc signedAppserverJarElements = buildJarElements(signedAppserverOrigins);
1327        
1328        /*
1329         *Build hrefs for the extension jars in this app client. The hrefs will be
1330         *inserted into the JNLP document for the app client.
1331         */

1332        Set JavaDoc<ExtensionFileManager.Extension> earExtJars = findExtensions(mainAttrs, dirPathForRelativeClassPathEntries);
1333        
1334        String JavaDoc earJarHrefs = prepareHrefsForFiles(earExtJars);
1335        
1336        
1337        tokenValues.setProperty("appserver.jar.elements", appserverJarElements.toString());
1338        tokenValues.setProperty("appserver.jar.elements.signed", signedAppserverJarElements.toString());
1339        tokenValues.put("appclient.jar.elements", jarHRefs);
1340
1341        /*
1342         *Prepare the main JNLP document.
1343         */

1344        String JavaDoc mainJNLPPath = NamingConventions.Main.JNLPPath(modName);
1345        addDynamicContent(
1346                origin,
1347                mainJNLPPath,
1348                NamingConventions.APPCLIENT_MAIN_JNLP_TEMPLATE_NAME,
1349                tokenValues,
1350                JNLP_MIME_TYPE,
1351                true /* requiresElevatedPrivs */
1352                );
1353
1354        /*
1355         *Prepare the main extension JNLP document.
1356         */

1357        String JavaDoc mainExtJNLPPath = NamingConventions.Main.JNLPExtPath(modName);
1358        addDynamicContent(
1359                origin,
1360                mainExtJNLPPath,
1361                NamingConventions.APPCLIENT_MAIN_JNLP_EXT_TEMPLATE_NAME,
1362                tokenValues,
1363                JNLP_MIME_TYPE);
1364        
1365        /*
1366         *Prepare the main HTML document.
1367         */

1368        String JavaDoc mainHTMLPath = NamingConventions.Main.HTMLPath(modName);
1369        addDynamicContent(
1370                origin,
1371                mainHTMLPath,
1372                NamingConventions.APPCLIENT_MAIN_HTML_TEMPLATE_NAME,
1373                tokenValues,
1374                HTML_MIME_TYPE);
1375        
1376        /*
1377         *Prepare the client HTML document.
1378         */

1379        String JavaDoc clientHTMLPath = NamingConventions.Client.HTMLPath(modName);
1380        addDynamicContent(
1381                origin,
1382                clientHTMLPath,
1383                NamingConventions.APPCLIENT_CLIENT_HTML_TEMPLATE_NAME,
1384                tokenValues,
1385                HTML_MIME_TYPE);
1386        
1387        /*
1388         *Prepare the client JNLP document. Get template, merge (future), substitute, add to map.
1389         *Note that this document's template contains a placeholder for the list of <jar>
1390         *elements to describe all user-provided jars it needs.
1391         */

1392        String JavaDoc clientJNLPPath = NamingConventions.Client.JNLPPath(modName);
1393        
1394        String JavaDoc contentKey = origin.getContentKeyPrefix() + clientJNLPPath;
1395        String JavaDoc docText = Util.replaceTokens(
1396                templateCache.getTemplate(NamingConventions.APPCLIENT_CLIENT_JNLP_TEMPLATE_NAME),
1397                tokenValues);
1398
1399        DynamicContent clientJNLPContent = new DynamicContent(
1400                origin,
1401                contentKey,
1402                clientJNLPPath,
1403                docText,
1404                JNLP_MIME_TYPE,
1405                true /* requiresElevatedPrivs */
1406                );
1407        
1408        /*
1409         *The security settings for the app client jar dynamic content is set
1410         *when the request arrives by checking the current availability of a
1411         *signed jar at that time. So it is not set here.
1412         */

1413        addDynamicContent(origin, clientJNLPContent);
1414    }
1415
1416    /**
1417     *Returns an initialized nested app client content origin.
1418     *@param the parent application content origin
1419     *@param the module descriptor for the app client
1420     *@return the new NestedAppclientContentOrigin
1421     */

1422    private NestedAppclientContentOrigin prepareNestedAppclient(
1423            ApplicationContentOrigin parent,
1424            ModuleDescriptor moduleDescr,
1425            String JavaDoc jarHRefs,
1426            String JavaDoc mainClassName,
1427            Attributes JavaDoc mainAttrs,
1428            String JavaDoc dirPathForRelativeClassPathEntries,
1429            StaticContent appclienJarContent)
1430                throws FileNotFoundException JavaDoc, IOException JavaDoc, URISyntaxException JavaDoc, ConfigException {
1431        
1432        String JavaDoc contextRoot = NamingConventions.NestedAppclient.defaultVirtualContextRoot(parent.getApplication(), moduleDescr);
1433        
1434        NestedAppclientContentOrigin result = new NestedAppclientContentOrigin(parent, moduleDescr, contextRoot);
1435
1436        prepareAppclient(
1437                result,
1438                parent.getApplication(),
1439                moduleDescr,
1440                appsManager,
1441                jarHRefs,
1442                result.getName(),
1443                mainClassName,
1444                mainAttrs,
1445                dirPathForRelativeClassPathEntries,
1446                appclienJarContent
1447                );
1448        
1449        return result;
1450    }
1451    
1452    /**
1453     *Refreshes the config context in use by the apps manager and the app
1454     *client modules manager. By doing this early in the response to a load
1455     *event, the code makes sure that the managers have the up-to-date
1456     *MBeans.
1457     *@throws ConfigException in case of error refreshing either context
1458     */

1459    private void refreshConfigContextForManagers() throws ConfigException {
1460        appsManager.refreshConfigContext();
1461        appclientModulesManager.refreshConfigContext();
1462    }
1463    
1464    /**
1465     * Returns Extension objects for the extension jars cited by the app client.
1466     * The jars represented by the Extension objects need to be available to app clients in the ear
1467     * (when dealing with an ear) or to the single stand-alone app client (when
1468     * dealing with a stand-alone app client).
1469     * @param attrs the main attributes of the jar of interest
1470     * @param appDirPath the app's directory to be used in resolving relative Class-Path entries
1471     * @return Set containing File objects for the required jars
1472     * @throws IOException for any error while processing the archive
1473     * @throws ConfigException for any error retrieving information about the application
1474     */

1475    private Set JavaDoc<ExtensionFileManager.Extension> findExtensions(Attributes JavaDoc attrs, String JavaDoc appDirPath) throws IOException JavaDoc, ConfigException {
1476        Set JavaDoc<ExtensionFileManager.Extension> result = null;
1477        
1478        File JavaDoc appDir = new File JavaDoc(appDirPath);
1479        result = extensionFileManager.findExtensionTransitiveClosure(appDir, attrs);
1480        return result;
1481    }
1482    
1483    /**
1484     *Returns the main attributes for the specified application.
1485     *@param application the Application of interest
1486     *@return Attributes from the application's manifest
1487     */

1488    private Attributes JavaDoc getMainAttributesForApplication(Application application) throws ConfigException, IOException JavaDoc {
1489        Attributes JavaDoc result = null;
1490        ModuleType JavaDoc type = application.getModuleType();
1491        BaseManager mgr = null;
1492        if (type.equals(type.EAR) ) {
1493            mgr = appsManager;
1494        } else {
1495            mgr = appclientModulesManager;
1496        }
1497        
1498        String JavaDoc dirPath = mgr.getLocation(application.getRegistrationName());
1499        Manifest JavaDoc mf = loadManifestFromFile(dirPath);
1500        result = mf.getMainAttributes();
1501        
1502        return result;
1503    }
1504          
1505    private Manifest JavaDoc loadManifestFromFile(String JavaDoc dirPath) throws IOException JavaDoc {
1506        Manifest JavaDoc result = null;
1507        InputStream JavaDoc is = null;
1508        try {
1509            File JavaDoc manifestFile = new File JavaDoc(dirPath, JarFile.MANIFEST_NAME);
1510            if (manifestFile.exists() && manifestFile.canRead()) {
1511                is = new FileInputStream JavaDoc(manifestFile);
1512                result = new Manifest JavaDoc(is);
1513            }
1514            return result;
1515        } finally {
1516            if (is != null) {
1517                is.close();
1518            }
1519        }
1520    }
1521    
1522    /**
1523     * Converts a set of ExtensionFileManager.Extension objects into a String containing JNLP-friendly
1524     * HREFs for those files.
1525     * @param extJarInfo List of ExtensionFileManager.Extension objects representing the jars
1526     * @return String containing an HREF for each jar in the set
1527     */

1528    private String JavaDoc prepareHrefsForFiles(Set JavaDoc<ExtensionFileManager.Extension> extJarInfo) {
1529        ContentOrigin extJarsOrigin = extJarAppserverOrigins.get(NamingConventions.APPSERVER_EXTJAR_FILES);
1530        StringBuilder JavaDoc result = new StringBuilder JavaDoc();
1531        for (ExtensionFileManager.Extension e : extJarInfo) {
1532            String JavaDoc path = NamingConventions.extJarFilePath(e.getExtDirectoryNumber(), e.getFile());
1533            String JavaDoc contentKey = extJarsOrigin.getContentKeyPrefix() + path;
1534            StaticContent content = (StaticContent) extJarsOrigin.getContent(contentKey);
1535            result.append(content.asJNLPJarElement()).append(lineSep);
1536        }
1537        return result.toString();
1538    }
1539
1540    /**
1541     *Convenience method to both add content to the origin and also to the
1542     *overall content map.
1543     *@param origin content origin to which to add the content
1544     *@param path URI path by which the content can be addressed within its origin
1545     *@param templateName name of the template to use for this dynamic content
1546     *@param tokenValues placeholder->value Properties object
1547     *@param mimeType MIME type of this content
1548     *@param requiresElevatedPrivs indicates if the JNLP should request privs
1549     *@return the newly-created Content
1550     *@throws IOException in case of errors retrieving the template
1551     */

1552    private DynamicContent addDynamicContent(
1553            ContentOrigin origin,
1554            String JavaDoc path,
1555            String JavaDoc templateName,
1556            Properties JavaDoc tokenValues,
1557            String JavaDoc mimeType,
1558            boolean requiresElevatedPrivs) throws IOException JavaDoc {
1559         
1560        DynamicContent content = origin.addDynamicContent(
1561                path,
1562                templateCache.getTemplate(templateName),
1563                tokenValues,
1564                mimeType,
1565                requiresElevatedPrivs);
1566        contentMap.put(content.getContentKey(), content);
1567        return content;
1568    }
1569     
1570    /**
1571     *Convenience method to both add content to the origin and also to the
1572     *overall content map.
1573     *@param origin content origin to which to add the content
1574     *@param path URI path by which the content can be addressed within its origin
1575     *@param templateName name of the template to use for this dynamic content
1576     *@param tokenValues placeholder->value Properties object
1577     *@param mimeType MIME type of this content
1578     *@return the newly-created Content
1579     *@throws IOException in case of errors retrieving the template
1580     */

1581    private DynamicContent addDynamicContent(
1582            ContentOrigin origin,
1583            String JavaDoc path,
1584            String JavaDoc templateName,
1585            Properties JavaDoc tokenValues,
1586            String JavaDoc mimeType) throws IOException JavaDoc {
1587        return addDynamicContent(origin, path, templateName, tokenValues, mimeType, false /* requiredElevatedPrivs */);
1588    }
1589    
1590    private DynamicContent addDynamicContent(
1591            ContentOrigin origin,
1592            DynamicContent content) {
1593         
1594        origin.addDynamicContent(content);
1595        contentMap.put(content.getContentKey(), content);
1596        return content;
1597    }
1598
1599    /**
1600     *Convenience method to both add content to the origin and also to the
1601     *overall content map.
1602     *@param the content origin to which to add the content
1603     *@param the path by which the content can be addressed within its origin
1604     *@param the file where the static content resides
1605     *@return the newly-created Content
1606     *@throws URISyntaxException in case of errors deriving a relative URI for the file
1607     */

1608     private StaticContent addStaticContent(
1609             ContentOrigin origin,
1610             String JavaDoc path,
1611             File JavaDoc file) throws URISyntaxException JavaDoc {
1612         
1613         StaticContent content = origin.addStaticContent(path, installRootURI, file);
1614         contentMap.put(content.getContentKey(), content);
1615         return content;
1616     }
1617     
1618     /**
1619      *Convenience method to both add content to the origin and also to the
1620      *overall content map.
1621      *@param origin the origin to add the content to
1622      *@param content the StaticContent instance to add
1623      *@returns the content added to the origin
1624      */

1625     private StaticContent addStaticContent(
1626             ContentOrigin origin,
1627             StaticContent content) throws URISyntaxException JavaDoc {
1628         
1629         origin.addStaticContent(content);
1630         contentMap.put(content.getContentKey(), content);
1631         return content;
1632     }
1633     
1634     /**
1635      *Adds the special app client static content object to the application
1636      *origin and to the global content map.
1637      *@param origin the ApplicationContentOrigin to add the content to
1638      *@return the newly-added static content
1639      */

1640     private SignedStaticContent addAppclientJarContent(
1641             ApplicationContentOrigin origin) throws FileNotFoundException JavaDoc, URISyntaxException JavaDoc, Exception JavaDoc {
1642
1643         return addAppclientJarContent(origin, origin.getAppclientJarPath(), appsManager);
1644     }
1645     
1646     /**
1647      *Adds the special app client static content object to the app client
1648      *origin and to the global content map.
1649      *@param origin the AppclientContentOrigin to add the content to
1650      *@return the newly-added static content
1651      */

1652     private SignedStaticContent addAppclientJarContent(
1653             AppclientContentOrigin origin) throws FileNotFoundException JavaDoc, URISyntaxException JavaDoc, Exception JavaDoc {
1654         
1655         return addAppclientJarContent(origin, origin.getAppclientJarPath(), appclientModulesManager);
1656     }
1657     
1658     /**
1659      *Adds the app client content to the specified origin, regardless of which
1660      *type of user content origin is involved.
1661      *@param origin the application or app client origin to add the content to
1662      *@param appclientJarPath path to the generated app client jar
1663      *@param manager appsManager or appclientModulesManager
1664      *@return the created StaticContent for the app client jar file
1665      */

1666     private SignedStaticContent addAppclientJarContent(
1667             UserContentOrigin origin,
1668             String JavaDoc appclientJarPath,
1669             BaseManager manager) throws FileNotFoundException JavaDoc, URISyntaxException JavaDoc, Exception JavaDoc {
1670         
1671         File JavaDoc generatedJar = origin.locateGeneratedAppclientJarFile(manager);
1672         File JavaDoc signedGeneratedJar =
1673                 NamingConventions.SignedJar.signedGeneratedAppclientJarFile(
1674                        origin,
1675                        instEnv,
1676                        generatedJar);
1677         String JavaDoc contentKey = origin.getContentKeyPrefix() + "/" + signedGeneratedJar.getName();
1678        
1679         SignedStaticContent content = new SignedStaticContent(
1680                 origin,
1681                 contentKey,
1682                 appclientJarPath,
1683                 signedGeneratedJar,
1684                 generatedJar,
1685                 installRootURI,
1686                 localStrings,
1687                 false /* isMain */);
1688        
1689         addAppclientJarContent(origin, content);
1690         return content;
1691     }
1692     
1693     /**
1694      *Adds the app client jar content to the origin - as with any content - but
1695      *also identifies it as the app client jar. This information is used
1696      *during the generation of the main JNLP document and the client JNLP
1697      *document when deciding if the app client jar is signed or not.
1698      *@param origin the origin to which to add the app client jar content
1699      *@param content the app client jar static content object
1700      *@return the content object itself
1701      */

1702     private SignedStaticContent addAppclientJarContent(UserContentOrigin origin, SignedStaticContent content) throws URISyntaxException JavaDoc {
1703         addStaticContent(origin, content);
1704// origin.setPublishedAppclientJarStaticContent(content);
1705
return content;
1706         
1707     }
1708
1709     /**
1710     *Returns a StringBuilder containing XML syntax suitable for inclusion in
1711     *a JNLP document's resources section listing the jar files required
1712     *by this module.
1713     *<p>
1714     *The return type is StringBuilder (rather than String) so the caller
1715     *can, if needed, add additional text to the result conveniently.
1716     *
1717     *@param map containing content origins of a particular category
1718     *@return StringBuilder containing JAR element text for the required jar files
1719     */

1720    private StringBuilder JavaDoc buildJarElements(Map JavaDoc<String JavaDoc,ContentOrigin> origins) {
1721
1722        StringBuilder JavaDoc appserverJarElements = new StringBuilder JavaDoc();
1723        /*
1724         *Go through each of the groups of app server files (aslib, mqlib, etc.)
1725         */

1726        for (ContentOrigin origin : origins.values()) {
1727            /*
1728             *For this group, go through all the files.
1729             */

1730            for (Content c : origin.pathToContent.values()) {
1731                if (c instanceof StaticContent) {
1732                    StaticContent sc = (StaticContent) c;
1733                    appserverJarElements.append(sc.asJNLPJarElement());
1734                }
1735            }
1736        }
1737        return appserverJarElements;
1738    }
1739    
1740}
1741
Popular Tags