| /* 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; |
| } |
| } |