Skip to content

Commit

Permalink
Add support to serialize and deserialize Guava's Immutable{Double,Int…
Browse files Browse the repository at this point in the history
…,Long}Array (#86)
  • Loading branch information
albertlr authored Mar 23, 2021
1 parent e919050 commit b61a69a
Show file tree
Hide file tree
Showing 14 changed files with 458 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.fasterxml.jackson.datatype.guava;

import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes;
import com.google.common.base.Optional;
import com.google.common.collect.*;
Expand All @@ -22,8 +23,6 @@

import java.io.Serializable;

import static com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes.isAssignableFromPrimitive;

/**
* Custom deserializers module offers.
*/
Expand Down Expand Up @@ -130,7 +129,7 @@ public ValueDeserializer<?> findCollectionDeserializer(CollectionType type,
null, null);
}

return isAssignableFromPrimitive(raw)
return PrimitiveTypes.isAssignableFromPrimitive(raw)
.transform(PrimitiveTypes.Primitives::newDeserializer)
.orNull();
}
Expand Down Expand Up @@ -298,7 +297,9 @@ public ValueDeserializer<?> findBeanDeserializer(final JavaType type, Deserializ
if (type.hasRawClass(HashCode.class)) {
return HashCodeDeserializer.std;
}
return null;
return ImmutablePrimitiveTypes.isAssignableFromImmutableArray(type.getRawClass())
.transform(ImmutablePrimitiveTypes.ImmutablePrimitiveArrays::newDeserializer)
.orNull();
}

@Override
Expand All @@ -315,7 +316,8 @@ public boolean hasDeserializerFor(DeserializationConfig config, Class<?> valueTy
|| ImmutableCollection.class.isAssignableFrom(valueType)
|| ImmutableMap.class.isAssignableFrom(valueType)
|| BiMap.class.isAssignableFrom(valueType)
|| isAssignableFromPrimitive(valueType).isPresent()
|| PrimitiveTypes.isAssignableFromPrimitive(valueType).isPresent()
|| ImmutablePrimitiveTypes.isAssignableFromImmutableArray(valueType).isPresent()
;
}
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fasterxml.jackson.datatype.guava;

import com.fasterxml.jackson.databind.type.CollectionLikeType;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes;
import java.io.Serializable;
import java.util.Set;
Expand Down Expand Up @@ -95,7 +96,9 @@ public ValueSerializer<?> findSerializer(SerializationConfig config, JavaType ty
JavaType iterableType = _findDeclared(type, Iterable.class);
return new StdDelegatingSerializer(FluentConverter.instance, iterableType, null, null);
}
return null;
return ImmutablePrimitiveTypes.isAssignableFromImmutableArray(raw)
.transform(ImmutablePrimitiveTypes.ImmutablePrimitiveArrays::newSerializer)
.orNull();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,18 @@
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;

import java.util.Collection;
import java.util.List;

public abstract class BasePrimitiveCollectionDeserializer<ObjectType, PrimitiveList extends List<ObjectType>, IntermediateCollection extends Collection<ObjectType>>
/**
* Base deserializer of a primitive collection or an immutable primitive array.
*
* @param <ObjectType> The base object type. Eg: {@code Long}
* @param <PrimitiveList> The collection type that we deserialize. Eg: type of {@code Longs.asList(..)} or
* {@code ImmutableLongArray}
* @param <IntermediateContainer> The intermediate container where we collect the collection elements before returning
* it as the {@code PrimitiveList} type. Eg. in case of collections would be a
* {@code ArrayList<Long>} or in case of an immutable array would be
* {@code ImmutableLongArray.Builder}
*/
public abstract class BasePrimitiveCollectionDeserializer<ObjectType, PrimitiveList, IntermediateContainer>
extends StdDeserializer<PrimitiveList> {

protected BasePrimitiveCollectionDeserializer(Class<? extends PrimitiveList> cls, Class<? super ObjectType> itemType) {
Expand All @@ -23,16 +31,16 @@ protected BasePrimitiveCollectionDeserializer(JavaType type) {
super(type);
}

protected abstract IntermediateCollection createIntermediateCollection();
protected abstract IntermediateContainer createIntermediateCollection();

protected IntermediateCollection createIntermediateCollection(int expectedSize) {
protected IntermediateContainer createIntermediateCollection(int expectedSize) {
return createIntermediateCollection();
}

protected abstract void add(IntermediateCollection intermediateCollection, JsonParser parser,
protected abstract void add(IntermediateContainer intermediateContainer, JsonParser parser,
DeserializationContext context) throws JacksonException;

protected abstract PrimitiveList finish(IntermediateCollection intermediateCollection);
protected abstract PrimitiveList finish(IntermediateContainer intermediateContainer);

@Override
public Object deserializeWithType(JsonParser parser, DeserializationContext context,
Expand All @@ -57,7 +65,7 @@ public PrimitiveList deserialize(JsonParser parser, DeserializationContext conte

protected PrimitiveList _deserializeContents(JsonParser parser, DeserializationContext context)
throws JacksonException {
IntermediateCollection collection = createIntermediateCollection();
IntermediateContainer collection = createIntermediateCollection();

while (parser.nextToken() != JsonToken.END_ARRAY) {
add(collection, parser, context);
Expand All @@ -67,9 +75,9 @@ protected PrimitiveList _deserializeContents(JsonParser parser, DeserializationC

protected PrimitiveList _deserializeFromSingleValue(JsonParser parser, DeserializationContext ctxt)
throws JacksonException {
IntermediateCollection intermediateCollection = createIntermediateCollection();
add(intermediateCollection, parser, ctxt);
return finish(intermediateCollection);
IntermediateContainer intermediateContainer = createIntermediateCollection();
add(intermediateContainer, parser, ctxt);
return finish(intermediateContainer);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.fasterxml.jackson.datatype.guava.deser.primitives;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.datatype.guava.deser.BasePrimitiveCollectionDeserializer;

public abstract class BaseImmutableArrayDeserializer<ObjectType, ImmutablePrimitiveArray, IntermediateArrayBuilder>
extends BasePrimitiveCollectionDeserializer<ObjectType, ImmutablePrimitiveArray, IntermediateArrayBuilder> {

protected BaseImmutableArrayDeserializer(Class<? extends ImmutablePrimitiveArray> cls, Class<? super ObjectType> itemType) {
super(cls, itemType);
}

@Override
protected final void add(IntermediateArrayBuilder intermediateBuilder, JsonParser parser, DeserializationContext context) throws JacksonException {
collect(intermediateBuilder, asPrimitive(parser));
}

protected abstract void collect(IntermediateArrayBuilder intermediateBuilder, ObjectType value);

protected abstract ObjectType asPrimitive(JsonParser parser) throws JacksonException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.fasterxml.jackson.datatype.guava.deser.primitives;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.google.common.primitives.ImmutableDoubleArray;

public class ImmutableDoubleArrayDeserializer
extends BaseImmutableArrayDeserializer<Double, ImmutableDoubleArray, ImmutableDoubleArray.Builder> {
public ImmutableDoubleArrayDeserializer() {
super(ImmutablePrimitiveTypes.ImmutableDoubleArrayType, Double.class);
}

@Override
protected ImmutableDoubleArray.Builder createIntermediateCollection() {
return ImmutableDoubleArray.builder();
}

@Override
protected void collect(ImmutableDoubleArray.Builder intermediateBuilder, Double value) {
intermediateBuilder.add(value);
}

@Override
protected ImmutableDoubleArray finish(ImmutableDoubleArray.Builder builder) {
return builder.build();
}

@Override
protected Double asPrimitive(JsonParser parser) throws JacksonException {
return parser.getDoubleValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.fasterxml.jackson.datatype.guava.deser.primitives;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.google.common.primitives.ImmutableIntArray;

public class ImmutableIntArrayDeserializer
extends BaseImmutableArrayDeserializer<Integer, ImmutableIntArray, ImmutableIntArray.Builder> {
public ImmutableIntArrayDeserializer() {
super(ImmutablePrimitiveTypes.ImmutableIntArrayType, Integer.class);
}

@Override
protected ImmutableIntArray.Builder createIntermediateCollection() {
return ImmutableIntArray.builder();
}

@Override
protected void collect(ImmutableIntArray.Builder intermediateBuilder, Integer value) {
intermediateBuilder.add(value);
}

@Override
protected ImmutableIntArray finish(ImmutableIntArray.Builder builder) {
return builder.build();
}

@Override
protected Integer asPrimitive(JsonParser parser) throws JacksonException {
return parser.getIntValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.fasterxml.jackson.datatype.guava.deser.primitives;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.google.common.primitives.ImmutableLongArray;

public class ImmutableLongArrayDeserializer
extends BaseImmutableArrayDeserializer<Long, ImmutableLongArray, ImmutableLongArray.Builder> {
public ImmutableLongArrayDeserializer() {
super(ImmutablePrimitiveTypes.ImmutableLongArrayType, Long.class);
}

@Override
protected ImmutableLongArray.Builder createIntermediateCollection() {
return ImmutableLongArray.builder();
}

@Override
protected void collect(ImmutableLongArray.Builder intermediateBuilder, Long value) {
intermediateBuilder.add(value);
}

@Override
protected ImmutableLongArray finish(ImmutableLongArray.Builder builder) {
return builder.build();
}

@Override
protected Long asPrimitive(JsonParser parser) throws JacksonException {
return parser.getLongValue();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.fasterxml.jackson.datatype.guava.ser.primitives;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;

public abstract class BaseImmutableArraySerializer<ImmutableArray> extends StdSerializer<ImmutableArray> {
protected BaseImmutableArraySerializer(ImmutablePrimitiveTypes.ImmutablePrimitiveArrays immutableArrayType) {
super(immutableArrayType.type());
}

@Override
public final void serialize(ImmutableArray immutableArray, JsonGenerator gen, SerializerProvider provider) throws JacksonException {
if (immutableArray == null) {
provider.defaultSerializeNullValue(gen);
} else {
writeArray(immutableArray, gen);
}
}

protected abstract void writeArray(ImmutableArray immutableArray, JsonGenerator gen);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fasterxml.jackson.datatype.guava.ser.primitives;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.google.common.primitives.ImmutableDoubleArray;

public class ImmutableDoubleArraySerializer extends BaseImmutableArraySerializer<ImmutableDoubleArray> {

public ImmutableDoubleArraySerializer() {
super(ImmutablePrimitiveTypes.ImmutablePrimitiveArrays.DOUBLE);
}

@Override
protected void writeArray(ImmutableDoubleArray immutableArray, JsonGenerator gen) {
if (!immutableArray.isEmpty()) {
gen.writeArray(immutableArray.toArray(), 0, immutableArray.length());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fasterxml.jackson.datatype.guava.ser.primitives;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.google.common.primitives.ImmutableIntArray;

public class ImmutableIntArraySerializer extends BaseImmutableArraySerializer<ImmutableIntArray> {

public ImmutableIntArraySerializer() {
super(ImmutablePrimitiveTypes.ImmutablePrimitiveArrays.INT);
}

@Override
protected void writeArray(ImmutableIntArray immutableArray, JsonGenerator gen) {
if (!immutableArray.isEmpty()) {
gen.writeArray(immutableArray.toArray(), 0, immutableArray.length());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.fasterxml.jackson.datatype.guava.ser.primitives;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.datatype.guava.util.ImmutablePrimitiveTypes;
import com.google.common.primitives.ImmutableLongArray;

public class ImmutableLongArraySerializer extends BaseImmutableArraySerializer<ImmutableLongArray> {

public ImmutableLongArraySerializer() {
super(ImmutablePrimitiveTypes.ImmutablePrimitiveArrays.LONG);
}

@Override
protected void writeArray(ImmutableLongArray immutableArray, JsonGenerator gen) {
if (!immutableArray.isEmpty()) {
gen.writeArray(immutableArray.toArray(), 0, immutableArray.length());
}
}

}
Loading

0 comments on commit b61a69a

Please sign in to comment.