From ddbc70279fded0a01f5f514fdf1ab622698289df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3-R=C3=B3bert=20Albert?= Date: Mon, 23 Mar 2020 19:14:02 +0200 Subject: [PATCH 1/5] Add support for Guava primitives (Booleans.asList(..), Bytes.asList(..), etc) --- .../datatype/guava/GuavaDeserializers.java | 1 + .../datatype/guava/GuavaSerializers.java | 16 + .../BasePrimitiveCollectionDeserializer.java | 75 +++++ ...GuavaPrimitivesCollectionDeserializer.java | 30 ++ ...oleansPrimitiveCollectionDeserializer.java | 27 ++ .../BytesPrimitiveCollectionDeserializer.java | 30 ++ .../CharsPrimitiveCollectionDeserializer.java | 27 ++ ...oublesPrimitiveCollectionDeserializer.java | 26 ++ ...FloatsPrimitiveCollectionDeserializer.java | 26 ++ .../IntsPrimitiveCollectionDeserializer.java | 26 ++ .../LongsPrimitiveCollectionDeserializer.java | 26 ++ ...ShortsPrimitiveCollectionDeserializer.java | 26 ++ .../ser/GuavaPrimitiveListSerializer.java | 148 ++++++++ .../GuavaPrimitiveIterableSerializer.java | 29 ++ .../ser/primitive/LongIterableSerializer.java | 31 ++ .../PrimitiveIterableSerializer.java | 75 +++++ .../datatype/guava/util/PrimitiveTypes.java | 152 +++++++++ .../datatype/guava/TestPrimitives.java | 317 ++++++++++++++++++ 18 files changed, 1088 insertions(+) create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java create mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/util/PrimitiveTypes.java create mode 100644 guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java index dfe2498f..2df1b793 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java @@ -1,5 +1,6 @@ package com.fasterxml.jackson.datatype.guava; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; import com.google.common.base.Optional; import com.google.common.collect.*; import com.google.common.hash.HashCode; diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java index 3c99d8be..af9f2e13 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java @@ -4,17 +4,20 @@ import java.util.Set; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonFormat.Value; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.ser.Serializers; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import com.fasterxml.jackson.databind.type.CollectionLikeType; import com.fasterxml.jackson.databind.type.MapLikeType; import com.fasterxml.jackson.databind.type.ReferenceType; import com.fasterxml.jackson.databind.ser.std.StdDelegatingSerializer; import com.fasterxml.jackson.databind.util.StdConverter; import com.fasterxml.jackson.datatype.guava.ser.RangeSetSerializer; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; import com.google.common.base.Optional; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilderSpec; @@ -112,6 +115,19 @@ public JsonSerializer findMapLikeSerializer(SerializationConfig config, return null; } + @Override + public JsonSerializer findCollectionLikeSerializer(SerializationConfig config, CollectionLikeType type, + BeanDescription beanDesc, Value formatOverrides, TypeSerializer elementTypeSerializer, + JsonSerializer elementValueSerializer) + { + Class raw = type.getRawClass(); + Optional> primitiveSerializer = PrimitiveTypes.isAssignableFromPrimitive(raw) + .transform((ignore) -> ToStringSerializer.instance); + + return primitiveSerializer + .or(() -> super.findCollectionLikeSerializer(config, type, beanDesc, formatOverrides, elementTypeSerializer, elementValueSerializer)); + } + private JavaType _findDeclared(JavaType subtype, Class target) { JavaType decl = subtype.findSuperType(target); if (decl == null) { // should never happen but diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..1172441e --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java @@ -0,0 +1,75 @@ +package com.fasterxml.jackson.datatype.guava.deser; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public abstract class BasePrimitiveCollectionDeserializer, IntermediateCollection extends Collection> + extends StdDeserializer { + + protected BasePrimitiveCollectionDeserializer(Class cls, Class itemType) { + super(cls); + } + + protected BasePrimitiveCollectionDeserializer(JavaType type) { + super(type); + } + + protected abstract IntermediateCollection createIntermediateCollection(); + + protected IntermediateCollection createIntermediateCollection(int expectedSize) { + return createIntermediateCollection(); + } + + protected abstract void add(IntermediateCollection intermediateCollection, JsonParser parser, + DeserializationContext context) throws IOException; + + protected abstract PrimitiveList finish(IntermediateCollection intermediateCollection); + + @Override + public Object deserializeWithType(JsonParser parser, DeserializationContext context, + TypeDeserializer typeDeserializer) throws IOException { + return typeDeserializer.deserializeTypedFromArray(parser, context); + } + + @SuppressWarnings("unchecked") + @Override + public PrimitiveList deserialize(JsonParser parser, DeserializationContext context) + throws IOException { + // Should usually point to START_ARRAY + if (parser.isExpectedStartArrayToken()) { + return _deserializeContents(parser, context); + } + // But may support implicit arrays from single values? + if (context.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) { + return _deserializeFromSingleValue(parser, context); + } + return (PrimitiveList) context.handleUnexpectedToken(getValueType(context), parser); + } + + protected PrimitiveList _deserializeContents(JsonParser parser, DeserializationContext context) + throws IOException { + IntermediateCollection collection = createIntermediateCollection(); + + while (parser.nextToken() != JsonToken.END_ARRAY) { + add(collection, parser, context); + } + return finish(collection); + } + + protected PrimitiveList _deserializeFromSingleValue(JsonParser parser, DeserializationContext ctxt) + throws IOException { + IntermediateCollection intermediateCollection = createIntermediateCollection(); + add(intermediateCollection, parser, ctxt); + return finish(intermediateCollection); + } + +} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java new file mode 100644 index 00000000..d37b92e4 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java @@ -0,0 +1,30 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.datatype.guava.deser.BasePrimitiveCollectionDeserializer; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public abstract class BaseGuavaPrimitivesCollectionDeserializer, IntermediateCollection extends Collection> + extends BasePrimitiveCollectionDeserializer { + + protected BaseGuavaPrimitivesCollectionDeserializer(Class cls, Class itemType) { + super(cls, itemType); + } + + @Override + protected IntermediateCollection createIntermediateCollection() { + return (IntermediateCollection) new ArrayList(); + } + + @Override + protected void add(IntermediateCollection intermediateCollection, JsonParser parser, DeserializationContext context) throws IOException { + intermediateCollection.add(asPrimitive(parser)); + } + + protected abstract ObjectType asPrimitive(JsonParser parser) throws IOException; +} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..bfa51ce2 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java @@ -0,0 +1,27 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Booleans; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class BooleansPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + + public BooleansPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.BooleansType, Boolean.class); + } + + @Override + protected Boolean asPrimitive(JsonParser parser) throws IOException { + return parser.getBooleanValue(); + } + + @Override + protected List finish(Collection booleans) { + return Booleans.asList(Booleans.toArray(booleans)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..6baf608c --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java @@ -0,0 +1,30 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.datatype.guava.deser.BasePrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Booleans; +import com.google.common.primitives.Bytes; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class BytesPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public BytesPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.BytesType, Byte.class); + } + + @Override + protected Byte asPrimitive(JsonParser parser) throws IOException { + return parser.getByteValue(); + } + + @Override + protected List finish(Collection bytes) { + return Bytes.asList(Bytes.toArray(bytes)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..c60a6d96 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java @@ -0,0 +1,27 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Bytes; +import com.google.common.primitives.Chars; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class CharsPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public CharsPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.CharsType, Character.class); + } + + @Override + protected Character asPrimitive(JsonParser parser) throws IOException { + return (char) parser.getValueAsString().toCharArray()[0]; + } + + @Override + protected List finish(Collection characters) { + return Chars.asList(Chars.toArray(characters)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..9aa40f87 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java @@ -0,0 +1,26 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Doubles; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class DoublesPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public DoublesPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.DoublesType, Double.class); + } + + @Override + protected Double asPrimitive(JsonParser parser) throws IOException { + return parser.getDoubleValue(); + } + + @Override + protected List finish(Collection doubles) { + return Doubles.asList(Doubles.toArray(doubles)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..45db9f25 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java @@ -0,0 +1,26 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Floats; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class FloatsPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public FloatsPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.FloatsType, Float.class); + } + + @Override + protected Float asPrimitive(JsonParser parser) throws IOException { + return parser.getFloatValue(); + } + + @Override + protected List finish(Collection floats) { + return Floats.asList(Floats.toArray(floats)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..b873eb3c --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java @@ -0,0 +1,26 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Ints; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class IntsPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public IntsPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.IntsType, Integer.class); + } + + @Override + protected Integer asPrimitive(JsonParser parser) throws IOException { + return parser.getIntValue(); + } + + @Override + protected List finish(Collection integers) { + return Ints.asList(Ints.toArray(integers)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..a6724a5d --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java @@ -0,0 +1,26 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Longs; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class LongsPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public LongsPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.LongsType, Long.class); + } + + @Override + protected Long asPrimitive(JsonParser parser) throws IOException { + return parser.getLongValue(); + } + + @Override + protected List finish(Collection longs) { + return Longs.asList(Longs.toArray(longs)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java new file mode 100644 index 00000000..81a3a6c7 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java @@ -0,0 +1,26 @@ +package com.fasterxml.jackson.datatype.guava.deser.primitives; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Shorts; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; + +public class ShortsPrimitiveCollectionDeserializer + extends BaseGuavaPrimitivesCollectionDeserializer, Collection> { + public ShortsPrimitiveCollectionDeserializer() { + super(PrimitiveTypes.ShortsType, Short.class); + } + + @Override + protected Short asPrimitive(JsonParser parser) throws IOException { + return parser.getShortValue(); + } + + @Override + protected List finish(Collection shorts) { + return Shorts.asList(Shorts.toArray(shorts)); + } +} \ No newline at end of file diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java new file mode 100644 index 00000000..0bff4db4 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java @@ -0,0 +1,148 @@ +//package com.fasterxml.jackson.datatype.guava.ser; +// +//import com.fasterxml.jackson.core.JsonGenerator; +//import com.fasterxml.jackson.databind.BeanProperty; +//import com.fasterxml.jackson.databind.JavaType; +//import com.fasterxml.jackson.databind.JsonMappingException; +//import com.fasterxml.jackson.databind.JsonSerializer; +//import com.fasterxml.jackson.databind.SerializerProvider; +//import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; +//import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +//import com.fasterxml.jackson.databind.ser.ContainerSerializer; +//import com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer; +//import com.fasterxml.jackson.databind.type.CollectionLikeType; +// +//import java.io.IOException; +// +///** +// * Note: this implementation does not yet properly handle all +// * polymorphic cases +// */ +//public class GuavaPrimitiveListSerializer +// extends ContainerSerializer> +//{ +// protected final JavaType _contentType; +// +// /** +// * We will basically just delegate serialization to the standard +// * Object[] serializer; as we can not sub-class it. +// */ +// protected final ObjectArraySerializer _delegate; +// +// /* +// /********************************************************************** +// /* Life-cycle +// /********************************************************************** +// */ +// +// public ObjectContainerSerializer(CollectionLikeType containerType, +// ObjectArraySerializer delegate) +// { +// // not sure if we can claim it is "object"... could be String, wrapper types etc: +// super(containerType, "any"); +// _contentType = containerType.getContentType(); +// _delegate = delegate; +// } +// +// protected ObjectContainerSerializer(ObjectContainerSerializer base, +// ObjectArraySerializer delegate) +// { +// super(base); +// _contentType = base._contentType; +// _delegate = delegate; +// } +// +// protected ObjectContainerSerializer withDelegate(ObjectArraySerializer newDelegate) { +// return (newDelegate == _delegate) ? this : new ObjectContainerSerializer(this, newDelegate); +// } +// +// @Override +// protected ContainerSerializer _withValueTypeSerializer(TypeSerializer vts) { +// ObjectArraySerializer ser = (ObjectArraySerializer) _delegate._withValueTypeSerializer(vts); +// if (ser == _delegate) { +// return this; +// } +// return withDelegate(ser); +// } +// +// /* +// /********************************************************************** +// /* Schema support +// /********************************************************************** +// */ +// +// @Override +// public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) +// throws JsonMappingException +// { +// _delegate.acceptJsonFormatVisitor(visitor, typeHint); +// } +// +// /* +// /********************************************************************** +// /* Overridden accessors +// /********************************************************************** +// */ +// +// @Override +// public JsonSerializer getContentSerializer() { +// return _delegate.getContentSerializer(); +// } +// +// @Override +// public boolean hasSingleElement(ObjectContainer value) { +// return value.size() == 1; +// } +// +// @Override +// public boolean isEmpty(SerializerProvider provider, ObjectContainer value) { +// // 27-Nov-2015, tatu: Not up to 2.7 full specs (wrt value vs content emptiness) +// // but better than we had before +// return value.isEmpty(); +// } +// +// @Override +// public JavaType getContentType() { +// return _contentType; +// } +// +// /* +// /********************************************************************** +// /* Contextualization +// /********************************************************************** +// */ +// +// @Override +// public JsonSerializer createContextual(SerializerProvider prov, +// BeanProperty property) throws JsonMappingException { +// return withDelegate((ObjectArraySerializer) _delegate.createContextual(prov, property)); +// } +// +// /* +// /********************************************************************** +// /* Serialization +// /********************************************************************** +// */ +// +// @Override +// public void serialize(ObjectContainer value, JsonGenerator gen, SerializerProvider provider) +// throws IOException +// { +// _delegate.serialize(value.toArray(), gen, provider); +// } +// +// @Override +// public void serializeWithType(ObjectContainer value, JsonGenerator gen, SerializerProvider provider, +// TypeSerializer typeSer) +// throws IOException +// { +// _delegate.serializeWithType(value.toArray(), gen, provider, typeSer); +// } +// +// @Override +// protected void serializeContents(ObjectContainer value, JsonGenerator gen, SerializerProvider provider) +// throws IOException +// { +// throw new IllegalStateException(); +// } +//} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java new file mode 100644 index 00000000..810fc8ea --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java @@ -0,0 +1,29 @@ +//package com.fasterxml.jackson.datatype.guava.ser.primitive; +// +//import com.fasterxml.jackson.databind.BeanProperty; +//import com.fasterxml.jackson.databind.JavaType; +//import com.fasterxml.jackson.databind.SerializerProvider; +// +//import java.util.List; +// +//public abstract class GuavaPrimitiveIterableSerializer +// extends PrimitiveIterableSerializer { +// +// protected GuavaPrimitiveIterableSerializer(Class type, JavaType elementType, +// BeanProperty property, Boolean unwrapSingle) { +// super(type, elementType, property, unwrapSingle); +// } +// +// @Override +// public boolean isEmpty(SerializerProvider prov, C value) { +// return value.isEmpty(); +// } +// +// @Override +// public boolean hasSingleElement(C value) { +// if (value != null) { +// return value.size() == 1; +// } +// return false; +// } +//} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java new file mode 100644 index 00000000..64a191b3 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java @@ -0,0 +1,31 @@ +//package com.fasterxml.jackson.datatype.guava.ser.primitive; +// +//import com.fasterxml.jackson.core.JsonGenerator; +//import com.fasterxml.jackson.databind.BeanProperty; +//import com.fasterxml.jackson.databind.JavaType; +//import com.fasterxml.jackson.databind.type.TypeFactory; +//import org.eclipse.collections.api.LongIterable; +//import org.eclipse.collections.api.iterator.LongIterator; +// +//import java.io.IOException; +// +//public final class LongIterableSerializer extends GuavaPrimitiveIterableSerializer { +// private static final JavaType ELEMENT_TYPE = TypeFactory.defaultInstance().constructType(long.class); +// +// public LongIterableSerializer(BeanProperty property, Boolean unwrapSingle) { +// super(LongIterable.class, ELEMENT_TYPE, property, unwrapSingle); +// } +// +// @Override +// protected LongIterableSerializer withResolved(BeanProperty property, Boolean unwrapSingle) { +// return new LongIterableSerializer(property, unwrapSingle); +// } +// +// @Override +// protected void serializeContents(LongIterable value, JsonGenerator gen) throws IOException { +// LongIterator iterator = value.longIterator(); +// while (iterator.hasNext()) { +// gen.writeNumber(iterator.next()); +// } +// } +//} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java new file mode 100644 index 00000000..26469d64 --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java @@ -0,0 +1,75 @@ +//package com.fasterxml.jackson.datatype.guava.ser.primitive; +// +//import com.fasterxml.jackson.core.JsonGenerator; +//import com.fasterxml.jackson.core.JsonToken; +//import com.fasterxml.jackson.core.type.WritableTypeId; +//import com.fasterxml.jackson.databind.BeanProperty; +//import com.fasterxml.jackson.databind.JavaType; +//import com.fasterxml.jackson.databind.JsonSerializer; +//import com.fasterxml.jackson.databind.SerializationFeature; +//import com.fasterxml.jackson.databind.SerializerProvider; +//import com.fasterxml.jackson.databind.jsontype.TypeSerializer; +//import com.fasterxml.jackson.databind.ser.ContainerSerializer; +// +//import java.io.IOException; +// +//public abstract class PrimitiveIterableSerializer extends ContainerSerializer { +// protected final JavaType _elementObjectType; +// protected final JavaType _elementPrimitiveType; +// protected final BeanProperty _property; +// protected final Boolean _unwrapSingle; +// +// protected PrimitiveIterableSerializer(Class type, JavaType elementType, +// BeanProperty property, Boolean unwrapSingle +// ) { +// super(type); +// _elementType = elementType; +// _property = property; +// _unwrapSingle = unwrapSingle; +// } +// +// protected abstract PrimitiveIterableSerializer withResolved(BeanProperty property, Boolean unwrapSingle); +// +// @Override +// public JavaType getContentType() { +// return _elementType; +// } +// +// @Override +// public JsonSerializer getContentSerializer() { +// return null; +// } +// +// @Override +// protected ContainerSerializer _withValueTypeSerializer(TypeSerializer vts) { +// // no type info for primitives +// return this; +// } +// +// @Override +// public final void serialize(C value, JsonGenerator gen, SerializerProvider ctxt) throws IOException { +// if (((_unwrapSingle == null) && +// ctxt.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) +// || (Boolean.TRUE.equals(_unwrapSingle))) { +// if (hasSingleElement(value)) { +// serializeContents(value, gen); +// return; +// } +// } +// gen.writeStartArray(); +// serializeContents(value, gen); +// gen.writeEndArray(); +// } +// +// @Override +// public void serializeWithType(C value, JsonGenerator g, SerializerProvider ctxt, TypeSerializer typeSer) +// throws IOException { +// g.setCurrentValue(value); +// WritableTypeId typeIdDef = typeSer.writeTypePrefix(g, ctxt, typeSer.typeId(value, JsonToken.START_ARRAY)); +// serializeContents(value, g); +// typeSer.writeTypeSuffix(g, ctxt, typeIdDef); +// } +// +// protected abstract void serializeContents(C value, JsonGenerator gen) throws IOException; +//} +// diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/util/PrimitiveTypes.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/util/PrimitiveTypes.java new file mode 100644 index 00000000..f9a01cdd --- /dev/null +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/util/PrimitiveTypes.java @@ -0,0 +1,152 @@ +package com.fasterxml.jackson.datatype.guava.util; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.datatype.guava.deser.BasePrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.BooleansPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.BytesPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.CharsPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.DoublesPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.FloatsPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.IntsPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.LongsPrimitiveCollectionDeserializer; +import com.fasterxml.jackson.datatype.guava.deser.primitives.ShortsPrimitiveCollectionDeserializer; +import com.google.common.base.Optional; +import com.google.common.primitives.Booleans; +import com.google.common.primitives.Bytes; +import com.google.common.primitives.Chars; +import com.google.common.primitives.Doubles; +import com.google.common.primitives.Floats; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import com.google.common.primitives.Shorts; + +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.List; +import java.util.function.Supplier; + +/** + * Utility class to cover all primitive types + * + * @author robert@albertlr.ro + */ +public class PrimitiveTypes { + + /** An enum with all the primitives */ + public enum Primitives { + BOOLEAN(BooleansType, boolean.class, Boolean.class, () -> new BooleansPrimitiveCollectionDeserializer()), + BYTE(BytesType, byte.class, Byte.class, () -> new BytesPrimitiveCollectionDeserializer()), + CHAR(CharsType, char.class, Character.class, () -> new CharsPrimitiveCollectionDeserializer()), + DOUBLE(DoublesType, double.class, Double.class, () -> new DoublesPrimitiveCollectionDeserializer()), + FLOAT(FloatsType, float.class, Float.class, () -> new FloatsPrimitiveCollectionDeserializer()), + INT(IntsType, int.class, Integer.class, () -> new IntsPrimitiveCollectionDeserializer()), + LONG(LongsType, long.class, Long.class, () -> new LongsPrimitiveCollectionDeserializer()), + SHORT(ShortsType, short.class, Short.class, () -> new ShortsPrimitiveCollectionDeserializer()); + + private final Class> type; + private final Class primitiveType; + private final Class objectType; + private final Supplier deserializerFactory; + + private Primitives(Class> type, Class primitiveType, Class objectType, Supplier deserializerFactory) { + this.type = type; + this.primitiveType = primitiveType; + this.objectType = objectType; + this.deserializerFactory = deserializerFactory; + } + + public Class> type() { + return (Class>) type; + } + + public Class primitiveType() { + return primitiveType; + } + + public Class objectType() { + return (Class) objectType; + } + + public BasePrimitiveCollectionDeserializer, Collection> newDeserializer() { + return deserializerFactory.get(); + } + } + + public static Optional isAssignableFromPrimitive(Class valueType) { + for (PrimitiveTypes.Primitives primitive : PrimitiveTypes.Primitives.values()) { + if (primitive.type().isAssignableFrom(valueType)) { + return Optional.of(primitive); + } + } + return Optional.absent(); + } + + /** Type of list returned by {@link Booleans#asList(boolean...)} */ + public static final Class> BooleansType; + /** Type of list returned by {@link Bytes#asList(byte...)} */ + public static final Class> BytesType; + /** Type of list returned by {@link Chars#asList(char...)} */ + public static final Class> CharsType; + /** Type of list returned by {@link Doubles#asList(double...)} */ + public static final Class> DoublesType; + /** Type of list returned by {@link Floats#asList(float...)} */ + public static final Class> FloatsType; + /** Type of list returned by {@link Ints#asList(int...)} */ + public static final Class> IntsType; + /** Type of list returned by {@link Longs#asList(long...)} */ + public static final Class> LongsType; + /** Type of list returned by {@link Shorts#asList(short...)} */ + public static final Class> ShortsType; + + static { + /* + * get the actual name of the underlying private class by creating a dummy list .. and than get its name + */ + + BooleansType = (Class>) Booleans.asList(true, false).getClass(); + BytesType = (Class>) Bytes.asList((byte) 1, (byte) 2).getClass(); + CharsType = (Class>) Chars.asList((char) 1, (char) 2).getClass(); + DoublesType = (Class>) Doubles.asList(1d, 2d).getClass(); + FloatsType = (Class>) Floats.asList((float) 1d, (float) 2d).getClass(); + IntsType = (Class>) Ints.asList(0, 1).getClass(); + LongsType = (Class>) Longs.asList(0L, 1L).getClass(); + ShortsType = (Class>) Shorts.asList((short) 0, (short) 1).getClass(); + } + + public static final TypeReference> BooleansTypeReference = typeRefOf(BooleansType); + public static final TypeReference> BytesTypeReference = typeRefOf(BytesType); + public static final TypeReference> CharsTypeReference = typeRefOf(CharsType); + public static final TypeReference> DoublesTypeReference = typeRefOf(DoublesType); + public static final TypeReference> FloatsTypeReference = typeRefOf(FloatsType); + public static final TypeReference> IntsTypeReference = typeRefOf(IntsType); + public static final TypeReference> LongsTypeReference = typeRefOf(LongsType); + public static final TypeReference> ShortsTypeReference = typeRefOf(ShortsType); + + public static final String BooleansTypeName = BooleansType.getName(); + public static final String BytesTypeName = BytesType.getName(); + public static final String CharsTypeName = CharsType.getName(); + public static final String DoublesTypeName = DoublesType.getName(); + public static final String FloatsTypeName = FloatsType.getName(); + public static final String IntsTypeName = IntsType.getName(); + public static final String LongsTypeName = LongsType.getName(); + public static final String ShortsTypeName = ShortsType.getName(); + + + private static TypeReference typeRefOf(Type type) { + return new PrimitiveTypeReference<>(type); + } + + private static class PrimitiveTypeReference extends TypeReference { + private final Type primitiveType; + + private PrimitiveTypeReference(Type primitiveType) { + this.primitiveType = primitiveType; + } + + @Override + public Type getType() { + return primitiveType; + } + } + +} diff --git a/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java b/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java new file mode 100644 index 00000000..1bb34953 --- /dev/null +++ b/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java @@ -0,0 +1,317 @@ +package com.fasterxml.jackson.datatype.guava; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; +import com.google.common.primitives.Booleans; +import com.google.common.primitives.Bytes; +import com.google.common.primitives.Chars; +import com.google.common.primitives.Doubles; +import com.google.common.primitives.Floats; +import com.google.common.primitives.ImmutableDoubleArray; +import com.google.common.primitives.ImmutableIntArray; +import com.google.common.primitives.ImmutableLongArray; +import com.google.common.primitives.Ints; +import com.google.common.primitives.Longs; +import com.google.common.primitives.Shorts; +import com.google.common.primitives.SignedBytes; +import com.google.common.primitives.UnsignedBytes; +import com.google.common.primitives.UnsignedInteger; +import com.google.common.primitives.UnsignedInts; +import com.google.common.primitives.UnsignedLong; +import com.google.common.primitives.UnsignedLongs; + +import java.util.Collections; +import java.util.List; + +/** + * Unit tests for verifying that various primitive types + * (like {@link Booleans}, {@link Bytes},{@link Chars},{@link Doubles},{@link Floats},{@link ImmutableDoubleArray}, + * {@link ImmutableIntArray},{@link ImmutableLongArray},{@link Ints},{@link Longs},{@link Shorts}, + * {@link SignedBytes},{@link UnsignedBytes},{@link UnsignedInteger},{@link UnsignedInts},{@link UnsignedLong}, + * and {@link UnsignedLongs}) + * work as expected. + * + * @author robert@albertlr.ro + */ +public class TestPrimitives extends ModuleTestBase { + private final ObjectMapper MAPPER = mapperWithModule(); + + // For polymorphic cases need to allow bit more access + private final ObjectMapper POLY_MAPPER = builderWithModule() + .polymorphicTypeValidator(BasicPolymorphicTypeValidator + .builder() + .allowIfBaseType(Object.class) + .build() + ).build(); + + private final ObjectMapper SINGLE_MAPPER = builderWithModule() + .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) + .build(); + + static class PolymorphicHolder { + @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) + public Object value; + + public PolymorphicHolder() { + } + + public PolymorphicHolder(Object v) { + value = v; + } + } + + /********************************************************************** + * Unit tests for verifying handling in absence of module registration + /***********************************************************************/ + + /** + * Immutable types can actually be serialized as regular collections, without + * problems. + */ + public void testWithoutSerializers() throws Exception { + assertEquals("[true,false,true]", MAPPER.writeValueAsString(Booleans.asList(true, false, true))); + assertEquals("[1,2,3]", MAPPER.writeValueAsString(Bytes.asList((byte) 1, (byte) 2, (byte) 3))); + assertEquals("[\"a\",\"b\",\"c\"]", MAPPER.writeValueAsString(Chars.asList('a', 'b', 'c'))); + assertEquals("[1.5,2.5,3.5]", MAPPER.writeValueAsString(Doubles.asList(1.5, 2.5, 3.5))); + assertEquals("[1.5,2.5,3.5]", MAPPER.writeValueAsString(Floats.asList((float) 1.5, (float) 2.5, (float) 3.5))); + assertEquals("[1,2,3]", MAPPER.writeValueAsString(Ints.asList(1, 2, 3))); + assertEquals("[1,2,3]", MAPPER.writeValueAsString(Longs.asList(1L, 2L, 3L))); + assertEquals("[1,2,3]", MAPPER.writeValueAsString(Shorts.asList((short) 1, (short) 2, (short) 3))); + } + + /** + * Deserialization will fail, however. + */ + public void testWithoutDeserializers() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + try { + mapper.readValue("[true,false,true]", PrimitiveTypes.BooleansTypeReference); + fail("Expected failure for missing deserializer"); + } catch (JsonMappingException e) { + verifyException(e, PrimitiveTypes.BooleansTypeName); + } + + try { + mapper.readValue("[1,2,3]", PrimitiveTypes.IntsTypeReference); + fail("Expected failure for missing deserializer"); + } catch (JsonMappingException e) { + verifyException(e, PrimitiveTypes.IntsTypeName); + } + + try { + mapper.readValue("[1,2,3]", PrimitiveTypes.LongsTypeReference); + fail("Expected failure for missing deserializer"); + } catch (JsonMappingException e) { + verifyException(e, PrimitiveTypes.LongsTypeName); + } + + } + + /********************************************************************** + * Basic tests for actual registered module + /***********************************************************************/ + + public void testBooleans() throws Exception { + List list = MAPPER.readValue("[true,false,true]", PrimitiveTypes.BooleansTypeReference); + assertEquals(3, list.size()); + assertEquals(Boolean.TRUE, list.get(0)); + assertEquals(Boolean.FALSE, list.get(1)); + assertEquals(Boolean.TRUE, list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.BooleansTypeName)); + } + + public void testBooleansFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("true", PrimitiveTypes.BooleansTypeReference); + assertEquals(1, list.size()); + assertEquals(Boolean.TRUE, list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.BooleansTypeName)); + } + + public void testBytes() throws Exception { + List list = MAPPER.readValue("[1,2,3]", PrimitiveTypes.BytesTypeReference); + assertEquals(3, list.size()); + assertEquals(Byte.valueOf((byte) 1), list.get(0)); + assertEquals(Byte.valueOf((byte) 2), list.get(1)); + assertEquals(Byte.valueOf((byte) 3), list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.BytesTypeName)); + } + + public void testBytesFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("1", PrimitiveTypes.BytesTypeReference); + assertEquals(1, list.size()); + assertEquals(Byte.valueOf((byte) 1), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.BytesTypeName)); + } + + public void testChars() throws Exception { + List list = MAPPER.readValue("[\"\\u0001\",\"\\u0002\",\"\\u0003\",\"a\",\"b\",\"c\",\"D\",\"E\"]", PrimitiveTypes.CharsTypeReference); + assertEquals(8, list.size()); + assertEquals(Character.valueOf((char) 1), list.get(0)); + assertEquals(Character.valueOf((char) 2), list.get(1)); + assertEquals(Character.valueOf((char) 3), list.get(2)); + assertEquals(Character.valueOf('a'), list.get(3)); + assertEquals(Character.valueOf('b'), list.get(4)); + assertEquals(Character.valueOf('c'), list.get(5)); + assertEquals(Character.valueOf('D'), list.get(6)); + assertEquals(Character.valueOf('E'), list.get(7)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.CharsTypeName)); + } + + public void testCharsFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("\"a\"", PrimitiveTypes.CharsType); + assertEquals(1, list.size()); + assertEquals(Character.valueOf('a'), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.CharsTypeName)); + } + + public void testFloats() throws Exception { + List list = MAPPER.readValue("[1.5,2.5,3.5]", PrimitiveTypes.FloatsTypeReference); + assertEquals(3, list.size()); + assertEquals(Float.valueOf((float) 1.5), list.get(0)); + assertEquals(Float.valueOf((float) 2.5), list.get(1)); + assertEquals(Float.valueOf((float) 3.5), list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.FloatsTypeName)); + } + + public void testFloatsFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("1", PrimitiveTypes.FloatsType); + assertEquals(1, list.size()); + assertEquals(Float.valueOf(1), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.FloatsTypeName)); + } + + public void testDoubles() throws Exception { + List list = MAPPER.readValue("[1.5,2.5,3.5]", PrimitiveTypes.DoublesTypeReference); + assertEquals(3, list.size()); + assertEquals(Double.valueOf(1.5), list.get(0)); + assertEquals(Double.valueOf(2.5), list.get(1)); + assertEquals(Double.valueOf(3.5), list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.DoublesTypeName)); + } + + public void testDoublesFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("1", PrimitiveTypes.DoublesType); + assertEquals(1, list.size()); + assertEquals(Double.valueOf(1d), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.DoublesTypeName)); + } + + public void testInts() throws Exception { + List list = MAPPER.readValue("[1,2,3]", PrimitiveTypes.IntsTypeReference); + assertEquals(3, list.size()); + assertEquals(Integer.valueOf(1), list.get(0)); + assertEquals(Integer.valueOf(2), list.get(1)); + assertEquals(Integer.valueOf(3), list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.IntsTypeName)); + } + + public void testIntsFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("1", PrimitiveTypes.IntsTypeReference); + assertEquals(1, list.size()); + assertEquals(Integer.valueOf(1), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.IntsTypeName)); + } + + public void testLongs() throws Exception { + List list = MAPPER.readValue("[1,2,3]", PrimitiveTypes.LongsTypeReference); + assertEquals(3, list.size()); + assertEquals(Long.valueOf(1), list.get(0)); + assertEquals(Long.valueOf(2), list.get(1)); + assertEquals(Long.valueOf(3), list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.LongsTypeName)); + } + + public void testLongsFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("1", PrimitiveTypes.LongsTypeReference); + assertEquals(1, list.size()); + assertEquals(Long.valueOf(1), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.LongsTypeName)); + } + + public void testShorts() throws Exception { + List list = MAPPER.readValue("[1,2,3]", PrimitiveTypes.ShortsTypeReference); + assertEquals(3, list.size()); + assertEquals(Short.valueOf((short) 1), list.get(0)); + assertEquals(Short.valueOf((short) 2), list.get(1)); + assertEquals(Short.valueOf((short) 3), list.get(2)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.ShortsTypeName)); + } + + public void testShortsFromSingle() throws Exception { + List list = SINGLE_MAPPER.readValue("1", PrimitiveTypes.ShortsTypeReference); + assertEquals(1, list.size()); + assertEquals(Short.valueOf((short) 1), list.get(0)); + assertTrue(list.getClass().getName().equals(PrimitiveTypes.ShortsTypeName)); + } + + /* + /********************************************************************** + /* Polymorphic handling + /********************************************************************** + */ + + public void testTypedInts() throws Exception { + PolymorphicHolder h; + String json; + PolymorphicHolder result; + + // First, with one entry + List ints = Ints.asList(1); + h = new PolymorphicHolder(ints); + json = POLY_MAPPER.writeValueAsString(h); + + // so far so good. and back? + result = POLY_MAPPER.readValue(json, PolymorphicHolder.class); + assertNotNull(result.value); + if (!(PrimitiveTypes.IntsType.isInstance(result.value))) { + fail("Expected " + PrimitiveTypes.IntsTypeName + ", got " + result.value.getClass()); + } + assertEquals(1, ((List) result.value).size()); + + // and then an empty version: + List emptyList = Ints.asList(new int[0]); + h = new PolymorphicHolder(emptyList); + json = POLY_MAPPER.writeValueAsString(h); + result = POLY_MAPPER.readValue(json, PolymorphicHolder.class); + assertNotNull(result.value); + if (!(Collections.emptyList().getClass().isInstance(result.value))) { + fail("Expected " + Collections.emptyList().getClass().getName() + ", got " + result.value.getClass()); + } + assertEquals(0, ((List) result.value).size()); + } + + public void testTypedLongs() throws Exception { + PolymorphicHolder h; + String json; + PolymorphicHolder result; + + // First, with one entry + List longs = Longs.asList(1L); + h = new PolymorphicHolder(longs); + json = POLY_MAPPER.writeValueAsString(h); + + // so far so good. and back? + result = POLY_MAPPER.readValue(json, PolymorphicHolder.class); + assertNotNull(result.value); + if (!(PrimitiveTypes.LongsType.isInstance(result.value))) { + fail("Expected " + PrimitiveTypes.LongsTypeName + ", got " + result.value.getClass()); + } + assertEquals(1, ((List) result.value).size()); + + // and then an empty version: + List emptyList = Longs.asList(new long[0]); + h = new PolymorphicHolder(emptyList); + json = POLY_MAPPER.writeValueAsString(h); + result = POLY_MAPPER.readValue(json, PolymorphicHolder.class); + assertNotNull(result.value); + if (!(Collections.emptyList().getClass().isInstance(result.value))) { + fail("Expected " + Collections.emptyList().getClass().getName() + ", got " + result.value.getClass()); + } + assertEquals(0, ((List) result.value).size()); + } + +} From 9537dbd8b4c50fd9f5dac2791541ae7427b7767d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3-R=C3=B3bert=20Albert?= Date: Mon, 23 Mar 2020 19:16:58 +0200 Subject: [PATCH 2/5] fix static import --- .../jackson/datatype/guava/GuavaDeserializers.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java index 2df1b793..76810b96 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaDeserializers.java @@ -22,6 +22,8 @@ import java.io.Serializable; +import static com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes.isAssignableFromPrimitive; + /** * Custom deserializers module offers. */ @@ -129,7 +131,9 @@ public JsonDeserializer findCollectionDeserializer(CollectionType type, null, null); } - return null; + return isAssignableFromPrimitive(raw) + .transform(PrimitiveTypes.Primitives::newDeserializer) + .orNull(); } private void requireCollectionOfComparableElements(CollectionType actualType, String targetType) { @@ -303,7 +307,6 @@ public JsonDeserializer findBeanDeserializer(final JavaType type, Deserializa @Override public boolean hasDeserializerFor(DeserializationConfig config, Class valueType) { if (valueType.getName().startsWith("com.google.")) { -System.err.println("DEBUG: hasDeserializerFor? "+valueType+"..."); return (valueType == Optional.class) || (valueType == RangeSet.class) || (valueType == HostAndPort.class) @@ -315,8 +318,10 @@ public boolean hasDeserializerFor(DeserializationConfig config, Class valueTy || ImmutableCollection.class.isAssignableFrom(valueType) || ImmutableMap.class.isAssignableFrom(valueType) || BiMap.class.isAssignableFrom(valueType) + || isAssignableFromPrimitive(valueType).isPresent() ; } return false; } + } From 7fe11577dd67025751b6d5af8068c4bee54a71aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3-R=C3=B3bert=20Albert?= Date: Mon, 23 Mar 2020 19:19:25 +0200 Subject: [PATCH 3/5] remove unused serializer classes --- .../GuavaPrimitiveIterableSerializer.java | 29 ------- .../ser/primitive/LongIterableSerializer.java | 31 -------- .../PrimitiveIterableSerializer.java | 75 ------------------- 3 files changed, 135 deletions(-) delete mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java delete mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java delete mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java deleted file mode 100644 index 810fc8ea..00000000 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/GuavaPrimitiveIterableSerializer.java +++ /dev/null @@ -1,29 +0,0 @@ -//package com.fasterxml.jackson.datatype.guava.ser.primitive; -// -//import com.fasterxml.jackson.databind.BeanProperty; -//import com.fasterxml.jackson.databind.JavaType; -//import com.fasterxml.jackson.databind.SerializerProvider; -// -//import java.util.List; -// -//public abstract class GuavaPrimitiveIterableSerializer -// extends PrimitiveIterableSerializer { -// -// protected GuavaPrimitiveIterableSerializer(Class type, JavaType elementType, -// BeanProperty property, Boolean unwrapSingle) { -// super(type, elementType, property, unwrapSingle); -// } -// -// @Override -// public boolean isEmpty(SerializerProvider prov, C value) { -// return value.isEmpty(); -// } -// -// @Override -// public boolean hasSingleElement(C value) { -// if (value != null) { -// return value.size() == 1; -// } -// return false; -// } -//} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java deleted file mode 100644 index 64a191b3..00000000 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/LongIterableSerializer.java +++ /dev/null @@ -1,31 +0,0 @@ -//package com.fasterxml.jackson.datatype.guava.ser.primitive; -// -//import com.fasterxml.jackson.core.JsonGenerator; -//import com.fasterxml.jackson.databind.BeanProperty; -//import com.fasterxml.jackson.databind.JavaType; -//import com.fasterxml.jackson.databind.type.TypeFactory; -//import org.eclipse.collections.api.LongIterable; -//import org.eclipse.collections.api.iterator.LongIterator; -// -//import java.io.IOException; -// -//public final class LongIterableSerializer extends GuavaPrimitiveIterableSerializer { -// private static final JavaType ELEMENT_TYPE = TypeFactory.defaultInstance().constructType(long.class); -// -// public LongIterableSerializer(BeanProperty property, Boolean unwrapSingle) { -// super(LongIterable.class, ELEMENT_TYPE, property, unwrapSingle); -// } -// -// @Override -// protected LongIterableSerializer withResolved(BeanProperty property, Boolean unwrapSingle) { -// return new LongIterableSerializer(property, unwrapSingle); -// } -// -// @Override -// protected void serializeContents(LongIterable value, JsonGenerator gen) throws IOException { -// LongIterator iterator = value.longIterator(); -// while (iterator.hasNext()) { -// gen.writeNumber(iterator.next()); -// } -// } -//} diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java deleted file mode 100644 index 26469d64..00000000 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/primitive/PrimitiveIterableSerializer.java +++ /dev/null @@ -1,75 +0,0 @@ -//package com.fasterxml.jackson.datatype.guava.ser.primitive; -// -//import com.fasterxml.jackson.core.JsonGenerator; -//import com.fasterxml.jackson.core.JsonToken; -//import com.fasterxml.jackson.core.type.WritableTypeId; -//import com.fasterxml.jackson.databind.BeanProperty; -//import com.fasterxml.jackson.databind.JavaType; -//import com.fasterxml.jackson.databind.JsonSerializer; -//import com.fasterxml.jackson.databind.SerializationFeature; -//import com.fasterxml.jackson.databind.SerializerProvider; -//import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -//import com.fasterxml.jackson.databind.ser.ContainerSerializer; -// -//import java.io.IOException; -// -//public abstract class PrimitiveIterableSerializer extends ContainerSerializer { -// protected final JavaType _elementObjectType; -// protected final JavaType _elementPrimitiveType; -// protected final BeanProperty _property; -// protected final Boolean _unwrapSingle; -// -// protected PrimitiveIterableSerializer(Class type, JavaType elementType, -// BeanProperty property, Boolean unwrapSingle -// ) { -// super(type); -// _elementType = elementType; -// _property = property; -// _unwrapSingle = unwrapSingle; -// } -// -// protected abstract PrimitiveIterableSerializer withResolved(BeanProperty property, Boolean unwrapSingle); -// -// @Override -// public JavaType getContentType() { -// return _elementType; -// } -// -// @Override -// public JsonSerializer getContentSerializer() { -// return null; -// } -// -// @Override -// protected ContainerSerializer _withValueTypeSerializer(TypeSerializer vts) { -// // no type info for primitives -// return this; -// } -// -// @Override -// public final void serialize(C value, JsonGenerator gen, SerializerProvider ctxt) throws IOException { -// if (((_unwrapSingle == null) && -// ctxt.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) -// || (Boolean.TRUE.equals(_unwrapSingle))) { -// if (hasSingleElement(value)) { -// serializeContents(value, gen); -// return; -// } -// } -// gen.writeStartArray(); -// serializeContents(value, gen); -// gen.writeEndArray(); -// } -// -// @Override -// public void serializeWithType(C value, JsonGenerator g, SerializerProvider ctxt, TypeSerializer typeSer) -// throws IOException { -// g.setCurrentValue(value); -// WritableTypeId typeIdDef = typeSer.writeTypePrefix(g, ctxt, typeSer.typeId(value, JsonToken.START_ARRAY)); -// serializeContents(value, g); -// typeSer.writeTypeSuffix(g, ctxt, typeIdDef); -// } -// -// protected abstract void serializeContents(C value, JsonGenerator gen) throws IOException; -//} -// From 7934df28228ad48198218d6ce7bad1addc03e87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3-R=C3=B3bert=20Albert?= Date: Mon, 23 Mar 2020 19:20:38 +0200 Subject: [PATCH 4/5] remove unused serializer classes --- .../ser/GuavaPrimitiveListSerializer.java | 148 ------------------ 1 file changed, 148 deletions(-) delete mode 100644 guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java deleted file mode 100644 index 0bff4db4..00000000 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaPrimitiveListSerializer.java +++ /dev/null @@ -1,148 +0,0 @@ -//package com.fasterxml.jackson.datatype.guava.ser; -// -//import com.fasterxml.jackson.core.JsonGenerator; -//import com.fasterxml.jackson.databind.BeanProperty; -//import com.fasterxml.jackson.databind.JavaType; -//import com.fasterxml.jackson.databind.JsonMappingException; -//import com.fasterxml.jackson.databind.JsonSerializer; -//import com.fasterxml.jackson.databind.SerializerProvider; -//import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; -//import com.fasterxml.jackson.databind.jsontype.TypeSerializer; -//import com.fasterxml.jackson.databind.ser.ContainerSerializer; -//import com.fasterxml.jackson.databind.ser.std.ObjectArraySerializer; -//import com.fasterxml.jackson.databind.type.CollectionLikeType; -// -//import java.io.IOException; -// -///** -// * Note: this implementation does not yet properly handle all -// * polymorphic cases -// */ -//public class GuavaPrimitiveListSerializer -// extends ContainerSerializer> -//{ -// protected final JavaType _contentType; -// -// /** -// * We will basically just delegate serialization to the standard -// * Object[] serializer; as we can not sub-class it. -// */ -// protected final ObjectArraySerializer _delegate; -// -// /* -// /********************************************************************** -// /* Life-cycle -// /********************************************************************** -// */ -// -// public ObjectContainerSerializer(CollectionLikeType containerType, -// ObjectArraySerializer delegate) -// { -// // not sure if we can claim it is "object"... could be String, wrapper types etc: -// super(containerType, "any"); -// _contentType = containerType.getContentType(); -// _delegate = delegate; -// } -// -// protected ObjectContainerSerializer(ObjectContainerSerializer base, -// ObjectArraySerializer delegate) -// { -// super(base); -// _contentType = base._contentType; -// _delegate = delegate; -// } -// -// protected ObjectContainerSerializer withDelegate(ObjectArraySerializer newDelegate) { -// return (newDelegate == _delegate) ? this : new ObjectContainerSerializer(this, newDelegate); -// } -// -// @Override -// protected ContainerSerializer _withValueTypeSerializer(TypeSerializer vts) { -// ObjectArraySerializer ser = (ObjectArraySerializer) _delegate._withValueTypeSerializer(vts); -// if (ser == _delegate) { -// return this; -// } -// return withDelegate(ser); -// } -// -// /* -// /********************************************************************** -// /* Schema support -// /********************************************************************** -// */ -// -// @Override -// public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) -// throws JsonMappingException -// { -// _delegate.acceptJsonFormatVisitor(visitor, typeHint); -// } -// -// /* -// /********************************************************************** -// /* Overridden accessors -// /********************************************************************** -// */ -// -// @Override -// public JsonSerializer getContentSerializer() { -// return _delegate.getContentSerializer(); -// } -// -// @Override -// public boolean hasSingleElement(ObjectContainer value) { -// return value.size() == 1; -// } -// -// @Override -// public boolean isEmpty(SerializerProvider provider, ObjectContainer value) { -// // 27-Nov-2015, tatu: Not up to 2.7 full specs (wrt value vs content emptiness) -// // but better than we had before -// return value.isEmpty(); -// } -// -// @Override -// public JavaType getContentType() { -// return _contentType; -// } -// -// /* -// /********************************************************************** -// /* Contextualization -// /********************************************************************** -// */ -// -// @Override -// public JsonSerializer createContextual(SerializerProvider prov, -// BeanProperty property) throws JsonMappingException { -// return withDelegate((ObjectArraySerializer) _delegate.createContextual(prov, property)); -// } -// -// /* -// /********************************************************************** -// /* Serialization -// /********************************************************************** -// */ -// -// @Override -// public void serialize(ObjectContainer value, JsonGenerator gen, SerializerProvider provider) -// throws IOException -// { -// _delegate.serialize(value.toArray(), gen, provider); -// } -// -// @Override -// public void serializeWithType(ObjectContainer value, JsonGenerator gen, SerializerProvider provider, -// TypeSerializer typeSer) -// throws IOException -// { -// _delegate.serializeWithType(value.toArray(), gen, provider, typeSer); -// } -// -// @Override -// protected void serializeContents(ObjectContainer value, JsonGenerator gen, SerializerProvider provider) -// throws IOException -// { -// throw new IllegalStateException(); -// } -//} From e6f3ca252838ff20c3f8e34af10ad4a8f6754a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3-R=C3=B3bert=20Albert?= Date: Thu, 25 Feb 2021 10:25:52 +0200 Subject: [PATCH 5/5] fix support for Guava primitives after syncing with upstream --- .../jackson/datatype/guava/GuavaSerializers.java | 16 +++++++--------- .../BasePrimitiveCollectionDeserializer.java | 12 ++++++------ ...aseGuavaPrimitivesCollectionDeserializer.java | 6 +++--- .../BooleansPrimitiveCollectionDeserializer.java | 4 ++-- .../BytesPrimitiveCollectionDeserializer.java | 8 ++------ .../CharsPrimitiveCollectionDeserializer.java | 5 ++--- .../DoublesPrimitiveCollectionDeserializer.java | 4 ++-- .../FloatsPrimitiveCollectionDeserializer.java | 4 ++-- .../IntsPrimitiveCollectionDeserializer.java | 4 ++-- .../LongsPrimitiveCollectionDeserializer.java | 4 ++-- .../ShortsPrimitiveCollectionDeserializer.java | 4 ++-- .../jackson/datatype/guava/TestPrimitives.java | 8 ++++---- 12 files changed, 36 insertions(+), 43 deletions(-) diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java index 42924861..49c1b15e 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/GuavaSerializers.java @@ -1,5 +1,7 @@ package com.fasterxml.jackson.datatype.guava; +import com.fasterxml.jackson.databind.type.CollectionLikeType; +import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; import java.io.Serializable; import java.util.Set; @@ -32,10 +34,6 @@ import com.google.common.hash.HashCode; import com.google.common.net.HostAndPort; import com.google.common.net.InternetDomainName; -import com.fasterxml.jackson.datatype.guava.ser.GuavaOptionalSerializer; -import com.fasterxml.jackson.datatype.guava.ser.MultimapSerializer; -import com.fasterxml.jackson.datatype.guava.ser.RangeSerializer; -import com.fasterxml.jackson.datatype.guava.ser.TableSerializer; public class GuavaSerializers extends Serializers.Base implements Serializable @@ -119,12 +117,12 @@ public ValueSerializer findMapLikeSerializer(SerializationConfig config, } @Override - public JsonSerializer findCollectionLikeSerializer(SerializationConfig config, CollectionLikeType type, - BeanDescription beanDesc, Value formatOverrides, TypeSerializer elementTypeSerializer, - JsonSerializer elementValueSerializer) + public ValueSerializer findCollectionLikeSerializer(SerializationConfig config, CollectionLikeType type, + BeanDescription beanDesc, JsonFormat.Value formatOverrides, TypeSerializer elementTypeSerializer, + ValueSerializer elementValueSerializer) { Class raw = type.getRawClass(); - Optional> primitiveSerializer = PrimitiveTypes.isAssignableFromPrimitive(raw) + Optional> primitiveSerializer = PrimitiveTypes.isAssignableFromPrimitive(raw) .transform((ignore) -> ToStringSerializer.instance); return primitiveSerializer @@ -132,7 +130,7 @@ public JsonSerializer findCollectionLikeSerializer(SerializationConfig config } private JavaType _findDeclared(JavaType subtype, Class target) { - JavaType decl = subtype.findSuperType(target); + JavaType decl = subtype.findSuperType(target); if (decl == null) { // should never happen but throw new IllegalArgumentException("Strange "+target.getName()+" sub-type, "+subtype+", can not find type parameters"); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java index 1172441e..343d72a1 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/BasePrimitiveCollectionDeserializer.java @@ -1,5 +1,6 @@ package com.fasterxml.jackson.datatype.guava.deser; +import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; @@ -8,7 +9,6 @@ import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -30,20 +30,20 @@ protected IntermediateCollection createIntermediateCollection(int expectedSize) } protected abstract void add(IntermediateCollection intermediateCollection, JsonParser parser, - DeserializationContext context) throws IOException; + DeserializationContext context) throws JacksonException; protected abstract PrimitiveList finish(IntermediateCollection intermediateCollection); @Override public Object deserializeWithType(JsonParser parser, DeserializationContext context, - TypeDeserializer typeDeserializer) throws IOException { + TypeDeserializer typeDeserializer) throws JacksonException { return typeDeserializer.deserializeTypedFromArray(parser, context); } @SuppressWarnings("unchecked") @Override public PrimitiveList deserialize(JsonParser parser, DeserializationContext context) - throws IOException { + throws JacksonException { // Should usually point to START_ARRAY if (parser.isExpectedStartArrayToken()) { return _deserializeContents(parser, context); @@ -56,7 +56,7 @@ public PrimitiveList deserialize(JsonParser parser, DeserializationContext conte } protected PrimitiveList _deserializeContents(JsonParser parser, DeserializationContext context) - throws IOException { + throws JacksonException { IntermediateCollection collection = createIntermediateCollection(); while (parser.nextToken() != JsonToken.END_ARRAY) { @@ -66,7 +66,7 @@ protected PrimitiveList _deserializeContents(JsonParser parser, DeserializationC } protected PrimitiveList _deserializeFromSingleValue(JsonParser parser, DeserializationContext ctxt) - throws IOException { + throws JacksonException { IntermediateCollection intermediateCollection = createIntermediateCollection(); add(intermediateCollection, parser, ctxt); return finish(intermediateCollection); diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java index d37b92e4..0b2b6454 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BaseGuavaPrimitivesCollectionDeserializer.java @@ -1,10 +1,10 @@ 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; -import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -22,9 +22,9 @@ protected IntermediateCollection createIntermediateCollection() { } @Override - protected void add(IntermediateCollection intermediateCollection, JsonParser parser, DeserializationContext context) throws IOException { + protected void add(IntermediateCollection intermediateCollection, JsonParser parser, DeserializationContext context) throws JacksonException { intermediateCollection.add(asPrimitive(parser)); } - protected abstract ObjectType asPrimitive(JsonParser parser) throws IOException; + protected abstract ObjectType asPrimitive(JsonParser parser) throws JacksonException; } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java index bfa51ce2..e633928e 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BooleansPrimitiveCollectionDeserializer.java @@ -1,10 +1,10 @@ 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.PrimitiveTypes; import com.google.common.primitives.Booleans; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -16,7 +16,7 @@ public BooleansPrimitiveCollectionDeserializer() { } @Override - protected Boolean asPrimitive(JsonParser parser) throws IOException { + protected Boolean asPrimitive(JsonParser parser) throws JacksonException { return parser.getBooleanValue(); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java index 6baf608c..abc06927 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/BytesPrimitiveCollectionDeserializer.java @@ -1,14 +1,10 @@ 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; import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; -import com.google.common.primitives.Booleans; import com.google.common.primitives.Bytes; -import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -19,7 +15,7 @@ public BytesPrimitiveCollectionDeserializer() { } @Override - protected Byte asPrimitive(JsonParser parser) throws IOException { + protected Byte asPrimitive(JsonParser parser) throws JacksonException { return parser.getByteValue(); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java index c60a6d96..a25b9096 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/CharsPrimitiveCollectionDeserializer.java @@ -1,11 +1,10 @@ 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.PrimitiveTypes; -import com.google.common.primitives.Bytes; import com.google.common.primitives.Chars; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -16,7 +15,7 @@ public CharsPrimitiveCollectionDeserializer() { } @Override - protected Character asPrimitive(JsonParser parser) throws IOException { + protected Character asPrimitive(JsonParser parser) throws JacksonException { return (char) parser.getValueAsString().toCharArray()[0]; } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java index 9aa40f87..51473554 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/DoublesPrimitiveCollectionDeserializer.java @@ -1,10 +1,10 @@ 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.PrimitiveTypes; import com.google.common.primitives.Doubles; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -15,7 +15,7 @@ public DoublesPrimitiveCollectionDeserializer() { } @Override - protected Double asPrimitive(JsonParser parser) throws IOException { + protected Double asPrimitive(JsonParser parser) throws JacksonException { return parser.getDoubleValue(); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java index 45db9f25..24d56e6d 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/FloatsPrimitiveCollectionDeserializer.java @@ -1,10 +1,10 @@ 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.PrimitiveTypes; import com.google.common.primitives.Floats; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -15,7 +15,7 @@ public FloatsPrimitiveCollectionDeserializer() { } @Override - protected Float asPrimitive(JsonParser parser) throws IOException { + protected Float asPrimitive(JsonParser parser) throws JacksonException { return parser.getFloatValue(); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java index b873eb3c..604ecd33 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/IntsPrimitiveCollectionDeserializer.java @@ -1,10 +1,10 @@ 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.PrimitiveTypes; import com.google.common.primitives.Ints; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -15,7 +15,7 @@ public IntsPrimitiveCollectionDeserializer() { } @Override - protected Integer asPrimitive(JsonParser parser) throws IOException { + protected Integer asPrimitive(JsonParser parser) throws JacksonException { return parser.getIntValue(); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java index a6724a5d..b0a5a8b6 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/LongsPrimitiveCollectionDeserializer.java @@ -1,10 +1,10 @@ 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.PrimitiveTypes; import com.google.common.primitives.Longs; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -15,7 +15,7 @@ public LongsPrimitiveCollectionDeserializer() { } @Override - protected Long asPrimitive(JsonParser parser) throws IOException { + protected Long asPrimitive(JsonParser parser) throws JacksonException { return parser.getLongValue(); } diff --git a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java index 81a3a6c7..ecfc9ae8 100644 --- a/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java +++ b/guava/src/main/java/com/fasterxml/jackson/datatype/guava/deser/primitives/ShortsPrimitiveCollectionDeserializer.java @@ -1,10 +1,10 @@ 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.PrimitiveTypes; import com.google.common.primitives.Shorts; -import java.io.IOException; import java.util.Collection; import java.util.List; @@ -15,7 +15,7 @@ public ShortsPrimitiveCollectionDeserializer() { } @Override - protected Short asPrimitive(JsonParser parser) throws IOException { + protected Short asPrimitive(JsonParser parser) throws JacksonException { return parser.getShortValue(); } diff --git a/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java b/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java index 1bb34953..450deb98 100644 --- a/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java +++ b/guava/src/test/java/com/fasterxml/jackson/datatype/guava/TestPrimitives.java @@ -1,8 +1,8 @@ package com.fasterxml.jackson.datatype.guava; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator; import com.fasterxml.jackson.datatype.guava.util.PrimitiveTypes; @@ -91,21 +91,21 @@ public void testWithoutDeserializers() throws Exception { try { mapper.readValue("[true,false,true]", PrimitiveTypes.BooleansTypeReference); fail("Expected failure for missing deserializer"); - } catch (JsonMappingException e) { + } catch (JacksonException e) { verifyException(e, PrimitiveTypes.BooleansTypeName); } try { mapper.readValue("[1,2,3]", PrimitiveTypes.IntsTypeReference); fail("Expected failure for missing deserializer"); - } catch (JsonMappingException e) { + } catch (JacksonException e) { verifyException(e, PrimitiveTypes.IntsTypeName); } try { mapper.readValue("[1,2,3]", PrimitiveTypes.LongsTypeReference); fail("Expected failure for missing deserializer"); - } catch (JsonMappingException e) { + } catch (JacksonException e) { verifyException(e, PrimitiveTypes.LongsTypeName); }