FileDocCategorySizeDatePackage
AppclientJWSSupportInfo.javaAPI DocGlassfish v2 API85093Tue Jul 10 10:49:14 BST 2007com.sun.enterprise.appclient.jws

AppclientJWSSupportInfo

public class AppclientJWSSupportInfo extends Object
Records and provides access to information about app clients that need Java Web Start support.

The basic purpose of this class is to map between the "virtual" location of files as will be specified by incoming HTTP requests and the content to be returned as the responses to those requests. The content itself can be dynamic (created based on information about the particular app client or the particular HTTP request) or static (a file that resides somewhere in the file system).

This information is updated as modules are loaded and unloaded in the server instance and as the administrator enables or disables modules for Java Web Start access to their app clients. The information is used by the system web application that responds to Java Web Start's requests for content related to the app clients.

This class is a singleton.

author
tjquinn

Fields Summary
private static final String
JNLP_MIME_TYPE
MIME types for dynamic documents
private static final String
HTML_MIME_TYPE
private static final String
XML_MIME_TYPE
private static AppclientJWSSupportInfo
instance
the singleton instance for this class
private static final String
REQUEST_PATH_INFO_PATTERN
pattern string describing the format of the pathInfo of incoming requests; includes capture of useful portions as separate groups The format is: // where category must be appclient, application, or appserver. The exact meaning of the subcategory can vary, depending on the category. The / part can be empty, and will be for requests for the main JNLP document. If the pattern is changed, then the int definitions just below may also need to be changed to reflect the correct positions in the pattern.
private static final int
PATTERN_CATEGORY_GROUP_NUMBER
private static final int
PATTERN_REGNAME_GROUP_NUMBER
private static final int
PATTERN_RELATIVEPATH_GROUP_NUMBER
private static final Pattern
requestPathInfoPattern
pattern used for processing incoming request pathInfo strings
private static final String
SERVER_RETAIN_TEMP_FILES_PROPERTYNAME
private static final String
IIOP_ENDPOINT_TYPE_PREFIX_IGNORE
private static final String
APPCLIENT_JAR_SECURITY_ELEMENT_PROPERTYNAME
Property name used to create request for elevated permissions in the JNLP document
private com.sun.enterprise.util.i18n.StringManager
localStrings
local strings manager
private Map
appclients
private Map
applications
private Map
appserverOrigins
private Map
signedAppserverOrigins
private Map
extJarAppserverOrigins
private Map
contentMap
private Map
originTypes
maps the category name to the particular map of key to content
protected com.sun.enterprise.server.ServerContext
appServerContext
the app server instance server context
protected com.sun.enterprise.instance.InstanceEnvironment
instEnv
the app server instance environment
protected com.sun.enterprise.instance.AppsManager
appsManager
the instance's J2EE applications manager
protected com.sun.enterprise.instance.AppclientModulesManager
appclientModulesManager
the instance's app client modules manager
private static final String
lineSep
private Logger
_logger
private TemplateCache
templateCache
Cache for the templates, bundled and retrieved from the jar file that contains this class.
private URI
installRootURI
URI to the app server's installation root directory
private File
installRootDir
File pointing to the app server's root directory
private URI
derbyRootURI
URI to the derby root directory
private File
derbyRootDir
File pointing to the derby root directory
private File
libRoot
File pointing to the app server's installed lib directory
private File
tempJarDirectory
File pointing to the temporary app client jar directory
private File
j2eeModulesDir
File pointing to the instance's j2ee-modules directory
private File
j2eeApplicationsDir
File pointing to the instance's j2ee-apps directory
private ExtensionFileManager
extensionFileManager
manages extension jar files
private String
UNSIGNED_JWSACC_JARFILE_NAME
private String
SIGNED_JWSACC_JARFILE_NAME
Constructors Summary
private AppclientJWSSupportInfo()
Creates a new instance of AppclientJWSSupportInfo. The constructor is private to prevent other objects from creating a new instance except through getInstance().

        
        extensionFileManager = new ExtensionFileManager();
        
        /*
         *Create the collections of content origins (such as the app server itself,
         *app clients, and applications that contain embedded app clients.
         */
        appclients = Collections.synchronizedMap(new HashMap<String,ContentOrigin>());
        applications = Collections.synchronizedMap(new HashMap<String,ContentOrigin>());
        appserverOrigins = Collections.synchronizedMap(new HashMap<String,ContentOrigin>());
        signedAppserverOrigins = Collections.synchronizedMap(new HashMap<String,ContentOrigin>());
        extJarAppserverOrigins = Collections.synchronizedMap(new HashMap<String,ContentOrigin>());
        
        contentMap = Collections.synchronizedMap(new HashMap<String,Content>());
        
        /*
         *Add these maps to the map of maps (!).
         */
        originTypes = new HashMap<String,Map<String,ContentOrigin>>();
        originTypes.put(NamingConventions.APPCLIENT_CATEGORY, appclients);
        originTypes.put(NamingConventions.APPLICATION_CATEGORY, applications);
        originTypes.put(NamingConventions.APPSERVER_CATEGORY, appserverOrigins);
        originTypes.put(NamingConventions.APPSERVER_CATEGORY, signedAppserverOrigins);
        originTypes.put(NamingConventions.APPSERVER_EXTJAR_FILES, extJarAppserverOrigins);
        
        /*
         *Get references to useful app server objects.
         */
        findAppServerObjects();

        /*
         *On Windows, the user may have entered the installation path with
         *different case compared to how the directories are actually spelled.
         *(For example, the directory might be on the disk as MyDir but the
         *user could have entered mydir.)  Windows is okay with this, but
         *a File object using mydir will yield a different URI than one
         *with MyDir.  Using the canonical path for the installation directory
         *makes sure the installRootURI is formatted consistently with the
         *ones for which we construct relative paths later on.
         */
        String installRootDirSpec = System.getProperty(SystemPropertyConstants.INSTALL_ROOT_PROPERTY);
        installRootDir = new File(installRootDirSpec).getCanonicalFile();
        installRootURI = installRootDir.toURI();
        
        String derbyRootDirSpec = System.getProperty(SystemPropertyConstants.DERBY_ROOT_PROPERTY);
        derbyRootDir = new File(derbyRootDirSpec).getCanonicalFile();
        derbyRootURI = derbyRootDir.toURI();
        
        /*
         *Create the template cache.
         */
        templateCache = new TemplateCache();
        
        /*
         *Set up the File objects for the app server's lib directory.  It is
         *used in setting up the content objects for the app server jars served
         *back to the client.
         */
        String instanceRootDirSpec = instEnv.getInstancesRoot();
        libRoot = new File(installRootDir, "lib");

        /*
         *Load the map with app server-provided files.  Do this now, because these
         *are the same for all applications or app clients.
         */
        preloadAppserverContent();
    
Methods Summary
private SignedStaticContentaddAppclientJarContent(ApplicationContentOrigin origin, java.lang.String generatedXMLLocation)
Adds the special app client static content object to the application origin and to the global content map.

param
origin the ApplicationContentOrigin to add the content to
param
generatedXMLLocation directory containing generated files for this app client
return
the newly-added static content


         return addAppclientJarContent(origin, origin.getAppclientJarPath(), generatedXMLLocation);
     
private SignedStaticContentaddAppclientJarContent(AppclientContentOrigin origin, java.lang.String generatedXMLLocation)
Adds the special app client static content object to the app client origin and to the global content map.

param
origin the AppclientContentOrigin to add the content to
param
generatedXMLLocation directory containing generated files for this app client
return
the newly-added static content

         
         return addAppclientJarContent(origin, origin.getAppclientJarPath(), generatedXMLLocation);
     
private SignedStaticContentaddAppclientJarContent(UserContentOrigin origin, java.lang.String appclientJarPath, java.lang.String generatedXMLLocation)
Adds the app client content to the specified origin, regardless of which type of user content origin is involved.

param
origin the application or app client origin to add the content to
param
appclientJarPath path to the generated app client jar
param
generatedXMLLocation directory containing the app client's generated files
return
the created StaticContent for the app client jar file

         
         File generatedJar = origin.locateGeneratedAppclientJarFile(generatedXMLLocation);
         File signedGeneratedJar = 
                 NamingConventions.SignedJar.signedGeneratedAppclientJarFile(
                        origin,
                        instEnv,
                        generatedJar);
         String contentKey = origin.getContentKeyPrefix() + "/" + signedGeneratedJar.getName();
        
         SignedStaticContent content = new SignedStaticContent(
                 origin,
                 contentKey,
                 appclientJarPath,
                 signedGeneratedJar,
                 generatedJar,
                 installRootURI,
                 localStrings,
                 false /* isMain */);
        
         addAppclientJarContent(origin, content);
         return content;
     
private SignedStaticContentaddAppclientJarContent(UserContentOrigin origin, SignedStaticContent content)
Adds the app client jar content to the origin - as with any content - but also identifies it as the app client jar. This information is used during the generation of the main JNLP document and the client JNLP document when deciding if the app client jar is signed or not.

param
origin the origin to which to add the app client jar content
param
content the app client jar static content object
return
the content object itself

         addStaticContent(origin, content);
//         origin.setPublishedAppclientJarStaticContent(content);
         return content;
         
     
private voidaddAppserverStaticContent(java.io.File dir, AppserverContentOrigin origin, boolean isMain, java.lang.String fileName)
Adds static content objects to an origin.

param
prefix to use at the beginning of the URL path for these files
param
the directory in which the files actually reside
param
the appserver origin whose pathToContent map should contain mappings for these paths to the files
param
list of file names

        for (String fn : fileName) {
            String path = "/" + fn;
            String contentKey = origin.getContentKeyPrefix() + path;
            
            AppserverStaticContent content = new AppserverStaticContent(
                origin,
                contentKey, 
                path, 
                new File(dir, fn), 
                installRootURI, 
                isMain);

            /*
             *Add the new content object both to the origin's map and also to 
             *the global content map.
             */
            addAppserverStaticContent(origin, content);
        }
    
private voidaddAppserverStaticContent(AppserverContentOrigin origin, StaticContent content)
Adds static content objects to an origin.

param
prefix to use at the beginning of the URL path for these files
param
the directory in which the files actually reside
param
the appserver origin whose pathToContent map should contain mappings for these paths to the files
param
list of file names

        /*
         *Add the new content object both to the origin's map and also to 
         *the global content map.
         */
        origin.pathToContent.put(content.getContentKey(), content);
        contentMap.put(content.getContentKey(), content);
    
private DynamicContentaddDynamicContent(ContentOrigin origin, java.lang.String path, java.lang.String templateName, java.util.Properties tokenValues, java.lang.String mimeType, boolean requiresElevatedPrivs)
Convenience method to both add content to the origin and also to the overall content map.

param
origin content origin to which to add the content
param
path URI path by which the content can be addressed within its origin
param
templateName name of the template to use for this dynamic content
param
tokenValues placeholder->value Properties object
param
mimeType MIME type of this content
param
requiresElevatedPrivs indicates if the JNLP should request privs
return
the newly-created Content
throws
IOException in case of errors retrieving the template

         
        DynamicContent content = origin.addDynamicContent(
                path, 
                templateCache.getTemplate(templateName), 
                tokenValues, 
                mimeType, 
                requiresElevatedPrivs);
        contentMap.put(content.getContentKey(), content);
        return content;
    
private DynamicContentaddDynamicContent(ContentOrigin origin, java.lang.String path, java.lang.String templateName, java.util.Properties tokenValues, java.lang.String mimeType)
Convenience method to both add content to the origin and also to the overall content map.

param
origin content origin to which to add the content
param
path URI path by which the content can be addressed within its origin
param
templateName name of the template to use for this dynamic content
param
tokenValues placeholder->value Properties object
param
mimeType MIME type of this content
return
the newly-created Content
throws
IOException in case of errors retrieving the template

        return addDynamicContent(origin, path, templateName, tokenValues, mimeType, false /* requiredElevatedPrivs */);
    
private DynamicContentaddDynamicContent(ContentOrigin origin, DynamicContent content)

         
        origin.addDynamicContent(content);
        contentMap.put(content.getContentKey(), content);
        return content;
    
private voidaddImageContent(AppclientContentOrigin origin, java.lang.String location, java.lang.String imageURI)

        addStaticContent(origin, ensureLeadingSlash(imageURI), new File(location, imageURI)); 
    
private voidaddJWSACCStaticContent(AppserverContentOrigin origin)


        String signedJarFileName = NamingConventions.SignedJar.signedJarPath(UNSIGNED_JWSACC_JARFILE_NAME);
        String path = "/" + signedJarFileName;
        String contentKey = origin.getContentKeyPrefix() + path;
        File unsignedJar = new File(installRootDir, "lib" + File.separator + UNSIGNED_JWSACC_JARFILE_NAME);
        File signedJar = new File(instEnv.getJavaWebStartPath(), signedJarFileName);
            
        SignedStaticContent content = new SignedStaticContent(
            origin,
            contentKey, 
            path,
            signedJar,
            unsignedJar,
            installRootURI,
            localStrings,
            true /* isMain */
            );
            
        addAppserverStaticContent(origin, content);
    
private StaticContentaddStaticContent(ContentOrigin origin, java.lang.String path, java.io.File file)
Convenience method to both add content to the origin and also to the overall content map.

param
the content origin to which to add the content
param
the path by which the content can be addressed within its origin
param
the file where the static content resides
return
the newly-created Content
throws
URISyntaxException in case of errors deriving a relative URI for the file

         
         StaticContent content = origin.addStaticContent(path, installRootURI, file);
         contentMap.put(content.getContentKey(), content);
         return content;
     
private StaticContentaddStaticContent(ContentOrigin origin, StaticContent content)
Convenience method to both add content to the origin and also to the overall content map.

param
origin the origin to add the content to
param
content the StaticContent instance to add
returns
the content added to the origin

         
         origin.addStaticContent(content);
         contentMap.put(content.getContentKey(), content);
         return content;
     
private java.lang.StringBuilderbuildJarElements(java.util.Map origins)
Returns a StringBuilder containing XML syntax suitable for inclusion in a JNLP document's resources section listing the jar files required by this module.

The return type is StringBuilder (rather than String) so the caller can, if needed, add additional text to the result conveniently.

param
map containing content origins of a particular category
return
StringBuilder containing JAR element text for the required jar files


        StringBuilder appserverJarElements = new StringBuilder();
        /*
         *Go through each of the groups of app server files (aslib, mqlib, etc.)
         */
        for (ContentOrigin origin : origins.values()) {
            /*
             *For this group, go through all the files.
             */
            for (Content c : origin.pathToContent.values()) {
                if (c instanceof StaticContent) {
                    StaticContent sc = (StaticContent) c;
                    appserverJarElements.append(sc.asJNLPJarElement());
                }
            }
        }
        return appserverJarElements;
    
private voidendJWSServices(AppclientContentOrigin origin)
Does the work to end Java Web Start support for the specified app client.

param
the app client for which Java Web Start is no longer needed

        
        for (Content c : origin.getContents()) {
            contentMap.remove(c.getContentKey());
        }
        
        WebPath path = new WebPath(origin.getVirtualPath());
        _logger.fine("Unregistering ad hoc servlet: " + path);

        WebContainer container = WebContainer.getInstance();
        if (container != null) {
            container.unregisterAdHocPath(path.path(), path.contextRoot());
        }
    
private voidendJWSServices(ApplicationContentOrigin origin)
Does the work to end Java Web Start support for the app clients within the specified parent application content origin.

param
the app client for which Java Web Start is no longer needed


        for (AppclientContentOrigin appclient : origin.getAppclientOrigins()) {
            endJWSServices(appclient); 
        }
        
        for (Content c : origin.getContents()) {
            contentMap.remove(c.getContentKey());
        }
    
public voidendJWSServicesForAppclient(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor moduleDescr, com.sun.enterprise.config.ConfigContext configContext)
Ends Java Web Start support for a stand-alone app client that is being unloaded from the server.

param
the application for the app client
param
the module descriptor for the app client

        _logger.fine("Ending Java Web Start services for stand-alone app client " + application.getRegistrationName());
        
        String appclientMapKey = NamingConventions.TopLevelAppclient.actualContextRoot(application);
        AppclientContentOrigin origin = findAppclient(appclientMapKey);
        if (origin != null) {
            endJWSServices(origin);
            appclients.remove(appclientMapKey);

            _logger.info("Java Web Start services ended for stand-alone app client " + origin);
        }
        refreshConfigContextForManagers(configContext);
    
public voidendJWSServicesForApplication(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor[] moduleDescrs, com.sun.enterprise.config.ConfigContext configContext)
Ends Java Web Start services for an application that may contain embedded app clients.

param
the application object for the application
param
the module descriptor for the application

         String applicationMapKey = NamingConventions.TopLevelApplication.contextRoot(application);
         ApplicationContentOrigin origin = findApplication(applicationMapKey);
         if (origin != null) {
             _logger.fine("Ending Java Web Start services for application " + origin.getTopLevelRegistrationName());
             endJWSServices(origin);
             _logger.info("Java Web Start services ended for application: " + origin);

             /*
              *Finally, remove the application's origin from the collection.
              */
             applications.remove(applicationMapKey);
         }
         refreshConfigContextForManagers(configContext);
     
private java.lang.StringensureLeadingSlash(java.lang.String s)

        if ( ! s.startsWith("/")) {
            return "/" + s;
        } else {
            return s;
        }
    
private voidfindAppServerObjects()
Loads several app server objects for retrieving useful information about the app server instance and applications deployed on it.

throws
IllegalStateException reporting any error retrieving the references

        /*
         *Build a string listing each failed attempt to locate a useful object.
         */
        StringBuilder failedObjects = new StringBuilder();
        
        Throwable relatedException = null;
        if ((appServerContext = ApplicationServer.getServerContext()) == null) {
            failedObjects.append(lineSep).append(" ApplicationServer.getServerContext()");
        }
        if ((instEnv = appServerContext.getInstanceEnvironment()) == null) {
            failedObjects.append(lineSep).append(" appServerContext.getInstanceEnvironment()");
        }
        try {
            appsManager = new AppsManager(instEnv, false);
            
        } catch (ConfigException ce) {
            relatedException = ce;
            failedObjects.append(lineSep).append(" AppsManager(instEnv)");
        }
    
        try {
            appclientModulesManager = new AppclientModulesManager(instEnv, false);
        } catch (ConfigException ce) {
            relatedException = ce;  // Might override earlier assignment; ok, since it'd be rare and both are config exc.
            failedObjects.append(lineSep).append(" AppclientModulesManager(instEnv)");
        } finally {
            /*
             *If there were any failures to find the objects, report them.
             */
            if (failedObjects.length() > 0) {
                if (relatedException == null) {
                     relatedException = new IllegalStateException("Null returned");
                }
                throw new IllegalStateException("The following utility objects could not be initialized: " + failedObjects.toString(), relatedException);
            }
        }
    
private AppclientContentOriginfindAppclient(java.lang.String regName)
Returns the AppclientContentOrigin corresponding to the app client with the specified registration name.

param
the reg name of the app client
return
the AppclientContentOrigin object for that app client; null if there is none

         AppclientContentOrigin result = (AppclientContentOrigin) appclients.get(regName);
        return result;
     
private AppclientContentOriginfindAppclient(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor moduleDescr)
Returns the AppclientContentOrigin that corresponds to the specified Application and ModuleDescriptor.

param
the Application object for the app client
param
the ModuleDescriptor object for the app client
return
the corresponding AppclientOrigin; null if no matching AppclientOrigin is found

        return findAppclient(application.getRegistrationName());
    
private ApplicationContentOriginfindApplication(java.lang.String regName)
Returns the ApplicationContentOrigin corresponding to the specified Application and ModuleDescriptor

param
the registration name for the application
return
the corresponding AppclientOrigin; null if no matching AppclientOrigin is found

        ApplicationContentOrigin result = (ApplicationContentOrigin) applications.get(regName);
        return result;
    
private ApplicationContentOriginfindApplication(com.sun.enterprise.deployment.Application application)
Returns the ApplicationContentOrigin corresponding to the specified Application and ModuleDescriptor

param
the Application object for the app client
return
the corresponding AppclientOrigin; null if no matching AppclientOrigin is found

        return findApplication(application.getRegistrationName());
    
private java.util.SetfindExtensions(java.util.jar.Attributes attrs, java.lang.String appDirPath)
Returns Extension objects for the extension jars cited by the app client. The jars represented by the Extension objects need to be available to app clients in the ear (when dealing with an ear) or to the single stand-alone app client (when dealing with a stand-alone app client).

param
attrs the main attributes of the jar of interest
param
appDirPath the app's directory to be used in resolving relative Class-Path entries
return
Set containing File objects for the required jars
throws
IOException for any error while processing the archive
throws
ConfigException for any error retrieving information about the application

        Set<ExtensionFileManager.Extension> result = null;
        
        File appDir = new File(appDirPath);
        result = extensionFileManager.findExtensionTransitiveClosure(appDir, attrs);
        return result;
    
public ContentgetContent(javax.servlet.http.HttpServletRequest request)
Returns the Content object corresponding to the path info in the HTTP request.

param
the HTTP request asking for the content
return
Content object representing the desired content; returns null if no content matches the HTTP request's information

        
        String pathInfo = request.getPathInfo();
        
        /*
         *Adjust the request's pathInfo - for instance, this removes the 
         *context-root of the web app if the web app is nested inside an ear.
         */
        String contentKey = NamingConventions.pathToContentKey(pathInfo);

        /*
         *Even though each origin tracks its own content as well, the single
         *contentMap allows a single look-up to find any content, regardless
         *of its origin.
         */
        Content result = contentMap.get(contentKey);

        /*
         *Make sure the origin for this content is currently enabled for Java 
         *Web Start access.
         */
         if (result != null) {
             ContentOrigin origin = result.getOrigin();
             if ( ! origin.isEnabled()) {
                 if (_logger.isLoggable(Level.FINE)) {
                     _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");
                 }
                 result = null;
             }
         } else if (_logger.isLoggable(Level.WARNING) && (result == null) ) {
             /*
              *Almost every request that reaches our system servlet results from
              *information we generated into the JNLP documents.  So we should not
              *receive requests for content we do not have.  If the look-up failed 
              *to find the content, report it.
              */
              _logger.warning("Attempt failed to find Java Web Start content at path " + pathInfo + "; content is available at these paths:" + contentMap.keySet());
          }
        
        return result;
    
private java.lang.StringgetIIOPEndpoints()
Returns the IIOP endpoints in the cluster in which the current instance participates.

return
String suitable for use in defining the IIOP property for endpoints; null if this instance is not in a cluster

        String result = com.sun.enterprise.iiop.IIOPEndpointsInfo.getIIOPEndpoints();
        return result;
    
public static synchronized com.sun.enterprise.appclient.jws.AppclientJWSSupportInfogetInstance()
Returns the single instance of the class.

return
the singleton AppclientJWSSupportInfo

    
                  
            
        if (instance == null) {
            instance = new AppclientJWSSupportInfo();
            
            /*
             *Make sure the manager is instantiated so it can register for
             *events.  No reference to the object needs to be kept here; 
             *just make sure the manager has been set up.
             */
             AppclientJWSSupportManager.getInstance();
        }
        return instance;
    
private java.util.jar.ManifestgetManifest(java.lang.String earDirectoryPath, com.sun.enterprise.deployment.util.ModuleDescriptor md)
Returns the manifest for the nested app client specified by the module descriptor.

param
earDirectoryPath the directory into which the ear has been expanded
param
md the ModuleDescriptor for the embedded app client of interest

        /*
         *Use the same logic that the J2EEModuleExploder uses to choose the
         *name for the embedded app client's subdirectory.
         */
        File submoduleDir = new File(DeploymentUtils.getEmbeddedModulePath(earDirectoryPath, md.getArchiveUri()));
        Manifest mf = EJBClassPathUtils.getManifest(submoduleDir.getAbsolutePath());
        return mf;
    
public booleanisEnabled(UserContentOrigin origin)
Returns whether the specified origin is currently enabled for Java Web Start access or not.

param
origin the UserContentOrigin to check
return
boolean indicating whether the app client origin is enabled for JWS access

          boolean result = false;
          String regName = origin.getApplication().getRegistrationName();
          try {
              if (origin instanceof ApplicationContentOrigin) {
                  result = appsManager.isJavaWebStartEnabled(regName);
              } else {
                  result = appclientModulesManager.isJavaWebStartEnabled(regName);
              }
              return result;
          } catch (ConfigException ce) {
              _logger.log(Level.SEVERE, "Error checking if Java Web Start access enabled for app client " + origin.getApplication().getRegistrationName(), ce);
              return false;
          }
      
public booleanisEnabled(ApplicationContentOrigin origin)
Returns whether the specified origin is currently enabled for Java Web Start access or not.

param
origin the ApplicationContentOrigin to check
return
boolean indicating whether the app client origin is enabled for JWS access

          try {
             return appsManager.isJavaWebStartEnabled(origin.getApplication().getRegistrationName());
          } catch (ConfigException ce) {
              _logger.log(Level.SEVERE, "Error checking if Java Web Start access enabled for application " + origin.getApplication().getRegistrationName(), ce);
              return false;
          }
      
private java.util.jar.ManifestloadManifestFromFile(java.lang.String dirPath)

        Manifest result = null;
        InputStream is = null;
        try {
            File manifestFile = new File(dirPath, JarFile.MANIFEST_NAME);
            if (manifestFile.exists() && manifestFile.canRead()) {
                is = new FileInputStream(manifestFile);
                result = new Manifest(is);
            }
            return result;
        } finally {
            if (is != null) {
                is.close();
            }
        }
    
private voidpreloadAppserverContent()
Loads the appserver files map.

This method loads the app server file entries into the map. This map is also used to populate part of the JNLP documents that list app server files for Java Web Start. This method is then the only place that needs to change if the list of app server files needs to change.

exception
IOException indicates problems loading a dynamic template

        
        /*
         *Build the collection of signed jar files as one content origin.
         *
         *Note that this may change so that the files listed below become part
         *of the previous group instead with only a small bootstrap jar needing
         *to be signed.
         */
        AppserverContentOrigin signedLibFilesOrigin = new AppserverContentOrigin(
                NamingConventions.APPSERVER_CATEGORY,
                NamingConventions.APPSERVER_LIB_FILES);

        addJWSACCStaticContent(signedLibFilesOrigin);
        
        /*
         *Add the app server lib files entry to the collection of app server entries.
         */
        signedAppserverOrigins.put(NamingConventions.APPSERVER_LIB_FILES, signedLibFilesOrigin);

        AppserverContentOrigin libFilesOrigin = new AppserverContentOrigin(
                NamingConventions.APPSERVER_CATEGORY,
                NamingConventions.APPSERVER_LIB_FILES);

        /*
         *Add a new static content object for each unsigned app server lib file to the
         *app server lib entry.
         */
        addAppserverStaticContent(libRoot, libFilesOrigin, false /* isMain */, 
                "appserv-rt.jar",
                "appserv-cmp.jar",
                "appserv-admin.jar",
                "appserv-deployment-client.jar",
                "javaee.jar",
                "jmac-api.jar",
                "appserv-ext.jar",
                "mail.jar",
                "activation.jar",
                "webservices-rt.jar",
                "webservices-tools.jar",
                "toplink-essentials.jar",
                "dbschema.jar"
                );

        /*
         *Add the app server lib files entry to the collection of app server origins.
         */
        appserverOrigins.put(NamingConventions.APPSERVER_LIB_FILES, libFilesOrigin);

        /*
         *Add the derby jar.
         */
        AppserverContentOrigin derbyLibFilesOrigin = new AppserverContentOrigin(
                NamingConventions.APPSERVER_CATEGORY,
                NamingConventions.APPSERVER_LIB_FILES);
        File derbyLib = new File(derbyRootDir, "lib");
        
    addAppserverStaticContent(derbyLib, derbyLibFilesOrigin, false /* isMain */, "derbyclient.jar");
        appserverOrigins.put(NamingConventions.APPSERVER_DERBY_FILES, derbyLibFilesOrigin);
        
        /*
         *Add static content objects for the mq files needed on the client and add
         *the origin to the appserver origins.
         */
        AppserverContentOrigin mqlibFilesOrigin = new AppserverContentOrigin(
            NamingConventions.APPSERVER_CATEGORY,
            NamingConventions.APPSERVER_LIB_FILES);

        File mqRoot = new File(installRootDir,  "imq");
        File mqlibRoot = new File(mqRoot, "lib");
        
        addAppserverStaticContent(mqlibRoot, mqlibFilesOrigin, false /* isMain */, "fscontext.jar");
        appserverOrigins.put(NamingConventions.APPSERVER_MQLIB_FILES, mqlibFilesOrigin);

        /*
         *Again, for the jms ra jar.
         */
        AppserverContentOrigin jmsraFilesOrigin = new AppserverContentOrigin(
            NamingConventions.APPSERVER_CATEGORY,
            NamingConventions.APPSERVER_LIB_FILES);
        
        File installRoot = new File(libRoot, "install");
        File appsRoot = new File(installRoot, "applications");
        File jmsraRoot = new File(appsRoot, "jmsra");
        
        addAppserverStaticContent(jmsraRoot, jmsraFilesOrigin, false /* isMain */, "imqjmsra.jar");
        
        appserverOrigins.put(NamingConventions.APPSERVER_JMSRALIB_FILES, jmsraFilesOrigin);
        
        /*
         *Add static content for the extension jars.
         */
        AppserverContentOrigin extJarsOrigin = new AppserverContentOrigin(
                NamingConventions.APPSERVER_CATEGORY,
                NamingConventions.APPSERVER_LIB_FILES);
        
        Map<ExtensionFileManager.ExtensionKey,ExtensionFileManager.Extension> extFileInfo = extensionFileManager.getExtensionFileEntries();
        
        for (ExtensionFileManager.Extension e : extFileInfo.values()) {
            File f = e.getFile();
            String path = NamingConventions.extJarFilePath(e.getExtDirectoryNumber(), f);
            String contentKey = extJarsOrigin.getContentKeyPrefix() + path;
            AppserverStaticContent extContent = new AppserverStaticContent(
                extJarsOrigin,
                contentKey,
                path,
                f,
                installRootURI,
                false);
                
            extJarsOrigin.pathToContent.put(extContent.getContentKey(), extContent);
            contentMap.put(extContent.getContentKey(), extContent);
        }
        
        extJarAppserverOrigins.put(NamingConventions.APPSERVER_EXTJAR_FILES, extJarsOrigin);
    
private voidprepareAppclient(AppclientContentOrigin origin, com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor moduleDescr, java.lang.String location, java.lang.String jarHRefs, java.lang.String modName, java.lang.String mainClassName, java.util.jar.Attributes mainAttrs, java.lang.String dirPathForRelativeClassPathEntries, StaticContent appclientJarContent)
Performs initialization that is common between top-level and nested app clients.

param
origin the app client origin object to be further set up
param
application the Application for this app client
param
moduleDescr the ModuleDescriptor for this app client
param
location the directory holding the app client files
param
jarHRefs a string representing the module name to be used in constructing virtual file names
param
modName the name of the module
param
mainClassName the name of the main class for this app client
param
mainAttrs the main attributes for the client that may contain extension jar requirements
param
dirPathForRelativeClassPathEntries location of the jar file to be used in resolving relative Class-Path manifest entries
param
appclientJarContent the content object describing the app client jar to publish


        /*
         *Using information now available, assemble as much of the JNLP and HTML
         *documents as possible and store them with the content origin object
         *for this app client.  As it handles specific incoming
         *requests, the JWS system servlet will do further substitutions.
         */
        Properties tokenValues = prepareInitPlaceholders(
                origin, 
                mainClassName,
                location
                );
        
        /*
         *Prepare the main JNLP document.
         *
         *Build a string containing the <jar> elements for the app server files 
         *that need to be listed in the main JNLP document.  Add the placeholder
         *name and the resulting string to the token values.
         *
         *Get the template, merge with user content (future), and substitute for placeholders.
         *Then add the now partially-substituted main JNLP document template to
         *the content map.
         */
        
        StringBuilder appserverJarElements = buildJarElements(appserverOrigins);
        StringBuilder signedAppserverJarElements = buildJarElements(signedAppserverOrigins);
        
        /*
         *Build hrefs for the extension jars in this app client.  The hrefs will be
         *inserted into the JNLP document for the app client.
         */
        Set<ExtensionFileManager.Extension> earExtJars = findExtensions(mainAttrs, dirPathForRelativeClassPathEntries);
        
        String earJarHrefs = prepareHrefsForFiles(earExtJars);
        
        
        tokenValues.setProperty("appserver.jar.elements", appserverJarElements.toString());
        tokenValues.setProperty("appserver.jar.elements.signed", signedAppserverJarElements.toString());
        tokenValues.put("appclient.jar.elements", jarHRefs);

        /*
         *Prepare the main JNLP document.
         */
        String mainJNLPPath = NamingConventions.Main.JNLPPath(modName);
        addDynamicContent(
                origin,
                mainJNLPPath,
                NamingConventions.APPCLIENT_MAIN_JNLP_TEMPLATE_NAME,
                tokenValues,
                JNLP_MIME_TYPE,
                true /* requiresElevatedPrivs */
                );

        /*
         *Prepare the main extension JNLP document.
         */
        String mainExtJNLPPath = NamingConventions.Main.JNLPExtPath(modName);
        addDynamicContent(
                origin,
                mainExtJNLPPath, 
                NamingConventions.APPCLIENT_MAIN_JNLP_EXT_TEMPLATE_NAME, 
                tokenValues, 
                JNLP_MIME_TYPE);
        
        /*
         *Prepare the main HTML document.
         */
        String mainHTMLPath = NamingConventions.Main.HTMLPath(modName);
        addDynamicContent(
                origin,
                mainHTMLPath, 
                NamingConventions.APPCLIENT_MAIN_HTML_TEMPLATE_NAME, 
                tokenValues, 
                HTML_MIME_TYPE);
        
        /*
         *Prepare the client HTML document.
         */
        String clientHTMLPath = NamingConventions.Client.HTMLPath(modName);
        addDynamicContent(
                origin,
                clientHTMLPath, 
                NamingConventions.APPCLIENT_CLIENT_HTML_TEMPLATE_NAME, 
                tokenValues, 
                HTML_MIME_TYPE);
        
        /*
         *Prepare the client JNLP document.  Get template, merge (future), substitute, add to map.
         *Note that this document's template contains a placeholder for the list of <jar>
         *elements to describe all user-provided jars it needs.  
         */
        String clientJNLPPath = NamingConventions.Client.JNLPPath(modName);
        
        String contentKey = origin.getContentKeyPrefix() + clientJNLPPath;
        String docText = Util.replaceTokens(
                templateCache.getTemplate(NamingConventions.APPCLIENT_CLIENT_JNLP_TEMPLATE_NAME),
                tokenValues);

        DynamicContent clientJNLPContent = new DynamicContent(
                origin,
                contentKey,
                clientJNLPPath,
                docText,
                JNLP_MIME_TYPE,
                true /* requiresElevatedPrivs */
                );
        
        /*
         *The security settings for the app client jar dynamic content is set
         *when the request arrives by checking the current availability of a
         *signed jar at that time. So it is not set here.
         */
        addDynamicContent(origin, clientJNLPContent);
    
private ApplicationContentOriginprepareApplication(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor[] moduleDescrs, java.lang.String earDirectory, java.lang.String generatedXMLLocation)
Prepares the document entries for an application's nested app clients.

param
application the Application descriptor
param
moduleDescrs array of ModuleDescriptor for the app's submodules
param
earDirectory the directory where the app is deployed
param
generatedXMLLocation the directory where the app's generated XML files reside

        
        ApplicationContentOrigin result = new ApplicationContentOrigin(application);
        
        /*
         *Add a static content instance for the single combined client jar file
         *for all app clients in this module.
         */
        SignedStaticContent jarFileContent = addAppclientJarContent(result, generatedXMLLocation);

        String jarHrefs = jarFileContent.asJNLPJarElement();
        
        /**
         *Each module descriptor in the array represents an app client that is eligible
         *for Java Web Start services.  For each, create a nested app client content
         *origin and add it to the parent application content origin.
         */
        for (ModuleDescriptor md : moduleDescrs) {
            /*
             *Get the descriptor for the app client of interest.
             *The prepareAppClient method uses it to extract the main class for use as a command line argument.
             */
            Manifest mf = getManifest(earDirectory, md);
            Attributes mainAttrs = mf.getMainAttributes();
            String mainClassName = mainAttrs.getValue(Attributes.Name.MAIN_CLASS);
            String appclientJarURI = md.getArchiveUri();

            /*
             *Extension libraries are not bundled into the generated jar file.
             *So any relevant extension library jar needs to be added as static
             *content for this appclient origin.  An extension library could
             *be referenced from a jar that appears in the app client's 
             *Class-Path expression.  URIs there are relative to the directory
             *that contains the jar with the Class-Path.  So we need the 
             *directory that contains the developer's app client jar.
             */
            File appclientJar = new File(appclientJarURI);
            File appclientJarDir = appclientJar.getParentFile();
            
            if ( ! appclientJar.isAbsolute()) {
                appclientJar = new File(earDirectory, appclientJarURI);
            }
            
            /*
             *Create and add the nested origin.
             */
            NestedAppclientContentOrigin nestedAppclient = prepareNestedAppclient(
                    result, 
                    md,
                    earDirectory,
                    jarHrefs, 
                    mainClassName, 
                    mainAttrs, 
                    appclientJar.getParent(), 
                    jarFileContent);
            result.addNestedOrigin(nestedAppclient);
        }
        
        return result;
    
private voidprepareAppserverPlaceholders(java.util.Properties p)
Adds values for placeholders used in the generated JNLP document that lists app server jars. These values do not depend on the particular app client but are retrieved from the local strings bundle.

param
p the Properties holding placeholders and their values

        p.setProperty(
                "appserver.information.title", 
                localStrings.getString("jws.appserver.information.title"));
        p.setProperty(
                "appserver.information.vendor", 
                localStrings.getString("jws.appserver.information.vendor"));
        p.setProperty(
                "appserver.information.description.one-line", 
                localStrings.getString("jws.appserver.information.description.one-line"));
        p.setProperty(
                "appserver.information.description.short", 
                localStrings.getString("jws.appserver.information.description.short"));
    
private java.lang.StringprepareHrefsForFiles(java.util.Set extJarInfo)
Converts a set of ExtensionFileManager.Extension objects into a String containing JNLP-friendly HREFs for those files.

param
extJarInfo List of ExtensionFileManager.Extension objects representing the jars
return
String containing an HREF for each jar in the set

        ContentOrigin extJarsOrigin = extJarAppserverOrigins.get(NamingConventions.APPSERVER_EXTJAR_FILES);
        StringBuilder result = new StringBuilder();
        for (ExtensionFileManager.Extension e : extJarInfo) {
            String path = NamingConventions.extJarFilePath(e.getExtDirectoryNumber(), e.getFile());
            String contentKey = extJarsOrigin.getContentKeyPrefix() + path;
            StaticContent content = (StaticContent) extJarsOrigin.getContent(contentKey);
            result.append(content.asJNLPJarElement()).append(lineSep);
        }
        return result.toString();
    
private voidprepareIIOPProperties(java.util.Properties props)
Prepares property value assignments for IIOP connectitivy.

        /*
         *Set the default IIOP information for the app client based on this server.  The template
         *uses the host retrieved from the incoming request as the default host value. Note that 
         *because this code and the app client container Main both must use the same property names
         *for this to work, those names are defined as constants in Main and the constants are used
         *both there and here.
         */
        props.setProperty("appclient.iiop.defaultHost.propertyName", MainWithModuleSupport.APPCLIENT_IIOP_DEFAULTHOST_PROPERTYNAME);
        props.setProperty("appclient.iiop.defaultPort.propertyName", MainWithModuleSupport.APPCLIENT_IIOP_DEFAULTPORT_PROPERTYNAME);
        props.setProperty("appclient.iiop.defaultPort", String.valueOf(ORBManager.getORBInitialPort()));
        
        /*
         *If this instance participates in a failover group, prepare the property 
         *that the JWS-aware ACC will recognize.
         */
        String failoverEndpoints = getIIOPEndpoints();
        String failoverEndpointsSetting = "";
        if (failoverEndpoints != null) {
            failoverEndpointsSetting = "<property name=\"" + MainWithModuleSupport.APPCLIENT_IIOP_FAILOVER_ENDPOINTS_PROPERTYNAME + "\" value=\"" + failoverEndpoints + "\"/>";
        }
        props.setProperty("appclient.iiop.failover.endpoints", failoverEndpointsSetting);
    
private java.lang.StringprepareImageInfo(AppclientContentOrigin origin, java.lang.String location)
Returns XML to specify the icon image, the splash screen image, neither, or both, depending on the contents of the text in the descriptor.

param
origin the AppclientContentOrigin
return
XML specifying one or both images; empty if the developer encoded no image information in the element.

        StringBuilder result = new StringBuilder();
        String imageURI = origin.getImageURI();
        if (imageURI.length() > 0) {
            result.append("<icon href=\"" + imageURI + "\"/>");
            addImageContent(origin, location, imageURI);
        }
        String splashImageURI = origin.getSplashImageURI();
        if (splashImageURI.length() > 0) {
            result.append("<icon kind=\"splash\" href=\"" + splashImageURI + "\"/>");
            addImageContent(origin, location, splashImageURI);
        }
        return result.toString();
    
protected java.util.PropertiesprepareInitPlaceholders(AppclientContentOrigin origin, java.lang.String mainClassName, java.lang.String location)
Creates Properties object containing names and values of placeholders known when an appclient or application is loaded. This excludes information available only when a request arrives. This Properties object is used to substitute the values for the names in the generated documents.

All properties are defined in a single Properties object, and that Properties instance is used in processing all dynamic documents before those dynamic documents are stored in the maps. At request-time, further substitution occurs with information available only then.

param
the origin for which values are to be assigned
param
the app client's specified main class name
param
the name of a class present in the generated app client jar file
return
Properties object containing the token-to-value correspondence
throws
IOException for errors getting information

        String appclientRegName = origin.getTopLevelRegistrationName();

        Properties answer = new Properties();

        answer.setProperty("appserver.codebase.path", NamingConventions.appServerCodebasePath());
        
        answer.setProperty("appclient.codebase.path", NamingConventions.appclientCodebasePath(origin));
        answer.setProperty("appclient.context-root", origin.getContextRoot());
        String vendor = origin.getVendor();
        answer.setProperty("appclient.vendor", (vendor == null || vendor.length() == 0) ? localStrings.getString("jws.defaultVendorName") : vendor);
        answer.setProperty("appclient.client.jnlp.filename", NamingConventions.Client.JNLPFilename(appclientRegName));
        answer.setProperty("appclient.client.html.filepath", NamingConventions.Client.HTMLPath(appclientRegName));
        answer.setProperty("appclient.mainext.jnlp.filename", NamingConventions.Main.JNLPExtFilename(appclientRegName));
        
        /*
         *Stop-gap support for specifying image and splash image.
         */
        String imageElements = prepareImageInfo(origin, location);
        answer.setProperty("appclient.information.images", imageElements);
        
//        answer.setProperty("default.wss.client.config.path", NamingConventions.defaultWSSClientConfigPathInJNLP());
//        
//        answer.setProperty("default.sun.acc.xml.url.property.name", com.sun.enterprise.appclient.MainWithModuleSupport.DEFAULT_SUN_ACC_URL_PROPERTY);
//        answer.setProperty("default.wss.client.config.xml.url.property.name", com.sun.enterprise.appclient.MainWithModuleSupport.DEFAULT_WSS_CONFIG_URL_PROPERTY);
//
//        answer.setProperty("default.sun.acc.xml.path", NamingConventions.defaultSunACCPathInJNLP());
//        answer.setProperty("security.config.file.property.name", com.sun.enterprise.appclient.MainWithModuleSupport.SUN_ACC_SECURITY_CONFIG_PROPERTY);

        prepareIIOPProperties(answer);
        
        /*
         *The Java Web Start ACC creates temporary files that are marked for deletion on exit. 
         *For diagnostic purposes, administrators can set a property on the server to
         *ask that these files be retained on the client.  The property value is sent to
         *each client when the user requests the main JNLP document.
         */
        boolean retainTempFiles = Boolean.getBoolean(SERVER_RETAIN_TEMP_FILES_PROPERTYNAME);
        answer.setProperty("appclient.retainTempFiles.propertyName", MainWithModuleSupport.APPCLIENT_RETAIN_TEMP_FILES_PROPERTYNAME);
        answer.setProperty("appclient.retainTempFiles", String.valueOf(retainTempFiles));
        
        /*
         *Set the JNLP information title to the app client module's display name,
         *if one is present.
         */
        String displayName = origin.getDisplayName();
        String jnlpInformationTitle = (displayName != null && displayName.length() > 0) ? displayName : "Application Client " + appclientRegName;
        answer.setProperty("appclient.information.title", jnlpInformationTitle);
        
        /*
         *Set the file part of the homepage URL.
         */
        String jnlpInformationHomepageFilepath = NamingConventions.Main.HTMLPath(appclientRegName);
        answer.setProperty("appclient.information.homepage.filepath", jnlpInformationHomepageFilepath);
        
        /*
         *Set the one-line description the same as the title for now.
         */
        answer.setProperty("appclient.information.description.one-line", jnlpInformationTitle);
        
        /*
         *Set the short description to the description from the descriptor, if any.
         */
        String description = origin.getDescription();
        String jnlpInformationShortDescription = (description != null && description.length() > 0) ? description : jnlpInformationTitle;
        answer.setProperty("appclient.information.description.short", jnlpInformationShortDescription);
        
        /*
         *Set up variables used for populating descriptive information in the
         *JNLP document that lists app server jars.  Although this document is
         *generated for each separate app client that is loaded, it's content
         *is basically the same for all since all app clients rely on the same
         *app server jars.
         */
        prepareAppserverPlaceholders(answer);
        
        /*
         *If a main class is specified in the manifest, use it to specify the
         *main class argument to ACC.  Otherwise, do not emit the mainclass
         *argument into the JNLP document and let the app client container
         *process any user-supplied mainclass or name argument.
         */
        String mainClassArgsValue = "";
        if ((mainClassName != null) && ( ! mainClassName.equals("")) ) {
            mainClassArgsValue = "        <argument>-mainclass</argument>" + lineSep + 
                    "        <argument>" + mainClassName + "</argument>";
        }
        answer.setProperty(
            "appclient.main.class.arguments", mainClassArgsValue);

        /*
         *Set a property that indicates to the app client container that it is
         *running under Java Web Start and what the download host name is.
         */
        answer.setProperty("appclient.isJWS.propertyName", MainWithModuleSupport.APPCLIENT_ISJWS_PROPERTYNAME);
        answer.setProperty("appclient.download.host.propertyName", MainWithModuleSupport.APPCLIENT_DOWNLOAD_HOST_PROPERTYNAME);
        answer.setProperty("appclient.user.code.is.signed.propertyName", AppClientInfo.USER_CODE_IS_SIGNED_PROPERTYNAME);
        return answer;
    
private NestedAppclientContentOriginprepareNestedAppclient(ApplicationContentOrigin parent, com.sun.enterprise.deployment.util.ModuleDescriptor moduleDescr, java.lang.String location, java.lang.String jarHRefs, java.lang.String mainClassName, java.util.jar.Attributes mainAttrs, java.lang.String dirPathForRelativeClassPathEntries, StaticContent appclienJarContent)
Returns an initialized nested app client content origin.

param
parent the parent application content origin
param
moduleDescr the module descriptor for the app client
param
location the directory containing the deployed parent EAR's files
param
jarHRefs a string representing the module name to be used in constructing virtual file names
param
mainClassName the name of the main class for this app client
param
mainAttrs the main attributes for the client that may contain extension jar requirements
param
dirPathForRelativeClassPathEntries location of the jar file to be used in resolving relative Class-Path manifest entries
param
appclientJarContent the content object describing the app client jar to publish
return
the new NestedAppclientContentOrigin

        
        String contextRoot = NamingConventions.NestedAppclient.defaultVirtualContextRoot(parent.getApplication(), moduleDescr);
        
        NestedAppclientContentOrigin result = new NestedAppclientContentOrigin(parent, moduleDescr, contextRoot);

        prepareAppclient(
                result, 
                parent.getApplication(), 
                moduleDescr, 
                location, 
                jarHRefs, 
                result.getName(), 
                mainClassName, 
                mainAttrs, 
                dirPathForRelativeClassPathEntries,
                appclienJarContent
                );
        
        return result;
    
private AppclientContentOriginprepareTopLevelAppclient(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor moduleDescr, java.lang.String location, java.lang.String generatedXMLLocation)
Prepares the content origin for a top-level app client.

The object returned describes a single, identifiable origin for content pertinent to a single app client.

param
application the Application for the app client
param
moduleDescr the ModuleDescriptor describing the app client
param
location the directory where the app client resides
param
generatedXMLLocation the directory where the app client's generated XML files reside
return
the populated content origin object for the app client; null if there is a problem creating it
throws
IOException for errors reading the app client's manifest
throws
URISyntaxException for errors preparing URIs for static content
throws
ConfigException for errors finding the app client's generated JAR directory

        
        String contextRoot = NamingConventions.TopLevelAppclient.defaultVirtualContextRoot(application);

        AppclientContentOrigin result = new AppclientContentOrigin(application, moduleDescr, contextRoot);
        String regName = result.getTopLevelRegistrationName();
        
        /*
         *Potentially, there could be multiple jar files needed by this app client.  
         *Currently, only the generated app client jar is needed.  Build the
         *string containing <jar href...> elements for insertion into the
         *client JNLP document.
         */
        
        String appclientJarPath = result.getAppclientJarPath();
        
        /*
         *Add a static content instance for the single combined client jar file
         *for all app clients in this module.
         */
        StaticContent jarFileContent = addAppclientJarContent(result, generatedXMLLocation);

        String jarHrefs = jarFileContent.asJNLPJarElement();

        String dirPath = location;
        Manifest mf = EJBClassPathUtils.getManifest(dirPath);
        Attributes mainAttrs = mf.getMainAttributes();
        String mainClassName = mainAttrs.getValue(Attributes.Name.MAIN_CLASS);
        
        /*
         *Perform the rest of the initialization which is shared with nested app client origins.
         */
        prepareAppclient(result, application, moduleDescr, dirPath, jarHrefs, regName, mainClassName, mainAttrs, dirPath, jarFileContent);
        return result;
    
private voidrefreshConfigContextForManagers(com.sun.enterprise.config.ConfigContext configContext)
Refreshes the config context in use by the apps manager and the app client modules manager.

throws
ConfigException in case of error refreshing either context

        if (configContext == null) {
            if (! ServerHelper.isDAS(appsManager.getConfigContext(), instEnv.getName())) {
                appsManager.refreshConfigContext();
                appclientModulesManager.refreshConfigContext();
            }
        } else {
            appsManager.refreshConfigContext(configContext);
            appclientModulesManager.refreshConfigContext(configContext);
        }
    
private voidstartJWSServices(AppclientContentOrigin origin)
Does the work to start Java Web Start services for an app client.

param
the appclientOrigin for which to begin JWS services

        
        WebContainer container = WebContainer.getInstance();
        if (container != null) { // Make sure that webcontainer is up.

            /*
             *Ask the web container to route requests for the app client's context-root to 
             *our ad hoc servlet using the appropriate target path for this origin.
             */
            String targetPathString = origin.getTargetPath();
            WebPath targetPath = new WebPath(targetPathString);
            JWSAdHocServletInfo info = new JWSAdHocServletInfo(targetPath.path(), targetPath.contextRoot());

            String virtualContextRoot = origin.getVirtualPath();
            WebPath virtualPath = new WebPath(virtualContextRoot);
            _logger.info("Registering ad hoc servlet: " + virtualPath);
            container.registerAdHocPath(virtualPath.path(),
                                        virtualPath.contextRoot(),
                                        origin.getTopLevelRegistrationName(),
                                        info);
            origin.adhocPathRegistered();
        }
    
private voidstartJWSServices(ApplicationContentOrigin origin)
Does the work to start Java Web Start services for app clients nested within an application.

param
the applicationOrigin for which to begin JWS services

        
        WebContainer container = WebContainer.getInstance();
        if (container != null) { // Make sure that webcontainer is up.
            /*
             *Start services for each of the child app clients.
             */
            for (AppclientContentOrigin appclient : origin.getAppclientOrigins()) {
                startJWSServices(appclient); 
            }
            origin.adhocPathRegistered();
        }
    
public voidstartJWSServicesForAppclient(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor moduleDescr, com.sun.enterprise.config.ConfigContext configContext)
Starts Java Web Start services for a stand-alone app client module.

param
the Application object for this app client
param
the ModuleDescriptor for the app client
param
the config context from the deploy event (null if the instance is restarting)

        String regName = application.getRegistrationName();
        AppClientConfig appClientConfig = new AppClientConfig(configContext, regName);
        if (appClientConfig == null) {
            throw new ConfigException("Cannot locate config information for app client " + regName);
        }

        /*
         *Make sure we don't already have services going for this app client.
         */
        String appclientMapKey = NamingConventions.TopLevelAppclient.actualContextRoot(application);
        AppclientContentOrigin origin = findAppclient(appclientMapKey);
        
        if (origin != null) {
            _logger.warning("Attempted to start Java Web Start services for stand-alone app client " + regName + " when they were already started; ignoring the duplicate request");
            return;
        }

        _logger.fine("Starting Java Web Start services for stand-alone app client " + application.getRegistrationName());
        
        /*
         *There is no pre-existing origin for this app client, so create one and
         *start Java Web Start services for it.
         */
        origin = prepareTopLevelAppclient(application, moduleDescr, 
                appClientConfig.getLocation(), appClientConfig.getGeneratedXMLLocation());
        if (origin != null) {
            startJWSServices(origin);

            appclients.put(appclientMapKey, origin);
            refreshConfigContextForManagers(configContext);

            String logOutput = (_logger.isLoggable(Level.FINE) ? origin.toLongString() : origin.toString());
            _logger.info("Java Web Start services started for stand-alone app client " + logOutput);
        }
        
    
public voidstartJWSServicesForApplication(com.sun.enterprise.deployment.Application application, com.sun.enterprise.deployment.util.ModuleDescriptor[] moduleDescriptors, com.sun.enterprise.config.ConfigContext configContext)
Starts Java Web Start services for an application that contains nested app clients which need Java Web Start support.

param
the application's registration ID
param
the module descriptors for child app clients eligible for Java Web Start access
param
the config context from the deploy event (null if during an instance restart)
exception
IOException during any retrieval of template for dynamic content

        String applicationMapKey = NamingConventions.TopLevelApplication.contextRoot(application);
        String regName = application.getRegistrationName();
        
        ApplicationConfig appConfig = new ApplicationConfig(configContext, regName);
        if (appConfig == null) {
            throw new ConfigException("Cannot locate config information for application " + regName);
        }
        _logger.fine("Starting Java Web Start services for application " + regName);

        /*
         *Make sure we don't have services running already for this application.
         */
        ApplicationContentOrigin origin = findApplication(applicationMapKey);
        if (origin != null) {
            _logger.warning("Attempt to start Java Web Start services for application " + regName + " when they were already started; ignoring the duplicate request");
            return;
        }
        
        /*
         *Preparing the application also includes preparing its child 
         *app clients, which is the real goal.
         */
        origin = prepareApplication(application, moduleDescriptors, 
                appConfig.getLocation(), appConfig.getGeneratedXMLLocation());

        startJWSServices(origin);

        /*
         *Add the origin to the collection.
         */
        applications.put(applicationMapKey, origin);

        refreshConfigContextForManagers(configContext);
        
        String logOutput = (_logger.isLoggable(Level.FINE) ? origin.toLongString() : origin.toString());
        _logger.info("Java Web Start services started for application " + logOutput);
    
public voidstartJWSServicesForDeployedAppclients()
Register all deployed appclients with JWS service. This will be called by OnDemand initialization framework, when webcontainer starts.

         for (ContentOrigin origin : appclients.values()) {
             AppclientContentOrigin acOrigin = (AppclientContentOrigin) origin;
             if (acOrigin.isAdhocPathRegistered() == false) {
                 startJWSServices(acOrigin);
             }
         }

         for (ContentOrigin origin : applications.values()) {
             ApplicationContentOrigin aOrigin = (ApplicationContentOrigin) origin;
             if (aOrigin.isAdhocPathRegistered() == false) {
                 startJWSServices(aOrigin);
             }
         }