Skip to content

97 Add dynamic-class resolution support to MutableClassDetailsRegistry #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,64 @@ void testSimpleBasics() {
checkPersistability( entityDetails.getFields().get( 1 ) );
}


@Test
void testResolveClassDetails() {
final SourceModelBuildingContext buildingContext = SourceModelTestHelper.createBuildingContext( (Index) null );
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getClassDetailsRegistry();

final ClassDetails integerClassDetails = classDetailsRegistry.getClassDetails( Integer.class.getName() );
final ClassTypeDetailsImpl integerTypeDetails = new ClassTypeDetailsImpl( integerClassDetails, TypeDetails.Kind.CLASS );

final ClassDetails stringClassDetails = classDetailsRegistry.getClassDetails( String.class.getName() );
final ClassTypeDetailsImpl stringTypeDetails = new ClassTypeDetailsImpl( stringClassDetails, TypeDetails.Kind.CLASS );

classDetailsRegistry.as( MutableClassDetailsRegistry.class )
.resolveClassDetails( "TheEntity", (name) -> new DynamicClassDetails( name, buildingContext ) );

final DynamicClassDetails entityDetails = (DynamicClassDetails) classDetailsRegistry.resolveClassDetails( "TheEntity" );
final Entity created = entityDetails.applyAnnotationUsage(
JpaAnnotations.ENTITY,
buildingContext
);
final Entity preExisting = entityDetails.applyAnnotationUsage(
JpaAnnotations.ENTITY,
buildingContext
);
assertThat( created ).isSameAs( preExisting );

final DynamicFieldDetails idMember = entityDetails.applyAttribute(
"id",
integerTypeDetails,
false,
false,
buildingContext
);
final Id first = idMember.applyAnnotationUsage(
JpaAnnotations.ID,
buildingContext
);
final Id second = idMember.applyAnnotationUsage(
JpaAnnotations.ID,
buildingContext
);
assertThat( first ).isSameAs( second );

entityDetails.applyAttribute(
"name",
stringTypeDetails,
false,
false,
buildingContext
);

assertThat( entityDetails.getFields() ).hasSize( 2 );
assertThat( entityDetails.getFields().get( 0 ).getName() ).isEqualTo( "id" );
assertThat( entityDetails.getFields().get( 0 ).hasDirectAnnotationUsage( Id.class ) ).isTrue();
checkPersistability( entityDetails.getFields().get( 0 ) );
checkPersistability( entityDetails.getFields().get( 1 ) );
}

private void checkPersistability(FieldDetails fieldDetails) {
assertThat( fieldDetails.isPersistable() ).isTrue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.ClassDetailsBuilder;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.models.spi.VoidTypeDetails;

/**
* @author Steve Ebersole
Expand Down Expand Up @@ -126,4 +125,40 @@ public void addClassDetails(String name, ClassDetails classDetails) {
subTypes.add( classDetails );
}
}

@Override
public ClassDetails resolveClassDetails(String name, ClassDetailsCreator creator) {
if ( name == null ) {
throw new IllegalArgumentException( "`name` cannot be null" );
}

if ( "void".equals( name ) ) {
return null;
}

final ClassDetails existing = classDetailsMap.get( name );
if ( existing != null ) {
return existing;
}

return createClassDetails( name, creator );
}

protected ClassDetails createClassDetails(String name, ClassDetailsCreator creator) {
try {
final ClassDetails created = creator.createClassDetails( name );
addClassDetails( name, created );
return created;
}
catch (UnknownClassException e) {
// see if it might be a package name...
try {
return creator.createClassDetails( name + ".package-info" );
}
catch (UnknownClassException noPackage) {
throw e;
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package org.hibernate.models.internal;

import org.hibernate.models.UnknownClassException;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.ClassDetailsRegistry;

Expand All @@ -24,4 +25,21 @@ public interface MutableClassDetailsRegistry extends ClassDetailsRegistry {
* Adds a managed-class descriptor using the given {@code name} as the registration key
*/
void addClassDetails(String name, ClassDetails classDetails);

/**
* Resolve (find or create) ClassDetails by name. If there is currently no
* such registration, one is created using the specified {@code creator}.
*/
ClassDetails resolveClassDetails(String name, ClassDetailsCreator creator);

/**
* Create a CLass Details
*/
@FunctionalInterface
interface ClassDetailsCreator {
/**
* @throws UnknownClassException
*/
ClassDetails createClassDetails(String name) throws UnknownClassException;
}
}
Loading