1 /*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.reflect.annotation;
27
28 import java.lang.annotation.*;
29 import java.lang.reflect.*;
30 import java.nio.ByteBuffer;
31 import java.nio.BufferUnderflowException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.HashMap;
36 import java.util.LinkedHashMap;
37 import java.util.Map;
38 import jdk.internal.misc.SharedSecrets;
39 import jdk.internal.misc.JavaLangAccess;
40 import sun.reflect.ConstantPool;
41 import static sun.reflect.annotation.TypeAnnotation.*;
42
43 /**
44 * TypeAnnotationParser implements the logic needed to parse
45 * TypeAnnotations from an array of bytes.
46 */
47 public final class TypeAnnotationParser {
48 private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0];
49
50 /**
51 * Build an AnnotatedType from the parameters supplied.
52 *
53 * This method and {@code buildAnnotatedTypes} are probably
54 * the entry points you are looking for.
55 *
56 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
57 * @param cp the ConstantPool needed to parse the embedded Annotation
58 * @param decl the declaration this type annotation is on
59 * @param container the Class this type annotation is on (may be the same as decl)
60 * @param type the type the AnnotatedType corresponds to
61 * @param filter the type annotation targets included in this AnnotatedType
62 */
63 public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations,
64 ConstantPool cp,
65 AnnotatedElement decl,
66 Class<?> container,
67 Type type,
68 TypeAnnotationTarget filter) {
69 TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
70 cp,
71 decl,
72 container);
73 List<TypeAnnotation> l = new ArrayList<>(tas.length);
74 for (TypeAnnotation t : tas) {
75 TypeAnnotationTargetInfo ti = t.getTargetInfo();
76 if (ti.getTarget() == filter)
77 l.add(t);
78 }
79 TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
80 return AnnotatedTypeFactory.buildAnnotatedType(type,
81 LocationInfo.BASE_LOCATION,
82 typeAnnotations,
83 typeAnnotations,
84 decl);
85 }
86
87 /**
88 * Build an array of AnnotatedTypes from the parameters supplied.
89 *
90 * This method and {@code buildAnnotatedType} are probably
91 * the entry points you are looking for.
92 *
93 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
94 * @param cp the ConstantPool needed to parse the embedded Annotation
95 * @param decl the declaration this type annotation is on
96 * @param container the Class this type annotation is on (may be the same as decl)
97 * @param types the Types the AnnotatedTypes corresponds to
98 * @param filter the type annotation targets that included in this AnnotatedType
99 */
100 public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations,
101 ConstantPool cp,
102 AnnotatedElement decl,
103 Class<?> container,
104 Type[] types,
105 TypeAnnotationTarget filter) {
106 int size = types.length;
107 AnnotatedType[] result = new AnnotatedType[size];
108 Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE);
109 @SuppressWarnings("rawtypes")
110 ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation>
111
112 TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
113 cp,
114 decl,
115 container);
116 for (TypeAnnotation t : tas) {
117 TypeAnnotationTargetInfo ti = t.getTargetInfo();
118 if (ti.getTarget() == filter) {
119 int pos = ti.getCount();
120 if (l[pos] == null) {
121 ArrayList<TypeAnnotation> tmp = new ArrayList<>(tas.length);
122 l[pos] = tmp;
123 }
124 @SuppressWarnings("unchecked")
125 ArrayList<TypeAnnotation> tmp = l[pos];
126 tmp.add(t);
127 }
128 }
129 for (int i = 0; i < size; i++) {
130 @SuppressWarnings("unchecked")
131 ArrayList<TypeAnnotation> list = l[i];
132 TypeAnnotation[] typeAnnotations;
133 if (list != null) {
134 typeAnnotations = list.toArray(new TypeAnnotation[list.size()]);
135 } else {
136 typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY;
137 }
138 result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
139 LocationInfo.BASE_LOCATION,
140 typeAnnotations,
141 typeAnnotations,
142 decl);
143
144 }
145 return result;
146 }
147
148 // Class helpers
149
150 /**
151 * Build an AnnotatedType for the class decl's supertype.
152 *
153 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
154 * @param cp the ConstantPool needed to parse the embedded Annotation
155 * @param decl the Class which annotated supertype is being built
156 */
157 public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations,
158 ConstantPool cp,
159 Class<?> decl) {
261 if (!(b0 instanceof Class<?>)) {
262 startIndex = 1;
263 } else {
264 Class<?> c = (Class<?>)b0;
265 if (c.isInterface()) {
266 startIndex = 1;
267 }
268 }
269 }
270
271 for (int i = 0; i < bounds.length; i++) {
272 List<TypeAnnotation> l = new ArrayList<>(candidates.size());
273 for (TypeAnnotation t : candidates) {
274 TypeAnnotationTargetInfo tInfo = t.getTargetInfo();
275 if (tInfo.getSecondaryIndex() == i + startIndex &&
276 tInfo.getCount() == typeVarIndex) {
277 l.add(t);
278 }
279 }
280 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
281 loc,
282 l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
283 candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
284 (AnnotatedElement)decl);
285 }
286 return res;
287 }
288 return new AnnotatedType[0];
289 }
290 private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) {
291 AnnotatedElement boundsDecl;
292 TypeAnnotationTarget target;
293 if (decl instanceof Class) {
294 target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND;
295 boundsDecl = (Class)decl;
296 } else {
297 target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND;
298 boundsDecl = (Executable)decl;
299 }
300 return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
301 }
|
1 /*
2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.reflect.annotation;
27
28 import java.lang.annotation.*;
29 import java.lang.reflect.*;
30 import java.nio.ByteBuffer;
31 import java.nio.BufferUnderflowException;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.List;
35 import java.util.LinkedHashMap;
36 import java.util.Map;
37 import jdk.internal.misc.SharedSecrets;
38 import jdk.internal.misc.JavaLangAccess;
39 import sun.reflect.ConstantPool;
40 import static sun.reflect.annotation.TypeAnnotation.*;
41
42 /**
43 * TypeAnnotationParser implements the logic needed to parse
44 * TypeAnnotations from an array of bytes.
45 */
46 public final class TypeAnnotationParser {
47 private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0];
48
49 /**
50 * Build an AnnotatedType from the parameters supplied.
51 *
52 * This method and {@code buildAnnotatedTypes} are probably
53 * the entry points you are looking for.
54 *
55 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
56 * @param cp the ConstantPool needed to parse the embedded Annotation
57 * @param decl the declaration this type annotation is on
58 * @param container the Class this type annotation is on (may be the same as decl)
59 * @param type the type the AnnotatedType corresponds to
60 * @param filter the type annotation targets included in this AnnotatedType
61 */
62 public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations,
63 ConstantPool cp,
64 AnnotatedElement decl,
65 Class<?> container,
66 Type type,
67 TypeAnnotationTarget filter) {
68 TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
69 cp, decl, container);
70
71 List<TypeAnnotation> l = new ArrayList<>(tas.length);
72 for (TypeAnnotation t : tas) {
73 TypeAnnotationTargetInfo ti = t.getTargetInfo();
74 if (ti.getTarget() == filter)
75 l.add(t);
76 }
77 TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
78 return AnnotatedTypeFactory.buildAnnotatedType(type,
79 AnnotatedTypeFactory.nestingForType(type, LocationInfo.BASE_LOCATION),
80 typeAnnotations,
81 typeAnnotations,
82 decl);
83 }
84
85 /**
86 * Build an array of AnnotatedTypes from the parameters supplied.
87 *
88 * This method and {@code buildAnnotatedType} are probably
89 * the entry points you are looking for.
90 *
91 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
92 * @param cp the ConstantPool needed to parse the embedded Annotation
93 * @param decl the declaration this type annotation is on
94 * @param container the Class this type annotation is on (may be the same as decl)
95 * @param types the Types the AnnotatedTypes corresponds to
96 * @param filter the type annotation targets that included in this AnnotatedType
97 */
98 public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations,
99 ConstantPool cp,
100 AnnotatedElement decl,
101 Class<?> container,
102 Type[] types,
103 TypeAnnotationTarget filter) {
104 int size = types.length;
105 AnnotatedType[] result = new AnnotatedType[size];
106 Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE);
107 @SuppressWarnings("rawtypes")
108 ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation>
109
110 TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
111 cp, decl, container);
112
113 for (TypeAnnotation t : tas) {
114 TypeAnnotationTargetInfo ti = t.getTargetInfo();
115 if (ti.getTarget() == filter) {
116 int pos = ti.getCount();
117 if (l[pos] == null) {
118 ArrayList<TypeAnnotation> tmp = new ArrayList<>(tas.length);
119 l[pos] = tmp;
120 }
121 @SuppressWarnings("unchecked")
122 ArrayList<TypeAnnotation> tmp = l[pos];
123 tmp.add(t);
124 }
125 }
126 for (int i = 0; i < size; i++) {
127 @SuppressWarnings("unchecked")
128 ArrayList<TypeAnnotation> list = l[i];
129 TypeAnnotation[] typeAnnotations;
130 if (list != null) {
131 typeAnnotations = list.toArray(new TypeAnnotation[list.size()]);
132 } else {
133 typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY;
134 }
135 result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
136 AnnotatedTypeFactory.nestingForType(types[i], LocationInfo.BASE_LOCATION),
137 typeAnnotations,
138 typeAnnotations,
139 decl);
140
141 }
142 return result;
143 }
144
145 // Class helpers
146
147 /**
148 * Build an AnnotatedType for the class decl's supertype.
149 *
150 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
151 * @param cp the ConstantPool needed to parse the embedded Annotation
152 * @param decl the Class which annotated supertype is being built
153 */
154 public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations,
155 ConstantPool cp,
156 Class<?> decl) {
258 if (!(b0 instanceof Class<?>)) {
259 startIndex = 1;
260 } else {
261 Class<?> c = (Class<?>)b0;
262 if (c.isInterface()) {
263 startIndex = 1;
264 }
265 }
266 }
267
268 for (int i = 0; i < bounds.length; i++) {
269 List<TypeAnnotation> l = new ArrayList<>(candidates.size());
270 for (TypeAnnotation t : candidates) {
271 TypeAnnotationTargetInfo tInfo = t.getTargetInfo();
272 if (tInfo.getSecondaryIndex() == i + startIndex &&
273 tInfo.getCount() == typeVarIndex) {
274 l.add(t);
275 }
276 }
277 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
278 AnnotatedTypeFactory.nestingForType(bounds[i], loc),
279 l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
280 candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
281 (AnnotatedElement)decl);
282 }
283 return res;
284 }
285 return new AnnotatedType[0];
286 }
287 private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) {
288 AnnotatedElement boundsDecl;
289 TypeAnnotationTarget target;
290 if (decl instanceof Class) {
291 target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND;
292 boundsDecl = (Class)decl;
293 } else {
294 target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND;
295 boundsDecl = (Executable)decl;
296 }
297 return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
298 }
|