1 /*
2 * Copyright (c) 2005, 2016, 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
153 private class AnnotationSetScanner extends
154 ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> {
155 // Insertion-order preserving set
156 private Set<Element> annotatedElements = new LinkedHashSet<>();
157
158 AnnotationSetScanner(Set<Element> defaultSet) {
159 super(defaultSet);
160 }
161
162 @Override @DefinedBy(Api.LANGUAGE_MODEL)
163 public Set<Element> scan(Element e, TypeElement annotation) {
164 for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
165 if (annotation.equals(mirrorAsElement(annotMirror))) {
166 annotatedElements.add(e);
167 break;
168 }
169 }
170 e.accept(this, annotation);
171 return annotatedElements;
172 }
173 }
174
175 // Could be written as a local class inside getElementsAnnotatedWithAny
176 private class AnnotationSetMultiScanner extends
177 ElementScanningIncludingTypeParameters<Set<Element>, Set<TypeElement>> {
178 // Insertion-order preserving set
179 private Set<Element> annotatedElements = new LinkedHashSet<>();
180
181 AnnotationSetMultiScanner(Set<Element> defaultSet) {
182 super(defaultSet);
183 }
184
185 @Override @DefinedBy(Api.LANGUAGE_MODEL)
186 public Set<Element> scan(Element e, Set<TypeElement> annotations) {
187 for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
188 if (annotations.contains(mirrorAsElement(annotMirror))) {
189 annotatedElements.add(e);
190 break;
191 }
192 }
193 e.accept(this, annotations);
194 return annotatedElements;
195 }
196 }
197
198 private static abstract class ElementScanningIncludingTypeParameters<R, P>
199 extends ElementScanner9<R, P> {
200
201 protected ElementScanningIncludingTypeParameters(R defaultValue) {
202 super(defaultValue);
203 }
204
205 @Override @DefinedBy(Api.LANGUAGE_MODEL)
206 public R visitType(TypeElement e, P p) {
207 // Type parameters are not considered to be enclosed by a type
208 scan(e.getTypeParameters(), p);
209 return super.visitType(e, p);
210 }
211
212 @Override @DefinedBy(Api.LANGUAGE_MODEL)
213 public R visitExecutable(ExecutableElement e, P p) {
214 // Type parameters are not considered to be enclosed by an executable
215 scan(e.getTypeParameters(), p);
216 return super.visitExecutable(e, p);
217 }
218 }
219
220 /**
221 * {@inheritDoc}
222 */
223 @DefinedBy(Api.ANNOTATION_PROCESSING)
224 public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
225 throwIfNotAnnotation(a);
226 String name = a.getCanonicalName();
227 if (name == null)
228 return Collections.emptySet();
229 else {
230 TypeElement annotationType = eltUtils.getTypeElement(name);
231 if (annotationType == null)
232 return Collections.emptySet();
233 else
234 return getElementsAnnotatedWith(annotationType);
235 }
236 }
237
238 @DefinedBy(Api.ANNOTATION_PROCESSING)
239 public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations) {
240 List<TypeElement> annotationsAsElements = new ArrayList<>(annotations.size());
241
242 for (Class<? extends Annotation> annotation : annotations) {
243 throwIfNotAnnotation(annotation);
244 String name = annotation.getCanonicalName();
245 if (name == null)
246 continue;
247 annotationsAsElements.add(eltUtils.getTypeElement(name));
248 }
249
250 return getElementsAnnotatedWithAny(annotationsAsElements.toArray(new TypeElement[0]));
251 }
252
253 private Element mirrorAsElement(AnnotationMirror annotationMirror) {
254 return annotationMirror.getAnnotationType().asElement();
255 }
256
257 private static final String NOT_AN_ANNOTATION_TYPE =
258 "The argument does not represent an annotation type: ";
259
260 private void throwIfNotAnnotation(Class<? extends Annotation> a) {
261 if (!a.isAnnotation())
262 throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
263 }
264
265 private void throwIfNotAnnotation(TypeElement a) {
266 if (a.getKind() != ElementKind.ANNOTATION_TYPE)
267 throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
268 }
269 }
|
1 /*
2 * Copyright (c) 2005, 2018, 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
153 private class AnnotationSetScanner extends
154 ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> {
155 // Insertion-order preserving set
156 private Set<Element> annotatedElements = new LinkedHashSet<>();
157
158 AnnotationSetScanner(Set<Element> defaultSet) {
159 super(defaultSet);
160 }
161
162 @Override @DefinedBy(Api.LANGUAGE_MODEL)
163 public Set<Element> scan(Element e, TypeElement annotation) {
164 for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
165 if (annotation.equals(mirrorAsElement(annotMirror))) {
166 annotatedElements.add(e);
167 break;
168 }
169 }
170 e.accept(this, annotation);
171 return annotatedElements;
172 }
173
174 @Override @DefinedBy(Api.LANGUAGE_MODEL)
175 public Set<Element> visitModule(ModuleElement e, TypeElement annotation) {
176 // Do not scan a module
177 return annotatedElements;
178 }
179
180 @Override @DefinedBy(Api.LANGUAGE_MODEL)
181 public Set<Element> visitPackage(PackageElement e, TypeElement annotation) {
182 // Do not scan a package
183 return annotatedElements;
184 }
185 }
186
187 // Could be written as a local class inside getElementsAnnotatedWithAny
188 private class AnnotationSetMultiScanner extends
189 ElementScanningIncludingTypeParameters<Set<Element>, Set<TypeElement>> {
190 // Insertion-order preserving set
191 private Set<Element> annotatedElements = new LinkedHashSet<>();
192
193 AnnotationSetMultiScanner(Set<Element> defaultSet) {
194 super(defaultSet);
195 }
196
197 @Override @DefinedBy(Api.LANGUAGE_MODEL)
198 public Set<Element> scan(Element e, Set<TypeElement> annotations) {
199 for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
200 if (annotations.contains(mirrorAsElement(annotMirror))) {
201 annotatedElements.add(e);
202 break;
203 }
204 }
205 e.accept(this, annotations);
206 return annotatedElements;
207 }
208
209 @Override @DefinedBy(Api.LANGUAGE_MODEL)
210 public Set<Element> visitModule(ModuleElement e, Set<TypeElement> annotations) {
211 // Do not scan a module
212 return annotatedElements;
213 }
214
215 @Override @DefinedBy(Api.LANGUAGE_MODEL)
216 public Set<Element> visitPackage(PackageElement e, Set<TypeElement> annotations) {
217 // Do not scan a package
218 return annotatedElements;
219 }
220 }
221
222 private static abstract class ElementScanningIncludingTypeParameters<R, P>
223 extends ElementScanner9<R, P> {
224
225 protected ElementScanningIncludingTypeParameters(R defaultValue) {
226 super(defaultValue);
227 }
228
229 @Override @DefinedBy(Api.LANGUAGE_MODEL)
230 public R visitType(TypeElement e, P p) {
231 // Type parameters are not considered to be enclosed by a type
232 scan(e.getTypeParameters(), p);
233 return super.visitType(e, p);
234 }
235
236 @Override @DefinedBy(Api.LANGUAGE_MODEL)
237 public R visitExecutable(ExecutableElement e, P p) {
238 // Type parameters are not considered to be enclosed by an executable
239 scan(e.getTypeParameters(), p);
240 return super.visitExecutable(e, p);
241 }
242 }
243
244 /**
245 * {@inheritDoc}
246 */
247 @DefinedBy(Api.ANNOTATION_PROCESSING)
248 public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
249 throwIfNotAnnotation(a);
250 String name = a.getCanonicalName();
251
252 if (name == null)
253 return Collections.emptySet();
254 else {
255 TypeElement annotationType = annotationToElement(a);
256
257 if (annotationType == null)
258 return Collections.emptySet();
259 else
260 return getElementsAnnotatedWith(annotationType);
261 }
262 }
263
264 @DefinedBy(Api.ANNOTATION_PROCESSING)
265 public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations) {
266 List<TypeElement> annotationsAsElements = new ArrayList<>(annotations.size());
267
268 for (Class<? extends Annotation> annotation : annotations) {
269 throwIfNotAnnotation(annotation);
270 String name = annotation.getCanonicalName();
271 if (name == null)
272 continue;
273 annotationsAsElements.add(annotationToElement(annotation));
274 }
275
276 return getElementsAnnotatedWithAny(annotationsAsElements.toArray(new TypeElement[0]));
277 }
278
279 private TypeElement annotationToElement(Class<? extends Annotation> annotation) {
280 // First, try an element lookup based on the annotation's
281 // canonical name. If that fails or is ambiguous, try a lookup
282 // using a particular module, perhaps an unnamed one. This
283 // offers more compatibility for compiling in single-module
284 // mode where the runtime module of an annotation type may
285 // differ from the single module being compiled.
286 String name = annotation.getCanonicalName();
287 TypeElement annotationElement = eltUtils.getTypeElement(name);
288 if (annotationElement != null)
289 return annotationElement;
290 else {
291 String moduleName = Objects.requireNonNullElse(annotation.getModule().getName(), "");
292 return eltUtils.getTypeElement(eltUtils.getModuleElement(moduleName), name);
293 }
294 }
295
296 private Element mirrorAsElement(AnnotationMirror annotationMirror) {
297 return annotationMirror.getAnnotationType().asElement();
298 }
299
300 private static final String NOT_AN_ANNOTATION_TYPE =
301 "The argument does not represent an annotation type: ";
302
303 private void throwIfNotAnnotation(Class<? extends Annotation> a) {
304 if (!a.isAnnotation())
305 throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
306 }
307
308 private void throwIfNotAnnotation(TypeElement a) {
309 if (a.getKind() != ElementKind.ANNOTATION_TYPE)
310 throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
311 }
312 }
|