Frames | No Frames |
1: /* JarInputStream.java - InputStream for reading jar files 2: Copyright (C) 2000, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package java.util.jar; 39: 40: import java.io.IOException; 41: import java.io.InputStream; 42: import java.util.zip.ZipEntry; 43: import java.util.zip.ZipInputStream; 44: 45: /** 46: * InputStream for reading jar files. 47: * XXX - verification of the signatures in the Manifest file is not yet 48: * implemented. 49: * 50: * @since 1.2 51: * @author Mark Wielaard (mark@klomp.org) 52: */ 53: 54: public class JarInputStream extends ZipInputStream 55: { 56: // Fields 57: 58: /** The manifest for this file or null when there was no manifest. */ 59: private Manifest manifest; 60: 61: /** The first real JarEntry for this file. Used by readManifest() to store 62: an entry that isn't the manifest but that should be returned by 63: getNextEntry next time it is called. Null when no firstEntry was read 64: while searching for the manifest entry, or when it has already been 65: returned by getNextEntry(). */ 66: private JarEntry firstEntry; 67: 68: // Constructors 69: 70: /** 71: * Creates a new JarInputStream and tries to read the manifest. 72: * If such a manifest is present the JarInputStream tries to verify all 73: * the entry signatures while reading. 74: * 75: * @param in InputStream to read the jar from 76: * @exception IOException when an error occurs when opening or reading 77: */ 78: public JarInputStream(InputStream in) throws IOException 79: { 80: this(in, true); 81: } 82: 83: /** 84: * Creates a new JarInputStream and tries to read the manifest. 85: * If such a manifest is present and verify is true, the JarInputStream 86: * tries to verify all the entry signatures while reading. 87: * 88: * @param in InputStream to read the jar from 89: * @param verify whether or not to verify the manifest entries 90: * @exception IOException when an error occurs when opening or reading 91: */ 92: public JarInputStream(InputStream in, boolean verify) throws IOException 93: { 94: super(in); 95: readManifest(verify); 96: } 97: 98: // Methods 99: 100: /** 101: * Set the manifest if found. Skips all entries that start with "META-INF/" 102: * 103: * @param verify when true (and a Manifest is found) checks the Manifest, 104: * when false no check is performed 105: * @exception IOException if an error occurs while reading 106: */ 107: private void readManifest(boolean verify) throws IOException 108: { 109: firstEntry = (JarEntry) super.getNextEntry(); 110: while ((firstEntry != null) && 111: firstEntry.getName().startsWith("META-INF/")) 112: { 113: if (firstEntry.getName().equals(JarFile.MANIFEST_NAME)) 114: { 115: manifest = new Manifest(this); 116: } 117: firstEntry = (JarEntry) super.getNextEntry(); 118: } 119: 120: if (verify) 121: { 122: // XXX 123: } 124: } 125: 126: /** 127: * Creates a JarEntry for a particular name and consults the manifest 128: * for the Attributes of the entry. 129: * Used by <code>ZipEntry.getNextEntry()</code> 130: * 131: * @param name the name of the new entry 132: */ 133: protected ZipEntry createZipEntry(String name) 134: { 135: ZipEntry zipEntry = super.createZipEntry(name); 136: JarEntry jarEntry = new JarEntry(zipEntry); 137: if (manifest != null) 138: { 139: jarEntry.attr = manifest.getAttributes(name); 140: } 141: return jarEntry; 142: } 143: 144: /** 145: * Returns the Manifest for the jar file or null if there was no Manifest. 146: */ 147: public Manifest getManifest() 148: { 149: return manifest; 150: } 151: 152: /** 153: * Returns the next entry or null when there are no more entries. 154: * Does actually return a JarEntry, if you don't want to cast it yourself 155: * use <code>getNextJarEntry()</code>. Does not return any entries found 156: * at the beginning of the ZipFile that are special 157: * (those that start with "META-INF/"). 158: * 159: * @exception IOException if an IO error occurs when reading the entry 160: */ 161: public ZipEntry getNextEntry() throws IOException 162: { 163: ZipEntry entry; 164: if (firstEntry != null) 165: { 166: entry = firstEntry; 167: firstEntry = null; 168: } 169: else 170: { 171: entry = super.getNextEntry(); 172: } 173: return entry; 174: } 175: 176: /** 177: * Returns the next jar entry or null when there are no more entries. 178: * 179: * @exception IOException if an IO error occurs when reading the entry 180: */ 181: public JarEntry getNextJarEntry() throws IOException 182: { 183: return (JarEntry) getNextEntry(); 184: } 185: 186: /** 187: * XXX 188: * 189: * @param buf XXX 190: * @param off XXX 191: * @param len XXX 192: * @return XXX 193: * @exception IOException XXX 194: */ 195: public int read(byte[]buf, int off, int len) throws IOException 196: { 197: // XXX if (verify) {} 198: return super.read(buf, off, len); 199: } 200: }