Skip to content

Package: AnnotationFinder

AnnotationFinder

nameinstructionbranchcomplexitylinemethod
AnnotationFinder(String, Class)
M: 9 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
findAnnotation(Annotation[], Class, Set)
M: 59 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
findAnnotation(Class)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
findAnnotationByName(String)
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
findConstructorProperties()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getOptionalAnnotationClass(String)
M: 18 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
in(Annotation[])
M: 13 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
invocateValueMethod(Annotation)
M: 32 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
toString()
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
valueIn(Annotation[])
M: 6 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0 which is available at
6: * http://www.eclipse.org/legal/epl-2.0,
7: * or the Eclipse Distribution License v. 1.0 which is available at
8: * http://www.eclipse.org/org/documents/edl-v10.php.
9: *
10: * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
11: */
12:
13: package org.eclipse.yasson.internal;
14:
15: import java.lang.annotation.Annotation;
16: import java.lang.reflect.InvocationTargetException;
17: import java.util.ArrayList;
18: import java.util.Arrays;
19: import java.util.HashSet;
20: import java.util.List;
21: import java.util.Set;
22: import java.util.logging.Logger;
23:
24: import org.eclipse.yasson.internal.properties.MessageKeys;
25: import org.eclipse.yasson.internal.properties.Messages;
26:
27: /**
28: * Finds an annotation including inherited annotations (e.g. meta-annotations).
29: */
30: class AnnotationFinder {
31:
32: private static final String CONSTRUCTOR_PROPERTIES_ANNOTATION = "java.beans.ConstructorProperties";
33: private static final Logger LOGGER = Logger.getLogger(AnnotationFinder.class.getName());
34:
35: private final String annotationClassName;
36: private final Class<? extends Annotation> annotationClass; // may be null
37:
38: /**
39: * Gets the {@link AnnotationFinder} for the given Annotation-Type.
40: *
41: * @param annotation {@link Class}, that is a sub-type of {@link Annotation}
42: * @return {@link AnnotationFinder}
43: */
44: public static AnnotationFinder findAnnotation(Class<?> annotation) {
45: return findAnnotationByName(annotation.getName());
46: }
47:
48: /**
49: * Gets the {@link AnnotationFinder} for the given Annotation-Type Name.
50: *
51: * @param annotationClassName {@link String}, that is a sub-type of {@link Annotation}
52: * @return {@link AnnotationFinder}
53: */
54: public static AnnotationFinder findAnnotationByName(String annotationClassName) {
55: return new AnnotationFinder(annotationClassName, getOptionalAnnotationClass(annotationClassName));
56: }
57:
58: /**
59: * Gets the {@link AnnotationFinder} for @ConstructorProperties-Annotation.
60: *
61: * @return {@link AnnotationFinder}
62: */
63: public static AnnotationFinder findConstructorProperties() {
64: return findAnnotationByName(CONSTRUCTOR_PROPERTIES_ANNOTATION);
65: }
66:
67: private AnnotationFinder(String annotationClassName, Class<? extends Annotation> annotationClass) {
68: this.annotationClassName = annotationClassName;
69: this.annotationClass = annotationClass;
70: }
71:
72: @SuppressWarnings("unchecked")
73: public <T extends Annotation> T in(Annotation[] annotations) {
74:• if (annotationClass == null) {
75: return null;
76: }
77: return (T) findAnnotation(annotations, annotationClass, new HashSet<>());
78: }
79:
80: /**
81: * Looks for the annotation {@link #in(Annotation[])} <br>
82: * and executes the "value" Method of it dynamically.
83: *
84: * @param annotations - Array of {@link Annotation}n.
85: * @return {@link Object}
86: */
87: public Object valueIn(Annotation[] annotations) {
88: return invocateValueMethod(in(annotations));
89: }
90:
91: private Object invocateValueMethod(Annotation annotation) {
92:• if (annotation == null) {
93: return null;
94: }
95: try {
96: return annotation.annotationType().getMethod("value").invoke(annotation);
97: } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
98: String message = Messages
99: .getMessage(MessageKeys.MISSING_VALUE_PROPERTY_IN_ANNOTATION, annotation.annotationType().getName());
100: LOGGER.finest(message);
101: return null;
102: }
103: }
104:
105: @SuppressWarnings("unchecked")
106: private static <T extends Annotation> Class<T> getOptionalAnnotationClass(String classname) {
107: try {
108: return (Class<T>) Class.forName(classname);
109: } catch (ClassNotFoundException e) {
110: String message = Messages.getMessage(MessageKeys.ANNOTATION_NOT_AVAILABLE, classname);
111: LOGGER.finest(message);
112: return null;
113: }
114: }
115:
116: /**
117: * Searches for annotation, collects processed, to avoid StackOverflow.
118: */
119: // "static" to use it in a hybrid procedural and object oriented manner.
120: @SuppressWarnings("unchecked")
121: public static <T extends Annotation> T findAnnotation(Annotation[] declaredAnnotations,
122: Class<T> annotationClass,
123: Set<Annotation> processed) {
124:• for (Annotation candidate : declaredAnnotations) {
125: final Class<? extends Annotation> annType = candidate.annotationType();
126:• if (annType.equals(annotationClass)) {
127: return (T) candidate;
128: }
129: processed.add(candidate);
130: final List<Annotation> inheritedAnnotations = new ArrayList<>(Arrays.asList(annType.getDeclaredAnnotations()));
131: inheritedAnnotations.removeAll(processed);
132:• if (inheritedAnnotations.size() > 0) {
133: final T inherited = findAnnotation(inheritedAnnotations.toArray(new Annotation[inheritedAnnotations.size()]),
134: annotationClass,
135: processed);
136:• if (inherited != null) {
137: return inherited;
138: }
139: }
140: }
141: return null;
142: }
143:
144: @Override
145: public String toString() {
146: return "AnnotationFinder [annotationClassName=" + annotationClassName + ", annotationClass=" + annotationClass + "]";
147: }
148: }