Skip to content

Commit

Permalink
Fix #53
Browse files Browse the repository at this point in the history
  • Loading branch information
Tatu Saloranta committed Aug 8, 2019
1 parent 2a56caf commit 0209187
Show file tree
Hide file tree
Showing 19 changed files with 328 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.deser.ValueInstantiators;
import com.fasterxml.jackson.datatype.eclipsecollections.deser.pair.PairInstantiators;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.fasterxml.jackson.datatype.eclipsecollections.deser;

import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanProperty;
Expand All @@ -11,9 +14,7 @@
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.type.CollectionLikeType;
import java.io.IOException;
import java.util.Arrays;

import org.eclipse.collections.api.BooleanIterable;
import org.eclipse.collections.api.ByteIterable;
import org.eclipse.collections.api.CharIterable;
Expand All @@ -33,6 +34,8 @@
import org.eclipse.collections.api.collection.primitive.MutableShortCollection;

public abstract class BaseCollectionDeserializer<T, Intermediate> extends StdDeserializer<T> {
private static final long serialVersionUID = 2L;

protected BaseCollectionDeserializer(Class<? super T> cls) {
super(cls);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -628,26 +628,26 @@ public void primitivePairs() throws Exception {

@Test
public void twin() throws Exception {
final ObjectMapper mapper = mapperWithModule();
Object sampleOne = randomSample(Object.class);
Object sampleTwo = randomSample(Object.class);
String expectedJson = "{\"one\":" + mapperWithModule().writeValueAsString(sampleOne)
+ ",\"two\":" + mapperWithModule().writeValueAsString(sampleTwo) + "}";
String expectedJson = "{\"one\":" + mapper.writeValueAsString(sampleOne)
+ ",\"two\":" + mapper.writeValueAsString(sampleTwo) + "}";
Twin<String> twin = Tuples.twin((String) sampleOne, (String) sampleTwo);
Assert.assertEquals(expectedJson, mapperWithModule().writeValueAsString(twin));
Assert.assertEquals(twin, mapperWithModule().readValue(expectedJson, new TypeReference<Twin<String>>() {}));
Assert.assertEquals(expectedJson, mapper.writeValueAsString(twin));
Assert.assertEquals(twin, mapper.readValue(expectedJson, new TypeReference<Twin<String>>() {}));
}

@Test
public void pairTyped() throws Exception {
final ObjectMapper mapper = mapperWithModule();
ObjectIntPair<A> pair = PrimitiveTuples.pair(new B(), 5);
String json = "{\"one\":{\"@c\":\".DeserializerTest$B\"},\"two\":5}";
Assert.assertEquals(
json,
mapperWithModule().writerFor(new TypeReference<ObjectIntPair<A>>() {}).writeValueAsString(pair)
);
Assert.assertEquals(
pair,
mapperWithModule().readValue(json, new TypeReference<ObjectIntPair<A>>() {})
final String actJson = mapper.writerFor(new TypeReference<ObjectIntPair<A>>() {})
.writeValueAsString(pair);
String expJson = "{\"one\":{\"@c\":\".DeserializerTest$B\"},\"two\":5}";
Assert.assertEquals(expJson, actJson);
Assert.assertEquals(pair,
mapper.readValue(actJson, new TypeReference<ObjectIntPair<A>>() {})
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,22 @@ public JsonDeserializer<?> findCollectionDeserializer(CollectionType type,
if (ImmutableCollection.class.isAssignableFrom(raw)) {
if (ImmutableList.class.isAssignableFrom(raw)) {
return new ImmutableListDeserializer(type,
elementTypeDeserializer, elementDeserializer);
elementDeserializer, elementTypeDeserializer,
null, null);
}
if (ImmutableMultiset.class.isAssignableFrom(raw)) {
// sorted one?
if (ImmutableSortedMultiset.class.isAssignableFrom(raw)) {
/* See considerations for ImmutableSortedSet below. */
requireCollectionOfComparableElements(type, "ImmutableSortedMultiset");
return new ImmutableSortedMultisetDeserializer(type,
elementTypeDeserializer, elementDeserializer);
elementDeserializer, elementTypeDeserializer,
null, null);
}
// nah, just regular one
return new ImmutableMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
return new ImmutableMultisetDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}
if (ImmutableSet.class.isAssignableFrom(raw)) {
// sorted one?
Expand All @@ -75,40 +79,54 @@ public JsonDeserializer<?> findCollectionDeserializer(CollectionType type,
*/
requireCollectionOfComparableElements(type, "ImmutableSortedSet");
return new ImmutableSortedSetDeserializer(type,
elementTypeDeserializer, elementDeserializer);
elementDeserializer, elementTypeDeserializer,
null, null);
}
// nah, just regular one
return new ImmutableSetDeserializer(type,
elementTypeDeserializer, elementDeserializer);
elementDeserializer, elementTypeDeserializer,
null, null);
}
// TODO: make configurable (for now just default blindly to a list)
return new ImmutableListDeserializer(type, elementTypeDeserializer, elementDeserializer);
return new ImmutableListDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}

// Multi-xxx collections?
if (Multiset.class.isAssignableFrom(raw)) {
if (SortedMultiset.class.isAssignableFrom(raw)) {
if (TreeMultiset.class.isAssignableFrom(raw)) {
return new TreeMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
return new TreeMultisetDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}

// TODO: make configurable (for now just default blindly)
return new TreeMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
return new TreeMultisetDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}

// Quite a few variations...
if (LinkedHashMultiset.class.isAssignableFrom(raw)) {
return new LinkedHashMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
}
return new LinkedHashMultisetDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}
if (HashMultiset.class.isAssignableFrom(raw)) {
return new HashMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
return new HashMultisetDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}
if (EnumMultiset.class.isAssignableFrom(raw)) {
// !!! TODO
}

// TODO: make configurable (for now just default blindly)
return new HashMultisetDeserializer(type, elementTypeDeserializer, elementDeserializer);
return new HashMultisetDeserializer(type,
elementDeserializer, elementTypeDeserializer,
null, null);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
package com.fasterxml.jackson.datatype.guava.deser;

import java.io.IOException;
import java.util.Collection;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.deser.NullValueProvider;
import com.fasterxml.jackson.databind.deser.std.ContainerDeserializerBase;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.type.CollectionType;

/**
* Base class for Guava-specific collection deserializers.
*/
public abstract class GuavaCollectionDeserializer<T>
extends StdDeserializer<T>
extends ContainerDeserializerBase<T>
implements ContextualDeserializer
{
private static final long serialVersionUID = 1L;

protected final CollectionType _containerType;

/**
* Deserializer used for values contained in collection being deserialized;
* either assigned on constructor, or during resolve().
Expand All @@ -28,14 +31,20 @@ public abstract class GuavaCollectionDeserializer<T>
* is the type deserializer that can deserialize required type
* information
*/
protected final TypeDeserializer _typeDeserializerForValue;

protected GuavaCollectionDeserializer(CollectionType type,
TypeDeserializer typeDeser, JsonDeserializer<?> deser)
protected final TypeDeserializer _valueTypeDeserializer;

/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/

protected GuavaCollectionDeserializer(JavaType selfType,
JsonDeserializer<?> deser, TypeDeserializer typeDeser,
NullValueProvider nuller, Boolean unwrapSingle)
{
super(type);
_containerType = type;
_typeDeserializerForValue = typeDeser;
super(selfType, nuller, unwrapSingle);
_valueTypeDeserializer = typeDeser;
_valueDeserializer = deser;
}

Expand All @@ -44,13 +53,8 @@ protected GuavaCollectionDeserializer(CollectionType type,
* instances.
*/
public abstract GuavaCollectionDeserializer<T> withResolved(
TypeDeserializer typeDeser, JsonDeserializer<?> valueDeser);

/*
/**********************************************************
/* Validation, post-processing
/**********************************************************
*/
JsonDeserializer<?> valueDeser, TypeDeserializer typeDeser,
NullValueProvider nuller, Boolean unwrapSingle);

/**
* Method called to finalize setup of this deserializer,
Expand All @@ -61,26 +65,47 @@ public abstract GuavaCollectionDeserializer<T> withResolved(
public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
BeanProperty property) throws JsonMappingException
{
JsonDeserializer<?> deser = _valueDeserializer;
TypeDeserializer typeDeser = _typeDeserializerForValue;
if (deser == null) {
deser = ctxt.findContextualValueDeserializer(_containerType.getContentType(), property);
Boolean unwrapSingle = findFormatFeature(ctxt, property, Collection.class,
JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

JsonDeserializer<?> valueDeser = _valueDeserializer;
TypeDeserializer valueTypeDeser = _valueTypeDeserializer;
if (valueDeser == null) {
valueDeser = ctxt.findContextualValueDeserializer(_containerType.getContentType(), property);
}
if (typeDeser != null) {
typeDeser = typeDeser.forProperty(property);
if (valueTypeDeser != null) {
valueTypeDeser = valueTypeDeser.forProperty(property);
}
if (deser == _valueDeserializer && typeDeser == _typeDeserializerForValue) {
return this;

NullValueProvider nuller = findContentNullProvider(ctxt, property, valueDeser);

if ( (unwrapSingle != _unwrapSingle)
|| (nuller != _nullProvider)
|| (valueDeser != _valueDeserializer)
|| (valueTypeDeser != _valueTypeDeserializer)) {
return withResolved(valueDeser, valueTypeDeser, nuller, unwrapSingle);
}
return withResolved(typeDeser, deser);
return this;
}

/*
/**********************************************************
/* Base class method implementations
/**********************************************************
*/

@SuppressWarnings("unchecked")
@Override
public JsonDeserializer<Object> getContentDeserializer() {
return (JsonDeserializer<Object>) _valueDeserializer;
}

/*
/**********************************************************
/* Deserialization interface
/**********************************************************
*/

/**
* Base implementation that does not assume specific type
* inclusion mechanism. Sub-classes are expected to override
Expand Down
Loading

0 comments on commit 0209187

Please sign in to comment.