HHH-18863 probably more efficient way to detect if a class is a Panache thing

This commit is contained in:
Gavin King 2024-11-20 16:23:57 +01:00
parent 453f0ff074
commit e24582a6ef
2 changed files with 58 additions and 68 deletions

View File

@ -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.expression.SqmParameter;
import org.hibernate.query.sqm.tree.select.SqmSelectStatement; import org.hibernate.query.sqm.tree.select.SqmSelectStatement;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element; 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.TypeMirror;
import javax.lang.model.type.TypeVariable; import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType; import javax.lang.model.type.WildcardType;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.tools.Diagnostic; 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.containsAnnotation;
import static org.hibernate.processor.util.TypeUtils.determineAccessTypeForHierarchy; import static org.hibernate.processor.util.TypeUtils.determineAccessTypeForHierarchy;
import static org.hibernate.processor.util.TypeUtils.determineAnnotationSpecifiedAccessType; 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.findMappedSuperClass;
import static org.hibernate.processor.util.TypeUtils.getAnnotationMirror; import static org.hibernate.processor.util.TypeUtils.getAnnotationMirror;
import static org.hibernate.processor.util.TypeUtils.getAnnotationValue; import static org.hibernate.processor.util.TypeUtils.getAnnotationValue;
import static org.hibernate.processor.util.TypeUtils.hasAnnotation; 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.primitiveClassMatchesKind;
import static org.hibernate.processor.util.TypeUtils.propertyName; import static org.hibernate.processor.util.TypeUtils.propertyName;
@ -652,41 +652,18 @@ public class AnnotationMetaEntity extends AnnotationMeta {
} }
private boolean isPanacheType(TypeElement type) { private boolean isPanacheType(TypeElement type) {
return isOrmPanacheType( type ) return context.usesQuarkusOrm() && isOrmPanacheType( type )
|| isReactivePanacheType( type ); || context.usesQuarkusReactive() && isReactivePanacheType( type );
} }
private boolean isOrmPanacheType(TypeElement type) { private boolean isOrmPanacheType(TypeElement type) {
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment(); return implementsInterface( type, PANACHE_ORM_REPOSITORY_BASE )
final Elements elements = processingEnvironment.getElementUtils(); || extendsClass( type, PANACHE_ORM_ENTITY_BASE );
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() );
}
} }
private boolean isReactivePanacheType(TypeElement type) { private boolean isReactivePanacheType(TypeElement type) {
final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment(); return implementsInterface( type, PANACHE_REACTIVE_REPOSITORY_BASE )
final Elements elements = processingEnvironment.getElementUtils(); || extendsClass( type, PANACHE_REACTIVE_ENTITY_BASE );
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() );
}
} }
/** /**

View File

@ -129,12 +129,11 @@ public final class TypeUtils {
} }
public static @Nullable TypeElement getSuperclassTypeElement(TypeElement element) { 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 //superclass of Object is of NoType which returns some other kind
if ( superClass.getKind() == TypeKind.DECLARED ) { if ( superclass.getKind() == TypeKind.DECLARED ) {
//F..king Ch...t Have those people used their horrible APIs even once? final DeclaredType declaredType = (DeclaredType) superclass;
final Element superClassElement = ( (DeclaredType) superClass ).asElement(); return (TypeElement) declaredType.asElement();
return (TypeElement) superClassElement;
} }
else { else {
return null; return null;
@ -466,14 +465,11 @@ public final class TypeUtils {
} }
private static @Nullable AccessType getAccessTypeOfIdAnnotation(Element element) { private static @Nullable AccessType getAccessTypeOfIdAnnotation(Element element) {
switch ( element.getKind() ) { return switch ( element.getKind() ) {
case FIELD: case FIELD -> AccessType.FIELD;
return AccessType.FIELD; case METHOD -> AccessType.PROPERTY;
case METHOD: default -> null;
return AccessType.PROPERTY; };
default:
return null;
}
} }
private static boolean isIdAnnotation(AnnotationMirror annotationMirror) { private static boolean isIdAnnotation(AnnotationMirror annotationMirror) {
@ -522,26 +518,17 @@ public final class TypeUtils {
} }
public static boolean primitiveClassMatchesKind(Class<?> itemType, TypeKind kind) { public static boolean primitiveClassMatchesKind(Class<?> itemType, TypeKind kind) {
switch (kind) { return switch ( kind ) {
case SHORT: case SHORT -> itemType.equals( Short.class );
return itemType.equals(Short.class); case INT -> itemType.equals( Integer.class );
case INT: case LONG -> itemType.equals( Long.class );
return itemType.equals(Integer.class); case BOOLEAN -> itemType.equals( Boolean.class );
case LONG: case FLOAT -> itemType.equals( Float.class );
return itemType.equals(Long.class); case DOUBLE -> itemType.equals( Double.class );
case BOOLEAN: case CHAR -> itemType.equals( Character.class );
return itemType.equals(Boolean.class); case BYTE -> itemType.equals( Byte.class );
case FLOAT: default -> false;
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;
}
} }
public static boolean isPropertyGetter(ExecutableType executable, Element element) { public static boolean isPropertyGetter(ExecutableType executable, Element element) {
@ -602,7 +589,7 @@ public final class TypeUtils {
return elementsUtil.getName(decapitalize(name.substring(3))).toString(); return elementsUtil.getName(decapitalize(name.substring(3))).toString();
} }
else if ( name.startsWith( "is" ) ) { 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(); return elementsUtil.getName(decapitalize(name)).toString();
} }
@ -613,8 +600,7 @@ public final class TypeUtils {
public static @Nullable String findMappedSuperClass(Metamodel entity, Context context) { public static @Nullable String findMappedSuperClass(Metamodel entity, Context context) {
final Element element = entity.getElement(); final Element element = entity.getElement();
if ( element instanceof TypeElement ) { if ( element instanceof TypeElement typeElement ) {
final TypeElement typeElement = (TypeElement) element;
TypeMirror superClass = typeElement.getSuperclass(); TypeMirror superClass = typeElement.getSuperclass();
//superclass of Object is of NoType which returns some other kind //superclass of Object is of NoType which returns some other kind
while ( superClass.getKind() == TypeKind.DECLARED ) { while ( superClass.getKind() == TypeKind.DECLARED ) {
@ -654,6 +640,33 @@ public final class TypeUtils {
|| !entityMetaComplete && containsAnnotation( superClassElement, ENTITY, MAPPED_SUPERCLASS ); || !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> { static class EmbeddedAttributeVisitor extends SimpleTypeVisitor8<@Nullable TypeElement, Element> {
private final Context context; private final Context context;
@ -665,7 +678,7 @@ public final class TypeUtils {
public @Nullable TypeElement visitDeclared(DeclaredType declaredType, Element element) { public @Nullable TypeElement visitDeclared(DeclaredType declaredType, Element element) {
final TypeElement returnedElement = (TypeElement) final TypeElement returnedElement = (TypeElement)
context.getTypeUtils().asElement( declaredType ); context.getTypeUtils().asElement( declaredType );
return containsAnnotation( NullnessUtil.castNonNull( returnedElement ), EMBEDDABLE ) ? returnedElement : null; return containsAnnotation( castNonNull( returnedElement ), EMBEDDABLE ) ? returnedElement : null;
} }
@Override @Override