Skip to content

Commit 7dde164

Browse files
mbelladesebersole
authored andcommitted
Better dynamic annotation usage default value extraction
1 parent 34f0448 commit 7dde164

File tree

4 files changed

+65
-94
lines changed

4 files changed

+65
-94
lines changed

src/main/java/org/hibernate/models/internal/dynamic/DynamicAnnotationUsage.java

Lines changed: 48 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class DynamicAnnotationUsage<A extends Annotation> implements MutableAnno
3232
private final AnnotationDescriptor<A> annotationDescriptor;
3333
private final AnnotationTarget target;
3434

35-
private Map<String,Object> values;
35+
private Map<String, Object> values;
3636

3737
public DynamicAnnotationUsage(
3838
AnnotationDescriptor<A> annotationDescriptor,
@@ -44,10 +44,16 @@ public DynamicAnnotationUsage(
4444
AnnotationDescriptor<A> annotationDescriptor,
4545
AnnotationTarget target,
4646
SourceModelContext context) {
47+
this( annotationDescriptor, target, extractBaselineValues( annotationDescriptor, target, context ) );
48+
}
49+
50+
private DynamicAnnotationUsage(
51+
AnnotationDescriptor<A> annotationDescriptor,
52+
AnnotationTarget target,
53+
Map<String, Object> values) {
4754
this.annotationDescriptor = annotationDescriptor;
4855
this.target = target;
49-
50-
this.values = extractBaselineValues( annotationDescriptor, target, context );
56+
this.values = values;
5157
}
5258

5359
@Override
@@ -80,22 +86,14 @@ public <V> V findAttributeValue(String name) {
8086
*/
8187
@Override
8288
public <V> V getAttributeValue(String name) {
83-
if ( annotationDescriptor.getAttribute( name ) == null ) {
84-
throw new UnknownAnnotationAttributeException(
85-
String.format(
86-
Locale.ROOT,
87-
"Unknown attribute `%s` for annotation `%s`",
88-
name,
89-
getAnnotationType().getName()
90-
)
91-
);
92-
}
93-
return findAttributeValue( name );
89+
// Validate the attribute exists on the annotation descriptor
90+
final AttributeDescriptor<V> attribute = annotationDescriptor.getAttribute( name );
91+
return findAttributeValue( attribute.getName() );
9492
}
9593

9694
@Override
9795
public <V> V setAttributeValue(String name, V value) {
98-
if (value == null){
96+
if ( value == null ) {
9997
throw new IllegalArgumentException(
10098
String.format(
10199
Locale.ROOT,
@@ -106,23 +104,15 @@ public <V> V setAttributeValue(String name, V value) {
106104
);
107105
}
108106

109-
if ( annotationDescriptor.getAttribute( name ) == null ) {
110-
throw new UnknownAnnotationAttributeException(
111-
String.format(
112-
Locale.ROOT,
113-
"Unknown attribute `%s` for annotation `%s`",
114-
name,
115-
getAnnotationType().getName()
116-
)
117-
);
118-
}
107+
// Validate the attribute exists on the annotation descriptor
108+
final AttributeDescriptor<V> attribute = annotationDescriptor.getAttribute( name );
119109

120110
if ( values == null ) {
121111
values = new HashMap<>();
122112
}
123113

124114
//noinspection unchecked
125-
return (V) values.put( name, value );
115+
return (V) values.put( attribute.getName(), value );
126116
}
127117

128118
private static <A extends Annotation> Map<String, Object> extractBaselineValues(
@@ -131,67 +121,64 @@ private static <A extends Annotation> Map<String, Object> extractBaselineValues(
131121
SourceModelContext context) {
132122
final HashMap<String, Object> values = new HashMap<>();
133123
for ( AttributeDescriptor<?> attribute : annotationDescriptor.getAttributes() ) {
134-
values.put( attribute.getName(), getDefaultValue( attribute, target, context ) );
124+
values.put(
125+
attribute.getName(),
126+
extractDefaultValue( attribute.getAttributeMethod().getDefaultValue(), target, context )
127+
);
135128
}
136129
return values;
137130
}
138131

139-
private static Object getDefaultValue(
140-
AttributeDescriptor<?> attribute,
132+
private static Object extractDefaultValue(
133+
Object value,
141134
AnnotationTarget target,
142135
SourceModelContext context) {
143-
final Object defaultValue = attribute.getAttributeMethod().getDefaultValue();
144-
Object annotation = wrapValue( defaultValue, target, context );
145-
if ( annotation != null ) {
146-
return annotation;
147-
}
148-
return defaultValue;
149-
}
150-
151-
private static Object wrapValue(Object value, AnnotationTarget target, SourceModelContext context) {
152-
if ( value instanceof Annotation annotation ) {
153-
try {
154-
return extractDynamicAnnotationUsage( annotation, target, context );
155-
}
156-
catch (InvocationTargetException | IllegalAccessException e) {
157-
throw new AnnotationAccessException( "Error accessing default annotation attribute value", e );
158-
}
159-
}
160-
else if ( value != null ) {
136+
if ( value != null ) {
161137
if ( value.getClass().isArray() ) {
162-
return getList( value, target, context );
138+
return extractList( value, target, context );
139+
}
140+
else if ( value instanceof Class<?> clazz ) {
141+
return context.getClassDetailsRegistry().resolveClassDetails( clazz.getName() );
163142
}
164-
else if ( value.getClass() == Class.class ) {
165-
return context.getClassDetailsRegistry().findClassDetails( ( (Class) value ).getName() );
143+
else if ( value instanceof Annotation annotation ) {
144+
try {
145+
return extractAnnotation( annotation, target, context );
146+
}
147+
catch (InvocationTargetException | IllegalAccessException e) {
148+
throw new AnnotationAccessException( "Error accessing default annotation-typed attribute", e );
149+
}
166150
}
167151
}
168-
169152
return value;
170153
}
171154

172-
private static <E> List getList(Object defaultValue, AnnotationTarget target, SourceModelContext context) {
173-
List result = new ArrayList<>();
174-
E[] d = (E[]) defaultValue;
175-
for ( E e : d ) {
176-
result.add( wrapValue( e, target, context ) );
155+
private static <E> List<Object> extractList(
156+
Object value,
157+
AnnotationTarget target,
158+
SourceModelContext context) {
159+
final List<Object> result = new ArrayList<>();
160+
//noinspection unchecked
161+
final E[] array = (E[]) value;
162+
for ( E element : array ) {
163+
result.add( extractDefaultValue( element, target, context ) );
177164
}
178165
return result;
179166
}
180167

181-
private static DynamicAnnotationUsage<?> extractDynamicAnnotationUsage(
168+
private static DynamicAnnotationUsage<?> extractAnnotation(
182169
Annotation annotation,
183170
AnnotationTarget target,
184171
SourceModelContext context) throws InvocationTargetException, IllegalAccessException {
185172
final Class<? extends Annotation> annotationType = annotation.annotationType();
186173
final AnnotationDescriptor<?> descriptor = context.getAnnotationDescriptorRegistry()
187174
.getDescriptor( annotationType );
188-
final DynamicAnnotationUsage<?> annotationUsage = new DynamicAnnotationUsage<>( descriptor, target, context );
175+
final Map<String, Object> values = new HashMap<>();
189176
for ( AttributeDescriptor<?> attribute : descriptor.getAttributes() ) {
190-
annotationUsage.setAttributeValue(
177+
values.put(
191178
attribute.getName(),
192-
attribute.getAttributeMethod().invoke( annotation )
179+
extractDefaultValue( attribute.getAttributeMethod().invoke( annotation ), target, context )
193180
);
194181
}
195-
return annotationUsage;
182+
return new DynamicAnnotationUsage<>( descriptor, target, values );
196183
}
197184
}

src/main/java/org/hibernate/models/internal/jdk/AnnotationDescriptorImpl.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,6 @@ public List<AttributeDescriptor<?>> getAttributes() {
7777
return attributeDescriptors;
7878
}
7979

80-
@Override
81-
public <V> AttributeDescriptor<V> findAttribute(String name) {
82-
for ( int i = 0; i < attributeDescriptors.size(); i++ ) {
83-
final AttributeDescriptor<?> attributeDescriptor = attributeDescriptors.get( i );
84-
if ( attributeDescriptor.getName().equals( name ) ) {
85-
//noinspection unchecked
86-
return (AttributeDescriptor<V>) attributeDescriptor;
87-
}
88-
}
89-
return null;
90-
}
91-
9280
@Override
9381
public String getName() {
9482
return annotationType.getName();

src/main/java/org/hibernate/models/internal/jdk/AnnotationDescriptorOrmImpl.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,18 +71,6 @@ public List<AttributeDescriptor<?>> getAttributes() {
7171
return attributeDescriptors;
7272
}
7373

74-
@Override
75-
public <V> AttributeDescriptor<V> findAttribute(String name) {
76-
for ( int i = 0; i < attributeDescriptors.size(); i++ ) {
77-
final AttributeDescriptor<?> attributeDescriptor = attributeDescriptors.get( i );
78-
if ( attributeDescriptor.getName().equals( name ) ) {
79-
//noinspection unchecked
80-
return (AttributeDescriptor<V>) attributeDescriptor;
81-
}
82-
}
83-
throw new UnknownAnnotationAttributeException( annotationType, name );
84-
}
85-
8674
@Override
8775
public String getName() {
8876
return annotationType.getName();

src/main/java/org/hibernate/models/spi/AnnotationDescriptor.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,31 @@ default boolean isRepeatable() {
5959
*/
6060
List<AttributeDescriptor<?>> getAttributes();
6161

62+
/**
63+
* Get an attribute descriptor by name, returning {@code null} if the name
64+
* is not an attribute of the described annotation.
65+
*/
66+
default <V> AttributeDescriptor<V> findAttribute(String name) {
67+
final List<AttributeDescriptor<?>> attributeDescriptors = getAttributes();
68+
for ( final AttributeDescriptor<?> attributeDescriptor : attributeDescriptors ) {
69+
if ( attributeDescriptor.getName().equals( name ) ) {
70+
//noinspection unchecked
71+
return (AttributeDescriptor<V>) attributeDescriptor;
72+
}
73+
}
74+
return null;
75+
}
76+
6277
/**
6378
* Get an attribute descriptor by name.
6479
*
6580
* @throws UnknownAnnotationAttributeException if the name is not an
6681
* attribute of the described annotation.
6782
*/
68-
<V> AttributeDescriptor<V> findAttribute(String name);
69-
70-
/**
71-
* Get an attribute descriptor by name, returning {@code null} if the name
72-
* is not an attribute of the described annotation.
73-
*/
7483
default <V> AttributeDescriptor<V> getAttribute(String name) {
75-
final AttributeDescriptor<Object> attribute = findAttribute( name );
84+
final AttributeDescriptor<V> attribute = findAttribute( name );
7685
if ( attribute != null ) {
77-
//noinspection unchecked
78-
return (AttributeDescriptor<V>) attribute;
86+
return attribute;
7987
}
8088

8189
throw new UnknownAnnotationAttributeException( getAnnotationType(), name );

0 commit comments

Comments
 (0)