Skip to content

Commit

Permalink
add Serializer and Deserializer for RangeSet (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
Felk authored and cowtowncoder committed Sep 19, 2019
1 parent 7caed4c commit b6ecd7e
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ public JsonDeserializer<?> findReferenceDeserializer(ReferenceType refType,
public JsonDeserializer<?> findBeanDeserializer(final JavaType type, DeserializationConfig config,
BeanDescription beanDesc)
{
if (type.hasRawClass(RangeSet.class)) {
return new RangeSetDeserializer();
}
if (type.hasRawClass(Range.class)) {
return new RangeDeserializer(type, _defaultBoundType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
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.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheBuilderSpec;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Multimap;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.Table;
import com.google.common.hash.HashCode;
import com.google.common.net.HostAndPort;
Expand Down Expand Up @@ -63,6 +65,9 @@ public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType typ
BeanDescription beanDesc, JsonFormat.Value formatOverrides)
{
Class<?> raw = type.getRawClass();
if (RangeSet.class.isAssignableFrom(raw)) {
return new RangeSetSerializer();
}
if (Range.class.isAssignableFrom(raw)) {
return new RangeSerializer(_findDeclared(type, Range.class));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.fasterxml.jackson.datatype.guava.deser;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;

import java.io.IOException;
import java.util.List;

public class RangeSetDeserializer extends JsonDeserializer<RangeSet<Comparable<?>>> {
private JavaType genericRangeListType;

@Override
public RangeSet<Comparable<?>> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (genericRangeListType == null) {
throw new JsonParseException(p, "RangeSetJsonSerializer was not contextualized (no deserialize target type). " +
"You need to specify the generic type down to the generic parameter of RangeSet.");
} else {
@SuppressWarnings("unchecked") final Iterable<Range<Comparable<?>>> ranges
= (Iterable<Range<Comparable<?>>>) ctxt
.findContextualValueDeserializer(genericRangeListType, null).deserialize(p, ctxt);
ImmutableRangeSet.Builder<Comparable<?>> builder = ImmutableRangeSet.builder();
for (Range<Comparable<?>> range : ranges) {
builder.add(range);
}
return builder.build();
}
}

@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) {
final JavaType genericType = ctxt.getContextualType().containedType(0);
if (genericType == null) return this;
final RangeSetDeserializer deserializer = new RangeSetDeserializer();
deserializer.genericRangeListType = ctxt.getTypeFactory().constructCollectionType(List.class,
ctxt.getTypeFactory().constructParametricType(Range.class, genericType));
return deserializer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
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.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;

import java.io.IOException;
import java.util.List;

public class RangeSetSerializer extends JsonSerializer<RangeSet<Comparable<?>>> {
private JavaType genericRangeListType;

@Override
public void serialize(RangeSet<Comparable<?>> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (genericRangeListType == null) {
serializers.findValueSerializer(List.class).serialize(value.asRanges(), gen, serializers);
} else {
serializers.findValueSerializer(genericRangeListType).serialize(value.asRanges(), gen, serializers);
}
}

@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
if (property == null) return this;
final RangeSetSerializer serializer = new RangeSetSerializer();
serializer.genericRangeListType = prov.getTypeFactory()
.constructCollectionType(List.class,
prov.getTypeFactory().constructParametricType(
Range.class, property.getType().containedType(0)));
return serializer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.fasterxml.jackson.datatype.guava;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;

import java.io.IOException;

public class TestRangeSet extends ModuleTestBase {

private final ObjectMapper MAPPER = mapperWithModule();

public void testSerializeDeserialize() throws IOException {

final RangeSet<Integer> rangeSet = TreeRangeSet.create();
rangeSet.add(Range.closedOpen(1, 2));
rangeSet.add(Range.openClosed(3, 4));

final String json = MAPPER.writeValueAsString(rangeSet);

final TypeFactory tf = MAPPER.getTypeFactory();
final JavaType type = tf.constructParametricType(RangeSet.class, Integer.class);
final ObjectReader reader = MAPPER.readerFor(type);

final RangeSet<Integer> deserialized = reader.readValue(json);

assertEquals(rangeSet, deserialized);

}

}

0 comments on commit b6ecd7e

Please sign in to comment.