Merge from the pain train
[official-gcc.git] / libjava / java / util / jar / Attributes.java
blobb8961411b6e1645cf879c160e8578cda5d08cc68
1 /* Attributes.java -- Represents attribute name/value pairs from a Manifest
2 Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
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.
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. */
38 package java.util.jar;
40 import java.util.Collection;
41 import java.util.Hashtable;
42 import java.util.Map;
43 import java.util.Set;
45 /**
46 * Represents attribute name/value pairs from a Manifest as a Map.
47 * The names of an attribute are represented by the
48 * <code>Attributes.Name</code> class and should confirm to the restrictions
49 * described in that class. Note that the Map interface that Attributes
50 * implements allows you to put names and values into the attribute that don't
51 * follow these restriction (and are not really Atrribute.Names, but if you do
52 * that it might cause undefined behaviour later).
53 * <p>
54 * If you use the constants defined in the inner class Name then you can be
55 * sure that you always access the right attribute names. This makes
56 * manipulating the Attributes more or less type safe.
57 * <p>
58 * Most of the methods are wrappers to implement the Map interface. The really
59 * useful and often used methods are <code>getValue(Name)</code> and
60 * <code>getValue(String)</code>. If you actually want to set attributes you
61 * may want to use the <code>putValue(String, String)</code> method
62 * (sorry there is no public type safe <code>putValue(Name, String)</code>
63 * method).
65 * @see java.util.jar.Attributes.Name
66 * @author Mark Wielaard (mark@klomp.org)
68 public class Attributes implements Cloneable, Map
71 // Fields
73 /**
74 * The map that holds all the attribute name/value pairs. In this
75 * implementation it is actually a Hashtable, but that can be different in
76 * other implementations.
78 protected Map map;
80 // Inner class
82 /**
83 * Represents a name of a Manifest Attribute. Defines a couple of well
84 * know names for the general main attributes, stand alone application
85 * attributes, applet attributes, extension identification attributes,
86 * package versioning and sealing attributes, file contents attributes,
87 * bean objects attribute and signing attributes. See the
89 * <p>The characters of a Name must obey the following restrictions:</p>
91 * <ul>
92 * <li>Must contain at least one character</li>
93 * <li>The first character must be alphanumeric (a-z, A-Z, 0-9)</li>
94 * <li>All other characters must be alphanumeric, a '-' or a '_'</li>
95 * </ul>
97 * <p>When comparing Names (with <code>equals</code>) all characters are
98 * converted to lowercase. But you can get the original case sensitive
99 * string with the <code>toString()</code> method.</p>
101 * <p>Most important attributes have a constant defined in this
102 * class. Some other attributes used in Manifest files are:
103 * <ul>
104 * <li> "Created-By" - General main attribute, tool and version
105 * that created this Manifest file.</li>
106 * <li> "Java-Bean" - Bean objects attribute, whether the entry is a Bean.
107 * Value is either "true" or "false".</li>
108 * <li> "Magic" - Signing attribute, application specific signing attribute.
109 * Must be understood by the manifest parser when present to validate the
110 * jar (entry).</li>
111 * </ul>
113 * @since 1.2
114 * @author Mark Wielaard (mark@klomp.org)
116 public static class Name
118 // General Main Attributes
121 * General main attribute -
122 * the version of this Manifest file.
124 public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
127 * General main attribute -
128 * the version of the jar file signature.
130 public static final Name SIGNATURE_VERSION
131 = new Name("Signature-Version");
134 * General main attribute -
135 * (relative) file paths of the libraries/classpaths that the Classes in
136 * this jar file depend on. Paths are separated by spaces.
138 public static final Name CLASS_PATH = new Name("Class-Path");
141 * Stand alone application attribute -
142 * the entry (without the .class ending) that is the main
143 * class of this jar file.
145 public static final Name MAIN_CLASS = new Name("Main-Class");
148 * Applet attribute -
149 * a list of extension libraries that the applet in this
150 * jar file depends on.
151 * For every named extension there should be some Attributes in the
152 * Manifest manifest file with the following Names:
153 * <ul>
154 * <li> &lt;extension&gt;-Extension-Name:
155 * unique name of the extension</li>
156 * <li> &lt;extension&gt;-Specification-Version:
157 * minimum specification version</li>
158 * <li> &lt;extension&gt;-Implementation-Version:
159 * minimum implementation version</li>
160 * <li> &lt;extension&gt;-Implementation-Vendor-Id:
161 * unique id of implementation vendor</li>
162 * <li> &lt;extension&gt;-Implementation-URL:
163 * where the latest version of the extension library can be found</li>
164 * </ul>
166 public static final Name EXTENSION_LIST = new Name("Extension-List");
169 * Extension identification attribute -
170 * the name if the extension library contained in the jar.
172 public static final Name EXTENSION_NAME = new Name("Extension-Name");
175 * Extension identification attribute -
176 * synonym for <code>EXTENSTION_NAME</code>.
178 public static final Name EXTENSION_INSTALLATION = EXTENSION_NAME;
180 // Package versioning and sealing attributes
183 * Package versioning -
184 * name of extension library contained in this jar.
186 public static final Name IMPLEMENTATION_TITLE
187 = new Name("Implementation-Title");
190 * Package versioning -
191 * version of the extension library contained in this jar.
193 public static final Name IMPLEMENTATION_VERSION
194 = new Name("Implementation-Version");
197 * Package versioning -
198 * name of extension library creator contained in this jar.
200 public static final Name IMPLEMENTATION_VENDOR
201 = new Name("Implementation-Vendor");
204 * Package versioning -
205 * unique id of extension library creator.
207 public static final Name IMPLEMENTATION_VENDOR_ID
208 = new Name("Implementation-Vendor-Id");
211 * Package versioning -
212 * location where this implementation can be downloaded.
214 public static final Name IMPLEMENTATION_URL
215 = new Name("Implementation-URL");
218 * Package versioning -
219 * title of the specification contained in this jar.
221 public static final Name SPECIFICATION_TITLE
222 = new Name("Specification-Title");
225 * Package versioning -
226 * version of the specification contained in this jar.
228 public static final Name SPECIFICATION_VERSION
229 = new Name("Specification-Version");
232 * Package versioning -
233 * organisation that maintains the specification contains in this
234 * jar.
236 public static final Name SPECIFICATION_VENDOR
237 = new Name("Specification-Vendor");
240 * Package sealing -
241 * whether (all) package(s) is(/are) sealed. Value is either "true"
242 * or "false".
244 public static final Name SEALED = new Name("Sealed");
247 * File contents attribute -
248 * Mime type and subtype for the jar entry.
250 public static final Name CONTENT_TYPE = new Name("Content-Type");
252 /** The (lowercase) String representation of this Name */
253 private final String name;
255 /** The original String given to the constructor */
256 private final String origName;
258 // Constructor
261 * Creates a new Name from the given String.
262 * Throws an IllegalArgumentException if the given String is empty or
263 * contains any illegal Name characters.
265 * @param name the name of the new Name
266 * @exception IllegalArgumentException if name isn't a valid String
267 * representation of a Name
268 * @exception NullPointerException if name is null
270 public Name(String name) throws IllegalArgumentException,
271 NullPointerException
273 // name must not be null
274 // this will throw a NullPointerException if it is
275 char chars[] = name.toCharArray();
277 // there must be at least one character
278 if (chars.length == 0)
279 throw new
280 IllegalArgumentException
281 ("There must be at least one character in a name");
283 // first character must be alphanum
284 char c = chars[0];
285 if (!((c >= 'a' && c <= 'z') ||
286 (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))
287 throw new
288 IllegalArgumentException("First character must be alphanum");
290 // all other characters must be alphanums, '-' or '_'
291 for (int i = 1; i < chars.length; i++)
293 c = chars[i];
294 if (!((c >= 'a' && c <= 'z') ||
295 (c >= 'A' && c <= 'Z') ||
296 (c >= '0' && c <= '9') || (c == '-') || (c == '_')))
297 throw new
298 IllegalArgumentException
299 ("Characters must be alphanums, '-' or '_'");
302 // Still here? Then convert to lower case and be done.
303 // Store the original name for toString();
304 this.origName = name;
305 this.name = name.toLowerCase();
309 * Returns the hash code of the (lowercase) String representation of
310 * this Name.
312 public int hashCode()
314 return name.hashCode();
318 * Checks if another object is equal to this Name object.
319 * Another object is equal to this Name object if it is an instance of
320 * Name and the (lowercase) string representation of the name is equal.
322 public boolean equals(Object o)
324 // Quick and dirty check
325 if (name == o)
326 return true;
330 // Note that the constructor already converts the strings to
331 // lowercase.
332 String otherName = ((Name) o).name;
333 return name.equals(otherName);
335 catch (ClassCastException cce)
337 return false;
339 catch (NullPointerException npe)
341 return false;
346 * Returns the string representation of this Name as given to the
347 * constructor (not neccesarily the lower case representation).
349 public String toString()
351 return origName;
355 // Constructors
358 * Creates an empty Attributes map.
360 public Attributes()
362 map = new Hashtable();
366 * Creates an empty Attributes map with the given initial size.
367 * @param size the initial size of the underlying map
369 public Attributes(int size)
371 map = new Hashtable(size);
375 * Creates an Attributes map with the initial values taken from another
376 * Attributes map.
377 * @param attr Attributes map to take the initial values from
379 public Attributes(Attributes attr)
381 map = new Hashtable(attr.map);
384 // Methods
387 * Gets the value of an attribute name given as a String.
389 * @param name a String describing the Name to look for
390 * @return the value gotten from the map of null when not found
392 public String getValue(String name)
394 return (String) get(new Name(name));
398 * Gets the value of the given attribute name.
400 * @param name the Name to look for
401 * @return the value gotten from the map of null when not found
403 public String getValue(Name name)
405 return (String) get(name);
409 * Stores an attribute name (represented by a String) and value in this
410 * Attributes map.
411 * When the (case insensitive string) name already exists the value is
412 * replaced and the old value is returned.
414 * @param name a (case insensitive) String representation of the attribite
415 * name to add/replace
416 * @param value the (new) value of the attribute name
417 * @returns the old value of the attribute name or null if it didn't exist
418 * yet
420 public String putValue(String name, String value)
422 return putValue(new Name(name), value);
426 * Stores an attribute name (represented by a String) and value in this
427 * Attributes map.
428 * When the name already exists the value is replaced and the old value
429 * is returned.
430 * <p>
431 * I don't know why there is no public method with this signature. I think
432 * there should be one.
434 * @param name the attribite name to add/replace
435 * @param value the (new) value of the attribute name
436 * @returns the old value of the attribute name or null if it didn't exist
437 * yet
439 String putValue(Name name, String value)
441 return (String) put(name, value);
444 // Methods from Cloneable interface
447 * Return a clone of this attribute map.
449 public Object clone()
451 return new Attributes(this);
454 // Methods from Map interface
457 * Removes all attributes.
459 public void clear()
461 map.clear();
465 * Checks to see if there is an attribute with the specified name.
466 * XXX - what if the object is a String?
468 * @param attrName the name of the attribute to check
469 * @return true if there is an attribute with the specified name, false
470 * otherwise
472 public boolean containsKey(Object attrName)
474 return map.containsKey(attrName);
478 * Checks to see if there is an attribute name with the specified value.
480 * @param attrValue the value of a attribute to check
481 * @return true if there is an attribute name with the specified value,
482 * false otherwise
484 public boolean containsValue(Object attrValue)
486 return map.containsValue(attrValue);
490 * Gives a Set of attribute name and values pairs as MapEntries.
491 * @see java.util.Map.Entry
492 * @see java.util.Map#entrySet()
494 * @return a set of attribute name value pairs
496 public Set entrySet()
498 return map.entrySet();
502 * Checks to see if two Attributes are equal. The supplied object must be
503 * a real instance of Attributes and contain the same attribute name/value
504 * pairs.
506 * @param o another Attribute object which should be checked for equality
507 * @return true if the object is an instance of Attributes and contains the
508 * same name/value pairs, false otherwise
510 public boolean equals(Object o)
512 // quick and dirty check
513 if (this == o)
514 return true;
518 return map.equals(((Attributes) o).map);
520 catch (ClassCastException cce)
522 return false;
524 catch (NullPointerException npe)
526 return false;
531 * Gets the value of a specified attribute name.
532 * XXX - what if the object is a String?
534 * @param attrName the name of the attribute we want the value of
535 * @return the value of the specified attribute name or null when there is
536 * no such attribute name
538 public Object get(Object attrName)
540 return map.get(attrName);
544 * Returns the hashcode of the attribute name/value map.
546 public int hashCode()
548 return map.hashCode();
552 * Returns true if there are no attributes set, false otherwise.
554 public boolean isEmpty()
556 return map.isEmpty();
560 * Gives a Set of all the values of defined attribute names.
562 public Set keySet()
564 return map.keySet();
568 * Adds or replaces a attribute name/value pair.
569 * XXX - What if the name is a string? What if the name is neither a Name
570 * nor a String? What if the value is not a string?
572 * @param name the name of the attribute
573 * @param value the (new) value of the attribute
574 * @return the old value of the attribute or null when there was no old
575 * attribute with this name
577 public Object put(Object name, Object value)
579 return map.put(name, value);
583 * Adds or replaces all attribute name/value pairs from another
584 * Attributes object to this one. The supplied Map must be an instance of
585 * Attributes.
587 * @param attr the Attributes object to merge with this one
588 * @exception ClassCastException if the supplied map is not an instance of
589 * Attributes
591 public void putAll(Map attr)
593 if (!(attr instanceof Attributes))
595 throw new
596 ClassCastException("Supplied Map is not an instance of Attributes");
598 map.putAll(attr);
602 * Remove a attribute name/value pair.
603 * XXX - What if the name is a String?
605 * @param name the name of the attribute name/value pair to remove
606 * @return the old value of the attribute or null if the attribute didn't
607 * exist
609 public Object remove(Object name)
611 return map.remove(name);
615 * Returns the number of defined attribute name/value pairs.
617 public int size()
619 return map.size();
623 * Returns all the values of the defined attribute name/value pairs as a
624 * Collection.
626 public Collection values()
628 return map.values();