11d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License.  You may obtain a copy of the License at
81d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
101d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.util.jar;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilsonimport java.io.UnsupportedEncodingException;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collection;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Map;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Set;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.archive.util.Util;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Attributes} class is used to store values for manifest entries.
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Attribute keys are generally instances of {@code Attributes.Name}. Values
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * associated with attribute keys are of type {@code String}.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Attributes implements Cloneable, Map<Object, Object> {
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The {@code Attributes} as name/value pairs. Maps the attribute names (as
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link Attributes.Name}) of a JAR file manifest to arbitrary values. The
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * attribute names thus are obtained from the {@link Manifest} for
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * convenience.
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected Map<Object, Object> map;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The name part of the name/value pairs constituting an attribute as
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * defined by the specification of the JAR manifest. May be composed of the
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * following ASCII signs as defined in the EBNF below:
47407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <pre>
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * name       = alphanum *headerchar
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * headerchar = alphanum | - | _
51407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * alphanum   = {A-Z} | {a-z} | {0-9}
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * </pre>
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static class Name {
55407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        private final byte[] name;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        private int hashCode;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The class path (a main attribute).
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name CLASS_PATH = new Name("Class-Path"); //$NON-NLS-1$
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The version of the manifest file (a main attribute).
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
67407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        public static final Name MANIFEST_VERSION = new Name("Manifest-Version"); //$NON-NLS-1$
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The main class's name (for stand-alone applications).
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name MAIN_CLASS = new Name("Main-Class"); //$NON-NLS-1$
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Defines the signature version of the JAR file.
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name SIGNATURE_VERSION = new Name(
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Signature-Version"); //$NON-NLS-1$
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Content-Type} manifest attribute.
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name CONTENT_TYPE = new Name("Content-Type"); //$NON-NLS-1$
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Sealed} manifest attribute which may have the value
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * {@code true} for sealed archives.
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name SEALED = new Name("Sealed"); //$NON-NLS-1$
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Implementation-Title} attribute whose value is a string
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that defines the title of the extension implementation.
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name IMPLEMENTATION_TITLE = new Name(
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Implementation-Title"); //$NON-NLS-1$
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Implementation-Version} attribute defining the version of
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the extension implementation.
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name IMPLEMENTATION_VERSION = new Name(
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Implementation-Version"); //$NON-NLS-1$
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Implementation-Vendor} attribute defining the organization
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that maintains the extension implementation.
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name IMPLEMENTATION_VENDOR = new Name(
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Implementation-Vendor"); //$NON-NLS-1$
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Specification-Title} attribute defining the title of the
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * extension specification.
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name SPECIFICATION_TITLE = new Name(
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Specification-Title"); //$NON-NLS-1$
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Specification-Version} attribute defining the version of
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the extension specification.
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name SPECIFICATION_VERSION = new Name(
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Specification-Version"); //$NON-NLS-1$
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Specification-Vendor} attribute defining the organization
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * that maintains the extension specification.
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name SPECIFICATION_VENDOR = new Name(
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Specification-Vendor"); //$NON-NLS-1$
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Extension-List} attribute defining the extensions that are
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * needed by the applet.
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name EXTENSION_LIST = new Name("Extension-List"); //$NON-NLS-1$
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Extension-Name} attribute which defines the unique name of
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * the extension.
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name EXTENSION_NAME = new Name("Extension-Name"); //$NON-NLS-1$
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Extension-Installation} attribute.
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name EXTENSION_INSTALLATION = new Name(
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Extension-Installation"); //$NON-NLS-1$
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Implementation-Vendor-Id} attribute specifies the vendor
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * of an extension implementation if the applet requires an
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * implementation from a specific vendor.
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name IMPLEMENTATION_VENDOR_ID = new Name(
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Implementation-Vendor-Id"); //$NON-NLS-1$
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The {@code Implementation-URL} attribute specifying a URL that can be
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * used to obtain the most recent version of the extension if the
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * required version is not already installed.
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public static final Name IMPLEMENTATION_URL = new Name(
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Implementation-URL"); //$NON-NLS-1$
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1671d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson        static final Name NAME = new Name("Name"); //$NON-NLS-1$
168407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * A String which must satisfy the following EBNF grammar to specify an
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * additional attribute:
172407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         *
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * <pre>
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * name       = alphanum *headerchar
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * headerchar = alphanum | - | _
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * alphanum   = {A-Z} | {a-z} | {0-9}
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * </pre>
178407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         *
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @param s
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            The Attribute string.
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @exception IllegalArgumentException
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *                if the string does not satisfy the EBNF grammar.
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public Name(String s) {
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int i = s.length();
186407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            if (i == 0 || i > Manifest.LINE_LENGTH_LIMIT - 2) {
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IllegalArgumentException();
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
189407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
190407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            name = new byte[i];
191407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (; --i >= 0;) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                char ch = s.charAt(i);
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        || ch == '_' || ch == '-' || (ch >= '0' && ch <= '9'))) {
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new IllegalArgumentException(s);
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
198407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                name[i] = (byte) ch;
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
200407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        }
201407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
202407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        /**
203407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         * A private constructor for a trusted attribute name.
204407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         */
205407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        Name(byte[] buf) {
206407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            name = buf;
207407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        }
208407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
209407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        byte[] getBytes() {
210407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            return name;
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Returns this attribute name.
215407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         *
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the attribute name.
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        @Override
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public String toString() {
220407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            try {
2211d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson                return new String(name, "ISO-8859-1"); //$NON-NLS-1$
222407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            } catch (UnsupportedEncodingException iee) {
223407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                throw new InternalError(iee.getLocalizedMessage());
224407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            }
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
2281d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson         * Returns whether the argument provided is the same as the attribute
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * name.
230407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         *
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return if the attribute names correspond.
232407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         * @param object
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *            An attribute name to be compared with this name.
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        @Override
236407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        public boolean equals(Object object) {
237407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson            if (object == null || object.getClass() != getClass()
238407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                    || object.hashCode() != hashCode()) {
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
241407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
2421d96b51e7f1e0a9d8cfa88f12dfe7cdb46d07634Jesse Wilson            return Util.asciiEqualsIgnoreCase(name, ((Name) object).name);
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /**
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Computes a hash code of the name.
247407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson         *
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * @return the hash value computed from the name.
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        @Override
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        public int hashCode() {
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (hashCode == 0) {
253407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                int hash = 0, multiplier = 1;
254407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                for (int i = name.length - 1; i >= 0; i--) {
255407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                    // 'A' & 0xDF == 'a' & 0xDF, ..., 'Z' & 0xDF == 'z' & 0xDF
256407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                    hash += (name[i] & 0xDF) * multiplier;
257407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                    int shifted = multiplier << 5;
258407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                    multiplier = shifted - multiplier;
259407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                }
260407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson                hashCode = hash;
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return hashCode;
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
264407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an {@code Attributes} instance.
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Attributes() {
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        map = new HashMap<Object, Object>();
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an {@code Attributes} instance obtaining keys and values from
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the parameter {@code attrib}.
277407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param attrib
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            The attributes to obtain entries from.
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("unchecked")
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Attributes(Attributes attrib) {
283407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        map = (Map<Object, Object>) ((HashMap) attrib.map).clone();
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an {@code Attributes} instance with initial capacity of size
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code size}.
289407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param size
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            Initial size of this {@code Attributes} instance.
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Attributes(int size) {
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        map = new HashMap<Object, Object>(size);
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Removes all key/value pairs from this {@code Attributes}.
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void clear() {
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        map.clear();
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Determines whether this {@code Attributes} contains the specified key.
306407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            The key to search for.
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the key is found, {@code false} otherwise.
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean containsKey(Object key) {
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.containsKey(key);
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Determines whether this {@code Attributes} contains the specified value.
317407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param value
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the value to search for.
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the value is found, {@code false} otherwise.
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean containsValue(Object value) {
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.containsValue(value);
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a set containing map entries for each of the key/value pair
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * contained in this {@code Attributes}.
329407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a set of Map.Entry's
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Set<Map.Entry<Object, Object>> entrySet() {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.entrySet();
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the value associated with the parameter key.
338407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to search for.
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return Object associated with key, or {@code null} if key does not
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         exist.
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Object get(Object key) {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.get(key);
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Determines whether this {@code Attributes} contains any keys.
350407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if one or more keys exist, {@code false} otherwise.
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isEmpty() {
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.isEmpty();
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a {@code Set} containing all the keys found in this {@code
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Attributes}.
360407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a {@code Set} of all keys.
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Set<Object> keySet() {
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.keySet();
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Stores key/value pairs in this {@code Attributes}.
369407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to associate with value.
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param value
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the value to store in this {@code Attributes}.
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the value being stored.
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @exception ClassCastException
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *                when key is not an {@code Attributes.Name} or value is not
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *                a {@code String}.
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
379407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson    @SuppressWarnings("cast")
380407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson    // Require cast to force ClassCastException
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Object put(Object key, Object value) {
382407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson        return map.put((Name) key, (String) value);
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
386407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * Stores all the key/value pairs in the argument in this {@code
387407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * Attributes}.
388407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param attrib
390407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *            the associations to store (must be of type {@code
391407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *            Attributes}).
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void putAll(Map<?, ?> attrib) {
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (attrib == null || !(attrib instanceof Attributes)) {
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new ClassCastException();
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.map.putAll(attrib);
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Deletes the key/value pair with key {@code key} from this {@code
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Attributes}.
403407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param key
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to remove.
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the values associated with the removed key, {@code null} if not
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         present.
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Object remove(Object key) {
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.remove(key);
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the number of key/value pairs associated with this {@code
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Attributes}.
416407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the size of this {@code Attributes}.
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int size() {
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.size();
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
424407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * Returns a collection of all the values present in this {@code
425407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     * Attributes}.
426407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a collection of all values present.
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Collection<Object> values() {
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.values();
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @SuppressWarnings("unchecked")
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Object clone() {
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Attributes clone;
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clone = (Attributes) super.clone();
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (CloneNotSupportedException e) {
440a0ebf91e58c17487a8bd1be6e64193193deae26fJesse Wilson            throw new AssertionError(e); // android-changed
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        clone.map = (Map<Object, Object>) ((HashMap) map).clone();
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return clone;
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the hash code of this {@code Attributes}.
448407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the hash code of this object.
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int hashCode() {
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return map.hashCode();
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Determines if this {@code Attributes} and the parameter {@code
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Attributes} are equal. Two {@code Attributes} instances are equal if they
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * contain the same keys and values.
460407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param obj
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the object with which this {@code Attributes} is compared.
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the {@code Attributes} are equal, {@code false}
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean equals(Object obj) {
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this == obj) {
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (obj instanceof Attributes) {
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return map.equals(((Attributes) obj).map);
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the value associated with the parameter {@code Attributes.Name}
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * key.
480407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to obtain the value for.
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the {@code String} associated with name, or {@code null} if name
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         is not a valid key.
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getValue(Attributes.Name name) {
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (String) map.get(name);
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the string associated with the parameter name.
492407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to obtain the value for.
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the string associated with name, or {@code null} if name is not a
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         valid key.
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getValue(String name) {
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (String) map.get(new Attributes.Name(name));
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Stores the value {@code val} associated with the key {@code name} in this
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code Attributes}.
505407a2013b289b6b0e860b4275671b7b0194c42fcJesse Wilson     *
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the key to store.
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param val
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the value to store in this {@code Attributes}.
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the value being stored.
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String putValue(String name, String val) {
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (String) map.put(new Attributes.Name(name), val);
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
516