FileDocCategorySizeDatePackage
JarFile.javaAPI DocAndroid 1.5 API14968Wed May 06 22:41:02 BST 2009java.util.jar

JarFile

public class JarFile extends ZipFile
{@code JarFile} is used to read jar entries and their associated data from jar files.
see
JarInputStream
see
JarEntry
since
Android 1.0

Fields Summary
public static final String
MANIFEST_NAME
The MANIFEST file name.
static final String
META_DIR
private Manifest
manifest
private ZipEntry
manifestEntry
JarVerifier
verifier
private boolean
closed
Constructors Summary
public JarFile(File file)
Create a new {@code JarFile} using the contents of the specified file.

param
file the JAR file as {@link File}.
throws
IOException If the file cannot be read.
since
Android 1.0

        this(file, true);
    
public JarFile(File file, boolean verify)
Create a new {@code JarFile} using the contents of the specified file.

param
file the JAR file as {@link File}.
param
verify if this JAR file is signed whether it must be verified.
throws
IOException If the file cannot be read.
since
Android 1.0

        super(file);
        if (verify) {
            verifier = new JarVerifier(file.getPath());
        }
        readMetaEntries();
    
public JarFile(File file, boolean verify, int mode)
Create a new {@code JarFile} using the contents of file.

param
file the JAR file as {@link File}.
param
verify if this JAR filed is signed whether it must be verified.
param
mode the mode to use, either {@link ZipFile#OPEN_READ OPEN_READ} or {@link ZipFile#OPEN_DELETE OPEN_DELETE}.
throws
IOException If the file cannot be read.
since
Android 1.0

        super(file, mode);
        if (verify) {
            verifier = new JarVerifier(file.getPath());
        }
        readMetaEntries();
    
public JarFile(String filename)
Create a new {@code JarFile} from the contents of the file specified by filename.

param
filename the file name referring to the JAR file.
throws
IOException if file name cannot be opened for reading.
since
Android 1.0

        this(filename, true);

    
public JarFile(String filename, boolean verify)
Create a new {@code JarFile} from the contents of the file specified by {@code filename}.

param
filename the file name referring to the JAR file.
param
verify if this JAR filed is signed whether it must be verified.
throws
IOException If file cannot be opened or read.
since
Android 1.0

        super(filename);
        if (verify) {
            verifier = new JarVerifier(filename);
        }
        readMetaEntries();
    
Methods Summary
public voidclose()
Closes this {@code JarFile}.

throws
IOException if an error occurs.
since
Android 1.0

        super.close();
        closed = true;
    
public java.util.Enumerationentries()
Return an enumeration containing the {@code JarEntrys} contained in this {@code JarFile}.

return
the {@code Enumeration} containing the JAR entries.
throws
IllegalStateException if this {@code JarFile} is closed.
since
Android 1.0

        class JarFileEnumerator implements Enumeration<JarEntry> {
            Enumeration<? extends ZipEntry> ze;

            JarFile jf;

            JarFileEnumerator(Enumeration<? extends ZipEntry> zenum, JarFile jf) {
                ze = zenum;
                this.jf = jf;
            }

            public boolean hasMoreElements() {
                return ze.hasMoreElements();
            }

            public JarEntry nextElement() {
                JarEntry je = new JarEntry(ze.nextElement());
                je.parentJar = jf;                
                return je;
            }
        }
        return new JarFileEnumerator(super.entries(), this);
    
private byte[]getAllBytesFromStreamAndClose(java.io.InputStream is)

        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        try {
            byte[] buf = new byte[666];
            int iRead; int off;
            while (is.available() > 0) {
                iRead = is.read(buf, 0, buf.length);
                if (iRead > 0)
                    bs.write(buf, 0, iRead);
            }
        } finally {
            is.close();
        }
        return bs.toByteArray();
    
public java.util.zip.ZipEntrygetEntry(java.lang.String name)
Return the {@code JarEntry} specified by name or {@code null} if no such entry exists.

param
name the name of the entry in the JAR file.
return
the ZIP entry extracted.
since
Android 1.0

        ZipEntry ze = super.getEntry(name);
        if (ze == null) {
            return ze;
        }
        JarEntry je = new JarEntry(ze);
        je.parentJar = this;        
        return je;
    
public java.io.InputStreamgetInputStream(java.util.zip.ZipEntry ze)
Return an {@code InputStream} for reading the decompressed contents of ZIP entry.

param
ze the ZIP entry to be read.
return
the input stream to read from.
throws
IOException if an error occurred while creating the input stream.
since
Android 1.0

        if (manifestEntry != null) {
            getManifest();
        }
        if (verifier != null) {
            verifier.setManifest(getManifest());
            if (manifest != null) {
                verifier.mainAttributesChunk = manifest
                        .getMainAttributesChunk();
            }
            if (verifier.readCertificates()) {
                verifier.removeMetaEntries();
                if (manifest != null) {
                    manifest.removeChunks();
                }
                if (!verifier.isSignedJar()) {
                    verifier = null;
                }
            }
        }
        InputStream in = super.getInputStream(ze);
        if (in == null) {
            return null;
        }
        return new JarFileInputStream(in, ze, ze.getSize() >= 0 ? verifier
                : null);
    
public java.util.jar.JarEntrygetJarEntry(java.lang.String name)
Return the {@code JarEntry} specified by its name or {@code null} if no such entry exists.

param
name the name of the entry in the JAR file.
return
the JAR entry defined by the name.
since
Android 1.0

        return (JarEntry) getEntry(name);
    
public java.util.jar.ManifestgetManifest()
Returns the {@code Manifest} object associated with this {@code JarFile} or {@code null} if no MANIFEST entry exists.

return
the MANIFEST.
throws
IOException if an error occurs reading the MANIFEST file.
throws
IllegalStateException if the jar file is closed.
see
Manifest
since
Android 1.0

        // BEGIN android-added
        if (closed) {
            throw new IllegalStateException("JarFile has been closed.");
        }
        // END android-added
        if (manifest != null) {
            return manifest;
        }
        try {
            // BEGIN android-modified
            InputStream is = super.getInputStream(manifestEntry);
            if (verifier != null) {
                verifier.addMetaEntry(manifestEntry.getName(), getAllBytesFromStreamAndClose(is));
                is = super.getInputStream(manifestEntry);
            }
            // END android-modified
            try {
                manifest = new Manifest(is, verifier != null);
            } finally {
                is.close();
            }
            manifestEntry = null;
        } catch(NullPointerException e) {
            manifestEntry = null;
        }
        return manifest;
    
private java.util.zip.ZipEntry[]getMetaEntriesImpl(byte[] buf)

        int n = 0;
        
        List<ZipEntry> list = new ArrayList<ZipEntry>();
        
        Enumeration<? extends ZipEntry> allEntries = entries();
        while (allEntries.hasMoreElements()) {
            ZipEntry ze = allEntries.nextElement();
            if (ze.getName().startsWith("META-INF/") && ze.getName().length() > 9) {
                list.add(ze);
            }
        }
        if (list.size() != 0) {
            ZipEntry[] result = new ZipEntry[list.size()];
            list.toArray(result);
            return result;
        }
        else {
            return null;
        }
    
private voidreadMetaEntries()

        ZipEntry[] metaEntries = getMetaEntriesImpl(null);
        int dirLength = META_DIR.length();

        boolean signed = false;

        if (null != metaEntries) {
            for (ZipEntry entry : metaEntries) {
                String entryName = entry.getName();
                if (manifestEntry == null
                        && manifest == null
                        && Util.ASCIIIgnoreCaseRegionMatches(entryName,
                                dirLength, MANIFEST_NAME, dirLength,
                                MANIFEST_NAME.length() - dirLength)) {
                    manifestEntry = entry;
                    if (verifier == null) {
                        break;
                    }
                } else if (verifier != null && entryName.length() > dirLength
                        && (Util.ASCIIIgnoreCaseRegionMatches(entryName, entryName.length() - 3, ".SF", 0 ,3) //$NON-NLS-1$
                           || Util.ASCIIIgnoreCaseRegionMatches(entryName, entryName.length() - 4, ".DSA", 0 ,4) //$NON-NLS-1$
                           || Util.ASCIIIgnoreCaseRegionMatches(entryName, entryName.length() - 4, ".RSA", 0 ,4))){ //$NON-NLS-1$
                    signed = true;
                    InputStream is = super.getInputStream(entry);
                    // BEGIN android-modified
                    byte[] buf = getAllBytesFromStreamAndClose(is);
                    // END android-modified
                    verifier.addMetaEntry(entryName, buf);
                }
            }
        }
        if (!signed) {
            verifier = null;
        }