| /* JarFile.java - Representation of a jar file | |
| Copyright (C) 2000 Free Software Foundation, Inc. | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
| 02111-1307 USA. | |
| As a special exception, if you link this library with other files to | |
| produce an executable, this library does not by itself cause the | |
| resulting executable to be covered by the GNU General Public License. | |
| This exception does not however invalidate any other reasons why the | |
| executable file might be covered by the GNU General Public License. */ | |
| package java.util.jar; | |
| import java.util.zip.ZipEntry; | |
| import java.util.zip.ZipException; | |
| import java.util.zip.ZipFile; | |
| import java.io.File; | |
| import java.io.FileNotFoundException; | |
| import java.io.InputStream; | |
| import java.io.IOException; | |
| import java.util.Enumeration; | |
| /** | |
| * Representation of a jar file. | |
| * <p> | |
| * Note that this class is not a subclass of java.io.File but a subclass of | |
| * java.util.zip.ZipFile and you can only read JarFiles with it (although | |
| * there are constructors that take a File object). | |
| * <p> | |
| * XXX - verification of Manifest signatures is not yet implemented. | |
| * | |
| * @since 1.2 | |
| * @author Mark Wielaard (mark@klomp.org) | |
| */ | |
| public class JarFile extends ZipFile | |
| { | |
| // Fields | |
| /** The name of the manifest entry: META-INF/MANIFEST.MF */ | |
| public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF"; | |
| /** | |
| * The manifest of this file, if any, otherwise null. | |
| * Read by the constructor. | |
| */ | |
| private final Manifest manifest; | |
| /** Wether to verify the manifest and all entries */ | |
| private boolean verify; | |
| // Constructors | |
| /** | |
| * Creates a new JarFile, tries to read the manifest and if the manifest | |
| * exists verifies it. | |
| * | |
| * @param fileName the name of the file to open | |
| * @exception FileNotFoundException if the fileName cannot be found | |
| * @exception IOException if another IO exception occurs while reading | |
| */ | |
| public JarFile(String fileName) throws FileNotFoundException, IOException | |
| { | |
| this(fileName, true); | |
| } | |
| /** | |
| * Creates a new JarFile, tries to read the manifest and if the manifest | |
| * exists and verify is true verfies it. | |
| * | |
| * @param fileName the name of the file to open | |
| * @param verify checks manifest and entries when true and a manifest | |
| * exists, when false no checks are made | |
| * @exception FileNotFoundException if the fileName cannot be found | |
| * @exception IOException if another IO exception occurs while reading | |
| */ | |
| public JarFile(String fileName, boolean verify) throws | |
| FileNotFoundException, IOException | |
| { | |
| super(fileName); | |
| manifest = readManifest(); | |
| if (verify) | |
| verify(); | |
| } | |
| /** | |
| * Creates a new JarFile, tries to read the manifest and if the manifest | |
| * exists verifies it. | |
| * | |
| * @param file the file to open as a jar file | |
| * @exception FileNotFoundException if the file does not exits | |
| * @exception IOException if another IO exception occurs while reading | |
| */ | |
| public JarFile(File file) throws FileNotFoundException, IOException | |
| { | |
| this(file, true); | |
| } | |
| /** | |
| * Creates a new JarFile, tries to read the manifest and if the manifest | |
| * exists and verify is true verfies it. | |
| * | |
| * @param file the file to open to open as a jar file | |
| * @param verify checks manifest and entries when true and a manifest | |
| * exists, when false no checks are made | |
| * @exception FileNotFoundException if file does not exist | |
| * @exception IOException if another IO exception occurs while reading | |
| */ | |
| public JarFile(File file, boolean verify) throws FileNotFoundException, | |
| IOException | |
| { | |
| super(file); | |
| manifest = readManifest(); | |
| if (verify) | |
| verify(); | |
| } | |
| /** | |
| * Creates a new JarFile with the indicated mode, tries to read the | |
| * manifest and if the manifest exists and verify is true verfies it. | |
| * | |
| * @param file the file to open to open as a jar file | |
| * @param verify checks manifest and entries when true and a manifest | |
| * exists, when false no checks are made | |
| * @param mode either ZipFile.OPEN_READ or | |
| * (ZipFile.OPEN_READ | ZipFile.OPEN_DELETE) | |
| * @exception FileNotFoundException if the file does not exist | |
| * @exception IOException if another IO exception occurs while reading | |
| * @exception IllegalArgumentException when given an illegal mode | |
| * | |
| * @since 1.3 | |
| */ | |
| public JarFile(File file, boolean verify, int mode) throws | |
| FileNotFoundException, IOException, IllegalArgumentException | |
| { | |
| super(file, mode); | |
| manifest = readManifest(); | |
| if (verify) | |
| verify(); | |
| } | |
| // Methods | |
| /** | |
| * XXX - should verify the manifest file | |
| */ | |
| private void verify() | |
| { | |
| // only check if manifest is not null | |
| if (manifest == null) | |
| { | |
| verify = false; | |
| return; | |
| } | |
| verify = true; | |
| // XXX - verify manifest | |
| } | |
| /** | |
| * Parses and returns the manifest if it exists, otherwise returns null. | |
| */ | |
| private Manifest readManifest() | |
| { | |
| try | |
| { | |
| ZipEntry manEntry = super.getEntry(MANIFEST_NAME); | |
| if (manEntry != null) | |
| { | |
| InputStream in = super.getInputStream(manEntry); | |
| return new Manifest(in); | |
| } | |
| else | |
| { | |
| return null; | |
| } | |
| } | |
| catch (IOException ioe) | |
| { | |
| return null; | |
| } | |
| } | |
| /** | |
| * Returns a enumeration of all the entries in the JarFile. | |
| * Note that also the Jar META-INF entries are returned. | |
| * | |
| * @exception IllegalStateException when the JarFile is already closed | |
| */ | |
| public Enumeration entries() throws IllegalStateException | |
| { | |
| return new JarEnumeration(super.entries()); | |
| } | |
| /** | |
| * Wraps a given Zip Entries Enumeration. For every zip entry a | |
| * JarEntry is created and the corresponding Attributes are looked up. | |
| * XXX - Should also look up the certificates. | |
| */ | |
| private class JarEnumeration implements Enumeration | |
| { | |
| private final Enumeration entries; | |
| JarEnumeration(Enumeration e) | |
| { | |
| entries = e; | |
| } | |
| public boolean hasMoreElements() | |
| { | |
| return entries.hasMoreElements(); | |
| } | |
| public Object nextElement() | |
| { | |
| ZipEntry zip = (ZipEntry) entries.nextElement(); | |
| JarEntry jar = new JarEntry(zip); | |
| if (manifest != null) | |
| { | |
| jar.attr = manifest.getAttributes(jar.getName()); | |
| } | |
| // XXX jar.certs | |
| return jar; | |
| } | |
| } | |
| /** | |
| * XXX | |
| * It actually returns a JarEntry not a zipEntry | |
| * @param name XXX | |
| */ | |
| public ZipEntry getEntry(String name) | |
| { | |
| ZipEntry entry = super.getEntry(name); | |
| if (entry != null) | |
| { | |
| JarEntry jarEntry = new JarEntry(entry); | |
| if (manifest != null) | |
| { | |
| jarEntry.attr = manifest.getAttributes(name); | |
| // XXX jarEntry.certs | |
| } | |
| return jarEntry; | |
| } | |
| return null; | |
| } | |
| /** | |
| * XXX should verify the inputstream | |
| * @param entry XXX | |
| * @exception ZipException XXX | |
| * @exception IOException XXX | |
| */ | |
| public synchronized InputStream getInputStream(ZipEntry entry) throws | |
| ZipException, IOException | |
| { | |
| return super.getInputStream(entry); // XXX verify | |
| } | |
| /** | |
| * Returns the JarEntry that belongs to the name if such an entry | |
| * exists in the JarFile. Returns null otherwise | |
| * Convenience method that just casts the result from <code>getEntry</code> | |
| * to a JarEntry. | |
| * | |
| * @param name the jar entry name to look up | |
| * @return the JarEntry if it exists, null otherwise | |
| */ | |
| public JarEntry getJarEntry(String name) | |
| { | |
| return (JarEntry) getEntry(name); | |
| } | |
| /** | |
| * Returns the manifest for this JarFile or null when the JarFile does not | |
| * contain a manifest file. | |
| */ | |
| public Manifest getManifest() | |
| { | |
| return manifest; | |
| } | |
| } |