FileDocCategorySizeDatePackage
J2EEModuleExploder.javaAPI DocGlassfish v2 API17289Fri May 04 22:34:32 BST 2007com.sun.enterprise.deployment.backend

J2EEModuleExploder

public class J2EEModuleExploder extends Object
this class is responsible for exploding a J2EE archive file into a directory/file based structures that is used by the deployment and app server runtime.
author
Jerome Dochez

Fields Summary
private static final com.sun.enterprise.util.i18n.StringManager
localStrings
private static Logger
logger
private static final String
PRESERVED_MANIFEST_NAME
private static final String
WEB_INF_PREFIX
private static String
validationLevel
Constructors Summary
Methods Summary
public static voidexplode(java.io.File archive, java.io.File directory, java.lang.String moduleName)
explode the passed archive file inside the directory

This is the original signature for this method. It now delegates to the other variant but specifies the directory argument as also the directory into which to expand nested jar file contents. This preserves the original behavior of the method.

param
the archive
param
the destination directory
param
the module name for the archive

    
                                                                          
            
       
        explode(archive, directory, moduleName, false);
    
public static voidexplode(java.io.File archive, java.io.File directory, java.lang.String moduleName, boolean preserveManifest)
explode the passed archive file inside the directory

param
the archive
param
the destination directory
param
the module name for the archive
param
whether to prevent manifests from exploded nested jar files from overwriting the archive's manifest

        assert archive != null;
        
        
        AbstractArchiveFactory factory = null;
        if (archive.isDirectory()) {
            factory = new FileArchiveFactory();
        } else {
            factory = new JarArchiveFactory();
        }
        AbstractArchive source = factory.openArchive(archive.getAbsolutePath());
        
        // now copy the archive, let the archivist do the job...
        Archivist archivist = null;
        try {
            archivist = ArchivistFactory.getArchivistForArchive(source);
            if (archivist == null) {
                String msg = localStrings.getString
                        ("enterprise.deployment.backend.no_archivist_recognized_arch",
                        archive.getAbsolutePath()
                        );
                throw new IASDeploymentException(msg);
            }
        } catch (IOException ioe) {
            String msg = localStrings.getString
                    ("enterprise.deployment.backend.error_getting_archivist",
                    archive.getAbsolutePath()
                    );
            throw new IASDeploymentException(msg, ioe);
        }
        if (!archivist.getModuleType().equals(ModuleType.EAR)) {
            explodeModule(archivist, source, directory, moduleName, preserveManifest);
        }
    
public static com.sun.enterprise.deployment.ApplicationexplodeEar(java.io.File source, java.io.File destination)

        
        // first explode the ear file
        explodeJar(source, destination);
        
        // now we need to load the application standard deployment descriptor.
        ApplicationArchivist archivist = new ApplicationArchivist();
        archivist.setXMLValidationLevel(getValidationLevel());
        FileArchive appArchive = new FileArchive();
        appArchive.open(destination.getAbsolutePath());
        
        archivist.setManifest(appArchive.getManifest());
        
        // read the standard deployment descriptors
        Application appDesc = null;
        if (archivist.hasStandardDeploymentDescriptor(appArchive)) {
            appDesc = (Application) 
            archivist.readStandardDeploymentDescriptor(appArchive);
        } else {
            appDesc = Application.createApplication(appArchive,true);
        }

        archivist.setDescriptor(appDesc);
        
        // ok we should now have the list of modules, so we can happily explode them...
        Iterator<ModuleDescriptor> bundles = appDesc.getModules();
        while (bundles.hasNext()) {
            
            ModuleDescriptor bundle = bundles.next();
            
            String moduleName = bundle.getArchiveUri();
            String massagedModuleName =  FileUtils.makeFriendlyFilename(moduleName);
            File archiveFile = new File(destination, moduleName);
            File moduleDir = new File(destination, massagedModuleName);
            explodeJar(archiveFile, moduleDir);
            
            // delete the original module file
            archiveFile.delete();
        }
        
        return appDesc;
    
public static voidexplodeJar(java.io.File source, java.io.File destination)

        JarFile jarFile = null;
        String fileSystemName = null; // declared outside the try block so it's available in the catch block
        try {
            jarFile = new JarFile(source);
            Enumeration<JarEntry> e = jarFile.entries();
            while (e.hasMoreElements()) {
                JarEntry entry = e.nextElement();
                fileSystemName = entry.getName().replace('/", File.separatorChar);
                File out = new File(destination, fileSystemName);
                if (OS.isWindows() ) {
                    FileUtils.validateWindowsFilePathLength(out);
                }
                
                if (entry.isDirectory()) {
                    out.mkdirs();
                } else {
                    InputStream is = null;
                    FileOutputStream fos = null;
                    try {
                        if (!out.getParentFile().exists()) {
                            out.getParentFile().mkdirs();
                        }
                        is = new BufferedInputStream(jarFile.getInputStream(entry));
                        fos = FileUtils.openFileOutputStream(out);
                        ReadableByteChannel inChannel = Channels.newChannel(is);
                        FileChannel outChannel = fos.getChannel();
                        outChannel.transferFrom(inChannel, 0, entry.getSize());
                    } finally {
                        if (is!=null)
                            is.close();
                        if (fos!=null)
                            fos.close();
                    }
                }
            }
        } catch(Throwable e) {
            /*
             *Use the logger here, even though we rethrow the exception.  In
             *at least some cases the caller does not propagate this exception 
             *further, instead replacing it with a serializable 
             *IASDeployException.  The added information is then lost.
             *By logging the exception here, we make sure the log file at least
             *displays as much as we know about the problem even though the 
             *exception sent to the client may not.
             */
            String msg0 = localStrings.getString(
                    "enterprise.deployment.backend.error_expanding", 
                    new Object[] {source.getAbsolutePath()});
            String msg = localStrings.getString(
                    "enterprise.deployment.backend.could_not_expand",
                    new Object[] {fileSystemName, destination.getAbsolutePath() });
            IOException ioe = new IOException(msg0);
            ioe.initCause(e);
            getLogger().log(Level.SEVERE, msg, ioe);
            throw ioe;
        } finally {
            if (jarFile != null) {
                jarFile.close();
            }
        }
    
private static voidexplodeModule(com.sun.enterprise.deployment.archivist.Archivist archivist, com.sun.enterprise.deployment.deploy.shared.AbstractArchive source, java.io.File directory, java.lang.String moduleName, boolean preserveManifest)

        
        File explodedManifest = null;
        File preservedManifestFromArchive = null;
        
        FileArchive target = new FileArchive();
        target.create(directory.getAbsolutePath());
        
        explodeJar(new File(source.getArchiveUri()), directory);
        //archivist.copyInto(source, target);
        
        if (preserveManifest) {
            explodedManifest = new File(directory, java.util.jar.JarFile.MANIFEST_NAME);
            if (explodedManifest.exists()) {
                /* Rename the manifest so it can be restored later. */
                preservedManifestFromArchive = new File(directory, PRESERVED_MANIFEST_NAME);
                try {
                    if (OS.isWindows()) {
                        FileUtils.validateWindowsFilePathLength(preservedManifestFromArchive);
                    }
                } catch (IOException ioe) {
                    IOException newIOE = new IOException(localStrings.getString(
                            "enterprise.deployment.backend.error_saving_manifest",
                            new Object[] 
                                { explodedManifest.getAbsolutePath(),
                                          preservedManifestFromArchive.getAbsolutePath()
                                }
                            ));
                    newIOE.initCause(ioe);
                    throw newIOE;
                }
                if ( ! explodedManifest.renameTo(preservedManifestFromArchive)) {
                    throw new RuntimeException(localStrings.getString(
                            "enterprise.deployment.backend.error_saving_manifest",
                            new Object[]
                    { explodedManifest.getAbsolutePath(),
                              preservedManifestFromArchive.getAbsolutePath()
                    } ) ) ;
                }
            }
        }
        // now explode all top level jar files and delete them.
        // this cannot be done before since the optionalPkgDependency
        // require access to the manifest file of each .jar file.
        for (Enumeration itr = source.entries();itr.hasMoreElements();) {
            String fileName = (String) itr.nextElement();
            
            
            // check for optional packages depencies
            // XXX : JEROME look if this is still done
            // optionalPkgDependencyLogic(new File(directory, fileName));
            
             /*
              *Expand the file only if it is a jar and only if it does not lie in WEB-INF/lib.
              */
            if (fileName.toLowerCase().endsWith(".jar") && ( ! fileName.replace('\\", '/").toUpperCase().startsWith(WEB_INF_PREFIX)) ) {
                
                try {
                    File f = new File(directory, fileName);
                    
                    File targetDirectory = directory;
                    
                    ZipFile zip = new ZipFile(f, targetDirectory);
                    zip.explode();
                } catch(ZipFileException e) {
                    IOException ioe = new IOException(e.getMessage());
                    ioe.initCause(e);
                    throw ioe;
                }
            }
        }
         /*
          *If the archive's manifest was renamed to protect it from being overwritten by manifests from
          *jar files, then rename it back.  Delete an existing manifest file first if needed.
          */
        if (preservedManifestFromArchive != null) {
            if (explodedManifest.exists()) {
                if ( ! explodedManifest.delete()) {
                    throw new RuntimeException(localStrings.getString(
                            "enterprise.deployment.backend.error_deleting_manifest",
                            new Object []
                    { explodedManifest.getAbsolutePath(),
                              preservedManifestFromArchive.getAbsolutePath()
                    }
                    ) );
                }
            }
            
            if ( ! preservedManifestFromArchive.renameTo(explodedManifest)) {
                throw new RuntimeException(localStrings.getString(
                        "enterprise.deployment.backend.error_restoring_manifest",
                        new Object []
                { preservedManifestFromArchive.getAbsolutePath(),
                          explodedManifest.getAbsolutePath()
                }
                ) );
            }
        }
        
        source.close();
        target.close();
    
private static java.util.logging.LoggergetLogger()
Retrieves the deployment-related logger for the exploder's private use.

return
Logger for deployment-related messages

        if (logger == null) {
            logger = DeploymentLogger.get();
        }
        return logger;
    
private static java.lang.StringgetValidationLevel()

return
the validation level

        if (validationLevel == null) {
	        try {
                if (ApplicationServer.getServerContext() == null) {//verifier
                    validationLevel = DeploymentDescriptorFile.FULL_VALIDATION;
                } else {
		            ConfigContext ctx = 
                    ApplicationServer.getServerContext().getConfigContext();
		            DasConfig dc = ServerBeansFactory.getDasConfigBean(ctx);
		            validationLevel = dc.getDeployXmlValidation();
                }
	        } catch(ConfigException ce) {
                //ignore error, provide default
                validationLevel = DeploymentDescriptorFile.FULL_VALIDATION;
	        }		
        }
        return validationLevel;