diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java index 55410c015..dabf2b503 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/QueryMapper.java @@ -25,6 +25,7 @@ import org.bson.types.ObjectId; import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; import org.springframework.data.mapping.PersistentEntity; +import org.springframework.data.mongodb.core.convert.MongoConverter; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.util.Assert; @@ -40,15 +41,17 @@ import com.mongodb.DBObject; public class QueryMapper { private final ConversionService conversionService; + private final MongoConverter converter; /** - * Creates a new {@link QueryMapper} with the given {@link ConversionService}. + * Creates a new {@link QueryMapper} with the given {@link MongoConverter}. * - * @param conversionService must not be {@literal null}. + * @param converter must not be {@literal null}. */ - public QueryMapper(ConversionService conversionService) { - Assert.notNull(conversionService); - this.conversionService = conversionService; + public QueryMapper(MongoConverter converter) { + Assert.notNull(converter); + this.conversionService = converter.getConversionService(); + this.converter = converter; } /** @@ -105,7 +108,7 @@ public class QueryMapper { value = convertId(value); } - newDbo.put(newKey, value); + newDbo.put(newKey, converter.convertToMongoType(value)); } return newDbo; diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 47df0ded0..c86d18d56 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -72,7 +72,7 @@ import com.mongodb.DBRef; * @author Oliver Gierke * @author Jon Brisbin */ -public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware, TypeKeyAware { +public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware { @SuppressWarnings("rawtypes") private static final TypeInformation MAP_TYPE_INFORMATION = ClassTypeInformation.from(Map.class); @@ -110,7 +110,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App this.mongoDbFactory = mongoDbFactory; this.mappingContext = mappingContext; this.typeMapper = new DefaultMongoTypeMapper(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY, mappingContext); - this.idMapper = new QueryMapper(conversionService); + this.idMapper = new QueryMapper(this); } /** @@ -126,14 +126,6 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App mappingContext) : typeMapper; } - /* - * (non-Javadoc) - * @see org.springframework.data.mongodb.core.convert.TypeKeyAware#isTypeKey(java.lang.String) - */ - public boolean isTypeKey(String key) { - return typeMapper.isTypeKey(key); - } - /* * (non-Javadoc) * @see org.springframework.data.convert.EntityConverter#getMappingContext() @@ -908,7 +900,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App DBObject newDbo = new BasicDBObject(); this.write(obj, newDbo); - return newDbo; + return removeTypeInfoRecursively(newDbo); } public BasicDBList maybeConvertList(Iterable source) { @@ -918,4 +910,41 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } return newDbl; } + + /** + * Removes the type information from the conversion result. + * + * @param object + * @return + */ + private Object removeTypeInfoRecursively(Object object) { + + if (!(object instanceof DBObject)) { + return object; + } + + DBObject dbObject = (DBObject) object; + String keyToRemove = null; + for (String key : dbObject.keySet()) { + + if (typeMapper.isTypeKey(key)) { + keyToRemove = key; + } + + Object value = dbObject.get(key); + if (value instanceof BasicDBList) { + for (Object element : (BasicDBList) value) { + removeTypeInfoRecursively(element); + } + } else { + removeTypeInfoRecursively(value); + } + } + + if (keyToRemove != null) { + dbObject.removeField(keyToRemove); + } + + return dbObject; + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoTypeMapper.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoTypeMapper.java index 118a47117..1eefce386 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoTypeMapper.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoTypeMapper.java @@ -20,11 +20,16 @@ import org.springframework.data.convert.TypeMapper; import com.mongodb.DBObject; /** - * Combining interface to express Mongo specific {@link TypeMapper} implementations will be {@link TypeKeyAware} as - * well. + * Mongo-specific {@link TypeMapper} exposing that {@link DBObject}s might contain a type key. * * @author Oliver Gierke */ -public interface MongoTypeMapper extends TypeMapper, TypeKeyAware { +public interface MongoTypeMapper extends TypeMapper { + /** + * Returns whether the given key is the type key. + * + * @return + */ + boolean isTypeKey(String key); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/TypeKeyAware.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/TypeKeyAware.java deleted file mode 100644 index 7848524f1..000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/TypeKeyAware.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.mongodb.core.convert; - -import org.springframework.data.convert.TypeMapper; - -/** - * Interfaces for components being able to provide a {@link TypeMapper}. - * - * @author Oliver Gierke - */ -public interface TypeKeyAware { - - /** - * Returns the {@link TypeMapper}. - * - * @return the {@link TypeMapper} or {@literal null} if none available. - */ - boolean isTypeKey(String key); -} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java index 130bea04d..e553ee911 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoSimpleTypes.java @@ -19,6 +19,7 @@ import java.math.BigInteger; import java.util.Collections; import java.util.HashSet; import java.util.Set; +import java.util.regex.Pattern; import org.bson.types.CodeWScope; import org.bson.types.ObjectId; @@ -48,6 +49,7 @@ public abstract class MongoSimpleTypes { simpleTypes.add(ObjectId.class); simpleTypes.add(CodeWScope.class); simpleTypes.add(DBObject.class); + simpleTypes.add(Pattern.class); MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java index 52e7417a4..46e3591b6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ConvertingParameterAccessor.java @@ -20,15 +20,11 @@ import java.util.Iterator; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.convert.MongoWriter; -import org.springframework.data.mongodb.core.convert.TypeKeyAware; import org.springframework.data.mongodb.core.geo.Distance; import org.springframework.data.mongodb.core.geo.Point; import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.util.Assert; -import com.mongodb.BasicDBList; -import com.mongodb.DBObject; - /** * Custom {@link ParameterAccessor} that uses a {@link MongoWriter} to serialize parameters into Mongo format. * @@ -111,49 +107,7 @@ public class ConvertingParameterAccessor implements MongoParameterAccessor { * @return */ private Object getConvertedValue(Object value) { - - if (!(writer instanceof TypeKeyAware)) { - return value; - } - - return removeTypeInfoRecursively(writer.convertToMongoType(value), ((TypeKeyAware) writer)); - } - - /** - * Removes the type information from the conversion result. - * - * @param object - * @return - */ - private Object removeTypeInfoRecursively(Object object, TypeKeyAware typeKeyAware) { - - if (!(object instanceof DBObject) || typeKeyAware == null) { - return object; - } - - DBObject dbObject = (DBObject) object; - String keyToRemove = null; - for (String key : dbObject.keySet()) { - - if (typeKeyAware.isTypeKey(key)) { - keyToRemove = key; - } - - Object value = dbObject.get(key); - if (value instanceof BasicDBList) { - for (Object element : (BasicDBList) value) { - removeTypeInfoRecursively(element, typeKeyAware); - } - } else { - removeTypeInfoRecursively(value, typeKeyAware); - } - } - - if (keyToRemove != null) { - dbObject.removeField(keyToRemove); - } - - return dbObject; + return writer.convertToMongoType(value); } /** diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java index ccf99e7ac..60dd3096f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoNamespaceTests.java @@ -68,6 +68,7 @@ public class MongoNamespaceTests { } @Test + @SuppressWarnings("deprecation") public void testMongoSingletonWithPropertyPlaceHolders() throws Exception { assertTrue(ctx.containsBean("mongo")); MongoFactoryBean mfb = (MongoFactoryBean) ctx.getBean("&mongo"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryMapperUnitTests.java index be0b3361e..f6884aed4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/QueryMapperUnitTests.java @@ -17,6 +17,8 @@ package org.springframework.data.mongodb.core.query; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; +import static org.springframework.data.mongodb.core.query.Query.*; +import static org.springframework.data.mongodb.core.query.Criteria.*; import java.math.BigInteger; @@ -59,7 +61,7 @@ public class QueryMapperUnitTests { MappingMongoConverter converter = new MappingMongoConverter(factory, context); converter.afterPropertiesSet(); - mapper = new QueryMapper(converter.getConversionService()); + mapper = new QueryMapper(converter); } @Test @@ -90,12 +92,12 @@ public class QueryMapperUnitTests { } /** - * @see DATADOC-278 + * @see DATAMONGO-278 */ @Test public void translates$NeCorrectly() { - Criteria criteria = Criteria.where("foo").ne(new ObjectId().toString()); + Criteria criteria = where("foo").ne(new ObjectId().toString()); DBObject result = mapper.getMappedObject(criteria.getCriteriaObject(), context.getPersistentEntity(Sample.class)); Object object = result.get("_id"); @@ -104,6 +106,18 @@ public class QueryMapperUnitTests { assertThat(dbObject.get("$ne"), is(ObjectId.class)); } + /** + * @see DATAMONGO-326 + */ + @Test + public void handlesEnumsCorrectly() { + Query query = query(where("foo").is(Enum.INSTANCE)); + DBObject result = mapper.getMappedObject(query.getQueryObject(), null); + + Object object = result.get("foo"); + assertThat(object, is(String.class)); + } + class Sample { @Id @@ -115,4 +129,8 @@ public class QueryMapperUnitTests { @Id private BigInteger id; } + + enum Enum { + INSTANCE; + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java index 50013974a..47b89d1fa 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java @@ -30,7 +30,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; @@ -50,9 +49,6 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.query.parser.PartTree; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; - /** * Unit test for {@link MongoQueryCreator}. * @@ -72,14 +68,12 @@ public class MongoQueryCreatorUnitTests { public void setUp() throws SecurityException, NoSuchMethodException { context = new MongoMappingContext(); - - doAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - DBObject dbObject = (DBObject) invocation.getArguments()[1]; - dbObject.put("value", new BasicDBObject("value", "value")); - return null; + + doAnswer(new Answer() { + public Object answer(InvocationOnMock invocation) throws Throwable { + return invocation.getArguments()[0]; } - }).when(converter).write(any(), Mockito.any(DBObject.class)); + }).when(converter).convertToMongoType(any()); } @Test