2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / util / jar / Attributes.java
blobea203446eaa6973b9c4613e5f688bd6ce3f91037
1 /* Attributes.java -- Represents attribute name/value pairs from a Manifest
2 Copyright (C) 2000, 2002 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
88 * <p>
89 * The characters of a Name must obey the following restrictions:
90 * <ul>
91 * <li> Must contain at least one character
92 * <li> The first character must be alphanumeric (a-z, A-Z, 0-9)
93 * <li> All other characters must be alphanumeric, a '-' or a '_'
94 * </ul>
95 * <p>
96 * When comparing Names (with <code>equals</code>) all characters are
97 * converted to lowercase. But you can get the original case sensitive
98 * string with the <code>toString()</code> method.
100 * @since 1.2
101 * @author Mark Wielaard (mark@klomp.org)
103 public static class Name
106 // Fields
108 // General Main Attributes
111 * General main attribute -
112 * the version of this Manifest file.
114 public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
116 * General main attribute -
117 * tool and version that created this Manifest file.
119 public static final Name CREATED_BY = new Name("Created-By");
121 * General main attribute -
122 * the version of the jar file signature.
124 public static final Name SIGNATURE_VERSION
125 = new Name("Signature-Version");
127 * General main attribute -
128 * (relative) URLs of the libraries/classpaths that the Classes in
129 * this jar file depend on.
131 public static final Name CLASS_PATH = new Name("Class-Path");
134 * Stand alone application attribute -
135 * the entry (without the .class ending) that is the main
136 * class of this jar file.
138 public static final Name MAIN_CLASS = new Name("Main-Class");
141 * Applet attribute -
142 * a list of extension libraries that the applet in this
143 * jar file depends on.
144 * For every named extension there should be some Attributes in the
145 * Manifest manifest file with the following Names:
146 * <ul>
147 * <li> &lt;extension&gt;-Extension-Name:
148 * unique name of the extension
149 * <li> &lt;extension&gt;-Specification-Version:
150 * minimum specification version
151 * <li> &lt;extension&gt;-Implementation-Version:
152 * minimum implementation version
153 * <li> &lt;extension&gt;-Implementation-Vendor-Id:
154 * unique id of implementation vendor
155 * <li> &lt;extension&gt;-Implementation-URL:
156 * where the latest version of the extension library can be found
157 * </ul>
159 public static final Name EXTENSION_LIST = new Name("Extension-List");
162 * Extension identification attribute -
163 * the name if the extension library contained in the jar.
165 public static final Name EXTENSION_NAME = new Name("Extension-Name");
167 * Extension identification attribute -
168 * synonym for <code>EXTENSTION_NAME</code>.
170 public static final Name EXTENSION_INSTALLATION = EXTENSION_NAME;
172 // Package versioning and sealing attributes
174 * Package versioning -
175 * name of extension library contained in this jar.
177 public static final Name IMPLEMENTATION_TITLE
178 = new Name("Implementation-Title");
180 * Package versioning -
181 * version of the extension library contained in this jar.
183 public static final Name IMPLEMENTATION_VERSION
184 = new Name("Implementation-Version");
186 * Package versioning -
187 * name of extension library creator contained in this jar.
189 public static final Name IMPLEMENTATION_VENDOR
190 = new Name("Implementation-Vendor");
192 * Package versioning -
193 * unique id of extension library creator.
195 public static final Name IMPLEMENTATION_VENDOR_ID
196 = new Name("Implementation-Vendor-Id");
198 * Package versioning -
199 * location where this implementation can be downloaded.
201 public static final Name IMPLEMENTATION_URL
202 = new Name("Implementation-URL");
204 * Package versioning -
205 * title of the specification contained in this jar.
207 public static final Name SPECIFICATION_TITLE
208 = new Name("Specification-Title");
210 * Package versioning -
211 * version of the specification contained in this jar.
213 public static final Name SPECIFICATION_VERSION
214 = new Name("Specification-Version");
216 * Package versioning -
217 * organisation that maintains the specification contains in this
218 * jar.
220 public static final Name SPECIFICATION_VENDOR
221 = new Name("Specification-Vendor");
223 * Package sealing -
224 * whether (all) package(s) is(/are) sealed. Value is either "true"
225 * or "false".
227 public static final Name SEALED = new Name("Sealed");
230 * File contents attribute -
231 * Mime type and subtype for the jar entry.
233 public static final Name CONTENT_TYPE = new Name("Content-Type");
236 * Bean objects attribute -
237 * whether the entry is a Java Bean. Value is either "true" or "false".
239 public static final Name JAVA_BEAN = new Name("Java-Bean");
242 * Signing attribute -
243 * application specific signing attribute. Must be understood by
244 * the manifest parser when present to validate the jar (entry).
246 public static final Name MAGIC = new Name("Magic");
248 /** The (lowercase) String representation of this Name */
249 private final String name;
250 /** The original String given to the constructor */
251 private final String origName;
253 // Constructor
256 * Creates a new Name from the given String.
257 * Throws an IllegalArgumentException if the given String is empty or
258 * contains any illegal Name characters.
260 * @param name the name of the new Name
261 * @exception IllegalArgumentException if name isn't a valid String
262 * representation of a Name
263 * @exception NullPointerException if name is null
265 public Name(String name) throws IllegalArgumentException,
266 NullPointerException
268 // name must not be null
269 // this will throw a NullPointerException if it is
270 char chars[] = name.toCharArray();
272 // there must be at least one character
273 if (chars.length == 0)
274 throw new
275 IllegalArgumentException
276 ("There must be at least one character in a name");
278 // first character must be alphanum
279 char c = chars[0];
280 if (!((c >= 'a' && c <= 'z') ||
281 (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')))
282 throw new
283 IllegalArgumentException("First character must be alphanum");
285 // all other characters must be alphanums, '-' or '_'
286 for (int i = 1; i < chars.length; i++)
288 c = chars[i];
289 if (!((c >= 'a' && c <= 'z') ||
290 (c >= 'A' && c <= 'Z') ||
291 (c >= '0' && c <= '9') || (c == '-') || (c == '_')))
292 throw new
293 IllegalArgumentException
294 ("Characters must be alphanums, '-' or '_'");
297 // Still here? Then convert to lower case and be done.
298 // Store the original name for toString();
299 this.origName = name;
300 this.name = name.toLowerCase();
304 * Returns the hash code of the (lowercase) String representation of
305 * this Name.
307 public int hashCode()
309 return name.hashCode();
313 * Checks if another object is equal to this Name object.
314 * Another object is equal to this Name object if it is an instance of
315 * Name and the (lowercase) string representation of the name is equal.
317 public boolean equals(Object o)
319 // Quick and dirty check
320 if (name == o)
321 return true;
325 // Note that the constructor already converts the strings to
326 // lowercase.
327 String otherName = ((Name) o).name;
328 return name.equals(otherName);
330 catch (ClassCastException cce)
332 return false;
334 catch (NullPointerException npe)
336 return false;
341 * Returns the string representation of this Name as given to the
342 * constructor (not neccesarily the lower case representation).
344 public String toString()
346 return origName;
350 // Constructors
353 * Creates an empty Attributes map.
355 public Attributes()
357 map = new Hashtable();
361 * Creates an empty Attributes map with the given initial size.
362 * @param size the initial size of the underlying map
364 public Attributes(int size)
366 map = new Hashtable(size);
370 * Creates an Attributes map with the initial values taken from another
371 * Attributes map.
372 * @param attr Attributes map to take the initial values from
374 public Attributes(Attributes attr)
376 map = new Hashtable(attr.map);
379 // Methods
382 * Gets the value of an attribute name given as a String.
384 * @param name a String describing the Name to look for
385 * @return the value gotten from the map of null when not found
387 public String getValue(String name)
389 return (String) get(new Name(name));
393 * Gets the value of the given attribute name.
395 * @param name the Name to look for
396 * @return the value gotten from the map of null when not found
398 public String getValue(Name name)
400 return (String) get(name);
404 * Stores an attribute name (represented by a String) and value in this
405 * Attributes map.
406 * When the (case insensitive string) name already exists the value is
407 * replaced and the old value is returned.
409 * @param name a (case insensitive) String representation of the attribite
410 * name to add/replace
411 * @param value the (new) value of the attribute name
412 * @returns the old value of the attribute name or null if it didn't exist
413 * yet
415 public String putValue(String name, String value)
417 return putValue(new Name(name), value);
421 * Stores an attribute name (represented by a String) and value in this
422 * Attributes map.
423 * When the name already exists the value is replaced and the old value
424 * is returned.
425 * <p>
426 * I don't know why there is no public method with this signature. I think
427 * there should be one.
429 * @param name the attribite name to add/replace
430 * @param value the (new) value of the attribute name
431 * @returns the old value of the attribute name or null if it didn't exist
432 * yet
434 String putValue(Name name, String value)
436 return (String) put(name, value);
439 // Methods from Cloneable interface
442 * Return a clone of this attribute map.
444 public Object clone()
446 return new Attributes(this);
449 // Methods from Map interface
452 * Removes all attributes.
454 public void clear()
456 map.clear();
460 * Checks to see if there is an attribute with the specified name.
461 * XXX - what if the object is a String?
463 * @param attrName the name of the attribute to check
464 * @return true if there is an attribute with the specified name, false
465 * otherwise
467 public boolean containsKey(Object attrName)
469 return map.containsKey(attrName);
473 * Checks to see if there is an attribute name with the specified value.
475 * @param attrValue the value of a attribute to check
476 * @return true if there is an attribute name with the specified value,
477 * false otherwise
479 public boolean containsValue(Object attrValue)
481 return map.containsValue(attrValue);
485 * Gives a Set of attribute name and values pairs as MapEntries.
486 * @see java.util.Map.Entry
487 * @see java.util.Map#entrySet()
489 * @return a set of attribute name value pairs
491 public Set entrySet()
493 return map.entrySet();
497 * Checks to see if two Attributes are equal. The supplied object must be
498 * a real instance of Attributes and contain the same attribute name/value
499 * pairs.
501 * @param o another Attribute object which should be checked for equality
502 * @return true if the object is an instance of Attributes and contains the
503 * same name/value pairs, false otherwise
505 public boolean equals(Object o)
507 // quick and dirty check
508 if (this == o)
509 return true;
513 return map.equals(((Attributes) o).map);
515 catch (ClassCastException cce)
517 return false;
519 catch (NullPointerException npe)
521 return false;
526 * Gets the value of a specified attribute name.
527 * XXX - what if the object is a String?
529 * @param attrName the name of the attribute we want the value of
530 * @return the value of the specified attribute name or null when there is
531 * no such attribute name
533 public Object get(Object attrName)
535 return map.get(attrName);
539 * Returns the hashcode of the attribute name/value map.
541 public int hashCode()
543 return map.hashCode();
547 * Returns true if there are no attributes set, false otherwise.
549 public boolean isEmpty()
551 return map.isEmpty();
555 * Gives a Set of all the values of defined attribute names.
557 public Set keySet()
559 return map.keySet();
563 * Adds or replaces a attribute name/value pair.
564 * XXX - What if the name is a string? What if the name is neither a Name
565 * nor a String? What if the value is not a string?
567 * @param name the name of the attribute
568 * @param value the (new) value of the attribute
569 * @return the old value of the attribute or null when there was no old
570 * attribute with this name
572 public Object put(Object name, Object value)
574 return map.put(name, value);
578 * Adds or replaces all attribute name/value pairs from another
579 * Attributes object to this one. The supplied Map must be an instance of
580 * Attributes.
582 * @param attr the Attributes object to merge with this one
583 * @exception ClassCastException if the supplied map is not an instance of
584 * Attributes
586 public void putAll(Map attr)
588 if (!(attr instanceof Attributes))
590 throw new
591 ClassCastException("Supplied Map is not an instance of Attributes");
593 map.putAll(attr);
597 * Remove a attribute name/value pair.
598 * XXX - What if the name is a String?
600 * @param name the name of the attribute name/value pair to remove
601 * @return the old value of the attribute or null if the attribute didn't
602 * exist
604 public Object remove(Object name)
606 return map.remove(name);
610 * Returns the number of defined attribute name/value pairs.
612 public int size()
614 return map.size();
618 * Returns all the values of the defined attribute name/value pairs as a
619 * Collection.
621 public Collection values()
623 return map.values();