3030import java .lang .classfile .AnnotationElement ;
3131import java .lang .classfile .AnnotationValue ;
3232import java .lang .classfile .Attribute ;
33+ import java .lang .classfile .Attributes ;
3334import java .lang .classfile .ClassFile ;
3435import java .lang .classfile .ClassModel ;
3536import java .lang .classfile .FieldModel ;
@@ -63,6 +64,7 @@ final class ClassInspector {
6364 private static final ClassDesc ANNOTATION_NAME = classDesc (Name .class );
6465 private static final ClassDesc ANNOTATION_ENABLED = classDesc (Enabled .class );
6566 private static final ClassDesc ANNOTATION_REMOVE_FIELDS = classDesc (RemoveFields .class );
67+ private static final String [] EMPTY_STRING_ARRAY = {};
6668
6769 private final ClassModel classModel ;
6870 private final Class <?> superClass ;
@@ -104,12 +106,12 @@ MethodDesc findStaticCommitMethod() {
104106 }
105107
106108 String getEventName () {
107- String name = annotationValue (ANNOTATION_NAME , String .class );
109+ String name = annotationValue (ANNOTATION_NAME , String .class , null );
108110 return name == null ? getClassName () : name ;
109111 }
110112
111113 boolean isRegistered () {
112- Boolean result = annotationValue (ANNOTATION_REGISTERED , Boolean .class );
114+ Boolean result = annotationValue (ANNOTATION_REGISTERED , Boolean .class , true );
113115 if (result != null ) {
114116 return result .booleanValue ();
115117 }
@@ -123,7 +125,7 @@ boolean isRegistered() {
123125 }
124126
125127 boolean isEnabled () {
126- Boolean result = annotationValue (ANNOTATION_ENABLED , Boolean .class );
128+ Boolean result = annotationValue (ANNOTATION_ENABLED , Boolean .class , true );
127129 if (result != null ) {
128130 return result .booleanValue ();
129131 }
@@ -201,52 +203,59 @@ private ImplicitFields determineImplicitFields() {
201203 }
202204 }
203205 ImplicitFields ifs = new ImplicitFields (superClass );
204- String [] value = annotationValue (ANNOTATION_REMOVE_FIELDS , String [].class );
206+ String [] value = annotationValue (ANNOTATION_REMOVE_FIELDS , String [].class , EMPTY_STRING_ARRAY );
205207 if (value != null ) {
206208 ifs .removeFields (value );
207209 }
208210 return ifs ;
209211 }
210212
211- private List <AnnotationValue > getAnnotationValues (ClassDesc classDesc ) {
212- List <AnnotationValue > list = new ArrayList <>();
213- for (Attribute <?> attribute : classModel .attributes ()) {
214- if (attribute instanceof RuntimeVisibleAnnotationsAttribute rvaa ) {
215- for (Annotation a : rvaa .annotations ()) {
216- if (a .classSymbol ().equals (classDesc ) && a .elements ().size () == 1 ) {
217- AnnotationElement ae = a .elements ().getFirst ();
218- if (ae .name ().equalsString ("value" )) {
219- list .add (ae .value ());
220- }
221- }
213+ private Annotation getFirstAnnotation (ClassDesc classDesc ) {
214+ for (RuntimeVisibleAnnotationsAttribute attribute : classModel .findAttributes (Attributes .runtimeVisibleAnnotations ())) {
215+ for (Annotation a : attribute .annotations ()) {
216+ if (a .classSymbol ().equals (classDesc )) {
217+ return a ;
222218 }
223219 }
224220 }
225- return list ;
221+ return null ;
226222 }
227223
228224 @ SuppressWarnings ("unchecked" )
229225 // Only supports String, String[] and Boolean values
230- private <T > T annotationValue (ClassDesc classDesc , Class <T > type ) {
231- for (AnnotationValue a : getAnnotationValues (classDesc )) {
232- if (a instanceof AnnotationValue .OfBoolean ofb && type .equals (Boolean .class )) {
233- Boolean b = ofb .booleanValue ();
234- return (T ) b ;
235- }
236- if (a instanceof AnnotationValue .OfString ofs && type .equals (String .class )) {
237- String s = ofs .stringValue ();
238- return (T ) s ;
239- }
240- if (a instanceof AnnotationValue .OfArray ofa && type .equals (String [].class )) {
241- List <AnnotationValue > list = ofa .values ();
242- String [] array = new String [list .size ()];
243- int index = 0 ;
244- for (AnnotationValue av : list ) {
245- var avs = (AnnotationValue .OfString ) av ;
246- array [index ++] = avs .stringValue ();
247- }
248- return (T ) array ;
226+ private <T > T annotationValue (ClassDesc classDesc , Class <T > type , T defaultValue ) {
227+ Annotation annotation = getFirstAnnotation (classDesc );
228+ if (annotation == null ) {
229+ return null ;
230+ }
231+ // Default values are not stored in the annotation element, so if the
232+ // element-value pair is empty, return the default value.
233+ if (annotation .elements ().isEmpty ()) {
234+ return defaultValue ;
235+ }
236+
237+ AnnotationElement ae = annotation .elements ().getFirst ();
238+ if (!ae .name ().equalsString ("value" )) {
239+ return null ;
240+ }
241+ AnnotationValue a = ae .value ();
242+ if (a instanceof AnnotationValue .OfBoolean ofb && type .equals (Boolean .class )) {
243+ Boolean b = ofb .booleanValue ();
244+ return (T ) b ;
245+ }
246+ if (a instanceof AnnotationValue .OfString ofs && type .equals (String .class )) {
247+ String s = ofs .stringValue ();
248+ return (T ) s ;
249+ }
250+ if (a instanceof AnnotationValue .OfArray ofa && type .equals (String [].class )) {
251+ List <AnnotationValue > list = ofa .values ();
252+ String [] array = new String [list .size ()];
253+ int index = 0 ;
254+ for (AnnotationValue av : list ) {
255+ var avs = (AnnotationValue .OfString ) av ;
256+ array [index ++] = avs .stringValue ();
249257 }
258+ return (T ) array ;
250259 }
251260 return null ;
252261 }
0 commit comments