Skip to content

Commit 5f30515

Browse files
Hacking mapper config
1 parent 58eb31c commit 5f30515

File tree

4 files changed

+59
-218
lines changed

4 files changed

+59
-218
lines changed

src/main/java/org/springframework/data/redis/hash/Jackson3HashMapper.java

Lines changed: 24 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import tools.jackson.core.JsonGenerator;
2020
import tools.jackson.core.JsonParser;
2121
import tools.jackson.core.Version;
22-
import tools.jackson.databind.DatabindContext;
2322
import tools.jackson.databind.DefaultTyping;
2423
import tools.jackson.databind.DeserializationContext;
2524
import tools.jackson.databind.DeserializationFeature;
@@ -29,10 +28,11 @@
2928
import tools.jackson.databind.SerializationContext;
3029
import tools.jackson.databind.ValueDeserializer;
3130
import tools.jackson.databind.ValueSerializer;
31+
import tools.jackson.databind.cfg.MapperBuilder;
3232
import tools.jackson.databind.deser.jdk.JavaUtilCalendarDeserializer;
3333
import tools.jackson.databind.json.JsonMapper;
34+
import tools.jackson.databind.json.JsonMapper.Builder;
3435
import tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
35-
import tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator.TypeMatcher;
3636
import tools.jackson.databind.module.SimpleDeserializers;
3737
import tools.jackson.databind.module.SimpleSerializers;
3838
import tools.jackson.databind.ser.Serializers;
@@ -48,12 +48,13 @@
4848
import java.util.HashMap;
4949
import java.util.Iterator;
5050
import java.util.LinkedHashMap;
51-
import java.util.LinkedHashSet;
5251
import java.util.List;
5352
import java.util.Map;
5453
import java.util.Map.Entry;
5554
import java.util.Set;
5655
import java.util.TimeZone;
56+
import java.util.function.Consumer;
57+
import java.util.function.Supplier;
5758

5859
import org.springframework.data.mapping.MappingException;
5960
import org.springframework.data.redis.support.collections.CollectionUtils;
@@ -159,87 +160,25 @@ public class Jackson3HashMapper implements HashMapper<Object, String, Object> {
159160
Jackson3HashMapper.class.getClassLoader());
160161

161162
private final ObjectMapper typingMapper;
162-
private final ObjectMapper untypedMapper;
163163
private final boolean flatten;
164164

165-
/**
166-
* Creates new {@link Jackson3HashMapper} with a default {@link ObjectMapper}.
167-
*
168-
* @param flatten boolean used to configure whether JSON de/serialized {@link Object} properties will be un/flattened
169-
* using {@literal dot notation}, or whether to retain the hierarchical node structure created by Jackson.
170-
*/
171-
public Jackson3HashMapper(boolean flatten) {
165+
public Jackson3HashMapper(
166+
Consumer<MapperBuilder<? extends ObjectMapper, ? extends MapperBuilder<?, ?>>> jsonMapperBuilder,
167+
boolean flatten) {
168+
this(((Supplier<JsonMapper>) () -> {
169+
Builder builder = JsonMapper.builder();
170+
jsonMapperBuilder.accept(builder);
171+
return builder.build();
172+
}).get(), flatten);
173+
}
172174

173-
this(JsonMapper.builder().findAndAddModules().addModules(new HashMapperModule())
174-
.activateDefaultTypingAsProperty(BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).allowIfSubType(new TypeMatcher() {
175-
@Override
176-
public boolean match(DatabindContext ctxt, Class<?> clazz) {
177-
return true;
178-
}
179-
}).build(),
180-
DefaultTyping.NON_FINAL_AND_ENUMS, "@class")
181-
.configure(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false)
175+
public static void preconfigure(MapperBuilder<? extends ObjectMapper, ? extends MapperBuilder<?, ?>> builder) {
176+
builder.findAndAddModules().addModules(new HashMapperModule())
177+
.activateDefaultTypingAsProperty(BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class)
178+
.allowIfSubType((ctx, clazz) -> true).build(), DefaultTyping.NON_FINAL_AND_ENUMS, "@class")
179+
.configure(DeserializationFeature.FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY, false)
182180
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
183-
.changeDefaultPropertyInclusion(value -> value.withValueInclusion(Include.NON_NULL)).build(), false);
184-
185-
//// this(new Supplier<ObjectMapper>() {
186-
// @Override
187-
// public ObjectMapper get() {
188-
//// return JsonMapper.builder()
189-
//// .findAndAddModules()
190-
//// .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
191-
//// .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
192-
//// .build();
193-
// return null;
194-
// }
195-
// }.get(), false);
196-
// this(new ObjectMapper() {
197-
//
198-
// @Override
199-
// protected DeserializationContextExt _deserializationContext(JsonParser p) {
200-
// return super._deserializationContext(p);
201-
// }
202-
//
203-
// @Override
204-
// protected TypeResolverBuilder<?> _constructDefaultTypeResolverBuilder(DefaultTyping applicability,
205-
// PolymorphicTypeValidator typeValidator) {
206-
//
207-
// return new DefaultTypeResolverBuilder(applicability, typeValidator, ) {
208-
//
209-
// public boolean useForType(JavaType type) {
210-
//
211-
// if (type.isPrimitive()) {
212-
// return false;
213-
// }
214-
//
215-
// if (flatten && (type.isTypeOrSubTypeOf(Number.class) || type.isEnumType())) {
216-
// return false;
217-
// }
218-
//
219-
// if (EVERYTHING.equals(_appliesFor)) {
220-
// return !TreeNode.class.isAssignableFrom(type.getRawClass());
221-
// }
222-
//
223-
// return super.useForType(type);
224-
// }
225-
// };
226-
// }
227-
// }.findAndRegisterModules(), flatten);
228-
// },flatten);
229-
230-
// this.typingMapper.de.activateDefaultTyping(this.typingMapper.getPolymorphicTypeValidator(),
231-
// DefaultTyping.EVERYTHING, As.PROPERTY);
232-
// this.typingMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
233-
//
234-
// if(flatten) {
235-
// this.typingMapper.disable(MapperFeature.REQUIRE_TYPE_ID_FOR_SUBTYPES);
236-
// }
237-
//
238-
// // Prevent splitting time types into arrays. E
239-
// this.typingMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
240-
// this.typingMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
241-
// this.typingMapper.setSerializationInclusion(Include.NON_NULL);
242-
// this.typingMapper.registerModule(new HashMapperModule());
181+
.changeDefaultPropertyInclusion(value -> value.withValueInclusion(Include.NON_NULL));
243182
}
244183

245184
/**
@@ -256,19 +195,14 @@ public Jackson3HashMapper(ObjectMapper mapper, boolean flatten) {
256195

257196
this.flatten = flatten;
258197
this.typingMapper = mapper;
259-
this.untypedMapper = new ObjectMapper();
260-
// this.untypedMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
261-
// this.untypedMapper.setSerializationInclusion(Include.NON_NULL);
262-
// this.untypedMapper.findAndRegisterModules();
263198
}
264199

265200
@Override
266201
@SuppressWarnings("unchecked")
267202
public Map<String, Object> toHash(Object source) {
268203

269204
JsonNode tree = this.typingMapper.valueToTree(source);
270-
271-
return this.flatten ? flattenMap(tree.properties()) : this.untypedMapper.convertValue(tree, Map.class);
205+
return this.flatten ? flattenMap(tree.properties()) : JsonMapper.shared().convertValue(tree, Map.class);
272206
}
273207

274208
@Override
@@ -279,13 +213,13 @@ public Object fromHash(Map<String, Object> hash) {
279213
if (this.flatten) {
280214

281215
Map<String, Object> unflattenedHash = doUnflatten(hash);
282-
byte[] unflattenedHashedBytes = this.untypedMapper.writeValueAsBytes(unflattenedHash);
216+
byte[] unflattenedHashedBytes = JsonMapper.shared().writeValueAsBytes(unflattenedHash);
283217
Object hashedObject = this.typingMapper.reader().forType(Object.class).readValue(unflattenedHashedBytes);
284218

285219
return hashedObject;
286220
}
287221

288-
return this.typingMapper.treeToValue(this.untypedMapper.valueToTree(hash), Object.class);
222+
return this.typingMapper.treeToValue(JsonMapper.shared().valueToTree(hash), Object.class);
289223

290224
} catch (Exception ex) {
291225
throw new MappingException(ex.getMessage(), ex);
@@ -295,8 +229,8 @@ public Object fromHash(Map<String, Object> hash) {
295229
@SuppressWarnings("unchecked")
296230
private Map<String, Object> doUnflatten(Map<String, Object> source) {
297231

298-
Map<String, Object> result = new LinkedHashMap<>();
299-
Set<String> treatSeparate = new LinkedHashSet<>();
232+
Map<String, Object> result = org.springframework.util.CollectionUtils.newLinkedHashMap(source.size());
233+
Set<String> treatSeparate = org.springframework.util.CollectionUtils.newLinkedHashSet(source.size());
300234

301235
for (Entry<String, Object> entry : source.entrySet()) {
302236

@@ -573,112 +507,4 @@ public Calendar deserialize(JsonParser p, DeserializationContext ctxt) throws Ja
573507
return utc;
574508
}
575509
}
576-
577-
// /**
578-
// * {@link JsonDeserializer} for {@link Date} objects without considering type hints.
579-
// */
580-
// private static class UntypedDateDeserializer extends JsonDeserializer<Date> {
581-
//
582-
// private final JsonDeserializer<?> delegate = new UntypedObjectDeserializer(null, null);
583-
//
584-
// @Override
585-
// public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
586-
// throws IOException {
587-
// return deserialize(p, ctxt);
588-
// }
589-
//
590-
// @Override
591-
// public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
592-
//
593-
// Object value = delegate.deserialize(p, ctxt);
594-
//
595-
// if (value instanceof Date) {
596-
// return (Date) value;
597-
// }
598-
//
599-
// try {
600-
// return ctxt.getConfig().getDateFormat().parse(value.toString());
601-
// } catch (ParseException ignore) {
602-
// return new Date(NumberUtils.parseNumber(value.toString(), Long.class));
603-
// }
604-
// }
605-
// }
606-
//
607-
// /**
608-
// * {@link JsonDeserializer} for {@link Calendar} objects without considering type hints.
609-
// */
610-
// private static class UntypedCalendarDeserializer extends JsonDeserializer<Calendar> {
611-
//
612-
// private final UntypedDateDeserializer dateDeserializer = new UntypedDateDeserializer();
613-
//
614-
// @Override
615-
// public Object deserializeWithType(JsonParser p, DeserializationContext ctxt, TypeDeserializer typeDeserializer)
616-
// throws IOException {
617-
// return deserialize(p, ctxt);
618-
// }
619-
//
620-
// @Override
621-
// public Calendar deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
622-
//
623-
// Date date = dateDeserializer.deserialize(p, ctxt);
624-
//
625-
// if (date != null) {
626-
// Calendar calendar = Calendar.getInstance();
627-
// calendar.setTime(date);
628-
// return calendar;
629-
// }
630-
//
631-
// return null;
632-
// }
633-
// }
634-
//
635-
// /**
636-
// * Untyped {@link JsonSerializer} to serialize plain values without writing JSON type hints.
637-
// *
638-
// * @param <T>
639-
// */
640-
// private static class UntypedSerializer<T> extends JsonSerializer<T> {
641-
//
642-
// private final JsonSerializer<T> delegate;
643-
//
644-
// UntypedSerializer(JsonSerializer<T> delegate) {
645-
// this.delegate = delegate;
646-
// }
647-
//
648-
// @Override
649-
// public void serializeWithType(T value, JsonGenerator jsonGenerator, SerializerProvider serializers,
650-
// TypeSerializer typeSerializer) throws IOException {
651-
//
652-
// serialize(value, jsonGenerator, serializers);
653-
// }
654-
//
655-
// @Override
656-
// public void serialize(@Nullable T value, JsonGenerator jsonGenerator, SerializerProvider serializers)
657-
// throws IOException {
658-
//
659-
// if (value != null) {
660-
// delegate.serialize(value, jsonGenerator, serializers);
661-
// } else {
662-
// serializers.defaultSerializeNull(jsonGenerator);
663-
// }
664-
// }
665-
// }
666-
//
667-
// private static class DateToTimestampSerializer extends DateSerializer {
668-
//
669-
// // Prevent splitting to array.
670-
// @Override
671-
// protected boolean _asTimestamp(SerializerProvider serializers) {
672-
// return true;
673-
// }
674-
// }
675-
//
676-
// private static class CalendarToTimestampSerializer extends CalendarSerializer {
677-
//
678-
// // Prevent splitting to array.
679-
// @Override
680-
// protected boolean _asTimestamp(SerializerProvider serializers) {
681-
// return true;
682-
// }
683-
// }
684510
}

src/test/java/org/springframework/data/redis/mapping/Jackson3HashMapperFlatteningUnitTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323

2424
import org.junit.jupiter.api.Test;
25+
import org.springframework.data.redis.hash.Jackson2HashMapper;
2526
import org.springframework.data.redis.hash.Jackson3HashMapper;
2627

2728
/**
@@ -32,7 +33,7 @@
3233
public class Jackson3HashMapperFlatteningUnitTests extends Jackson3HashMapperUnitTests {
3334

3435
Jackson3HashMapperFlatteningUnitTests() {
35-
super(new Jackson3HashMapper(true));
36+
super(new Jackson3HashMapper(Jackson3HashMapper::preconfigure, true), new Jackson2HashMapper(true));
3637
}
3738

3839
@Test // GH-2593

src/test/java/org/springframework/data/redis/mapping/Jackson3HashMapperNonFlatteningUnitTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323

2424
import org.junit.jupiter.api.Test;
25+
import org.springframework.data.redis.hash.Jackson2HashMapper;
2526
import org.springframework.data.redis.hash.Jackson3HashMapper;
2627

2728
/**
@@ -32,7 +33,7 @@
3233
public class Jackson3HashMapperNonFlatteningUnitTests extends Jackson3HashMapperUnitTests {
3334

3435
Jackson3HashMapperNonFlatteningUnitTests() {
35-
super(new Jackson3HashMapper(false));
36+
super(new Jackson3HashMapper(Jackson3HashMapper::preconfigure, false), new Jackson2HashMapper(false));
3637
}
3738

3839
@Test // GH-2593

0 commit comments

Comments
 (0)