Skip to content

Commit 0209187

Browse files
author
Tatu Saloranta
committed
Fix #53
1 parent 2a56caf commit 0209187

19 files changed

+328
-156
lines changed

eclipse-collections/src/main/java/com/fasterxml/jackson/datatype/eclipsecollections/EclipseCollectionsModule.java

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.fasterxml.jackson.core.Version;
44
import com.fasterxml.jackson.databind.Module;
5-
import com.fasterxml.jackson.databind.deser.ValueInstantiators;
65
import com.fasterxml.jackson.datatype.eclipsecollections.deser.pair.PairInstantiators;
76

87
/**

eclipse-collections/src/main/java/com/fasterxml/jackson/datatype/eclipsecollections/deser/BaseCollectionDeserializer.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.fasterxml.jackson.datatype.eclipsecollections.deser;
22

3+
import java.io.IOException;
4+
import java.util.Arrays;
5+
36
import com.fasterxml.jackson.core.JsonParser;
47
import com.fasterxml.jackson.core.JsonToken;
58
import com.fasterxml.jackson.databind.BeanProperty;
@@ -11,9 +14,7 @@
1114
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
1215
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
1316
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
14-
import com.fasterxml.jackson.databind.type.CollectionLikeType;
15-
import java.io.IOException;
16-
import java.util.Arrays;
17+
1718
import org.eclipse.collections.api.BooleanIterable;
1819
import org.eclipse.collections.api.ByteIterable;
1920
import org.eclipse.collections.api.CharIterable;
@@ -33,6 +34,8 @@
3334
import org.eclipse.collections.api.collection.primitive.MutableShortCollection;
3435

3536
public abstract class BaseCollectionDeserializer<T, Intermediate> extends StdDeserializer<T> {
37+
private static final long serialVersionUID = 2L;
38+
3639
protected BaseCollectionDeserializer(Class<? super T> cls) {
3740
super(cls);
3841
}

eclipse-collections/src/test/java/com/fasterxml/jackson/datatype/eclipsecollections/DeserializerTest.java

+12-12
Original file line numberDiff line numberDiff line change
@@ -628,26 +628,26 @@ public void primitivePairs() throws Exception {
628628

629629
@Test
630630
public void twin() throws Exception {
631+
final ObjectMapper mapper = mapperWithModule();
631632
Object sampleOne = randomSample(Object.class);
632633
Object sampleTwo = randomSample(Object.class);
633-
String expectedJson = "{\"one\":" + mapperWithModule().writeValueAsString(sampleOne)
634-
+ ",\"two\":" + mapperWithModule().writeValueAsString(sampleTwo) + "}";
634+
String expectedJson = "{\"one\":" + mapper.writeValueAsString(sampleOne)
635+
+ ",\"two\":" + mapper.writeValueAsString(sampleTwo) + "}";
635636
Twin<String> twin = Tuples.twin((String) sampleOne, (String) sampleTwo);
636-
Assert.assertEquals(expectedJson, mapperWithModule().writeValueAsString(twin));
637-
Assert.assertEquals(twin, mapperWithModule().readValue(expectedJson, new TypeReference<Twin<String>>() {}));
637+
Assert.assertEquals(expectedJson, mapper.writeValueAsString(twin));
638+
Assert.assertEquals(twin, mapper.readValue(expectedJson, new TypeReference<Twin<String>>() {}));
638639
}
639640

640641
@Test
641642
public void pairTyped() throws Exception {
643+
final ObjectMapper mapper = mapperWithModule();
642644
ObjectIntPair<A> pair = PrimitiveTuples.pair(new B(), 5);
643-
String json = "{\"one\":{\"@c\":\".DeserializerTest$B\"},\"two\":5}";
644-
Assert.assertEquals(
645-
json,
646-
mapperWithModule().writerFor(new TypeReference<ObjectIntPair<A>>() {}).writeValueAsString(pair)
647-
);
648-
Assert.assertEquals(
649-
pair,
650-
mapperWithModule().readValue(json, new TypeReference<ObjectIntPair<A>>() {})
645+
final String actJson = mapper.writerFor(new TypeReference<ObjectIntPair<A>>() {})
646+
.writeValueAsString(pair);
647+
String expJson = "{\"one\":{\"@c\":\".DeserializerTest$B\"},\"two\":5}";
648+
Assert.assertEquals(expJson, actJson);
649+
Assert.assertEquals(pair,
650+
mapper.readValue(actJson, new TypeReference<ObjectIntPair<A>>() {})
651651
);
652652
}
653653

guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java

+30-12
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,22 @@ public JsonDeserializer<?> findCollectionDeserializer(CollectionType type,
5454
if (ImmutableCollection.class.isAssignableFrom(raw)) {
5555
if (ImmutableList.class.isAssignableFrom(raw)) {
5656
return new ImmutableListDeserializer(type,
57-
elementTypeDeserializer, elementDeserializer);
57+
elementDeserializer, elementTypeDeserializer,
58+
null, null);
5859
}
5960
if (ImmutableMultiset.class.isAssignableFrom(raw)) {
6061
// sorted one?
6162
if (ImmutableSortedMultiset.class.isAssignableFrom(raw)) {
6263
/* See considerations for ImmutableSortedSet below. */
6364
requireCollectionOfComparableElements(type, "ImmutableSortedMultiset");
6465
return new ImmutableSortedMultisetDeserializer(type,
65-
elementTypeDeserializer, elementDeserializer);
66+
elementDeserializer, elementTypeDeserializer,
67+
null, null);
6668
}
6769
// nah, just regular one
68-
return new ImmutableMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
70+
return new ImmutableMultisetDeserializer(type,
71+
elementDeserializer, elementTypeDeserializer,
72+
null, null);
6973
}
7074
if (ImmutableSet.class.isAssignableFrom(raw)) {
7175
// sorted one?
@@ -75,40 +79,54 @@ public JsonDeserializer<?> findCollectionDeserializer(CollectionType type,
7579
*/
7680
requireCollectionOfComparableElements(type, "ImmutableSortedSet");
7781
return new ImmutableSortedSetDeserializer(type,
78-
elementTypeDeserializer, elementDeserializer);
82+
elementDeserializer, elementTypeDeserializer,
83+
null, null);
7984
}
8085
// nah, just regular one
8186
return new ImmutableSetDeserializer(type,
82-
elementTypeDeserializer, elementDeserializer);
87+
elementDeserializer, elementTypeDeserializer,
88+
null, null);
8389
}
8490
// TODO: make configurable (for now just default blindly to a list)
85-
return new ImmutableListDeserializer(type, elementTypeDeserializer, elementDeserializer);
91+
return new ImmutableListDeserializer(type,
92+
elementDeserializer, elementTypeDeserializer,
93+
null, null);
8694
}
8795

8896
// Multi-xxx collections?
8997
if (Multiset.class.isAssignableFrom(raw)) {
9098
if (SortedMultiset.class.isAssignableFrom(raw)) {
9199
if (TreeMultiset.class.isAssignableFrom(raw)) {
92-
return new TreeMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
100+
return new TreeMultisetDeserializer(type,
101+
elementDeserializer, elementTypeDeserializer,
102+
null, null);
93103
}
94104

95105
// TODO: make configurable (for now just default blindly)
96-
return new TreeMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
106+
return new TreeMultisetDeserializer(type,
107+
elementDeserializer, elementTypeDeserializer,
108+
null, null);
97109
}
98110

99111
// Quite a few variations...
100112
if (LinkedHashMultiset.class.isAssignableFrom(raw)) {
101-
return new LinkedHashMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
102-
}
113+
return new LinkedHashMultisetDeserializer(type,
114+
elementDeserializer, elementTypeDeserializer,
115+
null, null);
116+
}
103117
if (HashMultiset.class.isAssignableFrom(raw)) {
104-
return new HashMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
118+
return new HashMultisetDeserializer(type,
119+
elementDeserializer, elementTypeDeserializer,
120+
null, null);
105121
}
106122
if (EnumMultiset.class.isAssignableFrom(raw)) {
107123
// !!! TODO
108124
}
109125

110126
// TODO: make configurable (for now just default blindly)
111-
return new HashMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
127+
return new HashMultisetDeserializer(type,
128+
elementDeserializer, elementTypeDeserializer,
129+
null, null);
112130
}
113131

114132
return null;

guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/GuavaCollectionDeserializer.java

+54-29
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
package com.fasterxml.jackson.datatype.guava.deser;
22

33
import java.io.IOException;
4+
import java.util.Collection;
45

6+
import com.fasterxml.jackson.annotation.JsonFormat;
57
import com.fasterxml.jackson.core.*;
68
import com.fasterxml.jackson.databind.*;
79
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
8-
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
10+
import com.fasterxml.jackson.databind.deser.NullValueProvider;
11+
import com.fasterxml.jackson.databind.deser.std.ContainerDeserializerBase;
912
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
10-
import com.fasterxml.jackson.databind.type.CollectionType;
1113

14+
/**
15+
* Base class for Guava-specific collection deserializers.
16+
*/
1217
public abstract class GuavaCollectionDeserializer<T>
13-
extends StdDeserializer<T>
18+
extends ContainerDeserializerBase<T>
1419
implements ContextualDeserializer
1520
{
1621
private static final long serialVersionUID = 1L;
1722

18-
protected final CollectionType _containerType;
19-
2023
/**
2124
* Deserializer used for values contained in collection being deserialized;
2225
* either assigned on constructor, or during resolve().
@@ -28,14 +31,20 @@ public abstract class GuavaCollectionDeserializer<T>
2831
* is the type deserializer that can deserialize required type
2932
* information
3033
*/
31-
protected final TypeDeserializer _typeDeserializerForValue;
32-
33-
protected GuavaCollectionDeserializer(CollectionType type,
34-
TypeDeserializer typeDeser, JsonDeserializer<?> deser)
34+
protected final TypeDeserializer _valueTypeDeserializer;
35+
36+
/*
37+
/**********************************************************
38+
/* Life-cycle
39+
/**********************************************************
40+
*/
41+
42+
protected GuavaCollectionDeserializer(JavaType selfType,
43+
JsonDeserializer<?> deser, TypeDeserializer typeDeser,
44+
NullValueProvider nuller, Boolean unwrapSingle)
3545
{
36-
super(type);
37-
_containerType = type;
38-
_typeDeserializerForValue = typeDeser;
46+
super(selfType, nuller, unwrapSingle);
47+
_valueTypeDeserializer = typeDeser;
3948
_valueDeserializer = deser;
4049
}
4150

@@ -44,13 +53,8 @@ protected GuavaCollectionDeserializer(CollectionType type,
4453
* instances.
4554
*/
4655
public abstract GuavaCollectionDeserializer<T> withResolved(
47-
TypeDeserializer typeDeser, JsonDeserializer<?> valueDeser);
48-
49-
/*
50-
/**********************************************************
51-
/* Validation, post-processing
52-
/**********************************************************
53-
*/
56+
JsonDeserializer<?> valueDeser, TypeDeserializer typeDeser,
57+
NullValueProvider nuller, Boolean unwrapSingle);
5458

5559
/**
5660
* Method called to finalize setup of this deserializer,
@@ -61,26 +65,47 @@ public abstract GuavaCollectionDeserializer<T> withResolved(
6165
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
6266
BeanProperty property) throws JsonMappingException
6367
{
64-
JsonDeserializer<?> deser = _valueDeserializer;
65-
TypeDeserializer typeDeser = _typeDeserializerForValue;
66-
if (deser == null) {
67-
deser = ctxt.findContextualValueDeserializer(_containerType.getContentType(), property);
68+
Boolean unwrapSingle = findFormatFeature(ctxt, property, Collection.class,
69+
JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
70+
71+
JsonDeserializer<?> valueDeser = _valueDeserializer;
72+
TypeDeserializer valueTypeDeser = _valueTypeDeserializer;
73+
if (valueDeser == null) {
74+
valueDeser = ctxt.findContextualValueDeserializer(_containerType.getContentType(), property);
6875
}
69-
if (typeDeser != null) {
70-
typeDeser = typeDeser.forProperty(property);
76+
if (valueTypeDeser != null) {
77+
valueTypeDeser = valueTypeDeser.forProperty(property);
7178
}
72-
if (deser == _valueDeserializer && typeDeser == _typeDeserializerForValue) {
73-
return this;
79+
80+
NullValueProvider nuller = findContentNullProvider(ctxt, property, valueDeser);
81+
82+
if ( (unwrapSingle != _unwrapSingle)
83+
|| (nuller != _nullProvider)
84+
|| (valueDeser != _valueDeserializer)
85+
|| (valueTypeDeser != _valueTypeDeserializer)) {
86+
return withResolved(valueDeser, valueTypeDeser, nuller, unwrapSingle);
7487
}
75-
return withResolved(typeDeser, deser);
88+
return this;
89+
}
90+
91+
/*
92+
/**********************************************************
93+
/* Base class method implementations
94+
/**********************************************************
95+
*/
96+
97+
@SuppressWarnings("unchecked")
98+
@Override
99+
public JsonDeserializer<Object> getContentDeserializer() {
100+
return (JsonDeserializer<Object>) _valueDeserializer;
76101
}
77102

78103
/*
79104
/**********************************************************
80105
/* Deserialization interface
81106
/**********************************************************
82107
*/
83-
108+
84109
/**
85110
* Base implementation that does not assume specific type
86111
* inclusion mechanism. Sub-classes are expected to override

0 commit comments

Comments
 (0)