16
16
17
17
package org .springframework .data .couchbase .core .convert ;
18
18
19
- import static org .springframework .data .couchbase .core .mapping .id .GenerationStrategy .UNIQUE ;
20
- import static org .springframework .data .couchbase .core .mapping .id .GenerationStrategy .USE_ATTRIBUTES ;
19
+ import static org .springframework .data .couchbase .core .mapping .id .GenerationStrategy .*;
21
20
22
21
import java .beans .Transient ;
23
22
import java .lang .reflect .InaccessibleObjectException ;
34
33
import org .springframework .beans .factory .BeanClassLoaderAware ;
35
34
import org .springframework .context .ApplicationContext ;
36
35
import org .springframework .context .ApplicationContextAware ;
36
+ import org .springframework .context .EnvironmentAware ;
37
37
import org .springframework .core .CollectionFactory ;
38
38
import org .springframework .core .convert .ConversionService ;
39
39
import org .springframework .core .convert .TypeDescriptor ;
40
40
import org .springframework .core .convert .support .DefaultConversionService ;
41
+ import org .springframework .core .env .Environment ;
42
+ import org .springframework .core .env .EnvironmentCapable ;
43
+ import org .springframework .core .env .StandardEnvironment ;
41
44
import org .springframework .data .convert .CustomConversions ;
42
45
import org .springframework .data .convert .PropertyValueConverter ;
43
46
import org .springframework .data .couchbase .core .mapping .CouchbaseDocument ;
62
65
import org .springframework .data .mapping .PropertyHandler ;
63
66
import org .springframework .data .mapping .callback .EntityCallbacks ;
64
67
import org .springframework .data .mapping .context .MappingContext ;
68
+ import org .springframework .data .mapping .model .CachingValueExpressionEvaluatorFactory ;
65
69
import org .springframework .data .mapping .model .ConvertingPropertyAccessor ;
66
- import org .springframework .data .mapping .model .DefaultSpELExpressionEvaluator ;
67
70
import org .springframework .data .mapping .model .EntityInstantiator ;
68
71
import org .springframework .data .mapping .model .ParameterValueProvider ;
69
72
import org .springframework .data .mapping .model .PersistentEntityParameterValueProvider ;
70
73
import org .springframework .data .mapping .model .PropertyValueProvider ;
71
74
import org .springframework .data .mapping .model .SpELContext ;
72
- import org .springframework .data .mapping .model .SpELExpressionEvaluator ;
73
- import org .springframework .data .mapping .model .SpELExpressionParameterValueProvider ;
75
+ import org .springframework .data .mapping .model .ValueExpressionEvaluator ;
76
+ import org .springframework .data .mapping .model .ValueExpressionParameterValueProvider ;
74
77
import org .springframework .data .util .TypeInformation ;
78
+ import org .springframework .expression .spel .standard .SpelExpressionParser ;
75
79
import org .springframework .lang .Nullable ;
76
80
import org .springframework .util .Assert ;
77
81
import org .springframework .util .CollectionUtils ;
92
96
* @author Remi Bleuse
93
97
* @author Vipul Gupta
94
98
*/
95
- public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware {
99
+ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware , EnvironmentCapable , EnvironmentAware {
96
100
97
101
/**
98
102
* The default "type key", the name of the field that will hold type information.
@@ -113,6 +117,10 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
113
117
* Spring Expression Language context.
114
118
*/
115
119
private final SpELContext spELContext ;
120
+
121
+ private final SpelExpressionParser expressionParser = new SpelExpressionParser ();
122
+
123
+ private final CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory ;
116
124
/**
117
125
* The overall application context.
118
126
*/
@@ -127,6 +135,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implem
127
135
*/
128
136
private @ Nullable EntityCallbacks entityCallbacks ;
129
137
138
+ private @ Nullable Environment environment ;
139
+
130
140
public MappingCouchbaseConverter () {
131
141
this (new CouchbaseMappingContext (), null );
132
142
}
@@ -173,6 +183,9 @@ public MappingCouchbaseConverter(
173
183
((CouchbaseMappingContext ) mappingContext ).setSimpleTypeHolder (customConversions .getSimpleTypeHolder ());
174
184
typeMapper = new DefaultCouchbaseTypeMapper (typeKey != null ? typeKey : TYPEKEY_DEFAULT );
175
185
spELContext = new SpELContext (CouchbaseDocumentPropertyAccessor .INSTANCE );
186
+
187
+ expressionEvaluatorFactory = new CachingValueExpressionEvaluatorFactory (
188
+ expressionParser , this , o -> spELContext .getEvaluationContext (o ));
176
189
}
177
190
178
191
/**
@@ -200,6 +213,21 @@ private static boolean isSubtype(final Class<?> left, final Class<?> right) {
200
213
return left .isAssignableFrom (right ) && !left .equals (right );
201
214
}
202
215
216
+ @ Override
217
+ public void setEnvironment (Environment environment ) {
218
+ this .environment = environment ;
219
+ }
220
+
221
+ @ Override
222
+ public Environment getEnvironment () {
223
+
224
+ if (this .environment == null ) {
225
+ this .environment = new StandardEnvironment ();
226
+ }
227
+
228
+ return environment ;
229
+ }
230
+
203
231
@ Override
204
232
public MappingContext <? extends CouchbasePersistentEntity <?>, CouchbasePersistentProperty > getMappingContext () {
205
233
return mappingContext ;
@@ -273,7 +301,8 @@ protected <R> R read(final TypeInformation<R> type, final CouchbaseDocument sour
273
301
* @return the converted entity.
274
302
*/
275
303
protected <R > R read (final CouchbasePersistentEntity <R > entity , final CouchbaseDocument source , final Object parent ) {
276
- final DefaultSpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator (source , spELContext );
304
+
305
+ ValueExpressionEvaluator evaluator = expressionEvaluatorFactory .create (source );
277
306
ParameterValueProvider <CouchbasePersistentProperty > provider = getParameterProvider (entity , source , evaluator ,
278
307
parent );
279
308
EntityInstantiator instantiator = instantiators .getInstantiatorFor (entity );
@@ -284,7 +313,7 @@ protected <R> R read(final CouchbasePersistentEntity<R> entity, final CouchbaseD
284
313
entity .doWithProperties (new PropertyHandler <>() {
285
314
@ Override
286
315
public void doWithPersistentProperty (final CouchbasePersistentProperty prop ) {
287
- if (!doesPropertyExistInSource (prop ) || entity .isConstructorArgument (prop ) || isIdConstructionProperty (prop )
316
+ if (!doesPropertyExistInSource (prop ) || entity .isCreatorArgument (prop ) || isIdConstructionProperty (prop )
288
317
|| prop .isAnnotationPresent (N1qlJoin .class )) {
289
318
return ;
290
319
}
@@ -330,7 +359,7 @@ private boolean isIdConstructionProperty(final CouchbasePersistentProperty prope
330
359
*/
331
360
protected Object getValueInternal (final CouchbasePersistentProperty property , final CouchbaseDocument source ,
332
361
final Object parent , PersistentEntity entity ) {
333
- return new CouchbasePropertyValueProvider (source , spELContext , parent , entity ).getPropertyValue (property );
362
+ return new CouchbasePropertyValueProvider (source , expressionEvaluatorFactory . create ( source ) , parent , entity ).getPropertyValue (property );
334
363
}
335
364
336
365
/**
@@ -344,7 +373,7 @@ protected Object getValueInternal(final CouchbasePersistentProperty property, fi
344
373
*/
345
374
private ParameterValueProvider <CouchbasePersistentProperty > getParameterProvider (
346
375
final CouchbasePersistentEntity <?> entity , final CouchbaseDocument source ,
347
- final DefaultSpELExpressionEvaluator evaluator , final Object parent ) {
376
+ final ValueExpressionEvaluator evaluator , final Object parent ) {
348
377
CouchbasePropertyValueProvider provider = new CouchbasePropertyValueProvider (source , evaluator , parent , entity );
349
378
PersistentEntityParameterValueProvider <CouchbasePersistentProperty > parameterProvider = new PersistentEntityParameterValueProvider <>(
350
379
entity , provider , parent );
@@ -1070,7 +1099,7 @@ private class CouchbasePropertyValueProvider implements PropertyValueProvider<Co
1070
1099
/**
1071
1100
* The expression evaluator.
1072
1101
*/
1073
- private final SpELExpressionEvaluator evaluator ;
1102
+ private final ValueExpressionEvaluator evaluator ;
1074
1103
1075
1104
/**
1076
1105
* The optional parent object.
@@ -1082,15 +1111,10 @@ private class CouchbasePropertyValueProvider implements PropertyValueProvider<Co
1082
1111
*/
1083
1112
private final PersistentEntity entity ;
1084
1113
1085
- public CouchbasePropertyValueProvider (final CouchbaseDocument source , final SpELContext factory ,
1086
- final Object parent , final PersistentEntity entity ) {
1087
- this (source , new DefaultSpELExpressionEvaluator (source , factory ), parent , entity );
1088
- }
1089
-
1090
1114
public CouchbasePropertyValueProvider (final CouchbaseDocument source ,
1091
- final DefaultSpELExpressionEvaluator evaluator , final Object parent , final PersistentEntity entity ) {
1115
+ final ValueExpressionEvaluator evaluator , final Object parent , final PersistentEntity entity ) {
1092
1116
Assert .notNull (source , "CouchbaseDocument must not be null!" );
1093
- Assert .notNull (evaluator , "DefaultSpELExpressionEvaluator must not be null!" );
1117
+ Assert .notNull (evaluator , "ValueExpressionEvaluator must not be null!" );
1094
1118
1095
1119
this .source = source ;
1096
1120
this .evaluator = evaluator ;
@@ -1148,20 +1172,19 @@ String maybeMangle(PersistentProperty<?> property) {
1148
1172
* A expression parameter value provider.
1149
1173
*/
1150
1174
private class ConverterAwareSpELExpressionParameterValueProvider
1151
- extends SpELExpressionParameterValueProvider <CouchbasePersistentProperty > {
1175
+ extends ValueExpressionParameterValueProvider <CouchbasePersistentProperty > {
1152
1176
1153
1177
private final Object parent ;
1154
1178
1155
- public ConverterAwareSpELExpressionParameterValueProvider (final SpELExpressionEvaluator evaluator ,
1179
+ public ConverterAwareSpELExpressionParameterValueProvider (final ValueExpressionEvaluator evaluator ,
1156
1180
final ConversionService conversionService , final ParameterValueProvider <CouchbasePersistentProperty > delegate ,
1157
1181
final Object parent ) {
1158
1182
super (evaluator , conversionService , delegate );
1159
1183
this .parent = parent ;
1160
1184
}
1161
1185
1162
1186
@ Override
1163
- protected <T > T potentiallyConvertSpelValue (final Object object ,
1164
- final Parameter <T , CouchbasePersistentProperty > parameter ) {
1187
+ protected <T > T potentiallyConvertExpressionValue (Object object , Parameter <T , CouchbasePersistentProperty > parameter ) {
1165
1188
return readValue (object , parameter .getType (), parent );
1166
1189
}
1167
1190
}
0 commit comments