66 */
77package org .hibernate .processor ;
88
9+ import org .hibernate .processor .annotation .InnerClassMetaAttribute ;
910import org .hibernate .processor .model .MetaAttribute ;
1011import org .hibernate .processor .model .Metamodel ;
12+ import org .hibernate .processor .util .StringUtil ;
1113
1214import javax .annotation .processing .FilerException ;
15+ import javax .lang .model .element .Element ;
1316import javax .lang .model .element .ElementKind ;
17+ import javax .lang .model .element .Modifier ;
18+ import javax .lang .model .element .PackageElement ;
1419import javax .lang .model .element .TypeElement ;
1520import javax .tools .Diagnostic ;
1621import javax .tools .FileObject ;
2025import java .io .StringWriter ;
2126import java .time .OffsetDateTime ;
2227import java .time .format .DateTimeFormatter ;
28+ import java .util .Arrays ;
2329import java .util .List ;
30+ import java .util .Set ;
31+ import java .util .stream .Collectors ;
32+
33+ import static org .hibernate .processor .util .TypeUtils .isMemberType ;
2434
2535/**
2636 * Helper class to write the actual metamodel class using the {@link javax.annotation.processing.Filer} API.
@@ -41,7 +51,7 @@ public static void writeFile(Metamodel entity, Context context) {
4151 String body = generateBody ( entity , context ).toString ();
4252
4353 FileObject fo = context .getProcessingEnvironment ().getFiler ().createSourceFile (
44- getFullyQualifiedClassName ( entity , metaModelPackage ),
54+ getFullyQualifiedClassName ( entity ),
4555 entity .getElement ()
4656 );
4757 OutputStream os = fo .openOutputStream ();
@@ -103,6 +113,16 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {
103113 pw .println ();
104114
105115 final List <MetaAttribute > members = entity .getMembers ();
116+ for ( MetaAttribute metaMember : members ) {
117+ if (metaMember instanceof InnerClassMetaAttribute ) {
118+ InnerClassMetaAttribute innerClass = (InnerClassMetaAttribute ) metaMember ;
119+ generateBody ( innerClass .getMetaEntity (), context )
120+ .toString ().lines ()
121+ .forEach (line -> pw .println ('\t' + line ));
122+ context .markGenerated ( innerClass .getMetaEntity () );
123+ }
124+ }
125+
106126 for ( MetaAttribute metaMember : members ) {
107127 if ( metaMember .hasStringAttribute () ) {
108128 pw .println ( '\t' + metaMember .getAttributeNameDeclarationString () );
@@ -134,16 +154,29 @@ private static StringBuffer generateBody(Metamodel entity, Context context) {
134154 }
135155
136156 private static void printClassDeclaration (Metamodel entity , PrintWriter pw ) {
137- pw .print ( "public " );
157+ if ( isMemberType ( entity .getElement () ) ) {
158+ final Set <Modifier > modifiers = entity .getElement ().getModifiers ();
159+ if ( modifiers .contains ( Modifier .PUBLIC ) ) {
160+ pw .print ( "public " );
161+ }
162+ else if ( modifiers .contains ( Modifier .PROTECTED ) ) {
163+ pw .print ( "protected " );
164+ }
165+ pw .print ( "static " );
166+ }
167+ else {
168+ pw .print ( "public " );
169+ }
138170 if ( !entity .isImplementation () && !entity .isJakartaDataStyle () ) {
139171 pw .print ( "abstract " );
140172 }
141173 pw .print ( entity .isJakartaDataStyle () ? "interface " : "class " );
142174 pw .print ( getGeneratedClassName (entity ) );
143175
144- String superClassName = entity .getSupertypeName ();
145- if ( superClassName != null ) {
146- pw .print ( " extends " + getGeneratedSuperclassName (entity , superClassName ) );
176+ final Element superTypeElement = entity .getSuperTypeElement ();
177+ if ( superTypeElement != null ) {
178+ pw .print ( " extends " +
179+ entity .importType (getGeneratedSuperclassName ( superTypeElement , entity .isJakartaDataStyle () )) );
147180 }
148181 if ( entity .isImplementation () ) {
149182 pw .print ( entity .getElement ().getKind () == ElementKind .CLASS ? " extends " : " implements " );
@@ -153,34 +186,36 @@ private static void printClassDeclaration(Metamodel entity, PrintWriter pw) {
153186 pw .println ( " {" );
154187 }
155188
156- private static String getFullyQualifiedClassName (Metamodel entity , String metaModelPackage ) {
157- String fullyQualifiedClassName = "" ;
158- if ( !metaModelPackage .isEmpty () ) {
159- fullyQualifiedClassName = fullyQualifiedClassName + metaModelPackage + "." ;
189+ private static String getFullyQualifiedClassName (Metamodel entity ) {
190+ final String metaModelPackage = entity .getPackageName ();
191+ final String packageNamePrefix = !metaModelPackage .isEmpty () ? metaModelPackage + "." : "" ;
192+ final String className ;
193+ if ( entity .getElement ().getKind () == ElementKind .PACKAGE ) {
194+ className = getGeneratedClassName ( entity );
195+ }
196+ else {
197+ className = Arrays .stream (
198+ entity .getQualifiedName ().substring ( packageNamePrefix .length () ).split ( "\\ ." ) )
199+ .map ( StringUtil ::removeDollar )
200+ .map ( part -> entity .isJakartaDataStyle () ? '_' + part : part + '_' )
201+ .collect ( Collectors .joining ( "." ) );
160202 }
161- fullyQualifiedClassName = fullyQualifiedClassName + getGeneratedClassName ( entity );
162- return fullyQualifiedClassName ;
203+ return packageNamePrefix + className ;
163204 }
164205
165206 private static String getGeneratedClassName (Metamodel entity ) {
166207 final String className = entity .getSimpleName ();
167208 return entity .isJakartaDataStyle () ? '_' + className : className + '_' ;
168209 }
169210
170- private static String getGeneratedSuperclassName (Metamodel entity , String superClassName ) {
171- if ( entity .isJakartaDataStyle () ) {
172- int lastDot = superClassName .lastIndexOf ('.' );
173- if ( lastDot <0 ) {
174- return '_' + superClassName ;
175- }
176- else {
177- return superClassName .substring (0 ,lastDot +1 )
178- + '_' + superClassName .substring (lastDot +1 );
179- }
180- }
181- else {
182- return superClassName + '_' ;
183- }
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 + '_' );
184219 }
185220
186221 private static String writeGeneratedAnnotation (Metamodel entity , Context context ) {
@@ -228,6 +263,7 @@ private static String writeStaticMetaModelAnnotation(Metamodel entity) {
228263 final String annotation = entity .isJakartaDataStyle ()
229264 ? "jakarta.data.metamodel.StaticMetamodel"
230265 : "jakarta.persistence.metamodel.StaticMetamodel" ;
231- return "@" + entity .importType ( annotation ) + "(" + entity .getSimpleName () + ".class)" ;
266+ final String simpleName = entity .importType ( entity .getQualifiedName () );
267+ return "@" + entity .importType ( annotation ) + "(" + simpleName + ".class)" ;
232268 }
233269}
0 commit comments