Package com.sun.enterprise.module.common_impl

Source Code of com.sun.enterprise.module.common_impl.Jar$Directory

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.module.common_impl;

import com.sun.enterprise.module.ModuleMetadata;
import com.sun.enterprise.module.InhabitantsDescriptor;
import com.sun.hk2.component.InhabitantParser;
import com.sun.hk2.component.InhabitantsFile;
import com.sun.hk2.component.InhabitantIntrospectionScanner;
import org.glassfish.hk2.classmodel.reflect.Parser;
import org.glassfish.hk2.classmodel.reflect.ParsingContext;

import java.io.*;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.zip.ZipException;
import java.net.URL;

/**
* Abstraction of {@link JarFile} so that we can handle
* both a jar file and a directory image transparently.
*
* @author Kohsuke Kawaguchi
*/
public abstract class Jar {
    protected Jar() {}

    /**
     * See {@link JarFile#getManifest()} for the contract.
     */
    public abstract Manifest getManifest() throws IOException;

    /**
     * Loads all <tt>META-INF/habitats</tt> entries and store them to the list.
     */
    public abstract void loadMetadata(ModuleMetadata result);

    /**
     * Gets the base name of the jar.
     *
     * <p>
     * For example, "bar" for "bar.jar".
     */
    public abstract String getBaseName();

    public static Jar create(File file) throws IOException {
        if(file.isDirectory())
            return new Directory(file);
        else
            return new Archive(file);
    }

    private static final class Directory extends Jar {
        private final File dir;

        public Directory(File dir) {
            this.dir = dir;
        }

        public Manifest getManifest() throws IOException {
            File mf = new File(dir,JarFile.MANIFEST_NAME);
            if(mf.exists()) {
                FileInputStream in = new FileInputStream(mf);
                try {
                    return new Manifest(in);
                } finally {
                    in.close();
                }
            } else {
                return null;
            }
        }

        private File[] fixNull(File[] f) {
            if(f==null) return new File[0];
            else        return f;
        }

        public void loadMetadata(ModuleMetadata result) {
            File inhabitantFileLocation = new File(dir, InhabitantsFile.PATH);
            if (!inhabitantFileLocation.exists()) {
                // rely on introspection...
                result.addHabitat("default", new InhabitantsDescriptor() {
                    public String getSystemId() {
                        return null//To change body of implemented methods use File | Settings | File Templates.
                    }



                    public Iterable<InhabitantParser> createScanner() throws IOException {
                        ParsingContext context = (new ParsingContext.Builder()).build();
                        Parser parser = new Parser(context);
                        parser.parse(dir, null);
                        try {
                            parser.awaitTermination();
                        } catch (InterruptedException e) {
                            throw new IOException(e);
                        }

                        return new InhabitantIntrospectionScanner(context);
                    }                   
                });
            }
            for( File svc : fixNull(new File(dir, InhabitantsFile.PATH).listFiles())) {
                if(svc.isDirectory())
                    continue;

                try {
                    result.addHabitat(svc.getName(),
                        new ByteArrayInhabitantsDescriptor(svc.getPath(), readFully(svc))
                    );
                } catch(IOException e) {
                    LogHelper.getDefaultLogger().log(Level.SEVERE, "Error reading habitats file from " + svc, e);
                }
            }

            for( File svc : fixNull(new File(dir, SERVICE_LOCATION).listFiles()) ) {
                if(svc.isDirectory())
                    continue;

                try {
                    result.load( svc.toURL(), svc.getName() );
                } catch(IOException e) {
                    LogHelper.getDefaultLogger().log(Level.SEVERE, "Error reading service provider from " + svc, e);
                }
            }
        }

        public String getBaseName() {
            return dir.getName();
        }

        private byte[] readFully(File f) throws IOException {
            byte[] buf = new byte[(int)f.length()];
            DataInputStream in = new DataInputStream(new FileInputStream(f));
            try {
                in.readFully(buf);
                return buf;
            } finally {
                in.close();
            }
        }
    }

    private static final class Archive extends Jar {
        private final JarFile jar;
        private final File file;

        public Archive(File jar) throws IOException {
            try {
                this.jar = new JarFile(jar);
                this.file = jar;
            } catch (ZipException e) {
                // ZipException doesn't include this crucial information, so rewrap
                IOException x = new IOException("Failed to open " + jar);
                x.initCause(e);
                throw x;
            }
        }

        public Manifest getManifest() throws IOException {
            return jar.getManifest();
        }

        public void loadMetadata(ModuleMetadata result) {

            if (jar.getJarEntry(InhabitantsFile.PATH)==null
                    && jar.getJarEntry(SERVICE_LOCATION)==null) {
                return;
            }
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                if (!entry.isDirectory() && entry.getName().startsWith(InhabitantsFile.PATH)) {
                    String habitatName = entry.getName().substring(InhabitantsFile.PATH.length()+1);

                    try {
                        result.addHabitat(habitatName,new ByteArrayInhabitantsDescriptor(
                            "jar:"+file.toURL()+"!/"+entry.getName(),
                            loadFully(entry)
                        ));
                    } catch(IOException e) {
                        LogHelper.getDefaultLogger().log(Level.SEVERE, "Error reading inhabitants list in " + jar.getName(), e);
                    }
                } else {
                    if (!entry.isDirectory() && entry.getName().startsWith(SERVICE_LOCATION)) {
                        String serviceName = entry.getName().substring(SERVICE_LOCATION.length()+1);

                        try {
                            result.load( new URL("jar:"+file.toURL()+"!/"+entry.getName()), serviceName, jar.getInputStream(entry));
                        } catch(IOException e) {
                            LogHelper.getDefaultLogger().log(Level.SEVERE, "Error reading service provider in " + jar.getName(), e);
                        }
                    }
                }
            }
        }

        public String getBaseName() {
            String name = file.getName();
            int idx = name.lastIndexOf('.');
            if(idx>=0)
                name = name.substring(0,idx);
            return name;
        }

        private byte[] loadFully(JarEntry e) throws IOException {
            byte[] buf = new byte[(int)e.getSize()];
            DataInputStream in = new DataInputStream(jar.getInputStream(e));
            try {
                in.readFully(buf);
                return buf;
            } finally {
                in.close();
            }
        }
    }
    final static private String SERVICE_LOCATION = "META-INF/services";
}
TOP

Related Classes of com.sun.enterprise.module.common_impl.Jar$Directory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.