29
29
import java .lang .reflect .Type ;
30
30
import java .util .ArrayList ;
31
31
import java .util .Collections ;
32
+ import java .util .EnumMap ;
32
33
import java .util .HashSet ;
33
34
import java .util .LinkedHashMap ;
34
35
import java .util .List ;
55
56
import org .hibernate .metamodel .source .annotations .JPADotNames ;
56
57
import org .hibernate .metamodel .source .annotations .util .JandexHelper ;
57
58
import org .hibernate .metamodel .source .annotations .util .ReflectionHelper ;
58
- import org .hibernate .service .ServiceRegistry ;
59
- import org .hibernate .service .classloading .spi .ClassLoaderService ;
60
59
61
60
/**
62
61
* Represents an entity, mapped superclass or component configured via annotations/xml.
@@ -68,7 +67,15 @@ public class ConfiguredClass {
68
67
* The parent of this configured class or {@code null} in case this configured class is the root of a hierarchy.
69
68
*/
70
69
private final ConfiguredClass parent ;
70
+
71
+ /**
72
+ * The Jandex class info for this configured class. Provides access to the annotation defined on this configured class.
73
+ */
71
74
private final ClassInfo classInfo ;
75
+
76
+ /**
77
+ * The actual java type.
78
+ */
72
79
private final Class <?> clazz ;
73
80
74
81
private final boolean isRoot ;
@@ -83,19 +90,24 @@ public class ConfiguredClass {
83
90
private final IdType idType ;
84
91
85
92
private final Map <String , MappedAttribute > mappedAttributes ;
93
+ private final Set <String > transientFieldNames = new HashSet <String >();
94
+ private final Set <String > transientMethodNames = new HashSet <String >();
95
+
96
+ private final AnnotationBindingContext context ;
86
97
87
98
public ConfiguredClass (ClassInfo info ,
88
99
ConfiguredClass parent ,
89
100
AccessType hierarchyAccessType ,
90
101
InheritanceType inheritanceType ,
91
- ServiceRegistry serviceRegistry ,
92
- ResolvedTypeWithMembers resolvedType ) {
102
+ ResolvedTypeWithMembers resolvedType ,
103
+ AnnotationBindingContext context ) {
104
+ this .context = context ;
93
105
this .classInfo = info ;
94
106
this .parent = parent ;
95
107
this .isRoot = parent == null ;
96
108
this .hierarchyAccessType = hierarchyAccessType ;
97
109
this .inheritanceType = inheritanceType ;
98
- this .clazz = serviceRegistry . getService ( ClassLoaderService . class ).classForName ( info .toString () );
110
+ this .clazz = context . classLoaderService ( ).classForName ( info .toString () );
99
111
100
112
this .configuredClassType = determineType ();
101
113
this .classAccessType = determineClassAccessType ();
@@ -104,6 +116,9 @@ public ConfiguredClass(ClassInfo info,
104
116
this .hasOwnTable = definesItsOwnTable ();
105
117
this .primaryTableName = determinePrimaryTableName ();
106
118
119
+ // find transient field and method names
120
+ findTransientFieldAndMethodNames ();
121
+
107
122
List <MappedAttribute > simpleProps = collectAttributes ( resolvedType );
108
123
// make sure the properties are ordered by property name
109
124
Collections .sort ( simpleProps );
@@ -213,11 +228,6 @@ private AccessType determineClassAccessType() {
213
228
* @return A list of the persistent properties of this configured class
214
229
*/
215
230
private List <MappedAttribute > collectAttributes (ResolvedTypeWithMembers resolvedTypes ) {
216
- // create sets of transient field and method names
217
- Set <String > transientFieldNames = new HashSet <String >();
218
- Set <String > transientMethodNames = new HashSet <String >();
219
- populateTransientFieldAndMethodLists ( transientFieldNames , transientMethodNames );
220
-
221
231
// use the class mate library to generic types
222
232
ResolvedTypeWithMembers resolvedType = null ;
223
233
for ( HierarchicType hierarchicType : resolvedTypes .allTypesAndOverrides () ) {
@@ -381,42 +391,67 @@ private MappedAttribute createMappedProperty(Member member, ResolvedTypeWithMemb
381
391
);
382
392
383
393
MappedAttribute attribute ;
384
- AssociationType associationType = determineAssociationType ( annotations );
385
- switch ( associationType ) {
386
- case NO_ASSOCIATION : {
394
+ AttributeType attributeType = determineAttributeType ( annotations );
395
+ switch ( attributeType ) {
396
+ case BASIC : {
387
397
attribute = SimpleAttribute .createSimpleAttribute ( name , ( (Class ) type ).getName (), annotations );
388
398
break ;
389
399
}
400
+ case EMBEDDED : {
401
+ throw new HibernateException ( "foo" );
402
+ }
403
+ // TODO handle the different association types
390
404
default : {
391
405
attribute = AssociationAttribute .createAssociationAttribute (
392
- name , ( (Class ) type ).getName (), associationType , annotations
406
+ name , ( (Class ) type ).getName (), attributeType , annotations
393
407
);
394
408
}
395
409
}
396
410
397
411
return attribute ;
398
412
}
399
413
400
- private AssociationType determineAssociationType (Map <DotName , List <AnnotationInstance >> annotations ) {
414
+ /**
415
+ * Given the annotations defined on a persistent attribute this methods determines the attribute type.
416
+ *
417
+ * @param annotations the annotations defined on the persistent attribute
418
+ *
419
+ * @return an instance of the {@code AttributeType} enum
420
+ */
421
+ private AttributeType determineAttributeType (Map <DotName , List <AnnotationInstance >> annotations ) {
422
+ EnumMap <AttributeType , AnnotationInstance > discoveredAttributeTypes =
423
+ new EnumMap <AttributeType , AnnotationInstance >( AttributeType .class );
424
+
401
425
AnnotationInstance oneToOne = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .ONE_TO_ONE );
426
+ if ( oneToOne != null ) {
427
+ discoveredAttributeTypes .put ( AttributeType .ONE_TO_ONE , oneToOne );
428
+ }
429
+
402
430
AnnotationInstance oneToMany = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .ONE_TO_MANY );
403
- AnnotationInstance manyToOne = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .MANY_TO_ONE );
404
- AnnotationInstance manyToMany = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .MANY_TO_MANY );
431
+ if ( oneToMany != null ) {
432
+ discoveredAttributeTypes .put ( AttributeType .ONE_TO_MANY , oneToMany );
433
+ }
405
434
406
- if ( oneToOne == null && oneToMany == null && manyToOne == null && manyToMany == null ) {
407
- return AssociationType .NO_ASSOCIATION ;
435
+ AnnotationInstance manyToOne = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .MANY_TO_ONE );
436
+ if ( manyToOne != null ) {
437
+ discoveredAttributeTypes .put ( AttributeType .MANY_TO_ONE , manyToOne );
408
438
}
409
- else if ( oneToOne != null && oneToMany == null && manyToOne == null && manyToMany == null ) {
410
- return AssociationType .ONE_TO_ONE ;
439
+
440
+ AnnotationInstance manyToMany = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .MANY_TO_MANY );
441
+ if ( manyToMany != null ) {
442
+ discoveredAttributeTypes .put ( AttributeType .MANY_TO_MANY , manyToMany );
411
443
}
412
- else if ( oneToOne == null && oneToMany != null && manyToOne == null && manyToMany == null ) {
413
- return AssociationType .ONE_TO_MANY ;
444
+
445
+ AnnotationInstance embedded = JandexHelper .getSingleAnnotation ( annotations , JPADotNames .EMBEDDED );
446
+ if ( embedded != null ) {
447
+ discoveredAttributeTypes .put ( AttributeType .EMBEDDED , embedded );
414
448
}
415
- else if ( oneToOne == null && oneToMany == null && manyToOne != null && manyToMany == null ) {
416
- return AssociationType .MANY_TO_ONE ;
449
+
450
+ if ( discoveredAttributeTypes .size () == 0 ) {
451
+ return AttributeType .BASIC ;
417
452
}
418
- else if ( oneToOne == null && oneToMany == null && manyToOne == null && manyToMany != null ) {
419
- return AssociationType . MANY_TO_MANY ;
453
+ else if ( discoveredAttributeTypes . size () == 1 ) {
454
+ return discoveredAttributeTypes . keySet (). iterator (). next () ;
420
455
}
421
456
else {
422
457
throw new AnnotationException ( "More than one association type configured for property " + getName () + " of class " + getName () );
@@ -435,11 +470,8 @@ private Type findResolvedType(String name, ResolvedMember[] resolvedMembers) {
435
470
436
471
/**
437
472
* Populates the sets of transient field and method names.
438
- *
439
- * @param transientFieldNames Set to populate with the field names explicitly marked as @Transient
440
- * @param transientMethodNames set to populate with the method names explicitly marked as @Transient
441
473
*/
442
- private void populateTransientFieldAndMethodLists ( Set < String > transientFieldNames , Set < String > transientMethodNames ) {
474
+ private void findTransientFieldAndMethodNames ( ) {
443
475
List <AnnotationInstance > transientMembers = classInfo .annotations ().get ( JPADotNames .TRANSIENT );
444
476
if ( transientMembers == null ) {
445
477
return ;
@@ -524,5 +556,3 @@ private IdType determineIdType() {
524
556
return IdType .NONE ;
525
557
}
526
558
}
527
-
528
-
0 commit comments