39
39
import org .bson .conversions .Bson ;
40
40
import org .bson .json .JsonReader ;
41
41
import org .bson .types .ObjectId ;
42
+
42
43
import org .springframework .beans .BeansException ;
43
44
import org .springframework .beans .factory .BeanClassLoaderAware ;
44
45
import org .springframework .context .ApplicationContext ;
47
48
import org .springframework .core .convert .ConversionService ;
48
49
import org .springframework .core .convert .TypeDescriptor ;
49
50
import org .springframework .core .convert .support .DefaultConversionService ;
51
+ import org .springframework .core .env .Environment ;
52
+ import org .springframework .core .env .EnvironmentCapable ;
53
+ import org .springframework .core .env .StandardEnvironment ;
50
54
import org .springframework .data .annotation .Reference ;
51
55
import org .springframework .data .convert .CustomConversions ;
52
56
import org .springframework .data .convert .TypeMapper ;
59
63
import org .springframework .data .mapping .PersistentPropertyAccessor ;
60
64
import org .springframework .data .mapping .callback .EntityCallbacks ;
61
65
import org .springframework .data .mapping .context .MappingContext ;
66
+ import org .springframework .data .mapping .model .CachingValueExpressionEvaluatorFactory ;
62
67
import org .springframework .data .mapping .model .ConvertingPropertyAccessor ;
63
- import org .springframework .data .mapping .model .DefaultSpELExpressionEvaluator ;
64
68
import org .springframework .data .mapping .model .EntityInstantiator ;
65
69
import org .springframework .data .mapping .model .ParameterValueProvider ;
66
70
import org .springframework .data .mapping .model .PersistentEntityParameterValueProvider ;
67
71
import org .springframework .data .mapping .model .PropertyValueProvider ;
68
72
import org .springframework .data .mapping .model .SpELContext ;
69
- import org .springframework .data .mapping .model .SpELExpressionEvaluator ;
70
73
import org .springframework .data .mapping .model .SpELExpressionParameterValueProvider ;
74
+ import org .springframework .data .mapping .model .ValueExpressionEvaluator ;
75
+ import org .springframework .data .mapping .model .ValueExpressionParameterValueProvider ;
71
76
import org .springframework .data .mongodb .CodecRegistryProvider ;
72
77
import org .springframework .data .mongodb .MongoDatabaseFactory ;
73
78
import org .springframework .data .mongodb .core .mapping .BasicMongoPersistentProperty ;
88
93
import org .springframework .data .projection .SpelAwareProxyProjectionFactory ;
89
94
import org .springframework .data .util .Predicates ;
90
95
import org .springframework .data .util .TypeInformation ;
96
+ import org .springframework .expression .spel .standard .SpelExpressionParser ;
91
97
import org .springframework .lang .Nullable ;
92
98
import org .springframework .util .Assert ;
93
99
import org .springframework .util .ClassUtils ;
116
122
* @author Divya Srivastava
117
123
* @author Julia Lee
118
124
*/
119
- public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
125
+ public class MappingMongoConverter extends AbstractMongoConverter
126
+ implements ApplicationContextAware , EnvironmentCapable {
120
127
121
128
private static final String INCOMPATIBLE_TYPES = "Cannot convert %1$s of type %2$s into an instance of %3$s; Implement a custom Converter<%2$s, %3$s> and register it with the CustomConversions; Parent object was: %4$s" ;
122
129
private static final String INVALID_TYPE_TO_READ = "Expected to read Document %s into type %s but didn't find a PersistentEntity for the latter" ;
@@ -132,15 +139,20 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
132
139
protected final ReferenceLookupDelegate referenceLookupDelegate ;
133
140
134
141
protected @ Nullable ApplicationContext applicationContext ;
142
+ protected @ Nullable Environment environment ;
135
143
protected MongoTypeMapper typeMapper ;
136
144
protected @ Nullable String mapKeyDotReplacement = null ;
137
145
protected @ Nullable CodecRegistryProvider codecRegistryProvider ;
138
146
139
147
private MongoTypeMapper defaultTypeMapper ;
140
148
private SpELContext spELContext ;
141
149
private @ Nullable EntityCallbacks entityCallbacks ;
150
+ private final SpelExpressionParser expressionParser = new SpelExpressionParser ();
142
151
private final DocumentPointerFactory documentPointerFactory ;
143
- private final SpelAwareProxyProjectionFactory projectionFactory = new SpelAwareProxyProjectionFactory ();
152
+ private final SpelAwareProxyProjectionFactory projectionFactory = new SpelAwareProxyProjectionFactory (
153
+ expressionParser );
154
+ private final CachingValueExpressionEvaluatorFactory expressionEvaluatorFactory = new CachingValueExpressionEvaluatorFactory (
155
+ expressionParser , this , o -> spELContext .getEvaluationContext (o ));
144
156
145
157
/**
146
158
* Creates a new {@link MappingMongoConverter} given the new {@link DbRefResolver} and {@link MappingContext}.
@@ -169,7 +181,7 @@ public MappingMongoConverter(DbRefResolver dbRefResolver,
169
181
170
182
ConversionContext context = getConversionContext (path );
171
183
return MappingMongoConverter .this .getValueInternal (context , prop , bson , evaluator );
172
- });
184
+ }, expressionEvaluatorFactory :: create );
173
185
174
186
this .referenceLookupDelegate = new ReferenceLookupDelegate (mappingContext , spELContext );
175
187
this .documentPointerFactory = new DocumentPointerFactory (conversionService , mappingContext );
@@ -271,9 +283,11 @@ public MappingContext<? extends MongoPersistentEntity<?>, MongoPersistentPropert
271
283
return mappingContext ;
272
284
}
273
285
286
+ @ Override
274
287
public void setApplicationContext (ApplicationContext applicationContext ) throws BeansException {
275
288
276
289
this .applicationContext = applicationContext ;
290
+ this .environment = applicationContext .getEnvironment ();
277
291
this .spELContext = new SpELContext (this .spELContext , applicationContext );
278
292
this .projectionFactory .setBeanFactory (applicationContext );
279
293
this .projectionFactory .setBeanClassLoader (applicationContext .getClassLoader ());
@@ -288,6 +302,15 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
288
302
}
289
303
}
290
304
305
+ @ Override
306
+ public Environment getEnvironment () {
307
+
308
+ if (environment == null ) {
309
+ environment = new StandardEnvironment ();
310
+ }
311
+ return environment ;
312
+ }
313
+
291
314
/**
292
315
* Set the {@link EntityCallbacks} instance to use when invoking
293
316
* {@link org.springframework.data.mapping.callback.EntityCallback callbacks} like the {@link AfterConvertCallback}.
@@ -328,7 +351,7 @@ private <R> R doReadProjection(ConversionContext context, Bson bson, EntityProje
328
351
TypeInformation <?> mappedType = projection .getActualMappedType ();
329
352
MongoPersistentEntity <R > mappedEntity = (MongoPersistentEntity <R >) getMappingContext ()
330
353
.getPersistentEntity (mappedType );
331
- SpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator (bson , spELContext );
354
+ ValueExpressionEvaluator evaluator = expressionEvaluatorFactory . create (bson );
332
355
333
356
boolean isInterfaceProjection = mappedType .getType ().isInterface ();
334
357
if (isInterfaceProjection ) {
@@ -481,14 +504,14 @@ protected <S extends Object> S readDocument(ConversionContext context, Bson bson
481
504
}
482
505
483
506
private ParameterValueProvider <MongoPersistentProperty > getParameterProvider (ConversionContext context ,
484
- MongoPersistentEntity <?> entity , DocumentAccessor source , SpELExpressionEvaluator evaluator ) {
507
+ MongoPersistentEntity <?> entity , DocumentAccessor source , ValueExpressionEvaluator evaluator ) {
485
508
486
509
AssociationAwareMongoDbPropertyValueProvider provider = new AssociationAwareMongoDbPropertyValueProvider (context ,
487
510
source , evaluator );
488
511
PersistentEntityParameterValueProvider <MongoPersistentProperty > parameterProvider = new PersistentEntityParameterValueProvider <>(
489
512
entity , provider , context .getPath ().getCurrentObject ());
490
513
491
- return new ConverterAwareSpELExpressionParameterValueProvider (context , evaluator , conversionService ,
514
+ return new ConverterAwareValueExpressionParameterValueProvider (context , evaluator , conversionService ,
492
515
parameterProvider );
493
516
}
494
517
@@ -499,7 +522,7 @@ private <S> S read(ConversionContext context, MongoPersistentEntity<S> entity, D
499
522
return existing ;
500
523
}
501
524
502
- SpELExpressionEvaluator evaluator = new DefaultSpELExpressionEvaluator (bson , spELContext );
525
+ ValueExpressionEvaluator evaluator = expressionEvaluatorFactory . create (bson );
503
526
DocumentAccessor documentAccessor = new DocumentAccessor (bson );
504
527
505
528
InstanceCreatorMetadata <MongoPersistentProperty > instanceCreatorMetadata = entity .getInstanceCreatorMetadata ();
@@ -515,7 +538,7 @@ private <S> S read(ConversionContext context, MongoPersistentEntity<S> entity, D
515
538
}
516
539
517
540
private <S > S populateProperties (ConversionContext context , MongoPersistentEntity <S > entity ,
518
- DocumentAccessor documentAccessor , SpELExpressionEvaluator evaluator , S instance ) {
541
+ DocumentAccessor documentAccessor , ValueExpressionEvaluator evaluator , S instance ) {
519
542
520
543
if (!entity .requiresPropertyPopulation ()) {
521
544
return instance ;
@@ -545,7 +568,7 @@ private <S> S populateProperties(ConversionContext context, MongoPersistentEntit
545
568
*/
546
569
@ Nullable
547
570
private Object readAndPopulateIdentifier (ConversionContext context , PersistentPropertyAccessor <?> accessor ,
548
- DocumentAccessor document , MongoPersistentEntity <?> entity , SpELExpressionEvaluator evaluator ) {
571
+ DocumentAccessor document , MongoPersistentEntity <?> entity , ValueExpressionEvaluator evaluator ) {
549
572
550
573
Object rawId = document .getRawId (entity );
551
574
@@ -565,7 +588,7 @@ private Object readAndPopulateIdentifier(ConversionContext context, PersistentPr
565
588
}
566
589
567
590
@ Nullable
568
- private Object readIdValue (ConversionContext context , SpELExpressionEvaluator evaluator ,
591
+ private Object readIdValue (ConversionContext context , ValueExpressionEvaluator evaluator ,
569
592
MongoPersistentProperty idProperty , Object rawId ) {
570
593
571
594
String expression = idProperty .getSpelExpression ();
@@ -578,7 +601,7 @@ private Object readIdValue(ConversionContext context, SpELExpressionEvaluator ev
578
601
579
602
private void readProperties (ConversionContext context , MongoPersistentEntity <?> entity ,
580
603
PersistentPropertyAccessor <?> accessor , DocumentAccessor documentAccessor ,
581
- MongoDbPropertyValueProvider valueProvider , SpELExpressionEvaluator evaluator ,
604
+ MongoDbPropertyValueProvider valueProvider , ValueExpressionEvaluator evaluator ,
582
605
Predicate <MongoPersistentProperty > propertyFilter ) {
583
606
584
607
DbRefResolverCallback callback = null ;
@@ -622,7 +645,7 @@ private void readProperties(ConversionContext context, MongoPersistentEntity<?>
622
645
}
623
646
624
647
private DbRefResolverCallback getDbRefResolverCallback (ConversionContext context , DocumentAccessor documentAccessor ,
625
- SpELExpressionEvaluator evaluator ) {
648
+ ValueExpressionEvaluator evaluator ) {
626
649
627
650
return new DefaultDbRefResolverCallback (documentAccessor .getDocument (), context .getPath (), evaluator ,
628
651
(prop , bson , e , path ) -> MappingMongoConverter .this .getValueInternal (context , prop , bson , e ));
@@ -1387,7 +1410,7 @@ protected DBRef createDBRef(Object target, @Nullable MongoPersistentProperty pro
1387
1410
1388
1411
@ Nullable
1389
1412
private Object getValueInternal (ConversionContext context , MongoPersistentProperty prop , Bson bson ,
1390
- SpELExpressionEvaluator evaluator ) {
1413
+ ValueExpressionEvaluator evaluator ) {
1391
1414
return new MongoDbPropertyValueProvider (context , bson , evaluator ).getPropertyValue (prop );
1392
1415
}
1393
1416
@@ -1876,35 +1899,35 @@ static class MongoDbPropertyValueProvider implements PropertyValueProvider<Mongo
1876
1899
1877
1900
final ConversionContext context ;
1878
1901
final DocumentAccessor accessor ;
1879
- final SpELExpressionEvaluator evaluator ;
1902
+ final ValueExpressionEvaluator evaluator ;
1880
1903
final SpELContext spELContext ;
1881
1904
1882
1905
/**
1883
- * Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link SpELExpressionEvaluator } and
1906
+ * Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link ValueExpressionEvaluator } and
1884
1907
* {@link ObjectPath}.
1885
1908
*
1886
1909
* @param context must not be {@literal null}.
1887
1910
* @param source must not be {@literal null}.
1888
1911
* @param evaluator must not be {@literal null}.
1889
1912
*/
1890
- MongoDbPropertyValueProvider (ConversionContext context , Bson source , SpELExpressionEvaluator evaluator ) {
1913
+ MongoDbPropertyValueProvider (ConversionContext context , Bson source , ValueExpressionEvaluator evaluator ) {
1891
1914
this (context , new DocumentAccessor (source ), evaluator , null );
1892
1915
}
1893
1916
1894
1917
/**
1895
- * Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link SpELExpressionEvaluator } and
1918
+ * Creates a new {@link MongoDbPropertyValueProvider} for the given source, {@link ValueExpressionEvaluator } and
1896
1919
* {@link ObjectPath}.
1897
1920
*
1898
1921
* @param context must not be {@literal null}.
1899
1922
* @param accessor must not be {@literal null}.
1900
1923
* @param evaluator must not be {@literal null}.
1901
1924
*/
1902
1925
MongoDbPropertyValueProvider (ConversionContext context , DocumentAccessor accessor ,
1903
- SpELExpressionEvaluator evaluator , SpELContext spELContext ) {
1926
+ ValueExpressionEvaluator evaluator , SpELContext spELContext ) {
1904
1927
1905
1928
Assert .notNull (context , "ConversionContext must no be null" );
1906
1929
Assert .notNull (accessor , "DocumentAccessor must no be null" );
1907
- Assert .notNull (evaluator , "SpELExpressionEvaluator must not be null" );
1930
+ Assert .notNull (evaluator , "ValueExpressionEvaluator must not be null" );
1908
1931
1909
1932
this .context = context ;
1910
1933
this .accessor = accessor ;
@@ -1953,13 +1976,13 @@ class AssociationAwareMongoDbPropertyValueProvider extends MongoDbPropertyValueP
1953
1976
1954
1977
/**
1955
1978
* Creates a new {@link AssociationAwareMongoDbPropertyValueProvider} for the given source,
1956
- * {@link SpELExpressionEvaluator } and {@link ObjectPath}.
1979
+ * {@link ValueExpressionEvaluator } and {@link ObjectPath}.
1957
1980
*
1958
1981
* @param source must not be {@literal null}.
1959
1982
* @param evaluator must not be {@literal null}.
1960
1983
*/
1961
1984
AssociationAwareMongoDbPropertyValueProvider (ConversionContext context , DocumentAccessor source ,
1962
- SpELExpressionEvaluator evaluator ) {
1985
+ ValueExpressionEvaluator evaluator ) {
1963
1986
super (context , source , evaluator , MappingMongoConverter .this .spELContext );
1964
1987
}
1965
1988
@@ -2000,21 +2023,21 @@ public <T> T getPropertyValue(MongoPersistentProperty property) {
2000
2023
*
2001
2024
* @author Oliver Gierke
2002
2025
*/
2003
- private static class ConverterAwareSpELExpressionParameterValueProvider
2004
- extends SpELExpressionParameterValueProvider <MongoPersistentProperty > {
2026
+ private static class ConverterAwareValueExpressionParameterValueProvider
2027
+ extends ValueExpressionParameterValueProvider <MongoPersistentProperty > {
2005
2028
2006
2029
private final ConversionContext context ;
2007
2030
2008
2031
/**
2009
- * Creates a new {@link ConverterAwareSpELExpressionParameterValueProvider }.
2032
+ * Creates a new {@link ConverterAwareValueExpressionParameterValueProvider }.
2010
2033
*
2011
2034
* @param context must not be {@literal null}.
2012
2035
* @param evaluator must not be {@literal null}.
2013
2036
* @param conversionService must not be {@literal null}.
2014
2037
* @param delegate must not be {@literal null}.
2015
2038
*/
2016
- public ConverterAwareSpELExpressionParameterValueProvider (ConversionContext context ,
2017
- SpELExpressionEvaluator evaluator , ConversionService conversionService ,
2039
+ public ConverterAwareValueExpressionParameterValueProvider (ConversionContext context ,
2040
+ ValueExpressionEvaluator evaluator , ConversionService conversionService ,
2018
2041
ParameterValueProvider <MongoPersistentProperty > delegate ) {
2019
2042
2020
2043
super (evaluator , conversionService , delegate );
@@ -2025,7 +2048,7 @@ public ConverterAwareSpELExpressionParameterValueProvider(ConversionContext cont
2025
2048
}
2026
2049
2027
2050
@ Override
2028
- protected <T > T potentiallyConvertSpelValue (Object object , Parameter <T , MongoPersistentProperty > parameter ) {
2051
+ protected <T > T potentiallyConvertExpressionValue (Object object , Parameter <T , MongoPersistentProperty > parameter ) {
2029
2052
return context .convert (object , parameter .getType ());
2030
2053
}
2031
2054
}
0 commit comments