source: trunk/gcc/libjava/java/util/jar/Attributes.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 18.0 KB
Line 
1/* Attributes.java -- Represents attribute name/value pairs from a Manifest
2 Copyright (C) 2000, 2002 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38package java.util.jar;
39
40import java.util.Collection;
41import java.util.Hashtable;
42import java.util.Map;
43import java.util.Set;
44
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).
64 *
65 * @see java.util.jar.Attributes.Name
66 * @author Mark Wielaard (mark@klomp.org)
67 */
68public class Attributes implements Cloneable, Map
69{
70
71 // Fields
72
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.
77 */
78 protected Map map;
79
80 // Inner class
81
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.
99 *
100 * @since 1.2
101 * @author Mark Wielaard (mark@klomp.org)
102 */
103 public static class Name
104 {
105
106 // Fields
107
108 // General Main Attributes
109
110 /**
111 * General main attribute -
112 * the version of this Manifest file.
113 */
114 public static final Name MANIFEST_VERSION = new Name("Manifest-Version");
115 /**
116 * General main attribute -
117 * tool and version that created this Manifest file.
118 */
119 public static final Name CREATED_BY = new Name("Created-By");
120 /**
121 * General main attribute -
122 * the version of the jar file signature.
123 */
124 public static final Name SIGNATURE_VERSION
125 = new Name("Signature-Version");
126 /**
127 * General main attribute -
128 * (relative) URLs of the libraries/classpaths that the Classes in
129 * this jar file depend on.
130 */
131 public static final Name CLASS_PATH = new Name("Class-Path");
132
133 /**
134 * Stand alone application attribute -
135 * the entry (without the .class ending) that is the main
136 * class of this jar file.
137 */
138 public static final Name MAIN_CLASS = new Name("Main-Class");
139
140 /**
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>
158 */
159 public static final Name EXTENSION_LIST = new Name("Extension-List");
160
161 /**
162 * Extension identification attribute -
163 * the name if the extension library contained in the jar.
164 */
165 public static final Name EXTENSION_NAME = new Name("Extension-Name");
166 /**
167 * Extension identification attribute -
168 * synonym for <code>EXTENSTION_NAME</code>.
169 */
170 public static final Name EXTENSION_INSTALLATION = EXTENSION_NAME;
171
172 // Package versioning and sealing attributes
173 /**
174 * Package versioning -
175 * name of extension library contained in this jar.
176 */
177 public static final Name IMPLEMENTATION_TITLE
178 = new Name("Implementation-Title");
179 /**
180 * Package versioning -
181 * version of the extension library contained in this jar.
182 */
183 public static final Name IMPLEMENTATION_VERSION
184 = new Name("Implementation-Version");
185 /**
186 * Package versioning -
187 * name of extension library creator contained in this jar.
188 */
189 public static final Name IMPLEMENTATION_VENDOR
190 = new Name("Implementation-Vendor");
191 /**
192 * Package versioning -
193 * unique id of extension library creator.
194 */
195 public static final Name IMPLEMENTATION_VENDOR_ID
196 = new Name("Implementation-Vendor-Id");
197 /**
198 * Package versioning -
199 * location where this implementation can be downloaded.
200 */
201 public static final Name IMPLEMENTATION_URL
202 = new Name("Implementation-URL");
203 /**
204 * Package versioning -
205 * title of the specification contained in this jar.
206 */
207 public static final Name SPECIFICATION_TITLE
208 = new Name("Specification-Title");
209 /**
210 * Package versioning -
211 * version of the specification contained in this jar.
212 */
213 public static final Name SPECIFICATION_VERSION
214 = new Name("Specification-Version");
215 /**
216 * Package versioning -
217 * organisation that maintains the specification contains in this
218 * jar.
219 */
220 public static final Name SPECIFICATION_VENDOR
221 = new Name("Specification-Vendor");
222 /**
223 * Package sealing -
224 * whether (all) package(s) is(/are) sealed. Value is either "true"
225 * or "false".
226 */
227 public static final Name SEALED = new Name("Sealed");
228
229 /**
230 * File contents attribute -
231 * Mime type and subtype for the jar entry.
232 */
233 public static final Name CONTENT_TYPE = new Name("Content-Type");
234
235 /**
236 * Bean objects attribute -
237 * whether the entry is a Java Bean. Value is either "true" or "false".
238 */
239 public static final Name JAVA_BEAN = new Name("Java-Bean");
240
241 /**
242 * Signing attribute -
243 * application specific signing attribute. Must be understood by
244 * the manifest parser when present to validate the jar (entry).
245 */
246 public static final Name MAGIC = new Name("Magic");
247
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;
252
253 // Constructor
254
255 /**
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.
259 *
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
264 */
265 public Name(String name) throws IllegalArgumentException,
266 NullPointerException
267 {
268 // name must not be null
269 // this will throw a NullPointerException if it is
270 char chars[] = name.toCharArray();
271
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");
277
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");
284
285 // all other characters must be alphanums, '-' or '_'
286 for (int i = 1; i < chars.length; i++)
287 {
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 '_'");
295 }
296
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();
301 }
302
303 /**
304 * Returns the hash code of the (lowercase) String representation of
305 * this Name.
306 */
307 public int hashCode()
308 {
309 return name.hashCode();
310 }
311
312 /**
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.
316 */
317 public boolean equals(Object o)
318 {
319 // Quick and dirty check
320 if (name == o)
321 return true;
322
323 try
324 {
325 // Note that the constructor already converts the strings to
326 // lowercase.
327 String otherName = ((Name) o).name;
328 return name.equals(otherName);
329 }
330 catch (ClassCastException cce)
331 {
332 return false;
333 }
334 catch (NullPointerException npe)
335 {
336 return false;
337 }
338 }
339
340 /**
341 * Returns the string representation of this Name as given to the
342 * constructor (not neccesarily the lower case representation).
343 */
344 public String toString()
345 {
346 return origName;
347 }
348 }
349
350 // Constructors
351
352 /**
353 * Creates an empty Attributes map.
354 */
355 public Attributes()
356 {
357 map = new Hashtable();
358 }
359
360 /**
361 * Creates an empty Attributes map with the given initial size.
362 * @param size the initial size of the underlying map
363 */
364 public Attributes(int size)
365 {
366 map = new Hashtable(size);
367 }
368
369 /**
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
373 */
374 public Attributes(Attributes attr)
375 {
376 map = new Hashtable(attr.map);
377 }
378
379 // Methods
380
381 /**
382 * Gets the value of an attribute name given as a String.
383 *
384 * @param name a String describing the Name to look for
385 * @return the value gotten from the map of null when not found
386 */
387 public String getValue(String name)
388 {
389 return (String) get(new Name(name));
390 }
391
392 /**
393 * Gets the value of the given attribute name.
394 *
395 * @param name the Name to look for
396 * @return the value gotten from the map of null when not found
397 */
398 public String getValue(Name name)
399 {
400 return (String) get(name);
401 }
402
403 /**
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.
408 *
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
414 */
415 public String putValue(String name, String value)
416 {
417 return putValue(new Name(name), value);
418 }
419
420 /**
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.
428 *
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
433 */
434 String putValue(Name name, String value)
435 {
436 return (String) put(name, value);
437 }
438
439 // Methods from Cloneable interface
440
441 /**
442 * Return a clone of this attribute map.
443 */
444 public Object clone()
445 {
446 return new Attributes(this);
447 }
448
449 // Methods from Map interface
450
451 /**
452 * Removes all attributes.
453 */
454 public void clear()
455 {
456 map.clear();
457 }
458
459 /**
460 * Checks to see if there is an attribute with the specified name.
461 * XXX - what if the object is a String?
462 *
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
466 */
467 public boolean containsKey(Object attrName)
468 {
469 return map.containsKey(attrName);
470 }
471
472 /**
473 * Checks to see if there is an attribute name with the specified value.
474 *
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
478 */
479 public boolean containsValue(Object attrValue)
480 {
481 return map.containsValue(attrValue);
482 }
483
484 /**
485 * Gives a Set of attribute name and values pairs as MapEntries.
486 * @see java.util.Map.Entry
487 * @see java.util.Map#entrySet()
488 *
489 * @return a set of attribute name value pairs
490 */
491 public Set entrySet()
492 {
493 return map.entrySet();
494 }
495
496 /**
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.
500 *
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
504 */
505 public boolean equals(Object o)
506 {
507 // quick and dirty check
508 if (this == o)
509 return true;
510
511 try
512 {
513 return map.equals(((Attributes) o).map);
514 }
515 catch (ClassCastException cce)
516 {
517 return false;
518 }
519 catch (NullPointerException npe)
520 {
521 return false;
522 }
523 }
524
525 /**
526 * Gets the value of a specified attribute name.
527 * XXX - what if the object is a String?
528 *
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
532 */
533 public Object get(Object attrName)
534 {
535 return map.get(attrName);
536 }
537
538 /**
539 * Returns the hashcode of the attribute name/value map.
540 */
541 public int hashCode()
542 {
543 return map.hashCode();
544 }
545
546 /**
547 * Returns true if there are no attributes set, false otherwise.
548 */
549 public boolean isEmpty()
550 {
551 return map.isEmpty();
552 }
553
554 /**
555 * Gives a Set of all the values of defined attribute names.
556 */
557 public Set keySet()
558 {
559 return map.keySet();
560 }
561
562 /**
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?
566 *
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
571 */
572 public Object put(Object name, Object value)
573 {
574 return map.put(name, value);
575 }
576
577 /**
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.
581 *
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
585 */
586 public void putAll(Map attr)
587 {
588 if (!(attr instanceof Attributes))
589 {
590 throw new
591 ClassCastException("Supplied Map is not an instance of Attributes");
592 }
593 map.putAll(attr);
594 }
595
596 /**
597 * Remove a attribute name/value pair.
598 * XXX - What if the name is a String?
599 *
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
603 */
604 public Object remove(Object name)
605 {
606 return map.remove(name);
607 }
608
609 /**
610 * Returns the number of defined attribute name/value pairs.
611 */
612 public int size()
613 {
614 return map.size();
615 }
616
617 /**
618 * Returns all the values of the defined attribute name/value pairs as a
619 * Collection.
620 */
621 public Collection values()
622 {
623 return map.values();
624 }
625}
Note: See TracBrowser for help on using the repository browser.