From 148c4f9e249abc415c263f2e2d51ca5057763b48 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 12 Jan 2017 13:04:50 +0100 Subject: [PATCH] DATAMONGO-1517 - Polishing. Remove ReflectiveSimpleTypes in favor of MongoSimpleTypes. Add add integration test. --- .../core/convert/CustomConversions.java | 2 +- .../core/convert/ReflectiveSimpleTypes.java | 53 ------------------- .../core/mapping/MongoSimpleTypes.java | 10 +++- .../data/mongodb/util/MongoClientVersion.java | 16 +++++- .../data/mongodb/core/MongoTemplateTests.java | 53 +++++++++++++++---- 5 files changed, 66 insertions(+), 68 deletions(-) delete mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveSimpleTypes.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java index 6f9daebb3..e57c92a6c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java @@ -93,7 +93,7 @@ public class CustomConversions { this.readingPairs = new LinkedHashSet(); this.writingPairs = new LinkedHashSet(); - this.customSimpleTypes = new HashSet>(ReflectiveSimpleTypes.getSupportedSimpleTypes()); + this.customSimpleTypes = new HashSet>(); this.customReadTargetTypes = new ConcurrentHashMap>>(); this.customWriteTargetTypes = new ConcurrentHashMap>>(); this.rawWriteTargetTypes = new ConcurrentHashMap, CacheValue>>(); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveSimpleTypes.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveSimpleTypes.java deleted file mode 100644 index f4991c388..000000000 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/ReflectiveSimpleTypes.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2017 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 java.util.Collection; -import java.util.Collections; - -import org.springframework.util.ClassUtils; - -/** - * {@link ReflectiveSimpleTypes} provides reflective access to MongoDB types that are not consistently available for - * various driver versions. - * - * @author Mark Paluch - * @since 1.10 - */ -class ReflectiveSimpleTypes { - - private static final boolean HAS_DECIMAL_128 = ClassUtils.isPresent("org.bson.types.Decimal128", - ReflectiveSimpleTypes.class.getClassLoader()); - - /** - * Returns a {@link Collection} of simple MongoDB types (i.e. natively supported by the MongoDB driver) that are not - * consistently available for various driver versions. - * - * @return a {@link Collection} of simple MongoDB types. - */ - public static Collection> getSupportedSimpleTypes() { - - if (HAS_DECIMAL_128) { - return Collections.> singleton(getDecimal128Class()); - } - - return Collections.emptySet(); - } - - private static Class getDecimal128Class() { - return ClassUtils.resolveClassName("org.bson.types.Decimal128", ReflectiveSimpleTypes.class.getClassLoader()); - } -} 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 db2e63d89..ce23aa5a1 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 by the original author(s). + * Copyright (c) 2011-2017 by the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,6 +27,8 @@ import org.bson.types.Binary; import org.bson.types.CodeWScope; import org.bson.types.ObjectId; import org.springframework.data.mapping.model.SimpleTypeHolder; +import org.springframework.data.mongodb.util.MongoClientVersion; +import org.springframework.util.ClassUtils; import com.mongodb.DBRef; @@ -56,6 +58,12 @@ public abstract class MongoSimpleTypes { simpleTypes.add(Pattern.class); simpleTypes.add(Binary.class); simpleTypes.add(UUID.class); + + if (MongoClientVersion.isMongo34Driver()) { + simpleTypes + .add(ClassUtils.resolveClassName("org.bson.types.Decimal128", MongoSimpleTypes.class.getClassLoader())); + } + MONGO_SIMPLE_TYPES = Collections.unmodifiableSet(simpleTypes); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java index d23057491..272f885a7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2017 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. @@ -28,16 +28,28 @@ public class MongoClientVersion { private static final boolean IS_MONGO_30 = ClassUtils.isPresent("com.mongodb.binding.SingleServerBinding", MongoClientVersion.class.getClassLoader()); + + private static final boolean IS_MONGO_34 = ClassUtils.isPresent("org.bson.types.Decimal128", + MongoClientVersion.class.getClassLoader()); + private static final boolean IS_ASYNC_CLIENT = ClassUtils.isPresent("com.mongodb.async.client.MongoClient", MongoClientVersion.class.getClassLoader()); /** - * @return |literal true} if MongoDB Java driver version 3.0 or later is on classpath. + * @return {@literal true} if MongoDB Java driver version 3.0 or later is on classpath. */ public static boolean isMongo3Driver() { return IS_MONGO_30; } + /** + * @return {@literal true} if MongoDB Java driver version 3.4 or later is on classpath. + * @since 1.10 + */ + public static boolean isMongo34Driver() { + return IS_MONGO_34; + } + /** * @return {lliteral true} if MongoDB Java driver is on classpath. */ diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java index e1950a019..fc5ee345b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java @@ -24,6 +24,11 @@ import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Query.*; import static org.springframework.data.mongodb.core.query.Update.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; @@ -44,7 +49,6 @@ import org.hamcrest.collection.IsMapContaining; import org.joda.time.DateTime; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -73,7 +77,6 @@ import org.springframework.data.mongodb.core.convert.LazyLoadingProxy; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.geo.GeoJsonPoint; import org.springframework.data.mongodb.core.index.Index; -import org.springframework.data.mongodb.core.index.Index.Duplicates; import org.springframework.data.mongodb.core.index.IndexField; import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.mapping.Field; @@ -84,10 +87,12 @@ import org.springframework.data.mongodb.core.query.BasicQuery; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; +import org.springframework.data.mongodb.util.MongoClientVersion; import org.springframework.data.util.CloseableIterator; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -102,10 +107,6 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.result.UpdateResult; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; - /** * Integration test for {@link MongoTemplate}. * @@ -126,6 +127,8 @@ public class MongoTemplateTests { .parse("2.4"); private static final org.springframework.data.util.Version TWO_DOT_EIGHT = org.springframework.data.util.Version .parse("2.8"); + private static final org.springframework.data.util.Version THREE_DOT_FOUR = org.springframework.data.util.Version + .parse("3.4"); @Autowired MongoTemplate template; @Autowired MongoDbFactory factory; @@ -2937,7 +2940,7 @@ public class MongoTemplateTests { .min("longVal", 490) // .min("bigIntegerVal", new BigInteger("590")) // .min("bigDeciamVal", new BigDecimal("690")) // - ; + ; template.updateFirst(query(where("id").is(twn.id)), update, TypeWithNumbers.class); @@ -2993,7 +2996,7 @@ public class MongoTemplateTests { .max("longVal", 590) // .max("bigIntegerVal", new BigInteger("690")) // .max("bigDeciamVal", new BigDecimal("790")) // - ; + ; template.updateFirst(query(where("id").is(twn.id)), update, TypeWithNumbers.class); @@ -3022,7 +3025,7 @@ public class MongoTemplateTests { Update update = new Update()// .max("bigIntegerVal", new BigInteger("70")) // .max("bigDeciamVal", new BigDecimal("80")) // - ; + ; template.updateFirst(query(where("id").is(twn.id)), update, TypeWithNumbers.class); @@ -3046,7 +3049,7 @@ public class MongoTemplateTests { Update update = new Update()// .min("bigIntegerVal", new BigInteger("700")) // .min("bigDeciamVal", new BigDecimal("800")) // - ; + ; template.updateFirst(query(where("id").is(twn.id)), update, TypeWithNumbers.class); @@ -3155,7 +3158,6 @@ public class MongoTemplateTests { assertThat(document.id, is(notNullValue())); } - @Test // DATAMONGO-1509 public void findsByGenericNestedListElements() { @@ -3168,6 +3170,28 @@ public class MongoTemplateTests { assertThat(template.findOne(query, DocumentWithCollection.class), is(equalTo(dwc))); } + /** + * @see DATAMONGO-1517 + */ + @Test + public void decimal128TypeShouldBeSavedAndLoadedCorrectly() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + + assumeThat(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_FOUR), is(true)); + assumeThat(MongoClientVersion.isMongo34Driver(), is(true)); + + Class decimal128Type = ClassUtils.resolveClassName("org.bson.types.Decimal128", null); + + WithObjectTypeProperty source = new WithObjectTypeProperty(); + source.id = "decimal128-property-value"; + source.value = decimal128Type.getConstructor(BigDecimal.class).newInstance(new BigDecimal(100)); + + template.save(source); + + WithObjectTypeProperty loaded = template.findOne(query(where("id").is(source.id)), WithObjectTypeProperty.class); + assertThat(loaded.getValue(), instanceOf(decimal128Type)); + } + static class TypeWithNumbers { @Id String id; @@ -3539,4 +3563,11 @@ public class MongoTemplateTests { String description; GeoJsonPoint point; } + + @Data + static class WithObjectTypeProperty { + + @Id String id; + Object value; + } }