Skip to content

Commit 57edc75

Browse files
committed
97 Add dynamic-class resolution support to MutableClassDetailsRegistry
1 parent 698a873 commit 57edc75

File tree

3 files changed

+112
-1
lines changed

3 files changed

+112
-1
lines changed

hibernate-models-jandex/src/test/java/org/hibernate/models/dynamic/SimpleDynamicModelTests.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,64 @@ void testSimpleBasics() {
9090
checkPersistability( entityDetails.getFields().get( 1 ) );
9191
}
9292

93+
94+
@Test
95+
void testResolveClassDetails() {
96+
final SourceModelBuildingContext buildingContext = SourceModelTestHelper.createBuildingContext( (Index) null );
97+
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getClassDetailsRegistry();
98+
99+
final ClassDetails integerClassDetails = classDetailsRegistry.getClassDetails( Integer.class.getName() );
100+
final ClassTypeDetailsImpl integerTypeDetails = new ClassTypeDetailsImpl( integerClassDetails, TypeDetails.Kind.CLASS );
101+
102+
final ClassDetails stringClassDetails = classDetailsRegistry.getClassDetails( String.class.getName() );
103+
final ClassTypeDetailsImpl stringTypeDetails = new ClassTypeDetailsImpl( stringClassDetails, TypeDetails.Kind.CLASS );
104+
105+
classDetailsRegistry.as( MutableClassDetailsRegistry.class )
106+
.resolveClassDetails( "TheEntity", (name) -> new DynamicClassDetails( name, buildingContext ) );
107+
108+
final DynamicClassDetails entityDetails = (DynamicClassDetails) classDetailsRegistry.resolveClassDetails( "TheEntity" );
109+
final Entity created = entityDetails.applyAnnotationUsage(
110+
JpaAnnotations.ENTITY,
111+
buildingContext
112+
);
113+
final Entity preExisting = entityDetails.applyAnnotationUsage(
114+
JpaAnnotations.ENTITY,
115+
buildingContext
116+
);
117+
assertThat( created ).isSameAs( preExisting );
118+
119+
final DynamicFieldDetails idMember = entityDetails.applyAttribute(
120+
"id",
121+
integerTypeDetails,
122+
false,
123+
false,
124+
buildingContext
125+
);
126+
final Id first = idMember.applyAnnotationUsage(
127+
JpaAnnotations.ID,
128+
buildingContext
129+
);
130+
final Id second = idMember.applyAnnotationUsage(
131+
JpaAnnotations.ID,
132+
buildingContext
133+
);
134+
assertThat( first ).isSameAs( second );
135+
136+
entityDetails.applyAttribute(
137+
"name",
138+
stringTypeDetails,
139+
false,
140+
false,
141+
buildingContext
142+
);
143+
144+
assertThat( entityDetails.getFields() ).hasSize( 2 );
145+
assertThat( entityDetails.getFields().get( 0 ).getName() ).isEqualTo( "id" );
146+
assertThat( entityDetails.getFields().get( 0 ).hasDirectAnnotationUsage( Id.class ) ).isTrue();
147+
checkPersistability( entityDetails.getFields().get( 0 ) );
148+
checkPersistability( entityDetails.getFields().get( 1 ) );
149+
}
150+
93151
private void checkPersistability(FieldDetails fieldDetails) {
94152
assertThat( fieldDetails.isPersistable() ).isTrue();
95153

hibernate-models/src/main/java/org/hibernate/models/internal/AbstractClassDetailsRegistry.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.hibernate.models.spi.ClassDetails;
1616
import org.hibernate.models.spi.ClassDetailsBuilder;
1717
import org.hibernate.models.spi.SourceModelBuildingContext;
18-
import org.hibernate.models.spi.VoidTypeDetails;
1918

2019
/**
2120
* @author Steve Ebersole
@@ -126,4 +125,40 @@ public void addClassDetails(String name, ClassDetails classDetails) {
126125
subTypes.add( classDetails );
127126
}
128127
}
128+
129+
@Override
130+
public ClassDetails resolveClassDetails(String name, ClassDetailsCreator creator) {
131+
if ( name == null ) {
132+
throw new IllegalArgumentException( "`name` cannot be null" );
133+
}
134+
135+
if ( "void".equals( name ) ) {
136+
return null;
137+
}
138+
139+
final ClassDetails existing = classDetailsMap.get( name );
140+
if ( existing != null ) {
141+
return existing;
142+
}
143+
144+
return createClassDetails( name, creator );
145+
}
146+
147+
protected ClassDetails createClassDetails(String name, ClassDetailsCreator creator) {
148+
try {
149+
final ClassDetails created = creator.createClassDetails( name );
150+
addClassDetails( name, created );
151+
return created;
152+
}
153+
catch (UnknownClassException e) {
154+
// see if it might be a package name...
155+
try {
156+
return creator.createClassDetails( name + ".package-info" );
157+
}
158+
catch (UnknownClassException noPackage) {
159+
throw e;
160+
}
161+
}
162+
}
163+
129164
}

hibernate-models/src/main/java/org/hibernate/models/internal/MutableClassDetailsRegistry.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package org.hibernate.models.internal;
99

10+
import org.hibernate.models.UnknownClassException;
1011
import org.hibernate.models.spi.ClassDetails;
1112
import org.hibernate.models.spi.ClassDetailsRegistry;
1213

@@ -24,4 +25,21 @@ public interface MutableClassDetailsRegistry extends ClassDetailsRegistry {
2425
* Adds a managed-class descriptor using the given {@code name} as the registration key
2526
*/
2627
void addClassDetails(String name, ClassDetails classDetails);
28+
29+
/**
30+
* Resolve (find or create) ClassDetails by name. If there is currently no
31+
* such registration, one is created using the specified {@code creator}.
32+
*/
33+
ClassDetails resolveClassDetails(String name, ClassDetailsCreator creator);
34+
35+
/**
36+
* Create a CLass Details
37+
*/
38+
@FunctionalInterface
39+
interface ClassDetailsCreator {
40+
/**
41+
* @throws UnknownClassException
42+
*/
43+
ClassDetails createClassDetails(String name) throws UnknownClassException;
44+
}
2745
}

0 commit comments

Comments
 (0)