-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#100 - AnnotationTarget.getContainer()
- Loading branch information
Showing
17 changed files
with
585 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
...s-jandex/src/test/java/org/hibernate/models/annotations/target/AnnotationTargetTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.annotations.target; | ||
|
||
import org.hibernate.models.annotations.target.sub.SubNoGeneratorEntity; | ||
import org.hibernate.models.spi.ClassDetails; | ||
import org.hibernate.models.spi.ClassDetailsRegistry; | ||
import org.hibernate.models.spi.FieldDetails; | ||
import org.hibernate.models.spi.SourceModelBuildingContext; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import org.jboss.jandex.Index; | ||
import org.jboss.jandex.IndexView; | ||
|
||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; | ||
import static org.hibernate.models.SourceModelTestHelper.buildJandexIndex; | ||
import static org.hibernate.models.SourceModelTestHelper.createBuildingContext; | ||
|
||
/** | ||
* @author Steve Ebersole | ||
*/ | ||
public class AnnotationTargetTests { | ||
@Test | ||
void testPackageDefinedWithJandex() { | ||
testPackageDefined( buildJandexIndex( NoGeneratorEntity.class ) ); | ||
} | ||
|
||
@Test | ||
void testPackageDefinedWithoutJandex() { | ||
testPackageDefined( null ); | ||
} | ||
|
||
/** | ||
* We should find the annotation on the package | ||
*/ | ||
void testPackageDefined(IndexView jandexIndex) { | ||
final SourceModelBuildingContext buildingContext = createBuildingContext( jandexIndex, NoGeneratorEntity.class ); | ||
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getClassDetailsRegistry(); | ||
|
||
final ClassDetails entityClass = classDetailsRegistry.getClassDetails( NoGeneratorEntity.class.getName() ); | ||
final FieldDetails idMember = entityClass.findFieldByName( "id" ); | ||
assertThat( idMember.getContainer( buildingContext ) ).isSameAs( entityClass ); | ||
|
||
assertThat( idMember.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( idMember.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
final ClassDetails idMemberContainer = idMember.getContainer( buildingContext ); | ||
assertThat( idMemberContainer ).isSameAs( entityClass ); | ||
assertThat( idMemberContainer.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( idMemberContainer.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
final ClassDetails entityClassPackage = entityClass.getContainer( buildingContext ); | ||
assertThat( entityClassPackage.getName() ).endsWith( "annotations.target.package-info" ); | ||
assertThat( entityClassPackage.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isTrue(); | ||
assertThat( entityClassPackage.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isTrue(); | ||
} | ||
|
||
@Test | ||
void testClassDefinedWithJandex() { | ||
testClassDefined( buildJandexIndex( ClassGeneratorEntity.class ) ); | ||
} | ||
|
||
@Test | ||
void testClassDefinedWithoutJandex() { | ||
testClassDefined( null ); | ||
} | ||
|
||
private void testClassDefined(Index jandexIndex) { | ||
final SourceModelBuildingContext buildingContext = createBuildingContext( jandexIndex, ClassGeneratorEntity.class ); | ||
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getClassDetailsRegistry(); | ||
|
||
final ClassDetails entityClass = classDetailsRegistry.getClassDetails( ClassGeneratorEntity.class.getName() ); | ||
final FieldDetails idMember = entityClass.findFieldByName( "id" ); | ||
assertThat( idMember.getContainer( buildingContext ) ).isSameAs( entityClass ); | ||
|
||
assertThat( idMember.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( idMember.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
assertThat( entityClass.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isTrue(); | ||
assertThat( entityClass.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isTrue(); | ||
|
||
final ClassDetails entityClassPackage = entityClass.getContainer( buildingContext ); | ||
assertThat( entityClassPackage.getName() ).endsWith( "annotations.target.package-info" ); | ||
assertThat( entityClassPackage.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isTrue(); | ||
assertThat( entityClassPackage.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isTrue(); | ||
} | ||
|
||
@Test | ||
void testMemberDefinedWithJandex() { | ||
testMemberDefined( buildJandexIndex( MemberGeneratorEntity.class ) ); | ||
} | ||
|
||
@Test | ||
void testMemberDefinedWithoutJandex() { | ||
testMemberDefined( null ); | ||
} | ||
|
||
private void testMemberDefined(Index jandexIndex) { | ||
final SourceModelBuildingContext buildingContext = createBuildingContext( jandexIndex, MemberGeneratorEntity.class ); | ||
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getClassDetailsRegistry(); | ||
|
||
final ClassDetails entityClass = classDetailsRegistry.getClassDetails( MemberGeneratorEntity.class.getName() ); | ||
final FieldDetails idMember = entityClass.findFieldByName( "id" ); | ||
assertThat( idMember.getContainer( buildingContext ) ).isSameAs( entityClass ); | ||
|
||
assertThat( idMember.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isTrue(); | ||
assertThat( idMember.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isTrue(); | ||
|
||
assertThat( entityClass.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( entityClass.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
final ClassDetails entityClassPackage = entityClass.getContainer( buildingContext ); | ||
assertThat( entityClassPackage.getName() ).endsWith( "annotations.target.package-info" ); | ||
assertThat( entityClassPackage.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isTrue(); | ||
assertThat( entityClassPackage.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isTrue(); | ||
} | ||
|
||
@Test | ||
void testUpPackageDefinedWithJandex() { | ||
testUpPackageDefined( buildJandexIndex( SubNoGeneratorEntity.class ) ); | ||
} | ||
|
||
@Test | ||
void testUpPackageDefinedWithoutJandex() { | ||
testUpPackageDefined( null ); | ||
} | ||
|
||
/** | ||
*/ | ||
void testUpPackageDefined(IndexView jandexIndex) { | ||
final SourceModelBuildingContext buildingContext = createBuildingContext( jandexIndex, SubNoGeneratorEntity.class ); | ||
final ClassDetailsRegistry classDetailsRegistry = buildingContext.getClassDetailsRegistry(); | ||
|
||
final ClassDetails entityClass = classDetailsRegistry.getClassDetails( SubNoGeneratorEntity.class.getName() ); | ||
final FieldDetails idMember = entityClass.findFieldByName( "id" ); | ||
assertThat( idMember.getContainer( buildingContext ) ).isSameAs( entityClass ); | ||
|
||
assertThat( idMember.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( idMember.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
final ClassDetails idMemberContainer = idMember.getContainer( buildingContext ); | ||
assertThat( idMemberContainer ).isSameAs( entityClass ); | ||
assertThat( idMemberContainer.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( idMemberContainer.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
final ClassDetails entityClassPackage = entityClass.getContainer( buildingContext ); | ||
assertThat( entityClassPackage.getName() ).endsWith( "annotations.target.sub.package-info" ); | ||
assertThat( entityClassPackage.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isFalse(); | ||
assertThat( entityClassPackage.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isFalse(); | ||
|
||
final ClassDetails entityClassPackagePackage = entityClassPackage.getContainer( buildingContext ); | ||
assertThat( entityClassPackagePackage.getName() ).endsWith( "annotations.target.package-info" ); | ||
assertThat( entityClassPackagePackage.hasDirectAnnotationUsage( GeneratorAnnotation.class ) ).isTrue(); | ||
assertThat( entityClassPackagePackage.hasAnnotationUsage( GeneratorAnnotation.class, buildingContext ) ).isTrue(); | ||
} | ||
|
||
} |
14 changes: 14 additions & 0 deletions
14
...ls-jandex/src/test/java/org/hibernate/models/annotations/target/ClassGeneratorEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.annotations.target; | ||
|
||
/** | ||
* @author Steve Ebersole | ||
*/ | ||
@GeneratorAnnotation(GeneratorAnnotation.Source.TYPE) | ||
public class ClassGeneratorEntity { | ||
private Integer id; | ||
} |
23 changes: 23 additions & 0 deletions
23
...els-jandex/src/test/java/org/hibernate/models/annotations/target/GeneratorAnnotation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.annotations.target; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
import java.lang.annotation.Retention; | ||
|
||
/** | ||
* Let's mimic a Hibernate/JPA id generator annotation | ||
* | ||
* @author Steve Ebersole | ||
*/ | ||
@Target({ElementType.PACKAGE, ElementType.TYPE, ElementType.FIELD, ElementType.METHOD}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface GeneratorAnnotation { | ||
enum Source { PACKAGE, TYPE, MEMBER } | ||
Source value(); | ||
} |
14 changes: 14 additions & 0 deletions
14
...s-jandex/src/test/java/org/hibernate/models/annotations/target/MemberGeneratorEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.annotations.target; | ||
|
||
/** | ||
* @author Steve Ebersole | ||
*/ | ||
public class MemberGeneratorEntity { | ||
@GeneratorAnnotation(GeneratorAnnotation.Source.MEMBER) | ||
private Integer id; | ||
} |
15 changes: 15 additions & 0 deletions
15
...odels-jandex/src/test/java/org/hibernate/models/annotations/target/NoGeneratorEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.annotations.target; | ||
|
||
/** | ||
* Models an entity where we should get the generator from the package | ||
* | ||
* @author Steve Ebersole | ||
*/ | ||
public class NoGeneratorEntity { | ||
private Integer id; | ||
} |
10 changes: 10 additions & 0 deletions
10
...ate-models-jandex/src/test/java/org/hibernate/models/annotations/target/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
/** | ||
* @author Steve Ebersole | ||
*/ | ||
@GeneratorAnnotation(GeneratorAnnotation.Source.PACKAGE) | ||
package org.hibernate.models.annotations.target; |
15 changes: 15 additions & 0 deletions
15
...andex/src/test/java/org/hibernate/models/annotations/target/sub/SubNoGeneratorEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.annotations.target.sub; | ||
|
||
/** | ||
* This ideally should not have a generator. But | ||
* | ||
* @author Steve Ebersole | ||
*/ | ||
public class SubNoGeneratorEntity { | ||
private Integer id; | ||
} |
79 changes: 79 additions & 0 deletions
79
hibernate-models/src/main/java/org/hibernate/models/internal/AnnotationTargetHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* Copyright: Red Hat Inc. and Hibernate Authors | ||
*/ | ||
|
||
package org.hibernate.models.internal; | ||
|
||
import org.hibernate.models.internal.jdk.JdkClassDetails; | ||
import org.hibernate.models.internal.util.StringHelper; | ||
import org.hibernate.models.spi.ClassDetails; | ||
import org.hibernate.models.spi.SourceModelBuildingContext; | ||
|
||
/** | ||
* Utilities related to {@linkplain org.hibernate.models.spi.AnnotationTarget} | ||
* | ||
* @author Steve Ebersole | ||
*/ | ||
public class AnnotationTargetHelper { | ||
/** | ||
* Resolve the ClassDetails descriptor for the package which contains the | ||
* given {@code classDetails}. | ||
* | ||
* @apiNote {@code classDetails} may be the ClassDetails for a `package-info` itself, | ||
* in which case this returns the `package-info` ClassDetails for the containing package. | ||
*/ | ||
public static ClassDetails resolvePackageInfo( | ||
ClassDetails classDetails, | ||
SourceModelBuildingContext modelBuildingContext) { | ||
if ( classDetails.getClassName() == null ) { | ||
return null; | ||
} | ||
final String containingPackageName = determineContainingPackageName( classDetails ); | ||
final String packageInfoClassName = containingPackageName + ".package-info"; | ||
|
||
return modelBuildingContext.getClassDetailsRegistry() | ||
.as( MutableClassDetailsRegistry.class ) | ||
.resolveClassDetails( packageInfoClassName, name -> { | ||
// see if there is a physical package-info Class | ||
final Class<Object> packageInfoClass = modelBuildingContext.getClassLoading().findClassForName( packageInfoClassName ); | ||
if ( packageInfoClass == null ) { | ||
return new MissingPackageInfoDetails( containingPackageName, packageInfoClassName ); | ||
} | ||
else { | ||
return new JdkClassDetails( packageInfoClass, modelBuildingContext ); | ||
} | ||
} ); | ||
} | ||
|
||
public static String determineContainingPackageName(ClassDetails classDetails) { | ||
final String className = classDetails.getClassName(); | ||
assert className != null; | ||
|
||
// 2 broad cases here - | ||
// | ||
// 1. we have a "normal" class. | ||
// e.g. given `org.hibernate.FlushMode`, the containing package is `org.hibernate` | ||
// 2. we have a package-info class | ||
// e.g. given `org.hibernate.package-info`, the containing package is really `org` | ||
|
||
// in both cases, this is `org.hibernate` | ||
final String classNameNamespace = StringHelper.qualifier( className ); | ||
if ( className.endsWith( "package-info" ) ) { | ||
return classNameNamespace.indexOf( '.' ) > 1 | ||
? StringHelper.qualifier( classNameNamespace ) | ||
: null; | ||
} | ||
else { | ||
return classNameNamespace; | ||
} | ||
} | ||
|
||
private AnnotationTargetHelper() { | ||
} | ||
} |
Oops, something went wrong.