From 9aa2f631f1400784aa272664c7cf8333b4425169 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Sat, 24 Feb 2024 11:27:21 +0100 Subject: [PATCH] add a jakartaDataStyle option to processor --- .../hibernate/jpamodelgen/ClassWriter.java | 28 ++-- .../org/hibernate/jpamodelgen/Context.java | 8 ++ .../JPAMetaModelEntityProcessor.java | 126 +++++++++--------- ...ppressWarningsAnnotationGeneratedTest.java | 2 +- 4 files changed, 89 insertions(+), 75 deletions(-) diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java index 9e0b3b5295..53bbc4c896 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/ClassWriter.java @@ -38,7 +38,6 @@ import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation; * @author Hardy Ferentschik */ public final class ClassWriter { - private static final String META_MODEL_CLASS_NAME_SUFFIX = "_"; private ClassWriter() { } @@ -51,7 +50,7 @@ public final class ClassWriter { String body = generateBody( entity, context ).toString(); FileObject fo = context.getProcessingEnvironment().getFiler().createSourceFile( - getFullyQualifiedClassName( entity, metaModelPackage ), + getFullyQualifiedClassName( entity, metaModelPackage, context ), entity.getElement() ); OutputStream os = fo.openOutputStream(); @@ -96,7 +95,7 @@ public final class ClassWriter { pw.println( writeDependentAnnotation( entity ) ); } if ( entity.getElement() instanceof TypeElement ) { - pw.println( writeStaticMetaModelAnnotation( entity ) ); + pw.println( writeStaticMetaModelAnnotation( entity, context ) ); } if ( context.addGeneratedAnnotation() ) { pw.println( writeGeneratedAnnotation( entity, context ) ); @@ -131,11 +130,11 @@ public final class ClassWriter { private static void printClassDeclaration(Metamodel entity, PrintWriter pw, Context context) { pw.print( entity.isImplementation() ? "public class " : "public abstract class " ); - pw.print( entity.getSimpleName() + META_MODEL_CLASS_NAME_SUFFIX ); + pw.print( generatedClassName( context, entity.getSimpleName() ) ); String superClassName = findMappedSuperClass( entity, context ); if ( superClassName != null ) { - pw.print( " extends " + superClassName + META_MODEL_CLASS_NAME_SUFFIX ); + pw.print( " extends " + generatedClassName( context, superClassName ) ); } if ( entity.isImplementation() ) { pw.print( entity.getElement().getKind() == ElementKind.CLASS ? " extends " : " implements " ); @@ -145,13 +144,16 @@ public final class ClassWriter { pw.println( " {" ); } + private static String generatedClassName(Context context, String superClassName) { + return context.useJakartaDataStyle() ? '_' + superClassName : superClassName + '_'; + } + private static @Nullable String findMappedSuperClass(Metamodel entity, Context context) { Element element = entity.getElement(); if ( element instanceof TypeElement ) { TypeMirror superClass = ((TypeElement) element).getSuperclass(); //superclass of Object is of NoType which returns some other kind while ( superClass.getKind() == TypeKind.DECLARED ) { - //F..king Ch...t Have those people used their horrible APIs even once? final Element superClassElement = ( (DeclaredType) superClass ).asElement(); String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString(); if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) { @@ -195,12 +197,12 @@ public final class ClassWriter { return false; } - private static String getFullyQualifiedClassName(Metamodel entity, String metaModelPackage) { + private static String getFullyQualifiedClassName(Metamodel entity, String metaModelPackage, Context context) { String fullyQualifiedClassName = ""; if ( !metaModelPackage.isEmpty() ) { fullyQualifiedClassName = fullyQualifiedClassName + metaModelPackage + "."; } - fullyQualifiedClassName = fullyQualifiedClassName + entity.getSimpleName() + META_MODEL_CLASS_NAME_SUFFIX; + fullyQualifiedClassName = fullyQualifiedClassName + generatedClassName( context, entity.getSimpleName() ); return fullyQualifiedClassName; } @@ -230,15 +232,17 @@ public final class ClassWriter { } private static String writeSuppressWarnings() { - return "@SuppressWarnings({ \"deprecation\", \"rawtypes\" })"; + return "@SuppressWarnings({\"deprecation\", \"rawtypes\"})"; } private static String writeDependentAnnotation(Metamodel entity) { return "@" + entity.importType( "jakarta.enterprise.context.Dependent" ); } - private static String writeStaticMetaModelAnnotation(Metamodel entity) { - return "@" + entity.importType( "jakarta.persistence.metamodel.StaticMetamodel" ) - + "(" + entity.getSimpleName() + ".class)"; + private static String writeStaticMetaModelAnnotation(Metamodel entity, Context context) { + final String annotation = context.useJakartaDataStyle() + ? "jakarta.data.metamodel.StaticMetamodel" + : "jakarta.persistence.metamodel.StaticMetamodel"; + return "@" + entity.importType( annotation ) + "(" + entity.getSimpleName() + ".class)"; } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java index 2d3207bf7e..7268b811cf 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/Context.java @@ -74,6 +74,7 @@ public final class Context { private boolean addGenerationDate; private boolean addSuppressWarningsAnnotation; private AccessType persistenceUnitDefaultAccessType; + private boolean jakartaDataStyle; // keep track of all classes for which model have been generated private final Collection generatedModelClasses = new HashSet<>(); @@ -119,6 +120,13 @@ public final class Context { return processingEnvironment; } + public boolean useJakartaDataStyle() { + return jakartaDataStyle; + } + + public void setJakartaDataStyle(boolean jakartaDataStyle) { + this.jakartaDataStyle = jakartaDataStyle; + } public boolean addInjectAnnotation() { return addInjectAnnotation; } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java index da528833f0..4339950ac8 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/jpamodelgen/JPAMetaModelEntityProcessor.java @@ -8,6 +8,7 @@ package org.hibernate.jpamodelgen; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.processing.AbstractProcessor; @@ -31,7 +32,6 @@ import javax.tools.Diagnostic; import org.hibernate.jpamodelgen.annotation.AnnotationMetaEntity; import org.hibernate.jpamodelgen.annotation.AnnotationMetaPackage; import org.hibernate.jpamodelgen.model.Metamodel; -import org.hibernate.jpamodelgen.util.Constants; import org.hibernate.jpamodelgen.xml.JpaDescriptorParser; import org.checkerframework.checker.nullness.qual.Nullable; @@ -39,12 +39,10 @@ import org.checkerframework.checker.nullness.qual.Nullable; import static java.lang.Boolean.parseBoolean; import static javax.lang.model.util.ElementFilter.fieldsIn; import static javax.lang.model.util.ElementFilter.methodsIn; -import static org.hibernate.jpamodelgen.util.Constants.FIND; -import static org.hibernate.jpamodelgen.util.Constants.HQL; -import static org.hibernate.jpamodelgen.util.Constants.JD_REPOSITORY; -import static org.hibernate.jpamodelgen.util.Constants.SQL; +import static org.hibernate.jpamodelgen.util.Constants.*; import static org.hibernate.jpamodelgen.util.StringUtil.isProperty; import static org.hibernate.jpamodelgen.util.TypeUtils.*; +import static org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor.*; /** * Main annotation processor. @@ -52,36 +50,36 @@ import static org.hibernate.jpamodelgen.util.TypeUtils.*; * @author Max Andersen * @author Hardy Ferentschik * @author Emmanuel Bernard + * @author Gavin King */ @SupportedAnnotationTypes({ - Constants.ENTITY, - Constants.MAPPED_SUPERCLASS, - Constants.EMBEDDABLE, - Constants.HQL, - Constants.SQL, - Constants.FIND, - Constants.NAMED_QUERY, - Constants.NAMED_NATIVE_QUERY, - Constants.NAMED_ENTITY_GRAPH, - Constants.SQL_RESULT_SET_MAPPING, - Constants.HIB_FETCH_PROFILE, - Constants.HIB_FILTER_DEF, - Constants.HIB_NAMED_QUERY, - Constants.HIB_NAMED_NATIVE_QUERY, - // do not need to list other Jakarta Data annotations here - Constants.JD_REPOSITORY + // standard for JPA 2 + ENTITY, MAPPED_SUPERCLASS, EMBEDDABLE, + // standard for JPA 3.2 + NAMED_QUERY, NAMED_NATIVE_QUERY, NAMED_ENTITY_GRAPH, SQL_RESULT_SET_MAPPING, + // extra for Hibernate + HIB_FETCH_PROFILE, HIB_FILTER_DEF, HIB_NAMED_QUERY, HIB_NAMED_NATIVE_QUERY, + // Hibernate query methods + HQL, SQL, FIND, + // Jakarta Data repositories + JD_REPOSITORY // do not need to list any other Jakarta Data annotations here }) @SupportedOptions({ - JPAMetaModelEntityProcessor.DEBUG_OPTION, - JPAMetaModelEntityProcessor.PERSISTENCE_XML_OPTION, - JPAMetaModelEntityProcessor.ORM_XML_OPTION, - JPAMetaModelEntityProcessor.FULLY_ANNOTATION_CONFIGURED_OPTION, - JPAMetaModelEntityProcessor.LAZY_XML_PARSING, - JPAMetaModelEntityProcessor.ADD_GENERATION_DATE, - JPAMetaModelEntityProcessor.ADD_GENERATED_ANNOTATION, - JPAMetaModelEntityProcessor.ADD_SUPPRESS_WARNINGS_ANNOTATION + DEBUG_OPTION, + PERSISTENCE_XML_OPTION, + ORM_XML_OPTION, + FULLY_ANNOTATION_CONFIGURED_OPTION, + LAZY_XML_PARSING, + ADD_GENERATION_DATE, + ADD_GENERATED_ANNOTATION, + ADD_SUPPRESS_WARNINGS_ANNOTATION, + JAKARTA_DATA_OPTION }) public class JPAMetaModelEntityProcessor extends AbstractProcessor { + /** + * Produce Jakarta Data style static metamodel + */ + public static final String JAKARTA_DATA_OPTION = "jakartaDataStyle"; /** * Debug logging from the processor */ @@ -134,7 +132,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { context = new Context( processingEnvironment ); context.logMessage( Diagnostic.Kind.NOTE, - "Hibernate/JPA static Metamodel Generator " + Version.getVersionString() + "Hibernate compile-time tooling " + Version.getVersionString() ); boolean fullyAnnotationConfigured = handleSettings( processingEnvironment ); @@ -173,6 +171,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { context.setAddSuppressWarningsAnnotation( parseBoolean( options.get( ADD_SUPPRESS_WARNINGS_ANNOTATION ) ) ); + context.setJakartaDataStyle( parseBoolean( options.get( JAKARTA_DATA_OPTION ) ) ); + return parseBoolean( options.get( FULLY_ANNOTATION_CONFIGURED_OPTION ) ); } @@ -337,16 +337,18 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { new ContainsAttributeTypeVisitor( (TypeElement) element, context ); for ( Metamodel entity : entities ) { if ( !entity.equals( containedEntity ) ) { - for ( Element subElement : fieldsIn( entity.getElement().getEnclosedElements() ) ) { - TypeMirror mirror = subElement.asType(); + final List enclosedElements = + entity.getElement().getEnclosedElements(); + for ( Element subElement : fieldsIn(enclosedElements) ) { + final TypeMirror mirror = subElement.asType(); if ( TypeKind.DECLARED == mirror.getKind() ) { if ( mirror.accept( visitor, subElement ) ) { return true; } } } - for ( Element subElement : methodsIn( entity.getElement().getEnclosedElements() ) ) { - TypeMirror mirror = subElement.asType(); + for ( Element subElement : methodsIn(enclosedElements) ) { + final TypeMirror mirror = subElement.asType(); if ( TypeKind.DECLARED == mirror.getKind() ) { if ( mirror.accept( visitor, subElement ) ) { return true; @@ -362,31 +364,31 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { private static boolean isEntityOrEmbeddable(Element element) { return containsAnnotation( element, - Constants.ENTITY, - Constants.MAPPED_SUPERCLASS, - Constants.EMBEDDABLE + ENTITY, + MAPPED_SUPERCLASS, + EMBEDDABLE ); } private boolean hasAuxiliaryAnnotations(Element element) { return containsAnnotation( element, - Constants.NAMED_QUERY, - Constants.NAMED_QUERIES, - Constants.NAMED_NATIVE_QUERY, - Constants.NAMED_NATIVE_QUERIES, - Constants.SQL_RESULT_SET_MAPPING, - Constants.SQL_RESULT_SET_MAPPINGS, - Constants.NAMED_ENTITY_GRAPH, - Constants.NAMED_ENTITY_GRAPHS, - Constants.HIB_NAMED_QUERY, - Constants.HIB_NAMED_QUERIES, - Constants.HIB_NAMED_NATIVE_QUERY, - Constants.HIB_NAMED_NATIVE_QUERIES, - Constants.HIB_FETCH_PROFILE, - Constants.HIB_FETCH_PROFILES, - Constants.HIB_FILTER_DEF, - Constants.HIB_FILTER_DEFS + NAMED_QUERY, + NAMED_QUERIES, + NAMED_NATIVE_QUERY, + NAMED_NATIVE_QUERIES, + SQL_RESULT_SET_MAPPING, + SQL_RESULT_SET_MAPPINGS, + NAMED_ENTITY_GRAPH, + NAMED_ENTITY_GRAPHS, + HIB_NAMED_QUERY, + HIB_NAMED_QUERIES, + HIB_NAMED_NATIVE_QUERY, + HIB_NAMED_NATIVE_QUERIES, + HIB_FETCH_PROFILE, + HIB_FETCH_PROFILES, + HIB_FILTER_DEF, + HIB_FILTER_DEFS ); } @@ -404,8 +406,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { } else { boolean requiresLazyMemberInitialization - = containsAnnotation( element, Constants.EMBEDDABLE ) - || containsAnnotation( element, Constants.MAPPED_SUPERCLASS ); + = containsAnnotation( element, EMBEDDABLE ) + || containsAnnotation( element, MAPPED_SUPERCLASS ); final AnnotationMetaEntity metaEntity = AnnotationMetaEntity.create( typeElement, context, requiresLazyMemberInitialization, true ); if ( alreadyExistingMetaEntity != null ) { @@ -432,24 +434,24 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { } private @Nullable Metamodel tryGettingExistingEntityFromContext(AnnotationMirror mirror, String qualifiedName) { - if ( isAnnotationMirrorOfType( mirror, Constants.ENTITY ) - || isAnnotationMirrorOfType( mirror, Constants.MAPPED_SUPERCLASS ) ) { + if ( isAnnotationMirrorOfType( mirror, ENTITY ) + || isAnnotationMirrorOfType( mirror, MAPPED_SUPERCLASS ) ) { return context.getMetaEntity( qualifiedName ); } - else if ( isAnnotationMirrorOfType( mirror, Constants.EMBEDDABLE ) ) { + else if ( isAnnotationMirrorOfType( mirror, EMBEDDABLE ) ) { return context.getMetaEmbeddable( qualifiedName ); } return null; } private void addMetaEntityToContext(AnnotationMirror mirror, AnnotationMetaEntity metaEntity) { - if ( isAnnotationMirrorOfType( mirror, Constants.ENTITY ) ) { + if ( isAnnotationMirrorOfType( mirror, ENTITY ) ) { context.addMetaEntity( metaEntity.getQualifiedName(), metaEntity ); } - else if ( isAnnotationMirrorOfType( mirror, Constants.MAPPED_SUPERCLASS ) ) { + else if ( isAnnotationMirrorOfType( mirror, MAPPED_SUPERCLASS ) ) { context.addMetaEntity( metaEntity.getQualifiedName(), metaEntity ); } - else if ( isAnnotationMirrorOfType( mirror, Constants.EMBEDDABLE ) ) { + else if ( isAnnotationMirrorOfType( mirror, EMBEDDABLE ) ) { context.addMetaEmbeddable( metaEntity.getQualifiedName(), metaEntity ); } } @@ -470,7 +472,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor { TypeElement returnedElement = (TypeElement) context.getTypeUtils().asElement( declaredType ); final String fqNameOfReturnType = returnedElement.getQualifiedName().toString(); - final String collection = Constants.COLLECTIONS.get( fqNameOfReturnType ); + final String collection = COLLECTIONS.get( fqNameOfReturnType ); if ( collection != null ) { final TypeMirror collectionElementType = getCollectionElementType( declaredType, fqNameOfReturnType, null, context ); diff --git a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/supresswarnings/SuppressWarningsAnnotationGeneratedTest.java b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/supresswarnings/SuppressWarningsAnnotationGeneratedTest.java index e98a2d5152..9912c79291 100644 --- a/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/supresswarnings/SuppressWarningsAnnotationGeneratedTest.java +++ b/tooling/metamodel-generator/src/test/java/org/hibernate/jpamodelgen/test/supresswarnings/SuppressWarningsAnnotationGeneratedTest.java @@ -32,7 +32,7 @@ public class SuppressWarningsAnnotationGeneratedTest extends CompilationTest { String metaModelSource = getMetaModelSourceAsString( TestEntity.class ); assertTrue( "@SuppressWarnings should be added to the metamodel.", - metaModelSource.contains( "@SuppressWarnings({ \"deprecation\", \"rawtypes\" })" ) + metaModelSource.contains( "@SuppressWarnings({\"deprecation\", \"rawtypes\"})" ) ); } }