home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-20 | 7.1 KB | 260 lines |
- /*
- * @(#)JarFile.java 1.18 98/03/18
- *
- * Copyright 1997, 1998 by Sun Microsystems, Inc.,
- * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
- * All rights reserved.
- *
- * This software is the confidential and proprietary information
- * of Sun Microsystems, Inc. ("Confidential Information"). You
- * shall not disclose such Confidential Information and shall use
- * it only in accordance with the terms of the license agreement
- * you entered into with Sun.
- */
-
- package java.util.jar;
-
- import java.io.*;
- import java.util.Hashtable;
- import java.util.Enumeration;
- import java.util.zip.*;
- import java.lang.reflect.*;
- import java.security.Identity;
-
- /**
- * The <code>JarFile</code> class is used to read the contents of a JAR file
- * from any file that can be opened with <code>java.io.RandomAccessFile</code>.
- * It extends the class <code>java.util.zip.ZipFile</code> with support
- * for reading an optional <code>Manifest</code> entry. The
- * <code>Manifest</code> can be used to specify meta-information about the
- * JAR file and its entries.
- *
- * @author David Connelly
- * @version 1.18, 03/18/98
- * @see Manifest
- * @see java.util.zip.ZipFile
- * @see java.util.jar.JarEntry
- * @since JDK1.2
- */
- public
- class JarFile extends ZipFile {
- private Manifest man;
- private JarEntry manEntry;
- private boolean verifierInitialized = false;
- private JarVerifier jv;
- private byte[] buffer = new byte[8192];
- private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
- private byte[] rawManifestBytes;
-
- public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
-
- /**
- * Creates a new, unnamed <code>JarFile</code>.
- */
- protected JarFile() {
- super();
- }
-
- /**
- * Creates a new <code>JarFile</code> to read from the specified
- * file <code>name</code>. The <code>JarFile</code> will be verified if
- * it is signed.
- * @param name the name of the JAR file to be opened for reading
- * @exception FileNotFoundException if the file could not be found
- * @exception IOException if an I/O error has occurred
- */
- public JarFile(String name) throws IOException {
- this(name, true);
- }
-
- /**
- * Creates a new <code>JarFile</code> to read from the specified
- * file <code>name</code>.
- * @param name the name of the JAR file to be opened for reading
- * @param verify whether or not to verify the JarFile if
- * it is signed.
- * @exception FileNotFoundException if the file could not be found
- * @exception IOException if an I/O error has occurred
- */
- public JarFile(String name, boolean verify) throws IOException {
- super(name);
- JarEntry e = (JarEntry)getEntry(MANIFEST_NAME);
- if (e == null) {
- // Check all entries for matching name
- Enumeration enum = entries();
- while (enum.hasMoreElements() && e == null) {
- e = (JarEntry)enum.nextElement();
- if (!MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
- e = null;
- }
- }
- }
-
- if (e != null) {
- man = new Manifest();
- rawManifestBytes = getBytes(e);
- man.read(new ByteArrayInputStream(rawManifestBytes));
- verifierInitialized = !verify;
- manEntry = e;
- }
- }
-
- /**
- * Creates a new <code>JarFile</code> to read from the specified
- * <code>File</code> object. The <code>JarFile</code> will be verified if
- * it is signed.
- * @param file the JAR file to be opened for reading
- * @exception FileNotFoundException if the file could not be found
- * @exception IOException if an I/O error has occurred
- */
- public JarFile(File file) throws IOException {
- this(file.getPath(), true);
- }
-
-
- /**
- * Creates a new <code>JarFile</code> to read from the specified
- * <code>File</code> object.
- * @param file the JAR file to be opened for reading
- * @param verify whether or not to verify the JarFile if
- * it is signed.
- * @exception FileNotFoundException if the file could not be found
- * @exception IOException if an I/O error has occurred
- */
- public JarFile(File file, boolean verify) throws IOException {
- this(file.getPath(), verify);
- }
-
- /**
- * Returns the JAR file manifest, or <code>null</code> if none.
- */
- public Manifest getManifest() {
- return man;
- }
-
- /**
- * Returns the JarEntry for the manifest, or <code>null</code> if none.
- */
- public JarEntry getManifestEntry() {
- return manEntry;
- }
-
- /**
- * Returns the <code>JarEntry</code> for the given entry name. Returns
- * <code>null</code> if there is no entry corresponding to the given name.
- *
- * @param name the JAR file entry name
- * @see java.util.jar.JarEntry
- */
- public JarEntry getJarEntry(String name) {
- return (JarEntry)getEntry(name);
- }
-
-
- /*
- * Initializes the verifier object by reading all the META-INF
- * entries and passing them to the verifier.
- */
- private void initializeVerifier()
- {
- if (verifierInitialized) {
- return;
- }
- verifierInitialized = true;
- if (man == null) {
- return;
- }
- Enumeration e = entries();
- JarEntry je;
- String name;
- try {
- while (e.hasMoreElements()) {
- je = (JarEntry) e.nextElement();
- name = je.getName().toUpperCase();
- if (name.startsWith("META-INF/") && (!je.isDirectory())) {
- byte[] data = getBytes(je);
- if ((data != null) && (data.length > 0)) {
- if (jv == null) {
- jv = new JarVerifier(man, rawManifestBytes);
- rawManifestBytes = null;
- }
- jv.beginEntry(je);
- jv.update(data.length, data, 0, data.length);
- jv.update(-1, null, 0, 0);
- }
- }
- }
- } catch (IOException ioe) {
- // if we had an error parsing any blocks, just
- // treat the jar file as being unsigned
- jv = null;
- }
-
- }
-
- /*
- * Reads all the bytes for a given entry. This is needed
- * so we can verify all the bytes before returning them.
- */
- private synchronized byte[] getBytes(ZipEntry ze)
- throws IOException
- {
- int n;
- InputStream is = super.getInputStream(ze);
-
- baos.reset();
- long left = ze.getSize();
- while((left > 0) && (n = is.read(buffer, 0, buffer.length)) != -1) {
- baos.write(buffer, 0, n);
- left -= n;
- }
- is.close();
-
- return baos.toByteArray();
- }
-
- /**
- * Returns an input stream for reading the contents of the specified
- * ZIP file entry.
- * @param ze the zip file entry
- * @exception ZipException if a ZIP format error has occurred
- * @exception IOException if an I/O error has occurred
- */
- public synchronized InputStream getInputStream(ZipEntry ze)
- throws IOException
- {
- if (!verifierInitialized) {
- initializeVerifier();
- }
-
- // if its still null, just return super...
- if (jv == null) {
- return super.getInputStream(ze);
- }
-
- // get the bytes
- byte[] data = getBytes(ze);
-
- // verify them
- jv.beginEntry((JarEntry)ze);
- jv.update(data.length, data, 0, data.length);
- // signals end of entry
- jv.update(-1, null, 0, 0);
-
- // return them
- return new ByteArrayInputStream(data);
- }
-
- /**
- * Creates a new <code>JarEntry</code> for the specified JAR file
- * entry name.
- */
- protected ZipEntry createZipEntry(String name) {
- JarEntry e = new JarEntry(name);
- if (man != null) {
- e.attr = man.getAttributes(name);
- }
- return e;
- }
- }
-