Annotations.java revision 99409883d9c4c0ffb49b070ce307bb33a9dfe9f1
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.rop.annotation;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstType;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.MutabilityControl;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collection;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Iterator;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.TreeMap;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * List of {@link Annotation} instances.
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Annotations extends MutabilityControl
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        implements Comparable<Annotations> {
3299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} immutable empty instance */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final Annotations EMPTY = new Annotations();
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static {
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        EMPTY.setImmutable();
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} map from types to annotations */
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final TreeMap<CstType, Annotation> annotations;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an immutable instance which is the combination of the
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * two given instances. The two instances must contain disjoint sets
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * of types.
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param a1 {@code non-null;} an instance
4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param a2 {@code non-null;} the other instance
4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the combination
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException thrown if there is a duplicate type
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static Annotations combine(Annotations a1, Annotations a2) {
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Annotations result = new Annotations();
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.addAll(a1);
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.addAll(a2);
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.setImmutable();
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an immutable instance which is the combination of the
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * given instance with the given additional annotation. The latter's
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * type must not already appear in the former.
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param annotations {@code non-null;} the instance to augment
6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param annotation {@code non-null;} the additional annotation
6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the combination
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException thrown if there is a duplicate type
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static Annotations combine(Annotations annotations,
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Annotation annotation) {
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Annotations result = new Annotations();
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.addAll(annotations);
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.add(annotation);
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result.setImmutable();
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an empty instance.
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Annotations() {
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        annotations = new TreeMap<CstType, Annotation>();
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int hashCode() {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return annotations.hashCode();
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean equals(Object other) {
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! (other instanceof Annotations)) {
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Annotations otherAnnotations = (Annotations) other;
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return annotations.equals(otherAnnotations.annotations);
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int compareTo(Annotations other) {
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Iterator<Annotation> thisIter = annotations.values().iterator();
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Iterator<Annotation> otherIter = other.annotations.values().iterator();
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (thisIter.hasNext() && otherIter.hasNext()) {
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Annotation thisOne = thisIter.next();
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Annotation otherOne = otherIter.next();
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int result = thisOne.compareTo(otherOne);
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (result != 0) {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return result;
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thisIter.hasNext()) {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 1;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (otherIter.hasNext()) {
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return -1;
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return 0;
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toString() {
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuilder sb = new StringBuilder();
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean first = true;
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append("annotations{");
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Annotation a : annotations.values()) {
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (first) {
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                first = false;
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append(", ");
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(a.toHuman());
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append("}");
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sb.toString();
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the number of elements in this instance.
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
15599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the size
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int size() {
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return annotations.size();
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds an element to this instance. There must not already be an
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * element of the same type.
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
16599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param annotation {@code non-null;} the element to add
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException thrown if there is a duplicate type
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void add(Annotation annotation) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfImmutable();
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotation == null) {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("annotation == null");
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CstType type = annotation.getType();
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotations.containsKey(type)) {
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("duplicate type: " +
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    type.toHuman());
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        annotations.put(type, annotation);
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds all of the elements of the given instance to this one. The
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instances must not have any duplicate types.
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
18999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param toAdd {@code non-null;} the annotations to add
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException thrown if there is a duplicate type
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addAll(Annotations toAdd) {
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfImmutable();
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (toAdd == null) {
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("toAdd == null");
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (Annotation a : toAdd.annotations.values()) {
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            add(a);
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the set of annotations contained in this instance. The
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * result is always unmodifiable.
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
20899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the set of annotations
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Collection<Annotation> getAnnotations() {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Collections.unmodifiableCollection(annotations.values());
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
214