Skip to content

Commit b429cca

Browse files
tmp save for monday
1 parent 2d84a9c commit b429cca

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,8 @@ private JsonSchemaProperty computeSchemaForProperty(List<MongoPersistentProperty
185185
Class<?> rawTargetType = computeTargetType(property); // target type before conversion
186186
Class<?> targetType = converter.getTypeMapper().getWriteTargetTypeFor(rawTargetType); // conversion target type
187187

188-
if ((rawTargetType.isPrimitive() || ClassUtils.isPrimitiveArray(rawTargetType)) && targetType == Object.class) {
188+
189+
if ((rawTargetType.isPrimitive() || ClassUtils.isPrimitiveArray(rawTargetType)) && targetType == Object.class || ClassUtils.isAssignable(targetType, rawTargetType) ) {
189190
targetType = rawTargetType;
190191
}
191192

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
import org.springframework.core.convert.converter.ConditionalConverter;
5454
import org.springframework.core.convert.converter.Converter;
5555
import org.springframework.core.convert.converter.ConverterFactory;
56+
import org.springframework.core.env.Environment;
57+
import org.springframework.core.env.StandardEnvironment;
5658
import org.springframework.data.convert.ReadingConverter;
5759
import org.springframework.data.convert.WritingConverter;
5860
import org.springframework.data.domain.Vector;
@@ -89,14 +91,27 @@ private MongoConverters() {}
8991
*/
9092
static Collection<Object> getConvertersToRegister() {
9193

94+
Environment env = new StandardEnvironment();
95+
boolean flagPresent = env.containsProperty("mongo.decimal128.representation");
96+
boolean decimalToString = !flagPresent || env.getProperty("mongo.decimal128.representation", String.class, "string").equals("string");
97+
9298
List<Object> converters = new ArrayList<>();
9399

94-
converters.add(BigDecimalToStringConverter.INSTANCE);
100+
if(decimalToString) {
101+
converters.add(BigDecimalToStringConverter.INSTANCE);
102+
converters.add(StringToBigDecimalConverter.INSTANCE);
103+
} else {
104+
//converters.add(new NumberToNumberConverter<>())
105+
}
106+
95107
converters.add(BigDecimalToDecimal128Converter.INSTANCE);
96-
converters.add(StringToBigDecimalConverter.INSTANCE);
97108
converters.add(Decimal128ToBigDecimalConverter.INSTANCE);
98-
converters.add(BigIntegerToStringConverter.INSTANCE);
99-
converters.add(StringToBigIntegerConverter.INSTANCE);
109+
110+
if(decimalToString) {
111+
converters.add(BigIntegerToStringConverter.INSTANCE);
112+
converters.add(StringToBigIntegerConverter.INSTANCE);
113+
}
114+
100115
converters.add(URLToStringConverter.INSTANCE);
101116
converters.add(StringToURLConverter.INSTANCE);
102117
converters.add(DocumentToStringConverter.INSTANCE);
@@ -111,6 +126,7 @@ static Collection<Object> getConvertersToRegister() {
111126
converters.add(IntegerToAtomicIntegerConverter.INSTANCE);
112127
converters.add(BinaryToByteArrayConverter.INSTANCE);
113128
converters.add(BsonTimestampToInstantConverter.INSTANCE);
129+
converters.add(NumberToNumberConverterFactory.INSTANCE);
114130

115131
converters.add(VectorToBsonArrayConverter.INSTANCE);
116132
converters.add(ListToVectorConverter.INSTANCE);
@@ -174,12 +190,20 @@ public ObjectId convert(BigInteger source) {
174190
}
175191
}
176192

177-
enum BigDecimalToStringConverter implements Converter<BigDecimal, String> {
193+
enum BigDecimalToStringConverter implements Converter<BigDecimal, String>, ConditionalConverter {
178194
INSTANCE;
179195

196+
Environment env = new StandardEnvironment();
197+
180198
public String convert(BigDecimal source) {
181199
return source.toString();
182200
}
201+
202+
@Override
203+
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
204+
boolean flagPresent = env.containsProperty("mongo.decimal128.representation");
205+
return !flagPresent || env.getProperty("mongo.decimal128.representation", String.class, "string").equals("string");
206+
}
183207
}
184208

185209
/**
@@ -212,12 +236,21 @@ public BigDecimal convert(Decimal128 source) {
212236
}
213237
}
214238

215-
enum BigIntegerToStringConverter implements Converter<BigInteger, String> {
239+
enum BigIntegerToStringConverter implements Converter<BigInteger, String>, ConditionalConverter {
216240
INSTANCE;
217241

242+
Environment env = new StandardEnvironment();
243+
218244
public String convert(BigInteger source) {
219245
return source.toString();
220246
}
247+
248+
@Override
249+
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
250+
251+
boolean flagPresent = env.containsProperty("mongo.decimal128.representation");
252+
return !flagPresent || env.getProperty("mongo.decimal128.representation", String.class, "string").equals("string");
253+
}
221254
}
222255

223256
enum StringToBigIntegerConverter implements Converter<String, BigInteger> {
@@ -414,6 +447,17 @@ public NumberToNumberConverter(Class<T> targetType) {
414447
@Override
415448
public T convert(Number source) {
416449

450+
if(targetType == Decimal128.class) {
451+
452+
if (source instanceof BigDecimal bigDecimal) {
453+
return targetType.cast(BigDecimalToDecimal128Converter.INSTANCE.convert(bigDecimal));
454+
}
455+
456+
if(source instanceof BigInteger bigInteger) {
457+
return targetType.cast(new Decimal128(bigInteger.longValueExact()));
458+
}
459+
}
460+
417461
if (source instanceof AtomicInteger atomicInteger) {
418462
return NumberUtils.convertNumberToTargetClass(atomicInteger.get(), this.targetType);
419463
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoCustomConversions.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
import org.springframework.core.convert.converter.Converter;
3737
import org.springframework.core.convert.converter.ConverterFactory;
3838
import org.springframework.core.convert.converter.GenericConverter;
39+
import org.springframework.core.env.Environment;
40+
import org.springframework.core.env.StandardEnvironment;
3941
import org.springframework.data.convert.ConverterBuilder;
4042
import org.springframework.data.convert.PropertyValueConversions;
4143
import org.springframework.data.convert.PropertyValueConverter;
@@ -45,6 +47,7 @@
4547
import org.springframework.data.convert.SimplePropertyValueConversions;
4648
import org.springframework.data.convert.WritingConverter;
4749
import org.springframework.data.mapping.model.SimpleTypeHolder;
50+
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
4851
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
4952
import org.springframework.data.mongodb.core.mapping.MongoSimpleTypes;
5053
import org.springframework.lang.Nullable;
@@ -154,11 +157,18 @@ public static class MongoConverterConfigurationAdapter {
154157
private static final Set<Class<?>> JAVA_DRIVER_TIME_SIMPLE_TYPES = Set.of(LocalDate.class, LocalTime.class, LocalDateTime.class);
155158

156159
private boolean useNativeDriverJavaTimeCodecs = false;
160+
private boolean defaultToDecimal128;
157161
private final List<Object> customConverters = new ArrayList<>();
158162

159163
private final PropertyValueConversions internalValueConversion = PropertyValueConversions.simple(it -> {});
160164
private PropertyValueConversions propertyValueConversions = internalValueConversion;
161165

166+
{
167+
Environment env = new StandardEnvironment();
168+
boolean flagPresent = env.containsProperty("mongo.decimal128.representation");
169+
defaultToDecimal128 = !flagPresent || env.getProperty("mongo.decimal128.representation", String.class, "string").equals("string");
170+
}
171+
162172
/**
163173
* Create a {@link MongoConverterConfigurationAdapter} using the provided {@code converters} and our own codecs for
164174
* JSR-310 types.
@@ -347,6 +357,8 @@ ConverterConfiguration createConverterConfiguration() {
347357
svc.init();
348358
}
349359

360+
// TODO: all the config must go here now and omg get rid of the static blocks!!
361+
350362
if (!useNativeDriverJavaTimeCodecs) {
351363
return new ConverterConfiguration(STORE_CONVERSIONS, this.customConverters, convertiblePair -> true,
352364
this.propertyValueConversions);

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.junit.jupiter.params.provider.Arguments;
4848
import org.junit.jupiter.params.provider.MethodSource;
4949
import org.junit.jupiter.params.provider.ValueSource;
50+
import org.junitpioneer.jupiter.SetSystemProperty;
5051
import org.mockito.Mock;
5152
import org.mockito.Mockito;
5253
import org.mockito.junit.jupiter.MockitoExtension;
@@ -3360,7 +3361,48 @@ void writesByteArrayAsIsIfNoFieldInstructionsGiven() {
33603361
converter.write(source, target);
33613362

33623363
assertThat(target.get("arrayOfPrimitiveBytes", byte[].class)).isSameAs(source.arrayOfPrimitiveBytes);
3364+
}
3365+
3366+
@Test // GH-3444
3367+
void convertsBigIntegerToDecimal128IfFieldTypeIndicatesConversion() {
3368+
3369+
WithExplicitTargetTypes source = new WithExplicitTargetTypes();
3370+
source.bigInteger = BigInteger.valueOf(101);
33633371

3372+
org.bson.Document target = new org.bson.Document();
3373+
converter.write(source, target);
3374+
3375+
assertThat(target.get("bigInteger")).isEqualTo(new Decimal128(source.bigInteger.longValueExact()));
3376+
}
3377+
3378+
@Test // GH-3444
3379+
@SetSystemProperty(key = "mongo.decimal128.representation", value = "decimal128")
3380+
void usesConfiguredNumericFormat() {
3381+
3382+
MongoCustomConversions conversions = new MongoCustomConversions(
3383+
Arrays.asList(new ByteBufferToDoubleHolderConverter()));
3384+
3385+
MongoMappingContext mappingContext = new MongoMappingContext();
3386+
mappingContext.setApplicationContext(context);
3387+
mappingContext.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
3388+
mappingContext.afterPropertiesSet();
3389+
3390+
mappingContext.getPersistentEntity(Address.class);
3391+
3392+
MappingMongoConverter converter = new MappingMongoConverter(resolver, mappingContext);
3393+
converter.setCustomConversions(conversions);
3394+
converter.afterPropertiesSet();
3395+
3396+
BigDecimalContainer container = new BigDecimalContainer();
3397+
container.value = BigDecimal.valueOf(2.5d);
3398+
// container.map = Collections.singletonMap("foo", container.value);
3399+
3400+
org.bson.Document document = new org.bson.Document();
3401+
converter.write(container, document);
3402+
3403+
assertThat(document.get("value")).isInstanceOf(Decimal128.class);
3404+
// assertThat((String) document.get("value")).isEqualTo("2.5");
3405+
// assertThat(((org.bson.Document) document.get("map")).get("foo")).isInstanceOf(String.class);
33643406
}
33653407

33663408
org.bson.Document write(Object source) {
@@ -4017,6 +4059,9 @@ static class WithExplicitTargetTypes {
40174059
@Field(targetType = FieldType.DECIMAL128) //
40184060
BigDecimal bigDecimal;
40194061

4062+
@Field(targetType = FieldType.DECIMAL128)
4063+
BigInteger bigInteger;
4064+
40204065
@Field(targetType = FieldType.INT64) //
40214066
Date dateAsLong;
40224067

0 commit comments

Comments
 (0)