KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > jar > JarInputStream


1 /*
2  * @(#)JarInputStream.java 1.35 05/05/27
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.jar;
9
10 import java.util.zip.*;
11 import java.io.*;
12 import sun.security.util.ManifestEntryVerifier;
13
14 /**
15  * The <code>JarInputStream</code> class is used to read the contents of
16  * a JAR file from any input stream. It extends the class
17  * <code>java.util.zip.ZipInputStream</code> with support for reading
18  * an optional <code>Manifest</code> entry. The <code>Manifest</code>
19  * can be used to store meta-information about the JAR file and its entries.
20  *
21  * @author David Connelly
22  * @version 1.35, 05/27/05
23  * @see Manifest
24  * @see java.util.zip.ZipInputStream
25  * @since 1.2
26  */

27 public
28 class JarInputStream extends ZipInputStream {
29     private Manifest JavaDoc man;
30     private JarEntry JavaDoc first;
31     private JarVerifier JavaDoc jv;
32     private ManifestEntryVerifier mev;
33
34
35     /**
36      * Creates a new <code>JarInputStream</code> and reads the optional
37      * manifest. If a manifest is present, also attempts to verify
38      * the signatures if the JarInputStream is signed.
39      * @param in the actual input stream
40      * @exception IOException if an I/O error has occurred
41      */

42     public JarInputStream(InputStream in) throws IOException {
43     this(in, true);
44     }
45
46     /**
47      * Creates a new <code>JarInputStream</code> and reads the optional
48      * manifest. If a manifest is present and verify is true, also attempts
49      * to verify the signatures if the JarInputStream is signed.
50      *
51      * @param in the actual input stream
52      * @param verify whether or not to verify the JarInputStream if
53      * it is signed.
54      * @exception IOException if an I/O error has occurred
55      */

56     public JarInputStream(InputStream in, boolean verify) throws IOException {
57     super(in);
58     JarEntry JavaDoc e = (JarEntry JavaDoc)super.getNextEntry();
59
60         if (e != null && e.getName().equalsIgnoreCase("META-INF/"))
61             e = (JarEntry JavaDoc)super.getNextEntry();
62
63         if (e != null && JarFile.MANIFEST_NAME.equalsIgnoreCase(e.getName())) {
64             man = new Manifest JavaDoc();
65             byte bytes[] = getBytes(new BufferedInputStream(this));
66             man.read(new ByteArrayInputStream(bytes));
67             //man.read(new BufferedInputStream(this));
68
closeEntry();
69             if (verify) {
70                 jv = new JarVerifier JavaDoc(bytes);
71                 mev = new ManifestEntryVerifier(man);
72             }
73             first = getNextJarEntry();
74         } else {
75             first = e;
76         }
77     }
78
79     private byte[] getBytes(InputStream is)
80     throws IOException
81     {
82     byte[] buffer = new byte[8192];
83     ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
84
85     int n;
86
87     baos.reset();
88     while ((n = is.read(buffer, 0, buffer.length)) != -1) {
89         baos.write(buffer, 0, n);
90     }
91     return baos.toByteArray();
92     }
93
94     /**
95      * Returns the <code>Manifest</code> for this JAR file, or
96      * <code>null</code> if none.
97      *
98      * @return the <code>Manifest</code> for this JAR file, or
99      * <code>null</code> if none.
100      */

101     public Manifest JavaDoc getManifest() {
102     return man;
103     }
104
105     /**
106      * Reads the next ZIP file entry and positions the stream at the
107      * beginning of the entry data. If verification has been enabled,
108      * any invalid signature detected while positioning the stream for
109      * the next entry will result in an exception.
110      * @exception ZipException if a ZIP file error has occurred
111      * @exception IOException if an I/O error has occurred
112      * @exception SecurityException if any of the jar file entries
113      * are incorrectly signed.
114      */

115     public ZipEntry getNextEntry() throws IOException {
116     JarEntry JavaDoc e;
117     if (first == null) {
118         e = (JarEntry JavaDoc)super.getNextEntry();
119     } else {
120         e = first;
121         first = null;
122     }
123     if (jv != null && e != null) {
124         // At this point, we might have parsed all the meta-inf
125
// entries and have nothing to verify. If we have
126
// nothing to verify, get rid of the JarVerifier object.
127
if (jv.nothingToVerify() == true) {
128         jv = null;
129         mev = null;
130         } else {
131         jv.beginEntry(e, mev);
132         }
133     }
134     return e;
135     }
136
137     /**
138      * Reads the next JAR file entry and positions the stream at the
139      * beginning of the entry data. If verification has been enabled,
140      * any invalid signature detected while positioning the stream for
141      * the next entry will result in an exception.
142      * @return the next JAR file entry, or null if there are no more entries
143      * @exception ZipException if a ZIP file error has occurred
144      * @exception IOException if an I/O error has occurred
145      * @exception SecurityException if any of the jar file entries
146      * are incorrectly signed.
147      */

148     public JarEntry JavaDoc getNextJarEntry() throws IOException {
149     return (JarEntry JavaDoc)getNextEntry();
150     }
151
152     /**
153      * Reads from the current JAR file entry into an array of bytes.
154      * Blocks until some input is available.
155      * If verification has been enabled, any invalid signature
156      * on the current entry will be reported at some point before the
157      * end of the entry is reached.
158      * @param b the buffer into which the data is read
159      * @param off the start offset of the data
160      * @param len the maximum number of bytes to read
161      * @return the actual number of bytes read, or -1 if the end of the
162      * entry is reached
163      * @exception ZipException if a ZIP file error has occurred
164      * @exception IOException if an I/O error has occurred
165      * @exception SecurityException if any of the jar file entries
166      * are incorrectly signed.
167      */

168     public int read(byte[] b, int off, int len) throws IOException {
169     int n;
170     if (first == null) {
171         n = super.read(b, off, len);
172     } else {
173         n = -1;
174     }
175     if (jv != null) {
176         jv.update(n, b, off, len, mev);
177     }
178     return n;
179     }
180
181     /**
182      * Creates a new <code>JarEntry</code> (<code>ZipEntry</code>) for the
183      * specified JAR file entry name. The manifest attributes of
184      * the specified JAR file entry name will be copied to the new
185      * <CODE>JarEntry</CODE>.
186      *
187      * @param name the name of the JAR/ZIP file entry
188      * @return the <code>JarEntry</code> object just created
189      */

190     protected ZipEntry createZipEntry(String JavaDoc name) {
191     JarEntry JavaDoc e = new JarEntry JavaDoc(name);
192     if (man != null) {
193         e.attr = man.getAttributes(name);
194     }
195     return e;
196     }
197 }
198
Popular Tags