FileDocCategorySizeDatePackage
ClientJarMakerImpl.javaAPI DocGlassfish v2 API18172Mon Jul 09 10:30:20 BST 2007com.sun.enterprise.deployment.backend

ClientJarMakerImpl

public class ClientJarMakerImpl extends Object implements com.sun.enterprise.deployment.interfaces.ClientJarMaker
This class is responsible for creating an appclient jar file that will be used by the appclient container to run the appclients for the deployed application.
author
Jerome Dochez

Fields Summary
protected Properties
props
Constructors Summary
public ClientJarMakerImpl(Properties props)
Default constructor for this stateless object

param
props are the implementation properties (if any)

        this.props = props;
    
Methods Summary
private java.lang.StringcomputeLibraryDirectory(com.sun.enterprise.deployment.RootDeploymentDescriptor d)
Returns the library directory setting for an application, or null if the module type is not an application.

param
d the descriptor for the module being processed
return
the library directory for an Application; null for other module types

        String result = null;
        if (d instanceof Application) {
            result = ((Application) d).getLibraryDirectory();
        }
        return result;
    
private voidcopy(com.sun.enterprise.deployment.deploy.shared.AbstractArchive source, com.sun.enterprise.deployment.deploy.shared.AbstractArchive source2, com.sun.enterprise.deployment.deploy.shared.AbstractArchive target, java.lang.String fileEntryName, java.util.List xmlFiles)
copy corresponding deployment descriptor if necessary.

param
source original source
param
source2 overrided source
param
target
param
fileEntryName
param
xmlFiles list of xml files no need to copy
exception
IOException

        if (!xmlFiles.contains(fileEntryName)) {
            copyWithOverride(source, source2, target, fileEntryName);
        }
    
private voidcopy(com.sun.enterprise.deployment.deploy.shared.AbstractArchive source, com.sun.enterprise.deployment.deploy.shared.AbstractArchive target, java.lang.String entryName)
copy the entryName element from the source abstract archive into the target abstract archive

            
        InputStream is=null;
        OutputStream os=null;
        try {
            is = source.getEntry(entryName);
            if (is != null) {
                try {
                    os = target.putNextEntry(entryName);
                } catch(ZipException ze) {
                    // this is a dup...
                    return;
                }
                ArchivistUtils.copyWithoutClose(is, os);
            }
        } catch (IOException ioe) {
            throw ioe;
        } finally {
            IOException closeEntryIOException = null;
            if (os!=null) {
                try {
                    target.closeEntry();
                } catch (IOException ioe) { 
                    closeEntryIOException = ioe;
                }
            }
            if (is!=null) {
                is.close();
            }
 
            if (closeEntryIOException != null) {
                throw closeEntryIOException;
            } 
        }
    
private voidcopyWithOverride(com.sun.enterprise.deployment.deploy.shared.AbstractArchive normalSource, com.sun.enterprise.deployment.deploy.shared.AbstractArchive overridingSource, com.sun.enterprise.deployment.deploy.shared.AbstractArchive target, java.lang.String entryName)
Copy an entry from the overriding source to the target if it appears in the overriding source. Otherwise copy if from the normal source.

param
normalSource the AbstractArchive from which to copy the entry if not present in overridingSource
param
overridingSource the overriding AbstractArchive from which to copy the entry
param
target the AbstractArchive into which to copy the entry
param
entryName the name of the entry to copy
throws
IOException in case of error attempting to get the specified entry

        InputStream is = overridingSource.getEntry(entryName);
        boolean result = (is != null);
        if (is != null) {
            /*
             *If the getEntry succeeds, a stream has been opened so close it.
             */
            is.close();
            copy(overridingSource, target, entryName);
        } else {
            /*
             *The entry does not appear in the overriding source.  Copy from
             *the normal source.
             */
            copy(normalSource, target, entryName);
        }
    
public voidcreate(com.sun.enterprise.deployment.RootDeploymentDescriptor descriptor, com.sun.enterprise.deployment.deploy.shared.AbstractArchive source, com.sun.enterprise.deployment.deploy.shared.AbstractArchive target, com.sun.enterprise.util.zip.ZipItem[] stubs, java.util.Properties props)
creates the appclient container jar file

param
descriptor is the loaded module's deployment descriptor
param
source is the abstract archive for the source module deployed
param
target is the abstract archive for the desired appclient container jar file
param
stubs are the stubs generated by the deployment codegen
param
props is a properties collection to pass implementation parameters
throws
IOException when the jar file creation fail

        create(descriptor, source, source, target, stubs, props);
    
public voidcreate(com.sun.enterprise.deployment.RootDeploymentDescriptor descriptor, com.sun.enterprise.deployment.deploy.shared.AbstractArchive source, com.sun.enterprise.deployment.deploy.shared.AbstractArchive source2, com.sun.enterprise.deployment.deploy.shared.AbstractArchive target, com.sun.enterprise.util.zip.ZipItem[] stubs, java.util.Properties props)
creates the appclient container jar file

param
descriptor is the loaded module's deployment descriptor
param
source is the abstract archive for the source module deployed
param
source is the abstract archive for the generated xml directory
param
target is the abstract archive for the desired appclient container jar file
param
stubs are the stubs generated by the deployment codegen
param
props is a properties collection to pass implementation parameters
throws
IOException when the jar file creation fail

        
        // in all cases we copy the stubs file in the target archive
        Set elements = new HashSet();
        for (int i=0; i<stubs.length;i++) {
            ZipItem item = stubs[i];
            if (elements.contains(item.getName())) {
                continue;
            }
            elements.add(item.getName());
            OutputStream os = null;
            InputStream is = null;
            try {
                os = target.putNextEntry(item.getName());
                is = new BufferedInputStream(new FileInputStream(item.getFile()));
                ArchivistUtils.copyWithoutClose(is, os);
            } finally {
                if (is != null) {
                    is.close();
                }
                if (os != null) {
                    target.closeEntry();
                }
            }
        }
        Vector moduleNames = new Vector();
        
        if (descriptor.isApplication()) {
            Application app = (Application) descriptor;
            for (Iterator modules = app.getModules();modules.hasNext();) {
                ModuleDescriptor md = (ModuleDescriptor) modules.next();
                Archivist moduleArchivist = ArchivistFactory.getArchivistForType(md.getModuleType());
                
                AbstractArchive subSource = source.getEmbeddedArchive(md.getArchiveUri());
                AbstractArchive subSource2 = source2.getEmbeddedArchive(md.getArchiveUri());
                moduleNames.add(md.getArchiveUri());
                
                // any file that needs to be kept in the sub module should be 
                // calculated here
                Vector subEntries = new Vector();
                // manifest file always stay in embedded jar
                subEntries.add(JarFile.MANIFEST_NAME);
                
                // all mapping file stay within the embedded jar
                WebServicesDescriptor wsd = md.getDescriptor().getWebServices();
                if (wsd!=null) {
                    for (Iterator itr = wsd.getWebServices().iterator();itr.hasNext();) {
                        WebService ws = (WebService) itr.next();
                        subEntries.add(ws.getMappingFileUri());
                    }                
                }
                
                Set refs = md.getDescriptor().getServiceReferenceDescriptors();
                for (Iterator itr = refs.iterator();itr.hasNext();) {
                    ServiceReferenceDescriptor srd = (ServiceReferenceDescriptor) itr.next();
                    subEntries.add(srd.getMappingFileUri());
                }
                
                // first copy original module files in the root on the target
                // except for .rar files contents.
                // We need to do it first so we save the list of files to be saved in the
                // embedded archive (for proper deployment descriptor loading)
                List embeddedFiles = new ArrayList();
                for (Enumeration e = subSource.entries();e.hasMoreElements();) {
                    
                    String entryName = (String) e.nextElement();
                    
                    // Deployment Descriptors (and associated) go in the embedded files
                    if (entryName.endsWith(".xml")  ||
                        subEntries.contains(entryName) ||
                        entryName.startsWith(md.getDescriptor().getWsdlDir())) {
                        
	                        embeddedFiles.add(entryName);
                    } else {
                        try {
                            copy(subSource, target, entryName);
                        } catch(IOException ioe) {
                            // dup, we ignore
                        }
                    }
                }
                
                // now we need to copy the files we saved inside the embedded
                // archive file
                
                AbstractArchive subTarget = target.getEmbeddedArchive(md.getArchiveUri());
                
                // and copy the list of identified files inside it

                // copy deployment descriptor files from generated xml directory
                for (Iterator itr = embeddedFiles.iterator();itr.hasNext();) {
                    String entryName = (String) itr.next();
                    copyWithOverride(subSource, subSource2, subTarget, entryName);
                }

                copy(subSource, subSource2, subTarget, 
                    moduleArchivist.getStandardDDFile().getDeploymentDescriptorPath(),
                    embeddedFiles);

                // every module may not have a sun descriptor, e.g. par file does not have one.
                if(moduleArchivist.getConfigurationDDFile()!=null) {
                    copy(subSource, subSource2, subTarget,
                        moduleArchivist.getConfigurationDDFile().getDeploymentDescriptorPath(),
                        embeddedFiles);
                }

                // and the manifest file since it does not appear in the list of files...
                copy(subSource, subTarget, JarFile.MANIFEST_NAME);
                
                // we do not need to copy anything else from the source embedded module
                // since all .class files and resources have moved at the top level of the target
                // application client container jar, so we can close out both subarchives
                target.closeEntry(subTarget);
                source.closeEntry(subSource);
                source2.closeEntry(subSource2);
            }
        }
        // standalone modules and .ear file level entries fall back here, we
        // just need to copy the original archive file elements at the root level
        // of the target application client container jar file.
        Archivist archivist = ArchivistFactory.getArchivistForType(descriptor.getModuleType());

        // because of the backend layout, the appclient jar file appears in the list of files
        // in the source archive (which is the exploded directory where we started writing
        // the appclient file... this is also true when doing deploydir deployment
        String appClientFileName = target.getArchiveUri().substring(target.getArchiveUri().lastIndexOf(File.separatorChar)+1);

        // and the manifest file since it does not appear in the 
        // list of files...
        copy(source, target, JarFile.MANIFEST_NAME);
        
        List xmlFiles = new ArrayList();
        String libDir = computeLibraryDirectory(descriptor);
        for (Enumeration e = source.entries(moduleNames.elements());e.hasMoreElements();) {
            String entryName = (String) e.nextElement();
            
            // if this is the appclient we are creating, we pass
            if (entryName.equals(appClientFileName)) {
                continue;
            }
            
            // now we need to write the elements in the target file and explode
            // if it is a utility jar file
            if (entryName.endsWith(".jar") && ! inLibDirSubdirectory(libDir, entryName)) {
                // explode
                AbstractArchive subSource = null;
                try {
                    subSource = source.getEmbeddedArchive(entryName);
                    for (Enumeration subEntries = subSource.entries();subEntries.hasMoreElements();) {
                        String subEntryName = (String) subEntries.nextElement();
                        if(DescriptorConstants.PERSISTENCE_DD_ENTRY.equals(subEntryName)){
                            // If we copy DescriptorConstants.PAR_DD_ENTRY into
                            // *Client.jar then during subsequent app loading time
                            // server will treat that jar as another PU Root and try to load it.
                            // so don't copy such a file.
                            continue;
                        }
                        copy(subSource, target, subEntryName);
                    }
                } finally {
                    if (subSource != null) {
                        source.closeEntry(subSource);
                    }
                }
            } else {
                if (entryName.endsWith(".xml")) {
                    xmlFiles.add(entryName);
                }
                copyWithOverride(source, source2, target, entryName);
            }
        }

        copy(source, source2, target, 
            archivist.getStandardDDFile().getDeploymentDescriptorPath(),
            xmlFiles);
        copy(source, source2, target, 
            archivist.getConfigurationDDFile().getDeploymentDescriptorPath(),
            xmlFiles);
    
private booleaninLibDirSubdirectory(java.lang.String libDir, java.lang.String entryName)
Returns whether the entry name resides in a subdirectory of the library-directory for the application.

param
libDir the library directory string including the trailing slash; null if this is not an Application descriptor
param
entryName the entry to check
return
true if the entry name resides in a subdirectory of the library directory; false otherwise

        boolean result = false;
        if ((libDir != null) && entryName.startsWith(libDir)) {
            /*
             * Skip past the trailing slash from the library directory path.
             */
            String restOfPath = entryName.substring(libDir.length() + 1);
            result = restOfPath.contains("/");
        }
        return result;