1 package com.fasterxml.jackson.databind.introspect;
2
3 import java.lang.annotation.Annotation;
4 import java.util.HashMap;
5 import java.util.Iterator;
6 import java.util.Map;
7
8 import com.fasterxml.jackson.databind.util.Annotations;
9
10
16 public abstract class AnnotationCollector
17 {
18 protected final static Annotations NO_ANNOTATIONS = new NoAnnotations();
19
20
23 protected final Object _data;
24
25 protected AnnotationCollector(Object d) {
26 _data = d;
27 }
28
29 public static Annotations emptyAnnotations() { return NO_ANNOTATIONS; }
30
31 public static AnnotationCollector emptyCollector() {
32 return EmptyCollector.instance;
33 }
34
35 public static AnnotationCollector emptyCollector(Object data) {
36 return new EmptyCollector(data);
37 }
38
39 public abstract Annotations asAnnotations();
40 public abstract AnnotationMap asAnnotationMap();
41
42 public Object getData() {
43 return _data;
44 }
45
46
51
52 public abstract boolean isPresent(Annotation ann);
53
54 public abstract AnnotationCollector addOrOverride(Annotation ann);
55
56
61
62 static class EmptyCollector extends AnnotationCollector
63 {
64 public final static EmptyCollector instance = new EmptyCollector(null);
65
66 EmptyCollector(Object data) { super(data); }
67
68 @Override
69 public Annotations asAnnotations() {
70 return NO_ANNOTATIONS;
71 }
72
73 @Override
74 public AnnotationMap asAnnotationMap() {
75 return new AnnotationMap();
76 }
77
78 @Override
79 public boolean isPresent(Annotation ann) { return false; }
80
81 @Override
82 public AnnotationCollector addOrOverride(Annotation ann) {
83 return new OneCollector(_data, ann.annotationType(), ann);
84 }
85 }
86
87 static class OneCollector extends AnnotationCollector
88 {
89 private Class<?> _type;
90 private Annotation _value;
91
92 public OneCollector(Object data,
93 Class<?> type, Annotation value) {
94 super(data);
95 _type = type;
96 _value = value;
97 }
98
99 @Override
100 public Annotations asAnnotations() {
101 return new OneAnnotation(_type, _value);
102 }
103
104 @Override
105 public AnnotationMap asAnnotationMap() {
106 return AnnotationMap.of(_type, _value);
107 }
108
109 @Override
110 public boolean isPresent(Annotation ann) {
111 return ann.annotationType() == _type;
112 }
113
114 @Override
115 public AnnotationCollector addOrOverride(Annotation ann) {
116 final Class<?> type = ann.annotationType();
117
118 if (_type == type) {
119 _value = ann;
120 return this;
121 }
122 return new NCollector(_data, _type, _value, type, ann);
123 }
124 }
125
126 static class NCollector extends AnnotationCollector
127 {
128 protected final HashMap<Class<?>,Annotation> _annotations;
129
130 public NCollector(Object data,
131 Class<?> type1, Annotation value1,
132 Class<?> type2, Annotation value2) {
133 super(data);
134 _annotations = new HashMap<>();
135 _annotations.put(type1, value1);
136 _annotations.put(type2, value2);
137 }
138
139 @Override
140 public Annotations asAnnotations() {
141 if (_annotations.size() == 2) {
142 Iterator<Map.Entry<Class<?>,Annotation>> it = _annotations.entrySet().iterator();
143 Map.Entry<Class<?>,Annotation> en1 = it.next(), en2 = it.next();
144 return new TwoAnnotations(en1.getKey(), en1.getValue(),
145 en2.getKey(), en2.getValue());
146 }
147 return new AnnotationMap(_annotations);
148 }
149
150 @Override
151 public AnnotationMap asAnnotationMap() {
152 AnnotationMap result = new AnnotationMap();
153 for (Annotation ann : _annotations.values()) {
154 result.add(ann);
155 }
156 return result;
157 }
158
159 @Override
160 public boolean isPresent(Annotation ann) {
161 return _annotations.containsKey(ann.annotationType());
162 }
163
164 @Override
165 public AnnotationCollector addOrOverride(Annotation ann) {
166 _annotations.put(ann.annotationType(), ann);
167 return this;
168 }
169 }
170
171
176
177
183 public static class NoAnnotations
184 implements Annotations, java.io.Serializable
185 {
186 private static final long serialVersionUID = 1L;
187
188 NoAnnotations() { }
189
190 @Override
191 public <A extends Annotation> A get(Class<A> cls) {
192 return null;
193 }
194
195 @Override
196 public boolean has(Class<?> cls) {
197 return false;
198 }
199
200 @Override
201 public boolean hasOneOf(Class<? extends Annotation>[] annoClasses) {
202 return false;
203 }
204
205 @Override
206 public int size() {
207 return 0;
208 }
209 }
210
211 public static class OneAnnotation
212 implements Annotations, java.io.Serializable
213 {
214 private static final long serialVersionUID = 1L;
215
216 private final Class<?> _type;
217 private final Annotation _value;
218
219 public OneAnnotation(Class<?> type, Annotation value) {
220 _type = type;
221 _value = value;
222 }
223
224 @SuppressWarnings("unchecked")
225 @Override
226 public <A extends Annotation> A get(Class<A> cls) {
227 if (_type == cls) {
228 return (A) _value;
229 }
230 return null;
231 }
232
233 @Override
234 public boolean has(Class<?> cls) {
235 return (_type == cls);
236 }
237
238 @Override
239 public boolean hasOneOf(Class<? extends Annotation>[] annoClasses) {
240 for (Class<?> cls : annoClasses) {
241 if (cls == _type) {
242 return true;
243 }
244 }
245 return false;
246 }
247
248 @Override
249 public int size() {
250 return 1;
251 }
252 }
253
254 public static class TwoAnnotations
255 implements Annotations, java.io.Serializable
256 {
257 private static final long serialVersionUID = 1L;
258
259 private final Class<?> _type1, _type2;
260 private final Annotation _value1, _value2;
261
262 public TwoAnnotations(Class<?> type1, Annotation value1,
263 Class<?> type2, Annotation value2) {
264 _type1 = type1;
265 _value1 = value1;
266 _type2 = type2;
267 _value2 = value2;
268 }
269
270 @SuppressWarnings("unchecked")
271 @Override
272 public <A extends Annotation> A get(Class<A> cls) {
273 if (_type1 == cls) {
274 return (A) _value1;
275 }
276 if (_type2 == cls) {
277 return (A) _value2;
278 }
279 return null;
280 }
281
282 @Override
283 public boolean has(Class<?> cls) {
284 return (_type1 == cls) || (_type2 == cls);
285 }
286
287 @Override
288 public boolean hasOneOf(Class<? extends Annotation>[] annoClasses) {
289 for (Class<?> cls : annoClasses) {
290 if ((cls == _type1) || (cls == _type2)) {
291 return true;
292 }
293 }
294 return false;
295 }
296
297 @Override
298 public int size() {
299 return 2;
300 }
301 }
302 }
303