Skip to content

Commit b9a0bcf

Browse files
committed
HHH-18693 Fixing to work with Jakarta Data annotations; properly naming metadata classes
1 parent 2d51874 commit b9a0bcf

File tree

11 files changed

+94
-84
lines changed

11 files changed

+94
-84
lines changed

tooling/metamodel-generator/src/main/java/org/hibernate/processor/ClassWriter.java

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44
*/
55
package org.hibernate.processor;
66

7-
import jakarta.annotation.Nullable;
8-
import org.hibernate.processor.annotation.AnnotationMetaEntity;
97
import org.hibernate.processor.annotation.InnerClassMetaAttribute;
108
import org.hibernate.processor.model.MetaAttribute;
119
import org.hibernate.processor.model.Metamodel;
10+
import org.hibernate.processor.util.StringUtil;
1211

1312
import javax.annotation.processing.FilerException;
13+
import javax.lang.model.element.Element;
1414
import javax.lang.model.element.ElementKind;
1515
import javax.lang.model.element.Modifier;
16+
import javax.lang.model.element.PackageElement;
1617
import javax.lang.model.element.TypeElement;
1718
import javax.tools.Diagnostic;
1819
import javax.tools.FileObject;
@@ -40,7 +41,6 @@ private ClassWriter() {
4041
}
4142

4243
public static void writeFile(Metamodel entity, Context context) {
43-
if (entity.hasParent()) throw new IllegalStateException();
4444
try {
4545
String metaModelPackage = entity.getPackageName();
4646
// need to generate the body first, since this will also update
@@ -115,6 +115,7 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {
115115
generateBody( innerClass.getMetaEntity(), context )
116116
.toString().lines()
117117
.forEach(line -> pw.println('\t' + line));
118+
context.markGenerated( innerClass.getMetaEntity() );
118119
}
119120
}
120121

@@ -152,9 +153,10 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {
152153
private static void printClassDeclaration(Metamodel entity, PrintWriter pw, Context context) {
153154
if ( entity.hasParent() ) {
154155
final Set<Modifier> modifiers = entity.getElement().getModifiers();
155-
if (modifiers.contains( Modifier.PUBLIC )){
156+
if ( modifiers.contains( Modifier.PUBLIC ) ) {
156157
pw.print( "public " );
157-
}else if (modifiers.contains( Modifier.PROTECTED )) {
158+
}
159+
else if ( modifiers.contains( Modifier.PROTECTED ) ) {
158160
pw.print( "protected " );
159161
}
160162
pw.print( "static " );
@@ -168,25 +170,14 @@ private static void printClassDeclaration(Metamodel entity, PrintWriter pw, Cont
168170
pw.print( entity.isJakartaDataStyle() ? "interface " : "class " );
169171
pw.print( getGeneratedClassName(entity) );
170172

171-
String superClassName = entity.getSupertypeName();
173+
final Element superClassName = entity.getSupertypeElement();
172174
if ( superClassName != null ) {
173-
Metamodel superClassEntity = context.getMetaEntity( superClassName );
174-
if (superClassEntity == null) {
175-
superClassEntity = context.getMetaEmbeddable( superClassName );
176-
}
177-
final String superclassName = getGeneratedSuperclassName(
178-
superClassName, superClassEntity, entity.isJakartaDataStyle() );
179-
if (entity.getSimpleName().equals( "OffsetDateTimeTest" )) {
180-
System.err.printf( "Extends (?) %s - superClassName is not null%n", superClassName );
181-
}
182-
pw.print( " extends " + entity.importType(superclassName) );
175+
pw.print( " extends " +
176+
entity.importType(getGeneratedSuperclassName( superClassName, entity.isJakartaDataStyle() )) );
183177
}
184178
if ( entity.isImplementation() ) {
185179
pw.print( entity.getElement().getKind() == ElementKind.CLASS ? " extends " : " implements " );
186180
pw.print( entity.getSimpleName() );
187-
if (entity.getSimpleName().equals( "OffsetDateTimeTest" )) {
188-
System.err.printf( "Extends (?) %s -- implementation (?!?)%n", entity.getSimpleName() );
189-
}
190181
}
191182

192183
pw.println( " {" );
@@ -205,7 +196,7 @@ private static String getFullyQualifiedClassName(Metamodel entity) {
205196
else {
206197
className = Arrays.stream(
207198
entity.getQualifiedName().substring( fullyQualifiedClassName.length() ).split( "\\." ) )
208-
.map( AnnotationMetaEntity::removeDollar )
199+
.map( StringUtil::removeDollar )
209200
.map( part -> entity.isJakartaDataStyle() ? '_' + part : part + '_' )
210201
.collect( Collectors.joining( "." ) );
211202
}
@@ -217,21 +208,14 @@ private static String getGeneratedClassName(Metamodel entity) {
217208
return entity.isJakartaDataStyle() ? '_' + className : className + '_'; // TODO : check inner class!!!
218209
}
219210

220-
private static String getGeneratedSuperclassName(String superClassName, @Nullable Metamodel superClassEntity, boolean jakartaDataStyle) {
221-
if ( jakartaDataStyle ) {
222-
int lastDot = superClassName.lastIndexOf('.');
223-
if ( lastDot<0 ) {
224-
return '_' + superClassName;
225-
}
226-
else {
227-
return superClassName.substring(0,lastDot+1)
228-
+ '_' + superClassName.substring(lastDot+1);
229-
}
230-
}
231-
else {
232-
return superClassEntity == null ? superClassName + '_'
233-
: getFullyQualifiedClassName( superClassEntity );
234-
}
211+
private static String getGeneratedSuperclassName(Element superClassElement, boolean jakartaDataStyle) {
212+
final TypeElement typeElement = (TypeElement) superClassElement;
213+
final String simpleName = typeElement.getSimpleName().toString();
214+
final Element enclosingElement = typeElement.getEnclosingElement();
215+
return (enclosingElement instanceof TypeElement
216+
? getGeneratedSuperclassName( enclosingElement, jakartaDataStyle )
217+
: ((PackageElement) enclosingElement).getQualifiedName().toString())
218+
+ "." + (jakartaDataStyle ? '_' + simpleName : simpleName + '_');
235219
}
236220

237221
private static String writeGeneratedAnnotation(Metamodel entity, Context context) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -420,14 +420,26 @@ else if ( element instanceof TypeElement typeElement ) {
420420
parentMeta = parentMetaEntity;
421421
}
422422
}
423-
if (element.getSimpleName().toString().equals( "OffsetDateTimeTest" )) {
424-
System.err.println("Create OffsetDateTimeTest as non-entity class#1");
425-
}
426423
final NonManagedMetamodel metaEntity =
427424
NonManagedMetamodel .create(
428425
typeElement, context,
429-
parentMeta );
426+
false, parentMeta );
430427
context.addMetaEntity( metaEntity.getQualifiedName(), metaEntity );
428+
if ( context.generateJakartaDataStaticMetamodel()) {
429+
AnnotationMetaEntity parentDataMeta = null;
430+
if ( parent instanceof TypeElement parentElement ) {
431+
final String key = parentElement.getQualifiedName().toString();
432+
if ( context.getDataMetaEntity( key ) instanceof AnnotationMetaEntity parentMetaEntity ) {
433+
parentDataMeta = parentMetaEntity;
434+
}
435+
}
436+
final NonManagedMetamodel dataMetaEntity =
437+
NonManagedMetamodel .create(
438+
typeElement, context,
439+
true, parentDataMeta );
440+
context.addDataMetaEntity( dataMetaEntity.getQualifiedName(), dataMetaEntity );
441+
}
442+
431443
}
432444
}
433445
}
@@ -475,17 +487,8 @@ private void createMetaModelClasses() {
475487
}
476488
}
477489

478-
for ( Metamodel entity : context.getMetaEntities() ) {
479-
if ( !context.isAlreadyGenerated(entity) && !entity.hasParent()) {
480-
context.logMessage( Diagnostic.Kind.OTHER,
481-
"Writing Jakarta Persistence metamodel for entity '" + entity + "'" );
482-
ClassWriter.writeFile( entity, context );
483-
context.markGenerated(entity);
484-
}
485-
}
486-
487490
for ( Metamodel entity : context.getDataMetaEntities() ) {
488-
if ( !context.isAlreadyGenerated(entity) ) {
491+
if ( !context.isAlreadyGenerated(entity) && !entity.hasParent()) {
489492
context.logMessage( Diagnostic.Kind.OTHER,
490493
"Writing Jakarta Data metamodel for entity '" + entity + "'" );
491494
ClassWriter.writeFile( entity, context );
@@ -632,9 +635,6 @@ private void handleRootElementAnnotationMirrors(final Element element, @Nullable
632635
}
633636
final boolean requiresLazyMemberInitialization
634637
= hasAnnotation( element, EMBEDDABLE, MAPPED_SUPERCLASS );
635-
if (element.getSimpleName().toString().equals( "OffsetDateTimeTest" )) {
636-
System.err.println("Create OffsetDateTimeTest in handleRootElementAnnotationMirrors#2");
637-
}
638638
final AnnotationMetaEntity metaEntity =
639639
AnnotationMetaEntity.create( typeElement, context,
640640
requiresLazyMemberInitialization,
@@ -652,13 +652,17 @@ && hasAnnotation( element, ENTITY, MAPPED_SUPERCLASS )
652652
// let a handwritten metamodel "override" the generated one
653653
// (this is used in the Jakarta Data TCK)
654654
&& !hasHandwrittenMetamodel(element) ) {
655-
if (element.getSimpleName().toString().equals( "OffsetDateTimeTest" )) {
656-
System.err.println("Create OffsetDateTimeTest in handleRootElementAnnotationMirrors#3");
655+
AnnotationMetaEntity parentDataEntity = null;
656+
if ( parent instanceof TypeElement parentTypeElement ) {
657+
if ( context.getDataMetaEntity( parentTypeElement.getQualifiedName().toString() )
658+
instanceof AnnotationMetaEntity pme ) {
659+
parentDataEntity = pme;
660+
}
657661
}
658662
final AnnotationMetaEntity dataMetaEntity =
659663
AnnotationMetaEntity.create( typeElement, context,
660664
requiresLazyMemberInitialization,
661-
true, true, parentMetaEntity );
665+
true, true, parentDataEntity );
662666
// final Metamodel alreadyExistingDataMetaEntity =
663667
// tryGettingExistingDataEntityFromContext( mirror, '_' + qualifiedName );
664668
// if ( alreadyExistingDataMetaEntity != null ) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaEntity.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.hibernate.processor.model.Metamodel;
1818
import org.hibernate.processor.util.AccessTypeInformation;
1919
import org.hibernate.processor.util.Constants;
20+
import org.hibernate.processor.util.StringUtil;
2021
import org.hibernate.processor.validation.ProcessorSessionFactory;
2122
import org.hibernate.processor.validation.Validation;
2223
import org.hibernate.query.criteria.JpaEntityJoin;
@@ -85,7 +86,7 @@
8586
import static org.hibernate.processor.util.TypeUtils.containsAnnotation;
8687
import static org.hibernate.processor.util.TypeUtils.determineAccessTypeForHierarchy;
8788
import static org.hibernate.processor.util.TypeUtils.determineAnnotationSpecifiedAccessType;
88-
import static org.hibernate.processor.util.TypeUtils.findMappedSuperClass;
89+
import static org.hibernate.processor.util.TypeUtils.findMappedSuperElement;
8990
import static org.hibernate.processor.util.TypeUtils.getAnnotationMirror;
9091
import static org.hibernate.processor.util.TypeUtils.getAnnotationValue;
9192
import static org.hibernate.processor.util.TypeUtils.hasAnnotation;
@@ -225,25 +226,13 @@ public boolean isInitialized() {
225226

226227
@Override
227228
public final String getSimpleName() {
228-
return removeDollar( element.getSimpleName().toString() );
229+
return StringUtil.removeDollar( element.getSimpleName().toString() );
229230
}
230231

231232
private String getConstructorName() {
232233
return getSimpleName() + '_';
233234
}
234235

235-
/**
236-
* If this is an "intermediate" class providing {@code @Query}
237-
* annotations for the query by magical method name crap, then
238-
* by convention it will be named with a trailing $ sign. Strip
239-
* that off, so we get the standard constructor.
240-
*/
241-
public static String removeDollar(String simpleName) {
242-
return simpleName.endsWith("$")
243-
? simpleName.substring(0, simpleName.length()-1)
244-
: simpleName;
245-
}
246-
247236
@Override
248237
public final String getQualifiedName() {
249238
if ( qualifiedName == null ) {
@@ -253,8 +242,8 @@ public final String getQualifiedName() {
253242
}
254243

255244
@Override
256-
public @Nullable String getSupertypeName() {
257-
return repository ? null : findMappedSuperClass( this, context );
245+
public @Nullable Element getSupertypeElement() {
246+
return repository ? null : findMappedSuperElement( this, context );
258247
}
259248

260249
@Override
@@ -278,7 +267,9 @@ public List<MetaAttribute> getMembers() {
278267
}
279268

280269
public void addInnerClass(AnnotationMetaEntity metaEntity) {
281-
putMember( "INNER_"+ metaEntity.getQualifiedName(), new InnerClassMetaAttribute( metaEntity ) );
270+
putMember(
271+
(metaEntity.isJakartaDataStyle() ? "DATA_" : "INNER_")
272+
+ metaEntity.getQualifiedName(), new InnerClassMetaAttribute( metaEntity ) );
282273
}
283274

284275
@Override

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/AnnotationMetaPackage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.hibernate.processor.model.MetaAttribute;
1212

1313
import javax.lang.model.element.AnnotationMirror;
14+
import javax.lang.model.element.Element;
1415
import javax.lang.model.element.PackageElement;
1516
import javax.tools.Diagnostic;
1617
import java.util.ArrayList;
@@ -69,7 +70,7 @@ public final String getQualifiedName() {
6970
}
7071

7172
@Override
72-
public @Nullable String getSupertypeName() {
73+
public @Nullable Element getSupertypeElement() {
7374
return null;
7475
}
7576

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/DefaultConstructor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public String getAttributeDeclarationString() {
6666
final StringBuilder declaration = new StringBuilder();
6767
declaration
6868
.append('\n');
69-
if ( annotationMetaEntity.getSupertypeName() == null ) {
69+
if ( annotationMetaEntity.getSupertypeElement() == null ) {
7070
declaration
7171
.append("@")
7272
.append(annotationMetaEntity.importType("jakarta.persistence.PersistenceUnit"));

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/NonManagedMetamodel.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111

1212
public class NonManagedMetamodel extends AnnotationMetaEntity {
1313

14-
public NonManagedMetamodel(TypeElement element, Context context, @Nullable AnnotationMeta parent) {
15-
super( element, context, false, false, parent );
14+
public NonManagedMetamodel(TypeElement element, Context context, boolean jakartaDataStaticMetamodel, @Nullable AnnotationMeta parent) {
15+
super( element, context, false, jakartaDataStaticMetamodel, parent );
1616
}
1717

1818
public static NonManagedMetamodel create(
1919
TypeElement element, Context context,
20+
boolean jakartaDataStaticMetamodel,
2021
@Nullable AnnotationMetaEntity parent) {
2122
final NonManagedMetamodel metamodel =
22-
new NonManagedMetamodel( element, context, parent );
23+
new NonManagedMetamodel( element, context, jakartaDataStaticMetamodel, parent );
2324
if ( parent != null ) {
2425
metamodel.setParentElement( parent.getElement() );
2526
parent.addInnerClass( metamodel );

tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/RepositoryConstructor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public String getAttributeDeclarationString() {
6767
final StringBuilder declaration = new StringBuilder();
6868
declaration
6969
.append('\n');
70-
if ( annotationMetaEntity.getSupertypeName() == null ) {
70+
if ( annotationMetaEntity.getSupertypeElement() == null ) {
7171
declaration
7272
.append("protected ");
7373
if ( !dataRepository ) {
@@ -96,7 +96,7 @@ public String getAttributeDeclarationString() {
9696
.append(" ")
9797
.append(sessionVariableName)
9898
.append(") {\n");
99-
if ( annotationMetaEntity.getSupertypeName() != null ) {
99+
if ( annotationMetaEntity.getSupertypeElement() != null ) {
100100
declaration
101101
.append("\tsuper(")
102102
.append(sessionVariableName)
@@ -112,7 +112,7 @@ public String getAttributeDeclarationString() {
112112
}
113113
declaration
114114
.append("}");
115-
if ( annotationMetaEntity.getSupertypeName() == null ) {
115+
if ( annotationMetaEntity.getSupertypeElement() == null ) {
116116
declaration
117117
.append("\n\n");
118118
if (addOverrideAnnotation) {

tooling/metamodel-generator/src/main/java/org/hibernate/processor/model/Metamodel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public interface Metamodel extends ImportContext {
1919

2020
String getQualifiedName();
2121

22-
@Nullable String getSupertypeName();
22+
@Nullable Element getSupertypeElement();
2323

2424
String getPackageName();
2525

tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/StringUtil.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,16 @@ private static boolean startsWithSeveralUpperCaseLetters(String string) {
119119
&& isUpperCase( string.charAt( 0 ) )
120120
&& isUpperCase( string.charAt( 1 ) );
121121
}
122+
123+
/**
124+
* If this is an "intermediate" class providing {@code @Query}
125+
* annotations for the query by magical method name crap, then
126+
* by convention it will be named with a trailing $ sign. Strip
127+
* that off, so we get the standard constructor.
128+
*/
129+
public static String removeDollar(String simpleName) {
130+
return simpleName.endsWith("$")
131+
? simpleName.substring(0, simpleName.length()-1)
132+
: simpleName;
133+
}
122134
}

tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,23 @@ else if ( name.startsWith( "is" ) ) {
629629
return null;
630630
}
631631

632+
public static @Nullable Element findMappedSuperElement(Metamodel entity, Context context) {
633+
final Element element = entity.getElement();
634+
if ( element instanceof TypeElement typeElement ) {
635+
TypeMirror superClass = typeElement.getSuperclass();
636+
//superclass of Object is of NoType which returns some other kind
637+
while ( superClass.getKind() == TypeKind.DECLARED ) {
638+
final DeclaredType declaredType = (DeclaredType) superClass;
639+
final TypeElement superClassElement = (TypeElement) declaredType.asElement();
640+
if ( extendsSuperMetaModel( superClassElement, entity.isMetaComplete(), context ) ) {
641+
return superClassElement;
642+
}
643+
superClass = superClassElement.getSuperclass();
644+
}
645+
}
646+
return null;
647+
}
648+
632649
/**
633650
* Checks whether this metamodel class needs to extend another metamodel class.
634651
* This method checks whether the processor has generated a metamodel class for the super class, but it also

0 commit comments

Comments
 (0)