Browse Source

DATADOC-65 - Allow usage of SpEL in @Document.

@Document can now use SpEL expressions to let the collection an entity shall be stored to be calculated on the fly.
pull/1/head
Oliver Gierke 15 years ago
parent
commit
8a43b4bbc0
  1. 30
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
  2. 27
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java
  3. 3
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
  4. 51
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntityUnitTests.java

30
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java

@ -18,10 +18,19 @@ package org.springframework.data.mongodb.core.mapping; @@ -18,10 +18,19 @@ package org.springframework.data.mongodb.core.mapping;
import java.util.Comparator;
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.mapping.PersistentEntity;
import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.mongodb.MongoCollectionUtils;
import org.springframework.data.util.TypeInformation;
import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.StringUtils;
/**
@ -32,9 +41,11 @@ import org.springframework.util.StringUtils; @@ -32,9 +41,11 @@ import org.springframework.util.StringUtils;
* @author Oliver Gierke
*/
public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, MongoPersistentProperty> implements
MongoPersistentEntity<T> {
MongoPersistentEntity<T>, ApplicationContextAware {
private final String collection;
private final SpelExpressionParser parser;
private final StandardEvaluationContext context;
/**
* Creates a new {@link BasicMongoPersistentEntity} with the given {@link TypeInformation}. Will default the
@ -46,6 +57,9 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong @@ -46,6 +57,9 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
super(typeInformation, MongoPersistentPropertyComparator.INSTANCE);
this.parser = new SpelExpressionParser();
this.context = new StandardEvaluationContext();
Class<?> rawType = typeInformation.getType();
String fallback = MongoCollectionUtils.getPreferredCollectionName(rawType);
@ -57,13 +71,25 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong @@ -57,13 +71,25 @@ 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);
}
/**
* Returns the collection the entity should be stored in.
*
* @return
*/
public String getCollection() {
return collection;
Expression expression = parser.parseExpression(collection, ParserContext.TEMPLATE_EXPRESSION);
return expression.getValue(context, String.class);
}
/**

27
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoMappingContext.java

@ -19,6 +19,9 @@ package org.springframework.data.mongodb.core.mapping; @@ -19,6 +19,9 @@ package org.springframework.data.mongodb.core.mapping;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mapping.context.AbstractMappingContext;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.TypeInformation;
@ -27,7 +30,9 @@ import org.springframework.data.util.TypeInformation; @@ -27,7 +30,9 @@ import org.springframework.data.util.TypeInformation;
* @author Jon Brisbin <jbrisbin@vmware.com>
* @author Oliver Gierke ogierke@vmware.com
*/
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty> {
public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersistentEntity<?>, MongoPersistentProperty> implements ApplicationContextAware {
private ApplicationContext context;
/**
* Creates a new {@link MongoMappingContext}.
@ -46,11 +51,27 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis @@ -46,11 +51,27 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
return new CachingMongoPersistentProperty(field, descriptor, owner, simpleTypeHolder);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.BasicMappingContext#createPersistentEntity(org.springframework.data.util.TypeInformation, org.springframework.data.mapping.model.MappingContext)
*/
@Override
protected <T> BasicMongoPersistentEntity<T> createPersistentEntity(TypeInformation<T> typeInformation) {
return new BasicMongoPersistentEntity<T>(typeInformation);
BasicMongoPersistentEntity<T> entity = new BasicMongoPersistentEntity<T>(typeInformation);
if (context != null) {
entity.setApplicationContext(context);
}
return entity;
}
/*
* (non-Javadoc)
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}

3
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java

@ -28,10 +28,7 @@ import java.util.HashSet; @@ -28,10 +28,7 @@ import java.util.HashSet;
import java.util.List;
import org.bson.types.ObjectId;
import org.hamcrest.Matchers;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;

51
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntityUnitTests.java

@ -15,12 +15,15 @@ @@ -15,12 +15,15 @@
*/
package org.springframework.data.mongodb.core.mapping;
import static org.mockito.Mockito.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.Document;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.data.util.ClassTypeInformation;
/**
@ -28,8 +31,12 @@ import org.springframework.data.util.ClassTypeInformation; @@ -28,8 +31,12 @@ import org.springframework.data.util.ClassTypeInformation;
*
* @author Oliver Gierke
*/
@RunWith(MockitoJUnitRunner.class)
public class BasicMongoPersistentEntityUnitTests {
@Mock
ApplicationContext context;
@Test
public void subclassInheritsAtDocumentAnnotation() {
@ -38,6 +45,28 @@ public class BasicMongoPersistentEntityUnitTests { @@ -38,6 +45,28 @@ public class BasicMongoPersistentEntityUnitTests {
assertThat(entity.getCollection(), is("contacts"));
}
@Test
public void evaluatesSpELExpression() {
MongoPersistentEntity<Company> entity = new BasicMongoPersistentEntity<Company>(ClassTypeInformation.from(Company.class));
assertThat(entity.getCollection(), is("35"));
}
@Test
public void collectionAllowsReferencingSpringBean() {
CollectionProvider provider = new CollectionProvider();
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);
assertThat(entity.getCollection(), is("reference"));
}
@Document(collection = "contacts")
class Contact {
@ -46,4 +75,22 @@ public class BasicMongoPersistentEntityUnitTests { @@ -46,4 +75,22 @@ public class BasicMongoPersistentEntityUnitTests {
class Person extends Contact {
}
@Document(collection = "#{35}")
class Company {
}
@Document(collection = "#{myBean.collectionName}")
class DynamicallyMapped {
}
class CollectionProvider {
String collectionName;
public String getCollectionName() {
return collectionName;
}
}
}

Loading…
Cancel
Save