001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.util.jar;
019:
020: import java.util.Collection;
021: import java.util.HashMap;
022: import java.util.Map;
023: import java.util.Set;
024:
025: import org.apache.harmony.archive.util.Util;
026:
027: /**
028: * The Attributes class is used to store values for Manifest entries. Attributes
029: * keys are generally instances of Attributes.Name. Values associated with
030: * Attributes keys are of type String.
031: */
032: public class Attributes implements Cloneable, Map<Object, Object> {
033:
034: protected Map<Object, Object> map;
035:
036: public static class Name {
037: private final String name;
038:
039: private int hashCode;
040:
041: public static final Name CLASS_PATH = new Name("Class-Path"); //$NON-NLS-1$
042:
043: public static final Name MANIFEST_VERSION = new Name(
044: "Manifest-Version"); //$NON-NLS-1$
045:
046: public static final Name MAIN_CLASS = new Name("Main-Class"); //$NON-NLS-1$
047:
048: public static final Name SIGNATURE_VERSION = new Name(
049: "Signature-Version"); //$NON-NLS-1$
050:
051: public static final Name CONTENT_TYPE = new Name("Content-Type"); //$NON-NLS-1$
052:
053: public static final Name SEALED = new Name("Sealed"); //$NON-NLS-1$
054:
055: public static final Name IMPLEMENTATION_TITLE = new Name(
056: "Implementation-Title"); //$NON-NLS-1$
057:
058: public static final Name IMPLEMENTATION_VERSION = new Name(
059: "Implementation-Version"); //$NON-NLS-1$
060:
061: public static final Name IMPLEMENTATION_VENDOR = new Name(
062: "Implementation-Vendor"); //$NON-NLS-1$
063:
064: public static final Name SPECIFICATION_TITLE = new Name(
065: "Specification-Title"); //$NON-NLS-1$
066:
067: public static final Name SPECIFICATION_VERSION = new Name(
068: "Specification-Version"); //$NON-NLS-1$
069:
070: public static final Name SPECIFICATION_VENDOR = new Name(
071: "Specification-Vendor"); //$NON-NLS-1$
072:
073: public static final Name EXTENSION_LIST = new Name(
074: "Extension-List"); //$NON-NLS-1$
075:
076: public static final Name EXTENSION_NAME = new Name(
077: "Extension-Name"); //$NON-NLS-1$
078:
079: public static final Name EXTENSION_INSTALLATION = new Name(
080: "Extension-Installation"); //$NON-NLS-1$
081:
082: public static final Name IMPLEMENTATION_VENDOR_ID = new Name(
083: "Implementation-Vendor-Id"); //$NON-NLS-1$
084:
085: public static final Name IMPLEMENTATION_URL = new Name(
086: "Implementation-URL"); //$NON-NLS-1$
087:
088: public Name(String s) {
089: int i = s.length();
090: if (i == 0 || i > 70) {
091: throw new IllegalArgumentException();
092: }
093: for (; --i >= 0;) {
094: char ch = s.charAt(i);
095: if (!((ch >= 'a' && ch <= 'z')
096: || (ch >= 'A' && ch <= 'Z') || ch == '_'
097: || ch == '-' || (ch >= '0' && ch <= '9'))) {
098: throw new IllegalArgumentException(s);
099: }
100: }
101: name = s;
102: }
103:
104: @Override
105: public String toString() {
106: return name;
107: }
108:
109: @Override
110: public boolean equals(Object an) {
111: if (an == null) {
112: return false;
113: }
114: return an.getClass() == this .getClass()
115: && Util.equalsIgnoreCase(name, ((Name) an).name);
116: }
117:
118: @Override
119: public int hashCode() {
120: if (hashCode == 0) {
121: hashCode = Util.toASCIILowerCase(name).hashCode();
122: }
123: return hashCode;
124: }
125: }
126:
127: /**
128: * Constructs an Attributes instance
129: */
130: public Attributes() {
131: map = new HashMap<Object, Object>();
132: }
133:
134: /**
135: * Constructs an Attributes instance obtaining keys and values from the
136: * parameter Attributes, attrib
137: *
138: * @param attrib
139: * The Attributes to obtain entries from.
140: */
141: @SuppressWarnings("unchecked")
142: public Attributes(Attributes attrib) {
143: map = (Map<Object, Object>) ((HashMap) attrib.map).clone();
144: }
145:
146: /**
147: * Constructs an Attributes instance with initial capacity of size size
148: *
149: * @param size
150: * Initial size of this Attributes instance.
151: */
152: public Attributes(int size) {
153: map = new HashMap<Object, Object>(size);
154: }
155:
156: /**
157: * Removes all key/value pairs from this Attributes.
158: *
159: */
160: public void clear() {
161: map.clear();
162: }
163:
164: /**
165: * Determines whether this Attributes contains the specified key
166: *
167: *
168: * @param key
169: * The key to search for.
170: * @return true if the key is found, false otherwise
171: */
172: public boolean containsKey(Object key) {
173: return map.containsKey(key);
174: }
175:
176: /**
177: * Determines whether this Attributes contains the specified value
178: *
179: * @param value
180: * The value to search for.
181: * @return true if the value is found, false otherwise
182: */
183: public boolean containsValue(Object value) {
184: return map.containsValue(value);
185: }
186:
187: /**
188: * Returns a set containing MapEntry's for each of the key/value pairs
189: * contained in this Attributes.
190: *
191: * @return a set of MapEntry's
192: */
193: public Set<Map.Entry<Object, Object>> entrySet() {
194: return map.entrySet();
195: }
196:
197: /**
198: * Returns the value associated with the parameter key
199: *
200: * @param key
201: * The key to search for.
202: * @return Object associated with key, or null if key does not exist.
203: */
204: public Object get(Object key) {
205: return map.get(key);
206: }
207:
208: /**
209: * Determines whether this Attributes contains any keys
210: *
211: * @return true if one or more keys exist, false otherwise
212: */
213: public boolean isEmpty() {
214: return map.isEmpty();
215: }
216:
217: /**
218: * Returns a Set containing all the keys found in this Attributes.
219: *
220: * @return a Set of all keys
221: */
222: public Set<Object> keySet() {
223: return map.keySet();
224: }
225:
226: /**
227: * Store value in this Attributes and associate it with key.
228: *
229: * @param key
230: * The key to associate with value.
231: * @param value
232: * The value to store in this Attributes
233: * @return The value being stored
234: *
235: * @exception ClassCastException
236: * when key is not an Attributes.Name or value is not a
237: * String
238: */
239: @SuppressWarnings("cast")
240: // Require cast to force ClassCastException
241: public Object put(Object key, Object value) {
242: return map.put((Name) key, (String) value);
243: }
244:
245: /**
246: * Store all the key.value pairs in the argument in this Attributes.
247: *
248: * @param attrib
249: * the associations to store (must be of type Attributes).
250: */
251: public void putAll(Map<?, ?> attrib) {
252: if (attrib == null || !(attrib instanceof Attributes)) {
253: throw new ClassCastException();
254: }
255: this .map.putAll(attrib);
256: }
257:
258: /**
259: * Deletes the key/value pair with key key from this Attributes.
260: *
261: * @param key
262: * The key to remove
263: * @return the values associated with the removed key, null if not present.
264: */
265: public Object remove(Object key) {
266: return map.remove(key);
267: }
268:
269: /**
270: * Returns the number of key.value pairs associated with this Attributes.
271: *
272: * @return the size of this Attributes
273: */
274: public int size() {
275: return map.size();
276: }
277:
278: /**
279: * Returns a Collection of all the values present in this Attributes.
280: *
281: * @return a Collection of all values present
282: */
283: public Collection<Object> values() {
284: return map.values();
285: }
286:
287: @SuppressWarnings("unchecked")
288: @Override
289: public Object clone() {
290: Attributes clone;
291: try {
292: clone = (Attributes) super .clone();
293: } catch (CloneNotSupportedException e) {
294: return null;
295: }
296: clone.map = (Map<Object, Object>) ((HashMap) map).clone();
297: return clone;
298: }
299:
300: /**
301: * Returns the hashCode of this Attributes
302: *
303: * @return the hashCode of this Object.
304: */
305: @Override
306: public int hashCode() {
307: return map.hashCode();
308: }
309:
310: /**
311: * Determines if this Attributes and the parameter Attributes are equal. Two
312: * Attributes instances are equal if they contain the same keys and values.
313: *
314: * @return true if the Attributes are equals, false otherwise
315: */
316: @Override
317: public boolean equals(Object obj) {
318: if (this == obj) {
319: return true;
320: }
321: if (obj instanceof Attributes) {
322: return map.equals(((Attributes) obj).map);
323: }
324: return false;
325: }
326:
327: /**
328: * Returns the value associated with the parameter Attributes.Name key.
329: *
330: * @param name
331: * The key to obtain the value for.
332: * @return the String associated with name, or null if name is not a valid
333: * key
334: */
335: public String getValue(Attributes.Name name) {
336: return (String) map.get(name);
337: }
338:
339: /**
340: * Returns the String associated with the parameter name.
341: *
342: * @param name
343: * The key to obtain the value for.
344: * @return the String associated with name, or null if name is not a valid
345: * key
346: */
347: public String getValue(String name) {
348: return (String) map.get(new Attributes.Name(name));
349: }
350:
351: /**
352: * Stores value val against key name in this Attributes
353: *
354: * @param name
355: * The key to store against.
356: * @param val
357: * The value to store in this Attributes
358: * @return the Value being stored
359: */
360: public String putValue(String name, String val) {
361: return (String) map.put(new Attributes.Name(name), val);
362: }
363: }
|