From e24582a6ef52a8adafa942a1612fdf89b6a342c2 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 20 Nov 2024 16:23:57 +0100 Subject: [PATCH] HHH-18863 probably more efficient way to detect if a class is a Panache thing --- .../annotation/AnnotationMetaEntity.java | 39 ++------- .../hibernate/processor/util/TypeUtils.java | 87 +++++++++++-------- 2 files changed, 58 insertions(+), 68 deletions(-) diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java index a4b8a8f649..65b547399c 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java @@ -30,7 +30,6 @@ import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.select.SqmSelectStatement; -import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; @@ -48,7 +47,6 @@ import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; import javax.lang.model.type.WildcardType; -import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; @@ -85,10 +83,12 @@ import static org.hibernate.processor.util.NullnessUtil.castNonNull; import static org.hibernate.processor.util.TypeUtils.containsAnnotation; import static org.hibernate.processor.util.TypeUtils.determineAccessTypeForHierarchy; import static org.hibernate.processor.util.TypeUtils.determineAnnotationSpecifiedAccessType; +import static org.hibernate.processor.util.TypeUtils.extendsClass; import static org.hibernate.processor.util.TypeUtils.findMappedSuperClass; import static org.hibernate.processor.util.TypeUtils.getAnnotationMirror; import static org.hibernate.processor.util.TypeUtils.getAnnotationValue; import static org.hibernate.processor.util.TypeUtils.hasAnnotation; +import static org.hibernate.processor.util.TypeUtils.implementsInterface; import static org.hibernate.processor.util.TypeUtils.primitiveClassMatchesKind; import static org.hibernate.processor.util.TypeUtils.propertyName; @@ -652,41 +652,18 @@ public class AnnotationMetaEntity extends AnnotationMeta { } private boolean isPanacheType(TypeElement type) { - return isOrmPanacheType( type ) - || isReactivePanacheType( type ); + return context.usesQuarkusOrm() && isOrmPanacheType( type ) + || context.usesQuarkusReactive() && isReactivePanacheType( type ); } private boolean isOrmPanacheType(TypeElement type) { - final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment(); - final Elements elements = processingEnvironment.getElementUtils(); - final TypeElement panacheRepositorySuperType = elements.getTypeElement( PANACHE_ORM_REPOSITORY_BASE ); - final TypeElement panacheEntitySuperType = elements.getTypeElement( PANACHE_ORM_ENTITY_BASE ); - if ( panacheRepositorySuperType == null || panacheEntitySuperType == null ) { - return false; - } - else { - final Types types = processingEnvironment.getTypeUtils(); - // check against a raw supertype of PanacheRepositoryBase, which .asType() is not - return types.isSubtype( type.asType(), types.getDeclaredType( panacheRepositorySuperType ) ) - || types.isSubtype( type.asType(), panacheEntitySuperType.asType() ); - } + return implementsInterface( type, PANACHE_ORM_REPOSITORY_BASE ) + || extendsClass( type, PANACHE_ORM_ENTITY_BASE ); } private boolean isReactivePanacheType(TypeElement type) { - final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment(); - final Elements elements = processingEnvironment.getElementUtils(); - final TypeElement panacheRepositorySuperType = elements.getTypeElement( PANACHE_REACTIVE_REPOSITORY_BASE ); - final TypeElement panacheEntitySuperType = elements.getTypeElement( PANACHE_REACTIVE_ENTITY_BASE ); - - if ( panacheRepositorySuperType == null || panacheEntitySuperType == null ) { - return false; - } - else { - final Types types = processingEnvironment.getTypeUtils(); - // check against a raw supertype of PanacheRepositoryBase, which .asType() is not - return types.isSubtype( type.asType(), types.getDeclaredType( panacheRepositorySuperType ) ) - || types.isSubtype( type.asType(), panacheEntitySuperType.asType() ); - } + return implementsInterface( type, PANACHE_REACTIVE_REPOSITORY_BASE ) + || extendsClass( type, PANACHE_REACTIVE_ENTITY_BASE ); } /** diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java index 598813de93..556e6bec4b 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java @@ -129,12 +129,11 @@ public final class TypeUtils { } public static @Nullable TypeElement getSuperclassTypeElement(TypeElement element) { - final TypeMirror superClass = element.getSuperclass(); + final TypeMirror superclass = element.getSuperclass(); //superclass of Object is of NoType which returns some other kind - if ( superClass.getKind() == TypeKind.DECLARED ) { - //F..king Ch...t Have those people used their horrible APIs even once? - final Element superClassElement = ( (DeclaredType) superClass ).asElement(); - return (TypeElement) superClassElement; + if ( superclass.getKind() == TypeKind.DECLARED ) { + final DeclaredType declaredType = (DeclaredType) superclass; + return (TypeElement) declaredType.asElement(); } else { return null; @@ -466,14 +465,11 @@ public final class TypeUtils { } private static @Nullable AccessType getAccessTypeOfIdAnnotation(Element element) { - switch ( element.getKind() ) { - case FIELD: - return AccessType.FIELD; - case METHOD: - return AccessType.PROPERTY; - default: - return null; - } + return switch ( element.getKind() ) { + case FIELD -> AccessType.FIELD; + case METHOD -> AccessType.PROPERTY; + default -> null; + }; } private static boolean isIdAnnotation(AnnotationMirror annotationMirror) { @@ -522,26 +518,17 @@ public final class TypeUtils { } public static boolean primitiveClassMatchesKind(Class itemType, TypeKind kind) { - switch (kind) { - case SHORT: - return itemType.equals(Short.class); - case INT: - return itemType.equals(Integer.class); - case LONG: - return itemType.equals(Long.class); - case BOOLEAN: - return itemType.equals(Boolean.class); - case FLOAT: - return itemType.equals(Float.class); - case DOUBLE: - return itemType.equals(Double.class); - case CHAR: - return itemType.equals(Character.class); - case BYTE: - return itemType.equals(Byte.class); - default: - return false; - } + return switch ( kind ) { + case SHORT -> itemType.equals( Short.class ); + case INT -> itemType.equals( Integer.class ); + case LONG -> itemType.equals( Long.class ); + case BOOLEAN -> itemType.equals( Boolean.class ); + case FLOAT -> itemType.equals( Float.class ); + case DOUBLE -> itemType.equals( Double.class ); + case CHAR -> itemType.equals( Character.class ); + case BYTE -> itemType.equals( Byte.class ); + default -> false; + }; } public static boolean isPropertyGetter(ExecutableType executable, Element element) { @@ -602,7 +589,7 @@ public final class TypeUtils { return elementsUtil.getName(decapitalize(name.substring(3))).toString(); } else if ( name.startsWith( "is" ) ) { - return (elementsUtil.getName(decapitalize(name.substring(2)))).toString(); + return elementsUtil.getName(decapitalize(name.substring(2))).toString(); } return elementsUtil.getName(decapitalize(name)).toString(); } @@ -613,8 +600,7 @@ public final class TypeUtils { public static @Nullable String findMappedSuperClass(Metamodel entity, Context context) { final Element element = entity.getElement(); - if ( element instanceof TypeElement ) { - final TypeElement typeElement = (TypeElement) element; + if ( element instanceof TypeElement typeElement ) { TypeMirror superClass = typeElement.getSuperclass(); //superclass of Object is of NoType which returns some other kind while ( superClass.getKind() == TypeKind.DECLARED ) { @@ -654,6 +640,33 @@ public final class TypeUtils { || !entityMetaComplete && containsAnnotation( superClassElement, ENTITY, MAPPED_SUPERCLASS ); } + public static boolean implementsInterface(TypeElement type, String interfaceName) { + for ( TypeMirror iface : type.getInterfaces() ) { + if ( iface.getKind() == TypeKind.DECLARED ) { + final DeclaredType declaredType = (DeclaredType) iface; + final TypeElement typeElement = (TypeElement) declaredType.asElement(); + if ( typeElement.getQualifiedName().contentEquals( interfaceName ) + || implementsInterface( typeElement, interfaceName ) ) { + return true; + } + } + } + return false; + } + + public static boolean extendsClass(TypeElement type, String className) { + TypeMirror superclass = type.getSuperclass(); + while ( superclass != null && superclass.getKind() == TypeKind.DECLARED ) { + final DeclaredType declaredType = (DeclaredType) superclass; + final TypeElement typeElement = (TypeElement) declaredType.asElement(); + if ( typeElement.getQualifiedName().contentEquals( className ) ) { + return true; + } + superclass = typeElement.getSuperclass(); + } + return false; + } + static class EmbeddedAttributeVisitor extends SimpleTypeVisitor8<@Nullable TypeElement, Element> { private final Context context; @@ -665,7 +678,7 @@ public final class TypeUtils { public @Nullable TypeElement visitDeclared(DeclaredType declaredType, Element element) { final TypeElement returnedElement = (TypeElement) context.getTypeUtils().asElement( declaredType ); - return containsAnnotation( NullnessUtil.castNonNull( returnedElement ), EMBEDDABLE ) ? returnedElement : null; + return containsAnnotation( castNonNull( returnedElement ), EMBEDDABLE ) ? returnedElement : null; } @Override