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.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 );
}
/**

View File

@ -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