23
23
*/
24
24
package org .hibernate .metamodel .source .annotations .attribute ;
25
25
26
+ import java .util .Calendar ;
27
+ import java .util .Date ;
26
28
import java .util .HashMap ;
27
29
import java .util .List ;
28
30
import java .util .Map ;
31
+ import javax .persistence .TemporalType ;
29
32
30
33
import org .jboss .jandex .AnnotationInstance ;
31
34
import org .jboss .jandex .AnnotationValue ;
32
35
import org .jboss .jandex .DotName ;
33
36
37
+ import org .hibernate .AnnotationException ;
38
+ import org .hibernate .AssertionFailure ;
39
+ import org .hibernate .cfg .NotYetImplementedException ;
34
40
import org .hibernate .metamodel .source .annotations .AnnotationBindingContext ;
35
41
import org .hibernate .metamodel .source .annotations .HibernateDotNames ;
42
+ import org .hibernate .metamodel .source .annotations .JPADotNames ;
36
43
import org .hibernate .metamodel .source .annotations .JandexHelper ;
37
44
38
45
/**
@@ -72,6 +79,9 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
72
79
*/
73
80
private final Map <String , String > explicitHibernateTypeParameters ;
74
81
82
+ /**
83
+ * The binding context
84
+ */
75
85
private final AnnotationBindingContext context ;
76
86
77
87
MappedAttribute (String name , Class <?> attributeType , String accessType , Map <DotName , List <AnnotationInstance >> annotations , AnnotationBindingContext context ) {
@@ -80,34 +90,8 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
80
90
this .name = name ;
81
91
this .attributeType = attributeType ;
82
92
this .accessType = accessType ;
83
-
84
- final AnnotationInstance typeAnnotation = JandexHelper .getSingleAnnotation (
85
- annotations (),
86
- HibernateDotNames .TYPE
87
- );
88
- if ( typeAnnotation != null ) {
89
- this .explicitHibernateTypeName = typeAnnotation .value ( "type" ).asString ();
90
- this .explicitHibernateTypeParameters = extractTypeParameters ( typeAnnotation );
91
- }
92
- else {
93
- this .explicitHibernateTypeName = null ;
94
- this .explicitHibernateTypeParameters = new HashMap <String , String >();
95
- }
96
- }
97
-
98
- private Map <String , String > extractTypeParameters (AnnotationInstance typeAnnotation ) {
99
- HashMap <String , String > typeParameters = new HashMap <String , String >();
100
- AnnotationValue parameterAnnotationValue = typeAnnotation .value ( "parameters" );
101
- if ( parameterAnnotationValue != null ) {
102
- AnnotationInstance [] parameterAnnotations = parameterAnnotationValue .asNestedArray ();
103
- for ( AnnotationInstance parameterAnnotationInstance : parameterAnnotations ) {
104
- typeParameters .put (
105
- parameterAnnotationInstance .value ( "name" ).asString (),
106
- parameterAnnotationInstance .value ( "value" ).asString ()
107
- );
108
- }
109
- }
110
- return typeParameters ;
93
+ this .explicitHibernateTypeParameters = new HashMap <String , String >();
94
+ this .explicitHibernateTypeName = determineExplicitHibernateTypeName ();
111
95
}
112
96
113
97
public String getName () {
@@ -151,6 +135,86 @@ public String toString() {
151
135
sb .append ( '}' );
152
136
return sb .toString ();
153
137
}
138
+
139
+ private String getTemporalType () {
140
+ final AnnotationInstance temporalAnnotation = JandexHelper .getSingleAnnotation (
141
+ annotations (),
142
+ JPADotNames .TEMPORAL
143
+ );
144
+ if ( isTemporalType ( attributeType ) ) {
145
+ if ( temporalAnnotation == null ) {
146
+ //SPEC 11.1.47 The Temporal annotation must be specified for persistent fields or properties of type java.util.Date and java.util.Calendar.
147
+ throw new AnnotationException ( "Attribute " + name + " is a Temporal type, but no @Temporal annotation found." );
148
+ }
149
+ TemporalType temporalType = JandexHelper .getEnumValue ( temporalAnnotation , "value" , TemporalType .class );
150
+ boolean isDate = Date .class .isAssignableFrom ( attributeType );
151
+ String type = null ;
152
+ switch ( temporalType ) {
153
+ case DATE :
154
+ type = isDate ? "date" : "calendar_date" ;
155
+ break ;
156
+ case TIME :
157
+ type = "time" ;
158
+ if ( !isDate ) {
159
+ throw new NotYetImplementedException ( "Calendar cannot persist TIME only" );
160
+ }
161
+ break ;
162
+ case TIMESTAMP :
163
+ type = isDate ? "timestamp" : "calendar" ;
164
+ break ;
165
+ default :
166
+ throw new AssertionFailure ( "Unknown temporal type: " + temporalType );
167
+ }
168
+ return type ;
169
+ }
170
+ else {
171
+ if ( temporalAnnotation != null ) {
172
+ throw new AnnotationException (
173
+ "@Temporal should only be set on a java.util.Date or java.util.Calendar property: " + name
174
+ );
175
+ }
176
+ }
177
+ return null ;
178
+ }
179
+
180
+ private boolean isTemporalType (Class type ) {
181
+ return Date .class .isAssignableFrom ( type ) || Calendar .class .isAssignableFrom ( type );
182
+ //todo (stliu) java.sql.Date is not listed in spec
183
+ // || java.sql.Date.class.isAssignableFrom( type )
184
+ }
185
+
186
+ private Map <String , String > extractTypeParameters (AnnotationInstance typeAnnotation ) {
187
+ HashMap <String , String > typeParameters = new HashMap <String , String >();
188
+ AnnotationValue parameterAnnotationValue = typeAnnotation .value ( "parameters" );
189
+ if ( parameterAnnotationValue != null ) {
190
+ AnnotationInstance [] parameterAnnotations = parameterAnnotationValue .asNestedArray ();
191
+ for ( AnnotationInstance parameterAnnotationInstance : parameterAnnotations ) {
192
+ typeParameters .put (
193
+ parameterAnnotationInstance .value ( "name" ).asString (),
194
+ parameterAnnotationInstance .value ( "value" ).asString ()
195
+ );
196
+ }
197
+ }
198
+ return typeParameters ;
199
+ }
200
+
201
+ private String determineExplicitHibernateTypeName () {
202
+ String typeName = null ;
203
+ String temporalType = getTemporalType ();
204
+ final AnnotationInstance typeAnnotation = JandexHelper .getSingleAnnotation (
205
+ annotations (),
206
+ HibernateDotNames .TYPE
207
+ );
208
+ if ( typeAnnotation != null ) {
209
+ typeName = typeAnnotation .value ( "type" ).asString ();
210
+ this .explicitHibernateTypeParameters .putAll ( extractTypeParameters ( typeAnnotation ) );
211
+ }
212
+ else if ( temporalType != null ) {
213
+ typeName = temporalType ;
214
+
215
+ }
216
+ return typeName ;
217
+ }
154
218
}
155
219
156
220
0 commit comments