DATAMONGO-1874 - @Document's collection attribute now supports EvaluationContextExtensions.
We now use the API newly introduced with DATACMNS-1260 to expose EvaluationContextExtensions to the SpEL evaluation in case the collection attribute of @Document uses SpEL. Related tickets: DATACMNS-1260.
This commit is contained in:
@@ -21,11 +21,6 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.expression.BeanFactoryAccessor;
|
||||
import org.springframework.context.expression.BeanFactoryResolver;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mapping.Association;
|
||||
import org.springframework.data.mapping.AssociationHandler;
|
||||
@@ -38,7 +33,6 @@ import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -55,7 +49,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty>
|
||||
implements MongoPersistentEntity<T>, ApplicationContextAware {
|
||||
implements MongoPersistentEntity<T> {
|
||||
|
||||
private static final String AMBIGUOUS_FIELD_MAPPING = "Ambiguous field mapping detected! Both %s and %s map to the same field name %s! Disambiguate using @Field annotation!";
|
||||
private static final SpelExpressionParser PARSER = new SpelExpressionParser();
|
||||
@@ -63,7 +57,6 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
private final String collection;
|
||||
private final String language;
|
||||
|
||||
private final StandardEvaluationContext context;
|
||||
private final @Nullable Expression expression;
|
||||
|
||||
/**
|
||||
@@ -79,8 +72,6 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
Class<?> rawType = typeInformation.getType();
|
||||
String fallback = MongoCollectionUtils.getPreferredCollectionName(rawType);
|
||||
|
||||
this.context = new StandardEvaluationContext();
|
||||
|
||||
if (this.isAnnotationPresent(Document.class)) {
|
||||
Document document = this.getRequiredAnnotation(Document.class);
|
||||
|
||||
@@ -95,23 +86,15 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
context.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
|
||||
context.setRootObject(applicationContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentEntity#getCollection()
|
||||
*/
|
||||
public String getCollection() {
|
||||
return expression == null ? collection : expression.getValue(context, String.class);
|
||||
|
||||
return expression == null //
|
||||
? collection //
|
||||
: expression.getValue(getEvaluationContext(null), String.class);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -87,14 +87,7 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
*/
|
||||
@Override
|
||||
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
|
||||
|
||||
BasicMongoPersistentEntity<T> entity = new BasicMongoPersistentEntity<T>(typeInformation);
|
||||
|
||||
if (context != null) {
|
||||
entity.setApplicationContext(context);
|
||||
}
|
||||
|
||||
return entity;
|
||||
return new BasicMongoPersistentEntity<T>(typeInformation);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,6 +96,9 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
super.setApplicationContext(applicationContext);
|
||||
|
||||
this.context = applicationContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class ReactiveStringBasedMongoQuery extends AbstractReactiveMongoQuery {
|
||||
|
||||
/**
|
||||
* Creates a new {@link ReactiveStringBasedMongoQuery} for the given {@link String}, {@link MongoQueryMethod},
|
||||
* {@link MongoOperations}, {@link SpelExpressionParser} and {@link EvaluationContextProvider}.
|
||||
* {@link MongoOperations}, {@link SpelExpressionParser} and {@link QueryMethodEvaluationContextProvider}.
|
||||
*
|
||||
* @param query must not be {@literal null}.
|
||||
* @param method must not be {@literal null}.
|
||||
|
||||
@@ -40,7 +40,8 @@ import org.springframework.data.mongodb.core.convert.MongoTypeMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.data.spel.EvaluationContextProvider;
|
||||
import org.springframework.data.spel.ExtensionAwareEvaluationContextProvider;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
@@ -106,9 +107,10 @@ public class AbstractMongoConfigurationUnitTests {
|
||||
AbstractApplicationContext context = new AnnotationConfigApplicationContext(SampleMongoConfiguration.class);
|
||||
MongoMappingContext mappingContext = context.getBean(MongoMappingContext.class);
|
||||
BasicMongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(Entity.class);
|
||||
StandardEvaluationContext spElContext = (StandardEvaluationContext) ReflectionTestUtils.getField(entity, "context");
|
||||
EvaluationContextProvider provider = (EvaluationContextProvider) ReflectionTestUtils.getField(entity,
|
||||
"evaluationContextProvider");
|
||||
|
||||
assertThat(spElContext.getBeanResolver(), is(notNullValue()));
|
||||
assertThat(provider, is(instanceOf(ExtensionAwareEvaluationContextProvider.class)));
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.data.mongodb.config;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import example.first.First;
|
||||
import example.second.Second;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -37,16 +40,14 @@ import org.springframework.data.mongodb.core.convert.MongoTypeMapper;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.data.spel.EvaluationContextProvider;
|
||||
import org.springframework.data.spel.ExtensionAwareEvaluationContextProvider;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.reactivestreams.client.MongoClient;
|
||||
import com.mongodb.reactivestreams.client.MongoClients;
|
||||
|
||||
import example.first.First;
|
||||
import example.second.Second;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractReactiveMongoConfiguration}.
|
||||
*
|
||||
@@ -106,9 +107,10 @@ public class AbstractReactiveMongoConfigurationUnitTests {
|
||||
AbstractApplicationContext context = new AnnotationConfigApplicationContext(SampleMongoConfiguration.class);
|
||||
MongoMappingContext mappingContext = context.getBean(MongoMappingContext.class);
|
||||
BasicMongoPersistentEntity<?> entity = mappingContext.getRequiredPersistentEntity(Entity.class);
|
||||
StandardEvaluationContext spElContext = (StandardEvaluationContext) ReflectionTestUtils.getField(entity, "context");
|
||||
EvaluationContextProvider provider = (EvaluationContextProvider) ReflectionTestUtils.getField(entity,
|
||||
"evaluationContextProvider");
|
||||
|
||||
assertThat(spElContext.getBeanResolver(), is(notNullValue()));
|
||||
assertThat(provider, is(instanceOf(ExtensionAwareEvaluationContextProvider.class)));
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,18 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.mapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -31,6 +35,8 @@ import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.spel.ExtensionAwareEvaluationContextProvider;
|
||||
import org.springframework.data.spel.spi.EvaluationContextExtension;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
|
||||
/**
|
||||
@@ -68,11 +74,10 @@ public class BasicMongoPersistentEntityUnitTests {
|
||||
provider.collectionName = "reference";
|
||||
|
||||
when(context.getBean("myBean")).thenReturn(provider);
|
||||
when(context.containsBean("myBean")).thenReturn(true);
|
||||
|
||||
BasicMongoPersistentEntity<DynamicallyMapped> entity = new BasicMongoPersistentEntity<DynamicallyMapped>(
|
||||
ClassTypeInformation.from(DynamicallyMapped.class));
|
||||
entity.setApplicationContext(context);
|
||||
entity.setEvaluationContextProvider(new ExtensionAwareEvaluationContextProvider(context));
|
||||
|
||||
assertThat(entity.getCollection(), is("reference"));
|
||||
|
||||
@@ -221,6 +226,17 @@ public class BasicMongoPersistentEntityUnitTests {
|
||||
assertThat(entity.getCollection(), is("custom-collection"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1874
|
||||
public void usesEvaluationContextExtensionInDynamicDocumentName() {
|
||||
|
||||
BasicMongoPersistentEntity<MappedWithExtension> entity = new BasicMongoPersistentEntity<>(
|
||||
ClassTypeInformation.from(MappedWithExtension.class));
|
||||
entity.setEvaluationContextProvider(
|
||||
new ExtensionAwareEvaluationContextProvider(Arrays.asList(new SampleExtension())));
|
||||
|
||||
assertThat(entity.getCollection()).isEqualTo("collectionName");
|
||||
}
|
||||
|
||||
@Document("contacts")
|
||||
class Contact {}
|
||||
|
||||
@@ -229,7 +245,7 @@ public class BasicMongoPersistentEntityUnitTests {
|
||||
@Document("#{35}")
|
||||
class Company {}
|
||||
|
||||
@Document("#{myBean.collectionName}")
|
||||
@Document("#{@myBean.collectionName}")
|
||||
class DynamicallyMapped {}
|
||||
|
||||
class CollectionProvider {
|
||||
@@ -265,4 +281,30 @@ public class BasicMongoPersistentEntityUnitTests {
|
||||
@AliasFor(annotation = Document.class, attribute = "collection")
|
||||
String name() default "custom-collection";
|
||||
}
|
||||
|
||||
// DATAMONGO-1874
|
||||
|
||||
@Document("#{myProperty}")
|
||||
class MappedWithExtension {}
|
||||
|
||||
static class SampleExtension implements EvaluationContextExtension {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.spel.spi.EvaluationContextExtension#getExtensionId()
|
||||
*/
|
||||
@Override
|
||||
public String getExtensionId() {
|
||||
return "sampleExtension";
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.spel.spi.EvaluationContextExtension#getProperties()
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getProperties() {
|
||||
return Collections.singletonMap("myProperty", "collectionName");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,8 @@
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
</property>
|
||||
<property name="evaluationContextProvider" ref="extensionAwareEvaluationContextProvider"/>
|
||||
</bean>
|
||||
|
||||
<bean id="extensionAwareEvaluationContextProvider" class="org.springframework.data.repository.query.ExtensionAwareQueryMethodEvaluationContextProvider" autowire="constructor" />
|
||||
|
||||
<bean class="org.springframework.data.mongodb.repository.SampleEvaluationContextExtension" />
|
||||
|
||||
</beans>
|
||||
|
||||
Reference in New Issue
Block a user