Skip to content

Commit

Permalink
#45 - Allow full construction of DynamicClassDetails, DynamicFieldDet…
Browse files Browse the repository at this point in the history
…ails and DynamicMethodDetails
  • Loading branch information
sebersole committed Mar 18, 2024
1 parent 2eda68f commit 6dab68d
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.hibernate.models.spi.TypeVariableDetails;

/**
* ClassDetails which does not necessarily map to a physical Class (dynamic models)
*
* @author Steve Ebersole
*/
public class DynamicClassDetails extends AbstractAnnotationTarget implements ClassDetailsSupport {
Expand Down Expand Up @@ -53,12 +55,24 @@ public DynamicClassDetails(
ClassDetails superClass,
TypeDetails genericSuperType,
SourceModelBuildingContext buildingContext) {
this( name, className, null, isAbstract, superClass, genericSuperType, buildingContext );
}

public DynamicClassDetails(
String name,
String className,
Class<?> javaType,
boolean isAbstract,
ClassDetails superClass,
TypeDetails genericSuperType,
SourceModelBuildingContext buildingContext) {
super( buildingContext );
this.name = name;
this.className = className;
this.isAbstract = isAbstract;
this.superClass = superClass;
this.genericSuperType = genericSuperType;
this.javaType = javaType;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.hibernate.models.spi.TypeVariableScope;

/**
* FieldDetails which does not necessarily map to a physical Field (dynamic models)
*
* @author Steve Ebersole
*/
public class DynamicFieldDetails extends AbstractAnnotationTarget implements FieldDetails, MutableMemberDetails {
Expand All @@ -35,20 +37,32 @@ public DynamicFieldDetails(
ClassDetails declaringType,
int modifierFlags,
SourceModelBuildingContext buildingContext) {
this(
name,
type,
declaringType,
modifierFlags,
type != null && type.getName().startsWith( "[" ),
type != null && ( type.isImplementor( Collection.class ) || type.isImplementor( Map.class ) ),
buildingContext
);
}

public DynamicFieldDetails(
String name,
TypeDetails type,
ClassDetails declaringType,
int modifierFlags,
boolean isArray,
boolean isPlural,
SourceModelBuildingContext buildingContext) {
super( buildingContext );
this.name = name;
this.type = type;
this.declaringType = declaringType;
this.modifierFlags = modifierFlags;

if ( type != null ) {
this.isArray = type.getName().startsWith( "[" );
this.isPlural = isArray || type.isImplementor( Collection.class ) || type.isImplementor( Map.class );
}
else {
this.isArray = false;
this.isPlural = false;
}
this.isArray = isArray;
this.isPlural = isPlural;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import org.hibernate.models.spi.TypeVariableScope;

/**
* MethodDetails which does not necessarily map to a physical Method (dynamic models)
*
* @author Steve Ebersole
*/
public class DynamicMethodDetails extends AbstractAnnotationTarget implements MethodDetails, MutableMemberDetails {
Expand All @@ -43,23 +45,41 @@ public DynamicMethodDetails(
ClassDetails returnType,
List<ClassDetails> argumentTypes,
SourceModelBuildingContext buildingContext) {
this(
name,
type,
declaringType,
methodKind,
modifierFlags,
type != null && type.getName().startsWith( "[" ),
type != null && ( type.isImplementor( Collection.class ) || type.isImplementor( Map.class ) ),
returnType,
argumentTypes,
buildingContext
);
}

public DynamicMethodDetails(
String name,
TypeDetails type,
ClassDetails declaringType,
MethodKind methodKind,
int modifierFlags,
boolean isArray,
boolean isPlural,
ClassDetails returnType,
List<ClassDetails> argumentTypes,
SourceModelBuildingContext buildingContext) {
super( buildingContext );
this.name = name;
this.type = type;
this.declaringType = declaringType;
this.methodKind = methodKind;
this.modifierFlags = modifierFlags;
this.isArray = isArray;
this.isPlural = isPlural;
this.returnType = returnType;
this.argumentTypes = argumentTypes;

if ( type != null ) {
this.isArray = type.getName().startsWith( "[" );
this.isPlural = isArray || type.isImplementor( Collection.class ) || type.isImplementor( Map.class );
}
else {
this.isArray = false;
this.isPlural = false;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models.annotations;
package org.hibernate.models.dynamic;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

package org.hibernate.models.dynamic;

import java.lang.reflect.Modifier;

import org.hibernate.models.SourceModelTestHelper;
import org.hibernate.models.internal.ClassTypeDetailsImpl;
import org.hibernate.models.internal.SourceModelBuildingContextImpl;
import org.hibernate.models.internal.dynamic.DynamicClassDetails;
import org.hibernate.models.internal.dynamic.DynamicFieldDetails;
import org.hibernate.models.orm.JpaAnnotations;
import org.hibernate.models.spi.ClassDetails;
import org.hibernate.models.spi.ClassDetailsRegistry;
import org.hibernate.models.spi.MutableClassDetails;
import org.hibernate.models.spi.TypeDetails;

import org.junit.jupiter.api.Test;

import org.jboss.jandex.Index;

/**
* @author Steve Ebersole
*/
public class SimpleDynamicModelTests {
@Test
void testSimpleBasics() {
final SourceModelBuildingContextImpl 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 );

final MutableClassDetails entityDetails = (MutableClassDetails) classDetailsRegistry.resolveClassDetails(
"TheEntity",
name -> new DynamicClassDetails( name, buildingContext )
);
entityDetails.addAnnotationUsage( JpaAnnotations.ENTITY.createUsage( entityDetails, buildingContext ) );


final DynamicFieldDetails idFieldDetails = new DynamicFieldDetails(
"id",
integerTypeDetails,
entityDetails,
Modifier.fieldModifiers(),
false,
false,
buildingContext
);
entityDetails.addField( idFieldDetails );

final DynamicFieldDetails nameFieldDetails = new DynamicFieldDetails(
"name",
stringTypeDetails,
entityDetails,
Modifier.fieldModifiers(),
false,
false,
buildingContext
);
entityDetails.addField( nameFieldDetails );
}

@Test
void testSimpleEmbedded() {
final SourceModelBuildingContextImpl 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 );

final MutableClassDetails entityDetails = (MutableClassDetails) classDetailsRegistry.resolveClassDetails(
"TheEntity",
name -> new DynamicClassDetails( name, buildingContext )
);
entityDetails.addAnnotationUsage( JpaAnnotations.ENTITY.createUsage( entityDetails, buildingContext ) );

final MutableClassDetails nameEmbeddableDetails = (MutableClassDetails) classDetailsRegistry.resolveClassDetails(
"TheName",
name -> new DynamicClassDetails( name, buildingContext )
);
nameEmbeddableDetails.addAnnotationUsage( JpaAnnotations.EMBEDDABLE.createUsage( entityDetails, buildingContext ) );
final ClassTypeDetailsImpl nameEmbeddableTypeDetails = new ClassTypeDetailsImpl( nameEmbeddableDetails, TypeDetails.Kind.CLASS );

final DynamicFieldDetails firstFieldDetails = new DynamicFieldDetails(
"first",
stringTypeDetails,
nameEmbeddableDetails,
Modifier.fieldModifiers(),
false,
false,
buildingContext
);
nameEmbeddableDetails.addField( firstFieldDetails );

final DynamicFieldDetails lastFieldDetails = new DynamicFieldDetails(
"last",
stringTypeDetails,
nameEmbeddableDetails,
Modifier.fieldModifiers(),
false,
false,
buildingContext
);
nameEmbeddableDetails.addField( lastFieldDetails );


final DynamicFieldDetails nameFieldDetails = new DynamicFieldDetails(
"name",
nameEmbeddableTypeDetails,
entityDetails,
Modifier.fieldModifiers(),
false,
false,
buildingContext
);
entityDetails.addField( nameFieldDetails );
}
}
14 changes: 14 additions & 0 deletions src/test/java/org/hibernate/models/dynamic/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/

/**
* Tests verifying expected usage patterns of {@linkplain org.hibernate.models.dynamic dynamic models}
* as expected by Hibernate ORM
*
* @author Steve Ebersole
*/
package org.hibernate.models.dynamic;

0 comments on commit 6dab68d

Please sign in to comment.