HHH-17772 Jakarta Data static metamodel
This commit is contained in:
parent
a23792ca1b
commit
67a5590316
|
@ -6,6 +6,14 @@
|
|||
*/
|
||||
package org.hibernate.jpamodelgen;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
|
||||
import javax.annotation.processing.FilerException;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.FileObject;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
@ -13,23 +21,6 @@ import java.io.StringWriter;
|
|||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import javax.annotation.processing.FilerException;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.FileObject;
|
||||
|
||||
import org.hibernate.jpamodelgen.model.MetaAttribute;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
import org.hibernate.jpamodelgen.util.Constants;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation;
|
||||
|
||||
/**
|
||||
* Helper class to write the actual metamodel class using the {@link javax.annotation.processing.Filer} API.
|
||||
|
@ -50,7 +41,7 @@ public final class ClassWriter {
|
|||
String body = generateBody( entity, context ).toString();
|
||||
|
||||
FileObject fo = context.getProcessingEnvironment().getFiler().createSourceFile(
|
||||
getFullyQualifiedClassName( entity, metaModelPackage, context ),
|
||||
getFullyQualifiedClassName( entity, metaModelPackage ),
|
||||
entity.getElement()
|
||||
);
|
||||
OutputStream os = fo.openOutputStream();
|
||||
|
@ -95,7 +86,7 @@ public final class ClassWriter {
|
|||
pw.println( writeScopeAnnotation( entity ) );
|
||||
}
|
||||
if ( entity.getElement() instanceof TypeElement && !entity.isInjectable() ) {
|
||||
pw.println( writeStaticMetaModelAnnotation( entity, context ) );
|
||||
pw.println( writeStaticMetaModelAnnotation( entity ) );
|
||||
}
|
||||
if ( context.addGeneratedAnnotation() ) {
|
||||
pw.println( writeGeneratedAnnotation( entity, context ) );
|
||||
|
@ -104,7 +95,7 @@ public final class ClassWriter {
|
|||
pw.println( writeSuppressWarnings() );
|
||||
}
|
||||
|
||||
printClassDeclaration( entity, pw, context );
|
||||
printClassDeclaration( entity, pw );
|
||||
|
||||
pw.println();
|
||||
|
||||
|
@ -128,13 +119,13 @@ public final class ClassWriter {
|
|||
}
|
||||
}
|
||||
|
||||
private static void printClassDeclaration(Metamodel entity, PrintWriter pw, Context context) {
|
||||
private static void printClassDeclaration(Metamodel entity, PrintWriter pw) {
|
||||
pw.print( entity.isImplementation() ? "public class " : "public abstract class " );
|
||||
pw.print( generatedClassName( context, entity.getSimpleName() ) );
|
||||
pw.print( getGeneratedClassName(entity) );
|
||||
|
||||
String superClassName = findMappedSuperClass( entity, context );
|
||||
String superClassName = entity.getSupertypeName();
|
||||
if ( superClassName != null ) {
|
||||
pw.print( " extends " + generatedClassName( context, superClassName ) );
|
||||
pw.print( " extends " + getGeneratedSuperclassName(entity, superClassName) );
|
||||
}
|
||||
if ( entity.isImplementation() ) {
|
||||
pw.print( entity.getElement().getKind() == ElementKind.CLASS ? " extends " : " implements " );
|
||||
|
@ -144,68 +135,36 @@ 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 ) {
|
||||
final Element superClassElement = ( (DeclaredType) superClass ).asElement();
|
||||
String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString();
|
||||
if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) {
|
||||
return superClassName;
|
||||
}
|
||||
superClass = ( (TypeElement) superClassElement ).getSuperclass();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this metamodel class needs to extend another metamodel class.
|
||||
* This method checks whether the processor has generated a metamodel class for the super class, but it also
|
||||
* allows for the possibility that the metamodel class was generated in a previous compilation. (It could be
|
||||
* part of a separate jar. See also METAGEN-35.)
|
||||
*
|
||||
* @param superClassElement the super class element
|
||||
* @param entityMetaComplete flag indicating if the entity for which the metamodel should be generated is
|
||||
* metamodel complete. If so we cannot use reflection to decide whether we have to add the extends clause
|
||||
* @param context the execution context
|
||||
*
|
||||
* @return {@code true} in case there is super class metamodel to extend from {@code false} otherwise.
|
||||
*/
|
||||
private static boolean extendsSuperMetaModel(Element superClassElement, boolean entityMetaComplete, Context context) {
|
||||
// if we processed the superclass in the same run we definitely need to extend
|
||||
String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString();
|
||||
if ( context.containsMetaEntity( superClassName )
|
||||
|| context.containsMetaEmbeddable( superClassName ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// to allow for the case that the metamodel class for the super entity is for example contained in another
|
||||
// jar file we use reflection. However, we need to consider the fact that there is xml configuration
|
||||
// and annotations should be ignored
|
||||
if ( !entityMetaComplete
|
||||
&& containsAnnotation( superClassElement, Constants.ENTITY, Constants.MAPPED_SUPERCLASS ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getFullyQualifiedClassName(Metamodel entity, String metaModelPackage, Context context) {
|
||||
private static String getFullyQualifiedClassName(Metamodel entity, String metaModelPackage) {
|
||||
String fullyQualifiedClassName = "";
|
||||
if ( !metaModelPackage.isEmpty() ) {
|
||||
fullyQualifiedClassName = fullyQualifiedClassName + metaModelPackage + ".";
|
||||
}
|
||||
fullyQualifiedClassName = fullyQualifiedClassName + generatedClassName( context, entity.getSimpleName() );
|
||||
fullyQualifiedClassName = fullyQualifiedClassName + getGeneratedClassName( entity );
|
||||
return fullyQualifiedClassName;
|
||||
}
|
||||
|
||||
private static String getGeneratedClassName(Metamodel entity) {
|
||||
final String className = entity.getSimpleName();
|
||||
return entity.isJakartaDataStyle() ? '_' + className : className + '_';
|
||||
}
|
||||
|
||||
private static String getGeneratedSuperclassName(Metamodel entity, String superClassName) {
|
||||
if ( entity.isJakartaDataStyle() ) {
|
||||
int lastDot = superClassName.lastIndexOf('.');
|
||||
if ( lastDot<0 ) {
|
||||
return '_' + superClassName;
|
||||
}
|
||||
else {
|
||||
return superClassName.substring(0,lastDot+1)
|
||||
+ '_' + superClassName.substring(lastDot+1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return superClassName + '_';
|
||||
}
|
||||
}
|
||||
|
||||
private static String writeGeneratedAnnotation(Metamodel entity, Context context) {
|
||||
StringBuilder generatedAnnotation = new StringBuilder();
|
||||
generatedAnnotation
|
||||
|
@ -239,8 +198,8 @@ public final class ClassWriter {
|
|||
return "@" + entity.importType( entity.scope() );
|
||||
}
|
||||
|
||||
private static String writeStaticMetaModelAnnotation(Metamodel entity, Context context) {
|
||||
final String annotation = context.useJakartaDataStyle()
|
||||
private static String writeStaticMetaModelAnnotation(Metamodel entity) {
|
||||
final String annotation = entity.isJakartaDataStyle()
|
||||
? "jakarta.data.metamodel.StaticMetamodel"
|
||||
: "jakarta.persistence.metamodel.StaticMetamodel";
|
||||
return "@" + entity.importType( annotation ) + "(" + entity.getSimpleName() + ".class)";
|
||||
|
|
|
@ -76,7 +76,6 @@ public final class Context {
|
|||
private boolean addTransactionScopedAnnotation;
|
||||
private AccessType persistenceUnitDefaultAccessType;
|
||||
private boolean generateJakartaDataStaticMetamodel;
|
||||
private boolean jakartaDataStyle;
|
||||
|
||||
// keep track of all classes for which model have been generated
|
||||
private final Collection<String> generatedModelClasses = new HashSet<>();
|
||||
|
@ -122,14 +121,6 @@ public final class Context {
|
|||
return processingEnvironment;
|
||||
}
|
||||
|
||||
public boolean useJakartaDataStyle() {
|
||||
return jakartaDataStyle;
|
||||
}
|
||||
|
||||
public void setJakartaDataStyle(boolean jakartaDataStyle) {
|
||||
this.jakartaDataStyle = jakartaDataStyle;
|
||||
}
|
||||
|
||||
public boolean generateJakartaDataStaticMetamodel() {
|
||||
return generateJakartaDataStaticMetamodel;
|
||||
}
|
||||
|
@ -210,61 +201,61 @@ public final class Context {
|
|||
return ormXmlFiles;
|
||||
}
|
||||
|
||||
public boolean containsMetaEntity(String fqcn) {
|
||||
return metaEntities.containsKey( fqcn );
|
||||
public boolean containsMetaEntity(String qualifiedName) {
|
||||
return metaEntities.containsKey( qualifiedName );
|
||||
}
|
||||
|
||||
public @Nullable Metamodel getMetaEntity(String fqcn) {
|
||||
return metaEntities.get( fqcn );
|
||||
public @Nullable Metamodel getMetaEntity(String qualifiedName) {
|
||||
return metaEntities.get( qualifiedName );
|
||||
}
|
||||
|
||||
public Collection<Metamodel> getMetaEntities() {
|
||||
return metaEntities.values();
|
||||
}
|
||||
|
||||
public void addMetaEntity(String fqcn, Metamodel metaEntity) {
|
||||
metaEntities.put( fqcn, metaEntity );
|
||||
public void addMetaEntity(String qualifiedName, Metamodel metaEntity) {
|
||||
metaEntities.put( qualifiedName, metaEntity );
|
||||
}
|
||||
|
||||
public boolean containsMetaEmbeddable(String fqcn) {
|
||||
return metaEmbeddables.containsKey( fqcn );
|
||||
public boolean containsMetaEmbeddable(String qualifiedName) {
|
||||
return metaEmbeddables.containsKey( qualifiedName );
|
||||
}
|
||||
|
||||
public @Nullable Metamodel getMetaEmbeddable(String fqcn) {
|
||||
return metaEmbeddables.get( fqcn );
|
||||
public @Nullable Metamodel getMetaEmbeddable(String qualifiedName) {
|
||||
return metaEmbeddables.get( qualifiedName );
|
||||
}
|
||||
|
||||
public void addMetaEmbeddable(String fqcn, Metamodel metaEntity) {
|
||||
metaEmbeddables.put( fqcn, metaEntity );
|
||||
public void addMetaEmbeddable(String qualifiedName, Metamodel metaEntity) {
|
||||
metaEmbeddables.put( qualifiedName, metaEntity );
|
||||
}
|
||||
|
||||
public Collection<Metamodel> getMetaEmbeddables() {
|
||||
return metaEmbeddables.values();
|
||||
}
|
||||
|
||||
public @Nullable Metamodel getMetaAuxiliary(String fqcn) {
|
||||
return metaAuxiliaries.get( fqcn );
|
||||
public @Nullable Metamodel getMetaAuxiliary(String qualifiedName) {
|
||||
return metaAuxiliaries.get( qualifiedName );
|
||||
}
|
||||
|
||||
public Collection<Metamodel> getMetaAuxiliaries() {
|
||||
return metaAuxiliaries.values();
|
||||
}
|
||||
|
||||
public void addMetaAuxiliary(String fqcn, Metamodel metamodel) {
|
||||
metaAuxiliaries.put( fqcn, metamodel);
|
||||
public void addMetaAuxiliary(String qualifiedName, Metamodel metamodel) {
|
||||
metaAuxiliaries.put( qualifiedName, metamodel);
|
||||
}
|
||||
|
||||
public void addAccessTypeInformation(String fqcn, AccessTypeInformation info) {
|
||||
accessTypeInformation.put( fqcn, info );
|
||||
public void addAccessTypeInformation(String qualifiedName, AccessTypeInformation info) {
|
||||
accessTypeInformation.put( qualifiedName, info );
|
||||
}
|
||||
|
||||
public @Nullable AccessTypeInformation getAccessTypeInfo(String fqcn) {
|
||||
return accessTypeInformation.get( fqcn );
|
||||
public @Nullable AccessTypeInformation getAccessTypeInfo(String qualifiedName) {
|
||||
return accessTypeInformation.get( qualifiedName );
|
||||
}
|
||||
|
||||
public TypeElement getTypeElementForFullyQualifiedName(String fqcn) {
|
||||
public TypeElement getTypeElementForFullyQualifiedName(String qualifiedName) {
|
||||
Elements elementUtils = processingEnvironment.getElementUtils();
|
||||
return elementUtils.getTypeElement( fqcn );
|
||||
return elementUtils.getTypeElement( qualifiedName );
|
||||
}
|
||||
|
||||
void markGenerated(String name) {
|
||||
|
|
|
@ -67,14 +67,10 @@ import static org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor.*;
|
|||
LAZY_XML_PARSING,
|
||||
ADD_GENERATION_DATE,
|
||||
ADD_GENERATED_ANNOTATION,
|
||||
ADD_SUPPRESS_WARNINGS_ANNOTATION,
|
||||
JAKARTA_DATA_OPTION
|
||||
ADD_SUPPRESS_WARNINGS_ANNOTATION
|
||||
})
|
||||
public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
||||
/**
|
||||
* Produce Jakarta Data style static metamodel
|
||||
*/
|
||||
public static final String JAKARTA_DATA_OPTION = "jakartaDataStyle";
|
||||
|
||||
/**
|
||||
* Debug logging from the processor
|
||||
*/
|
||||
|
@ -174,8 +170,6 @@ 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 ) );
|
||||
}
|
||||
|
||||
|
@ -287,18 +281,22 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
private void createMetaModelClasses() {
|
||||
|
||||
for ( Metamodel aux : context.getMetaAuxiliaries() ) {
|
||||
if ( !context.isAlreadyGenerated( aux.getQualifiedName() ) ) {
|
||||
final String key = aux.getQualifiedName();
|
||||
if ( !context.isAlreadyGenerated(key) ) {
|
||||
context.logMessage( Diagnostic.Kind.OTHER, "Writing metamodel for auxiliary '" + aux + "'" );
|
||||
ClassWriter.writeFile( aux, context );
|
||||
context.markGenerated( aux.getQualifiedName() );
|
||||
context.markGenerated(key);
|
||||
}
|
||||
}
|
||||
|
||||
for ( Metamodel entity : context.getMetaEntities() ) {
|
||||
if ( !context.isAlreadyGenerated( entity.getQualifiedName() ) ) {
|
||||
final String key = entity.isJakartaDataStyle()
|
||||
? '_' + entity.getQualifiedName()
|
||||
: entity.getQualifiedName();
|
||||
if ( !context.isAlreadyGenerated(key) ) {
|
||||
context.logMessage( Diagnostic.Kind.OTHER, "Writing metamodel for entity '" + entity + "'" );
|
||||
ClassWriter.writeFile( entity, context );
|
||||
context.markGenerated( entity.getQualifiedName() );
|
||||
context.markGenerated(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +308,10 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
int toProcessCountBeforeLoop = toProcessEntities.size();
|
||||
for ( Metamodel entity : toProcessEntities ) {
|
||||
// see METAGEN-36
|
||||
if ( context.isAlreadyGenerated( entity.getQualifiedName() ) ) {
|
||||
final String key = entity.isJakartaDataStyle()
|
||||
? '_' + entity.getQualifiedName()
|
||||
: entity.getQualifiedName();
|
||||
if ( context.isAlreadyGenerated(key) ) {
|
||||
processedEntities.add( entity );
|
||||
}
|
||||
else if ( !modelGenerationNeedsToBeDeferred( toProcessEntities, entity ) ) {
|
||||
|
@ -319,7 +320,7 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
"Writing meta model for embeddable/mapped superclass " + entity
|
||||
);
|
||||
ClassWriter.writeFile( entity, context );
|
||||
context.markGenerated( entity.getQualifiedName() );
|
||||
context.markGenerated(key);
|
||||
processedEntities.add( entity );
|
||||
}
|
||||
}
|
||||
|
@ -400,7 +401,8 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
for ( AnnotationMirror mirror : element.getAnnotationMirrors() ) {
|
||||
final TypeElement typeElement = (TypeElement) element;
|
||||
final String qualifiedName = typeElement.getQualifiedName().toString();
|
||||
final Metamodel alreadyExistingMetaEntity = tryGettingExistingEntityFromContext( mirror, qualifiedName );
|
||||
final Metamodel alreadyExistingMetaEntity =
|
||||
tryGettingExistingEntityFromContext( mirror, qualifiedName );
|
||||
if ( alreadyExistingMetaEntity != null && alreadyExistingMetaEntity.isMetaComplete() ) {
|
||||
context.logMessage(
|
||||
Diagnostic.Kind.OTHER,
|
||||
|
@ -408,15 +410,29 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
+ "' since XML configuration is metadata complete.");
|
||||
}
|
||||
else {
|
||||
boolean requiresLazyMemberInitialization
|
||||
= containsAnnotation( element, EMBEDDABLE )
|
||||
|| containsAnnotation( element, MAPPED_SUPERCLASS );
|
||||
final boolean requiresLazyMemberInitialization
|
||||
= hasAnnotation( element, EMBEDDABLE, MAPPED_SUPERCLASS );
|
||||
final AnnotationMetaEntity metaEntity =
|
||||
AnnotationMetaEntity.create( typeElement, context, requiresLazyMemberInitialization, true );
|
||||
AnnotationMetaEntity.create( typeElement, context,
|
||||
requiresLazyMemberInitialization, true );
|
||||
if ( alreadyExistingMetaEntity != null ) {
|
||||
metaEntity.mergeInMembers( alreadyExistingMetaEntity );
|
||||
}
|
||||
addMetaEntityToContext( mirror, metaEntity );
|
||||
if ( context.generateJakartaDataStaticMetamodel()
|
||||
// Don't generate a Jakarta Data metamodel
|
||||
// if this entity was partially mapped in XML
|
||||
&& alreadyExistingMetaEntity == null ) {
|
||||
final AnnotationMetaEntity dataMetaEntity =
|
||||
AnnotationMetaEntity.create( typeElement, context,
|
||||
requiresLazyMemberInitialization, true, true );
|
||||
// final Metamodel alreadyExistingDataMetaEntity =
|
||||
// tryGettingExistingEntityFromContext( mirror, '_' + qualifiedName );
|
||||
// if ( alreadyExistingDataMetaEntity != null ) {
|
||||
// dataMetaEntity.mergeInMembers( alreadyExistingDataMetaEntity );
|
||||
// }
|
||||
addMetaEntityToContext( mirror, dataMetaEntity );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -448,14 +464,17 @@ public class JPAMetaModelEntityProcessor extends AbstractProcessor {
|
|||
}
|
||||
|
||||
private void addMetaEntityToContext(AnnotationMirror mirror, AnnotationMetaEntity metaEntity) {
|
||||
final String key = metaEntity.isJakartaDataStyle()
|
||||
? '_' + metaEntity.getQualifiedName()
|
||||
: metaEntity.getQualifiedName();
|
||||
if ( isAnnotationMirrorOfType( mirror, ENTITY ) ) {
|
||||
context.addMetaEntity( metaEntity.getQualifiedName(), metaEntity );
|
||||
context.addMetaEntity( key, metaEntity );
|
||||
}
|
||||
else if ( isAnnotationMirrorOfType( mirror, MAPPED_SUPERCLASS ) ) {
|
||||
context.addMetaEntity( metaEntity.getQualifiedName(), metaEntity );
|
||||
context.addMetaEntity( key, metaEntity );
|
||||
}
|
||||
else if ( isAnnotationMirrorOfType( mirror, EMBEDDABLE ) ) {
|
||||
context.addMetaEmbeddable( metaEntity.getQualifiedName(), metaEntity );
|
||||
context.addMetaEmbeddable( key, metaEntity );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ public abstract class AnnotationMetaAttribute implements MetaAttribute {
|
|||
.append( parent.importType( getTypeDeclaration() ) )
|
||||
.append( "> " )
|
||||
.append( getPropertyName() )
|
||||
.append( parent.getContext().useJakartaDataStyle() ? "_" : "" )
|
||||
.append( ";" )
|
||||
.toString();
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ import static org.hibernate.jpamodelgen.util.NullnessUtil.castNonNull;
|
|||
import static org.hibernate.jpamodelgen.util.TypeUtils.containsAnnotation;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.determineAccessTypeForHierarchy;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.determineAnnotationSpecifiedAccessType;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.findMappedSuperClass;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationMirror;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationValue;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.getAnnotationValueRef;
|
||||
|
@ -113,6 +114,8 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
private final Context context;
|
||||
private final boolean managed;
|
||||
private boolean dataRepository;
|
||||
private String qualifiedName;
|
||||
private final boolean jakartaDataStaticModel;
|
||||
|
||||
private AccessTypeInformation entityAccessTypeInfo;
|
||||
|
||||
|
@ -148,16 +151,25 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
|
||||
private final Map<String,String> memberTypes = new HashMap<>();
|
||||
|
||||
public AnnotationMetaEntity(TypeElement element, Context context, boolean managed) {
|
||||
public AnnotationMetaEntity(TypeElement element, Context context, boolean managed, boolean jakartaData) {
|
||||
this.element = element;
|
||||
this.context = context;
|
||||
this.managed = managed;
|
||||
this.members = new HashMap<>();
|
||||
this.importContext = new ImportContextImpl( getPackageName( context, element ) );
|
||||
jakartaDataStaticModel = jakartaData;
|
||||
}
|
||||
|
||||
public static AnnotationMetaEntity create(TypeElement element, Context context, boolean lazilyInitialised, boolean managed) {
|
||||
final AnnotationMetaEntity annotationMetaEntity = new AnnotationMetaEntity( element, context, managed );
|
||||
public static AnnotationMetaEntity create(
|
||||
TypeElement element, Context context,
|
||||
boolean lazilyInitialised, boolean managed) {
|
||||
return create( element,context, lazilyInitialised, managed, false );
|
||||
}
|
||||
|
||||
public static AnnotationMetaEntity create(
|
||||
TypeElement element, Context context,
|
||||
boolean lazilyInitialised, boolean managed, boolean jakartaData) {
|
||||
final AnnotationMetaEntity annotationMetaEntity = new AnnotationMetaEntity( element, context, managed, jakartaData );
|
||||
if ( !lazilyInitialised ) {
|
||||
annotationMetaEntity.init();
|
||||
}
|
||||
|
@ -182,6 +194,11 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
return repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJakartaDataStyle() {
|
||||
return jakartaDataStaticModel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSimpleName() {
|
||||
return element.getSimpleName().toString();
|
||||
|
@ -189,7 +206,15 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
|
||||
@Override
|
||||
public final String getQualifiedName() {
|
||||
return element.getQualifiedName().toString();
|
||||
if ( qualifiedName == null ) {
|
||||
qualifiedName = element.getQualifiedName().toString();
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getSupertypeName() {
|
||||
return findMappedSuperClass( this, context );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -498,13 +523,7 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
private void addPersistentMembers(List<? extends Element> membersOfClass, AccessType membersKind) {
|
||||
for ( Element memberOfClass : membersOfClass ) {
|
||||
if ( isPersistent( memberOfClass, membersKind ) ) {
|
||||
final AnnotationMetaAttribute jpaMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new MetaAttributeGenerationVisitor( this, context ), memberOfClass );
|
||||
if ( jpaMetaAttribute != null ) {
|
||||
members.put( jpaMetaAttribute.getPropertyName(), jpaMetaAttribute );
|
||||
}
|
||||
if ( context.generateJakartaDataStaticMetamodel() ) {
|
||||
if ( jakartaDataStaticModel ) {
|
||||
final DataAnnotationMetaAttribute dataMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new DataMetaAttributeGenerationVisitor( this, context ), memberOfClass );
|
||||
|
@ -512,6 +531,14 @@ public class AnnotationMetaEntity extends AnnotationMeta {
|
|||
members.put( '_' + dataMetaAttribute.getPropertyName(), dataMetaAttribute );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final AnnotationMetaAttribute jpaMetaAttribute =
|
||||
memberOfClass.asType()
|
||||
.accept( new MetaAttributeGenerationVisitor( this, context ), memberOfClass );
|
||||
if ( jpaMetaAttribute != null ) {
|
||||
members.put( jpaMetaAttribute.getPropertyName(), jpaMetaAttribute );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ public class AnnotationMetaMap extends AnnotationMetaCollection {
|
|||
.append( parent.importType( getTypeDeclaration() ) )
|
||||
.append("> ")
|
||||
.append( getPropertyName() )
|
||||
.append( parent.getContext().useJakartaDataStyle() ? "_" : "" )
|
||||
.append(";")
|
||||
.toString();
|
||||
}
|
||||
|
|
|
@ -67,6 +67,11 @@ public class AnnotationMetaPackage extends AnnotationMeta {
|
|||
return element.getQualifiedName().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getSupertypeName() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getPackageName() {
|
||||
return getPackageName( context, element );
|
||||
|
@ -154,4 +159,9 @@ public class AnnotationMetaPackage extends AnnotationMeta {
|
|||
public String scope() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJakartaDataStyle() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ public class DataAnnotationMetaAttribute implements MetaAttribute {
|
|||
.append( "<" )
|
||||
.append( className )
|
||||
.append( "> " )
|
||||
.append( parent.getContext().useJakartaDataStyle() ? "" : "_" )
|
||||
.append( getPropertyName() )
|
||||
.append(" = ")
|
||||
.append( getMetaImpl(className, memberName) )
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.jpamodelgen.model;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.hibernate.jpamodelgen.Context;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -19,6 +20,8 @@ public interface Metamodel extends ImportContext {
|
|||
|
||||
String getQualifiedName();
|
||||
|
||||
@Nullable String getSupertypeName();
|
||||
|
||||
String getPackageName();
|
||||
|
||||
List<MetaAttribute> getMembers();
|
||||
|
@ -40,4 +43,6 @@ public interface Metamodel extends ImportContext {
|
|||
boolean isInjectable();
|
||||
|
||||
String scope();
|
||||
|
||||
boolean isJakartaDataStyle();
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||
import org.hibernate.jpamodelgen.Context;
|
||||
import org.hibernate.jpamodelgen.MetaModelGenerationException;
|
||||
import org.hibernate.jpamodelgen.annotation.AnnotationMetaEntity;
|
||||
import org.hibernate.jpamodelgen.model.Metamodel;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
|
@ -610,6 +611,55 @@ public final class TypeUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public 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 ) {
|
||||
final Element superClassElement = ( (DeclaredType) superClass ).asElement();
|
||||
String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString();
|
||||
if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) {
|
||||
return superClassName;
|
||||
}
|
||||
superClass = ( (TypeElement) superClassElement ).getSuperclass();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this metamodel class needs to extend another metamodel class.
|
||||
* This method checks whether the processor has generated a metamodel class for the super class, but it also
|
||||
* allows for the possibility that the metamodel class was generated in a previous compilation. (It could be
|
||||
* part of a separate jar. See also METAGEN-35.)
|
||||
*
|
||||
* @param superClassElement the super class element
|
||||
* @param entityMetaComplete flag indicating if the entity for which the metamodel should be generated is
|
||||
* metamodel complete. If so we cannot use reflection to decide whether we have to add the extends clause
|
||||
* @param context the execution context
|
||||
*
|
||||
* @return {@code true} in case there is super class metamodel to extend from {@code false} otherwise.
|
||||
*/
|
||||
private static boolean extendsSuperMetaModel(Element superClassElement, boolean entityMetaComplete, Context context) {
|
||||
// if we processed the superclass in the same run we definitely need to extend
|
||||
String superClassName = ( (TypeElement) superClassElement ).getQualifiedName().toString();
|
||||
if ( context.containsMetaEntity( superClassName )
|
||||
|| context.containsMetaEmbeddable( superClassName ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// to allow for the case that the metamodel class for the super entity is for example contained in another
|
||||
// jar file we use reflection. However, we need to consider the fact that there is xml configuration
|
||||
// and annotations should be ignored
|
||||
if ( !entityMetaComplete
|
||||
&& containsAnnotation( superClassElement, Constants.ENTITY, Constants.MAPPED_SUPERCLASS ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static class EmbeddedAttributeVisitor extends SimpleTypeVisitor8<@Nullable String, Element> {
|
||||
private final Context context;
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ import org.hibernate.jpamodelgen.xml.jaxb.OneToOne;
|
|||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static org.hibernate.jpamodelgen.util.StringUtil.determineFullyQualifiedClassName;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.extractClosestRealTypeAsString;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.findMappedSuperClass;
|
||||
import static org.hibernate.jpamodelgen.util.TypeUtils.getElementKindForAccessType;
|
||||
import static org.hibernate.jpamodelgen.xml.jaxb.AccessType.*;
|
||||
|
||||
|
@ -132,7 +134,7 @@ public class XmlMetaEntity implements Metamodel {
|
|||
this.isMetaComplete = initIsMetaComplete( context, metaComplete );
|
||||
}
|
||||
|
||||
private final void init() {
|
||||
private void init() {
|
||||
context.logMessage( Diagnostic.Kind.OTHER, "Initializing type " + getQualifiedName() + "." );
|
||||
|
||||
this.accessTypeInfo = NullnessUtil.castNonNull( context.getAccessTypeInfo( getQualifiedName() ) );
|
||||
|
@ -158,6 +160,11 @@ public class XmlMetaEntity implements Metamodel {
|
|||
return packageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getSupertypeName() {
|
||||
return findMappedSuperClass( this, context );
|
||||
}
|
||||
|
||||
public List<MetaAttribute> getMembers() {
|
||||
if ( !initialized ) {
|
||||
init();
|
||||
|
@ -265,12 +272,12 @@ public class XmlMetaEntity implements Metamodel {
|
|||
private void determineTargetType(DeclaredType type, String propertyName, String explicitTargetEntity, @Nullable String[] types) {
|
||||
List<? extends TypeMirror> typeArguments = type.getTypeArguments();
|
||||
|
||||
if ( typeArguments.size() == 0 && explicitTargetEntity == null ) {
|
||||
if ( typeArguments.isEmpty() && explicitTargetEntity == null ) {
|
||||
throw new MetaModelGenerationException( "Unable to determine target entity type for " + clazzName + "." + propertyName + "." );
|
||||
}
|
||||
|
||||
if ( explicitTargetEntity == null ) {
|
||||
types[0] = TypeUtils.extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
|
||||
types[0] = extractClosestRealTypeAsString( typeArguments.get( 0 ), context );
|
||||
}
|
||||
else {
|
||||
types[0] = explicitTargetEntity;
|
||||
|
@ -632,4 +639,9 @@ public class XmlMetaEntity implements Metamodel {
|
|||
public String scope() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isJakartaDataStyle() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue