Source for java.util.jar.Manifest

   1: /* Manifest.java -- Reads, writes and manipulates jar manifest 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 gnu.java.util.jar.JarUtils;
  41:  
  42: import java.io.IOException;
  43: import java.io.InputStream;
  44: import java.io.OutputStream;
  45: import java.util.Hashtable;
  46: import java.util.Map;
  47: 
  48: /**
  49:  * Reads, writes and manipulaties jar manifest files.
  50:  * XXX
  51:  * 
  52:  * @since 1.2
  53:  * @author Mark Wielaard (mark@klomp.org)
  54:  */
  55: public class Manifest implements Cloneable
  56: {
  57:   // Fields
  58: 
  59:   /** The main attributes of the manifest (jar file). */
  60:   private final Attributes mainAttr;
  61: 
  62:   /** A map of atrributes for all entries described in this Manifest. */
  63:   private final Map<String, Attributes> entries;
  64: 
  65:   // Constructors
  66: 
  67:   /**
  68:    * Creates a new empty Manifest.
  69:    */
  70:   public Manifest()
  71:   {
  72:     mainAttr = new Attributes();
  73:     entries = new Hashtable<String, Attributes>();
  74:   }
  75: 
  76:   /**
  77:    * Creates a Manifest from the supplied input stream.
  78:    *
  79:    * @see #read(InputStream)
  80:    * @see #write(OutputStream)
  81:    *
  82:    * @param in the input stream to read the manifest from
  83:    * @exception IOException when an i/o exception occurs or the input stream
  84:    * does not describe a valid manifest
  85:    */
  86:   public Manifest(InputStream in) throws IOException
  87:   {
  88:     this();
  89:     read(in);
  90:   }
  91: 
  92:   /**
  93:    * Creates a Manifest from another Manifest.
  94:    * Makes a deep copy of the main attributes, but a shallow copy of
  95:    * the other entries. This means that you can freely add, change or remove
  96:    * the main attributes or the entries of the new manifest without effecting
  97:    * the original manifest, but adding, changing or removing attributes from
  98:    * a particular entry also changes the attributes of that entry in the
  99:    * original manifest.
 100:    *
 101:    * @see #clone()
 102:    * @param man the Manifest to copy from
 103:    */
 104:   public Manifest(Manifest man)
 105:   {
 106:     mainAttr = new Attributes(man.getMainAttributes());
 107:     entries = new Hashtable<String, Attributes>(man.getEntries());
 108:   }
 109: 
 110:   // Methods
 111: 
 112:   /**
 113:    * Gets the main attributes of this Manifest.
 114:    */
 115:   public Attributes getMainAttributes()
 116:   {
 117:     return mainAttr;
 118:   }
 119: 
 120:   /**
 121:    * Gets a map of entry Strings to Attributes for all the entries described
 122:    * in this manifest. Adding, changing or removing from this entries map
 123:    * changes the entries of this manifest.
 124:    */
 125:   public Map<String, Attributes> getEntries()
 126:   {
 127:     return entries;
 128:   }
 129: 
 130:   /**
 131:    * Returns the Attributes associated with the Entry.
 132:    * <p>
 133:    * Implemented as:
 134:    * <code>return (Attributes)getEntries().get(entryName)</code>
 135:    *
 136:    * @param entryName the name of the entry to look up
 137:    * @return the attributes associated with the entry or null when none
 138:    */
 139:   public Attributes getAttributes(String entryName)
 140:   {
 141:     return (Attributes) getEntries().get(entryName);
 142:   }
 143: 
 144:   /**
 145:    * Clears the main attributes and removes all the entries from the
 146:    * manifest.
 147:    */
 148:   public void clear()
 149:   {
 150:     mainAttr.clear();
 151:     entries.clear();
 152:   }
 153: 
 154:   /**
 155:    * Read and merge a <code>Manifest</code> from the designated input stream.
 156:    * 
 157:    * @param in the input stream to read from.
 158:    * @throws IOException if an I/O related exception occurs during the process.
 159:    */
 160:   public void read(InputStream in) throws IOException
 161:   {
 162:     JarUtils.readMFManifest(getMainAttributes(), getEntries(), in);
 163:   }
 164: 
 165:   /**
 166:    * Writes the contents of this <code>Manifest</code> to the designated
 167:    * output stream. Line-endings are platform-independent and consist of the
 168:    * 2-codepoint sequence <code>0x0D</code> and <code>0x0A</code>.
 169:    * 
 170:    * @param out the output stream to write this <code>Manifest</code> to.
 171:    * @throws IOException if an I/O related exception occurs during the process.
 172:    */
 173:   public void write(OutputStream out) throws IOException
 174:   {
 175:     JarUtils.writeMFManifest(getMainAttributes(), getEntries(), out);
 176:   }
 177: 
 178:   /**
 179:    * Makes a deep copy of the main attributes, but a shallow copy of
 180:    * the other entries. This means that you can freely add, change or remove
 181:    * the main attributes or the entries of the new manifest without effecting
 182:    * the original manifest, but adding, changing or removing attributes from
 183:    * a particular entry also changes the attributes of that entry in the
 184:    * original manifest. Calls <CODE>new Manifest(this)</CODE>.
 185:    */
 186:   public Object clone()
 187:   {
 188:     return new Manifest(this);
 189:   }
 190: 
 191:   /**
 192:    * Checks if another object is equal to this Manifest object.
 193:    * Another Object is equal to this Manifest object if it is an instance of
 194:    * Manifest and the main attributes and the entries of the other manifest
 195:    * are equal to this one.
 196:    */
 197:   public boolean equals(Object o)
 198:   {
 199:     return (o instanceof Manifest) &&
 200:       (mainAttr.equals(((Manifest) o).mainAttr)) &&
 201:       (entries.equals(((Manifest) o).entries));
 202:   }
 203: 
 204:   /**
 205:    * Calculates the hash code of the manifest. Implemented by a xor of the
 206:    * hash code of the main attributes with the hash code of the entries map.
 207:    */
 208:   public int hashCode()
 209:   {
 210:     return mainAttr.hashCode() ^ entries.hashCode();
 211:   }
 212: 
 213: }