Source for java.util.jar.JarInputStream

   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: }