home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / util / jar / Manifest.java < prev   
Encoding:
Java Source  |  1998-03-20  |  6.7 KB  |  271 lines

  1. /*
  2.  * @(#)Manifest.java    1.13 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.util.jar;
  16.  
  17. import java.io.DataInputStream;
  18. import java.io.DataOutputStream;
  19. import java.io.InputStream;
  20. import java.io.OutputStream;
  21. import java.io.IOException;
  22. import java.util.Map;
  23. import java.util.HashMap;
  24. import java.util.Set;
  25. import java.util.Iterator;
  26. import java.util.AbstractSet;
  27.  
  28. /**
  29.  * The Manifest class is used to maintain Manifest entry names and their
  30.  * associated Attributes. There are main Manifest Attributes as well as
  31.  * per-entry Attributes.
  32.  *
  33.  * @author  David Connelly
  34.  * @version 1.13, 03/18/98
  35.  * @see        Attributes
  36.  * @since   JDK1.2
  37.  */
  38. public
  39. class Manifest implements Cloneable {
  40.     // manifest main attributes
  41.     private Attributes attr = new Attributes();
  42.  
  43.     // manifest entries
  44.     private Map entries = new Entries();
  45.  
  46.     /*
  47.      * Inner class used to maintain the Map of entry String names and
  48.      * associated Attributes. Also handles runtime type checking of method
  49.      * parameters.
  50.      */
  51.     private static class Entries extends HashMap {
  52.     public Object get(Object name) {
  53.         return super.get((String)name);
  54.     }
  55.  
  56.     public Object put(Object name, Object attr) {
  57.         return (Attributes)super.put((String)name, (Attributes)attr);
  58.     }
  59.  
  60.     public Object remove(Object name) {
  61.         return (Attributes)super.remove((String)name);
  62.     }
  63.  
  64.     public boolean containsKey(Object name) {
  65.         return super.containsKey((String)name);
  66.     }
  67.  
  68.     public void putAll(Map map) {
  69.         super.putAll((Manifest.Entries)map);
  70.     }
  71.  
  72.     public Set entries() {
  73.         final Set c = super.entries();
  74.         return new AbstractSet() {
  75.         public int size() {
  76.             return c.size();
  77.         }
  78.         public Iterator iterator() {
  79.             return new Iterator() {
  80.             private Iterator it = c.iterator();
  81.             public boolean hasNext() {
  82.                 return it.hasNext();
  83.             }
  84.             public Object next() {
  85.                 return new Entry((Map.Entry)it.next());
  86.             }
  87.             public void remove() {
  88.                 it.remove();
  89.             }
  90.             };
  91.         }
  92.         };
  93.     }
  94.  
  95.     // XXX Workaround for inner class bug
  96.     private static class Entry implements Map.Entry {
  97.         private Map.Entry e;
  98.         Entry(Map.Entry e) {
  99.         this.e = e;
  100.         }
  101.         public Object getKey() {
  102.         return (String)e.getKey();
  103.         }
  104.         public Object getValue() {
  105.         return (Attributes)e.getValue();
  106.         }
  107.         public Object setValue(Object o) {
  108.         return (Attributes)e.setValue((Attributes)o);
  109.         }
  110.         public boolean equals(Object o) {
  111.         if (o instanceof Entry) {
  112.             return e.equals(((Entry)o).e);
  113.         } else {
  114.             return false;
  115.         }
  116.         }
  117.         public int hashCode() {
  118.         return e.hashCode();
  119.         }
  120.     }
  121.  
  122.     public boolean equals(Object o) {
  123.         if (o instanceof Entries) {
  124.         return super.equals(o);
  125.         } else {
  126.         return false;
  127.         }
  128.     }
  129.     }
  130.  
  131.     /**
  132.      * Constructs a new, empty Manifest.
  133.      */
  134.     public Manifest() {
  135.     }
  136.  
  137.     /**
  138.      * Constructs a new Manifest that is a copy of the specified Manifest.
  139.      *
  140.      * @param man the Manifest to copy
  141.      */
  142.     public Manifest(Manifest man) {
  143.     attr.putAll(man.getMainAttributes());
  144.     entries.putAll(man.getEntries());
  145.     }
  146.  
  147.     /**
  148.      * Returns the main Attributes for the Manifest.
  149.      */
  150.     public Attributes getMainAttributes() {
  151.     return attr;
  152.     }
  153.  
  154.     /**
  155.      * Returns a Map of the entries contained in this Manifest. Each entry
  156.      * is represented by a String name (key) and associated Attributes (value).
  157.      */
  158.     public Map getEntries() {
  159.     return entries;
  160.     }
  161.  
  162.     /**
  163.      * Returns the Attributes for the specified entry name.
  164.      * This method is merely shorthand for the expression:
  165.      * <pre>
  166.      *        (Attributes)getEntries().get(name)
  167.      * </pre>
  168.      */
  169.     public Attributes getAttributes(String name) {
  170.     return (Attributes)getEntries().get(name);
  171.     }
  172.  
  173.     /**
  174.      * Clears the main Attributes as well as the entries in this Manifest.
  175.      */
  176.     public void clear() {
  177.     attr.clear();
  178.     entries.clear();
  179.     }
  180.  
  181.     /**
  182.      * Writes the Manifest to the specified OutputStream.
  183.      *
  184.      * @param out the output stream
  185.      * @exception IOException if an I/O error has occurred
  186.      */
  187.     public void write(OutputStream out) throws IOException {
  188.     DataOutputStream dos = new DataOutputStream(out);
  189.     // Write out the main attributes for the manifest
  190.     attr.write(dos);
  191.     // Now write out the pre-entry attributes
  192.     Iterator it = entries.entries().iterator();
  193.     while (it.hasNext()) {
  194.         Map.Entry e = (Map.Entry)it.next();
  195.         dos.writeBytes("Name: ");
  196.         dos.writeBytes((String)e.getKey());
  197.         dos.writeBytes("\r\n");
  198.         ((Attributes)e.getValue()).write(dos);
  199.     }
  200.     dos.flush();
  201.     }
  202.  
  203.     /**
  204.      * Reads the Manifest from the specified InputStream. The entry
  205.      * names and attributes read will be merged in with the current
  206.      * manifest entries.
  207.      *
  208.      * @param in the input stream
  209.      * @exception IOException if an I/O error has occurred
  210.      */
  211.     public void read(InputStream in) throws IOException {
  212.     DataInputStream dis = new DataInputStream(in);
  213.     // Read the main attributes for the manifest
  214.     attr.read(dis);
  215.     // Now parse the manifest entries
  216.     String line;
  217.     while ((line = dis.readLine()) != null) {
  218.         String name = parseField(line, "Name");
  219.         if (name == null) {
  220.         throw new IOException("invalid manifest format");
  221.         }
  222.         Attributes attr = getAttributes(name);
  223.         if (attr == null) {
  224.         attr = new Attributes();
  225.         entries.put(name, attr);
  226.         }
  227.         attr.read(dis);
  228.     }
  229.     }
  230.  
  231.     /*
  232.      * Parses a header field line from the manifest using the specified
  233.      * header field name. Returns the header field value or null if the
  234.      * name did not match.
  235.      */
  236.     private String parseField(String line, String name) {
  237.     int i = line.indexOf(": ");
  238.     if (i != -1 && name.equalsIgnoreCase(line.substring(0, i))) {
  239.         return line.substring(i + 2);
  240.     } else {
  241.         return null;
  242.     }
  243.     }
  244.  
  245.     /**
  246.      * Returns true if the specified Object is also a Manifest and has
  247.      * the same main Attributes and entries.
  248.      *
  249.      * @param o the object to be compared
  250.      */
  251.     public boolean equals(Object o) {
  252.     if (o instanceof Manifest) {
  253.         Manifest m = (Manifest)o;
  254.         return attr.equals(m.getMainAttributes()) &&
  255.            entries.equals(m.getEntries());
  256.     } else {
  257.         return false;
  258.     }
  259.     }
  260.  
  261.     /**
  262.      * Returns a shallow copy of this Manifest, implemented as follows:
  263.      * <pre>
  264.      *     public Object clone() { return new Manifest(this); }
  265.      * </pre>
  266.      */
  267.     public Object clone() {
  268.     return new Manifest(this);
  269.     }
  270. }
  271.