Skip to content
This repository was archived by the owner on Jan 20, 2025. It is now read-only.

Commit 6032623

Browse files
committed
Partial implementation for #11, from #62; adds serialization support, tests
1 parent d5ff04f commit 6032623

File tree

8 files changed

+393
-8
lines changed

8 files changed

+393
-8
lines changed

release-notes/VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Project: jackson-datatype-guava
88

99
#79: New configuration for Guava Range default bound type.
1010
(contributed by Jonathan R-d-O)
11+
(partial, serialization works) #11: Add support for Table<R, C, V>
1112

1213
2.6.2 (not yet released)
1314

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.google.common.collect.FluentIterable;
1313
import com.google.common.collect.Multimap;
1414
import com.google.common.collect.Range;
15+
import com.google.common.collect.Table;
1516
import com.google.common.hash.HashCode;
1617
import com.google.common.net.HostAndPort;
1718
import com.google.common.net.InternetDomainName;
@@ -24,6 +25,7 @@
2425
import com.fasterxml.jackson.datatype.guava.ser.GuavaOptionalSerializer;
2526
import com.fasterxml.jackson.datatype.guava.ser.MultimapSerializer;
2627
import com.fasterxml.jackson.datatype.guava.ser.RangeSerializer;
28+
import com.fasterxml.jackson.datatype.guava.ser.TableSerializer;
2729

2830
public class GuavaSerializers extends Serializers.Base
2931
{
@@ -46,6 +48,10 @@ public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType typ
4648
if (Range.class.isAssignableFrom(raw)) {
4749
return new RangeSerializer(type);
4850
}
51+
if (Table.class.isAssignableFrom(raw)) {
52+
return new TableSerializer(type);
53+
}
54+
4955
// since 2.4
5056
if (HostAndPort.class.isAssignableFrom(raw)) {
5157
return ToStringSerializer.instance;

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@
22

33
import java.io.IOException;
44

5-
import com.fasterxml.jackson.datatype.guava.deser.util.RangeFactory;
65
import com.google.common.base.Preconditions;
76
import com.google.common.collect.BoundType;
87
import com.google.common.collect.Range;
9-
import com.fasterxml.jackson.core.JsonParser;
10-
import com.fasterxml.jackson.core.JsonProcessingException;
11-
import com.fasterxml.jackson.core.JsonToken;
8+
9+
import com.fasterxml.jackson.core.*;
10+
1211
import com.fasterxml.jackson.databind.*;
1312
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
1413
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
1514
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
1615
import com.fasterxml.jackson.databind.type.TypeFactory;
1716

17+
import com.fasterxml.jackson.datatype.guava.deser.util.RangeFactory;
18+
1819
/**
1920
* Jackson deserializer for a Guava {@link Range}.
2021
*<p>

src/main/java/com/fasterxml/jackson/datatype/guava/deser/multimap/GuavaMultimapDeserializer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,17 @@ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOExcept
159159
@SuppressWarnings("unchecked") T map = (T) creatorMethod.invoke(null, multimap);
160160
return map;
161161
} catch (InvocationTargetException e) {
162-
throw new JsonMappingException("Could not map to " + type, _peel(e));
162+
throw new JsonMappingException(jp, "Could not map to " + type, _peel(e));
163163
} catch (IllegalArgumentException e) {
164-
throw new JsonMappingException("Could not map to " + type, _peel(e));
164+
throw new JsonMappingException(jp, "Could not map to " + type, _peel(e));
165165
} catch (IllegalAccessException e) {
166-
throw new JsonMappingException("Could not map to " + type, _peel(e));
166+
throw new JsonMappingException(jp, "Could not map to " + type, _peel(e));
167167
}
168168
}
169169

170170
private void expect(JsonParser jp, JsonToken token) throws IOException {
171171
if (jp.getCurrentToken() != token) {
172-
throw new JsonMappingException("Expecting " + token + ", found " + jp.getCurrentToken(),
172+
throw new JsonMappingException(jp, "Expecting " + token + ", found " + jp.getCurrentToken(),
173173
jp.getCurrentLocation());
174174
}
175175
}

src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaOptionalBeanPropertyWriter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
public class GuavaOptionalBeanPropertyWriter extends BeanPropertyWriter
1111
{
12+
private static final long serialVersionUID = 1;
13+
1214
protected GuavaOptionalBeanPropertyWriter(BeanPropertyWriter base) {
1315
super(base);
1416
}

src/main/java/com/fasterxml/jackson/datatype/guava/ser/GuavaUnwrappingOptionalBeanPropertyWriter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
public class GuavaUnwrappingOptionalBeanPropertyWriter extends UnwrappingBeanPropertyWriter
1212
{
13+
private static final long serialVersionUID = 1L;
14+
1315
public GuavaUnwrappingOptionalBeanPropertyWriter(BeanPropertyWriter base,
1416
NameTransformer transformer) {
1517
super(base, transformer);
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
package com.fasterxml.jackson.datatype.guava.ser;
2+
3+
import java.io.IOException;
4+
import java.util.Map;
5+
6+
import com.fasterxml.jackson.core.*;
7+
8+
import com.fasterxml.jackson.databind.*;
9+
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
10+
import com.fasterxml.jackson.databind.ser.ContainerSerializer;
11+
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
12+
import com.fasterxml.jackson.databind.ser.std.MapSerializer;
13+
import com.fasterxml.jackson.databind.type.MapType;
14+
import com.fasterxml.jackson.databind.type.TypeFactory;
15+
16+
import com.google.common.collect.Table;
17+
18+
/**
19+
* @author stevenmhood (via hyandell) - Initial implementation
20+
* @author tatu - Some refactoring to streamline code
21+
*/
22+
public class TableSerializer
23+
extends ContainerSerializer<Table<?, ?, ?>> implements ContextualSerializer
24+
{
25+
private static final long serialVersionUID = -1449462718192917949L;
26+
27+
private final JavaType _type;
28+
private final BeanProperty _property;
29+
30+
private final JsonSerializer<Object> _rowSerializer;
31+
private final JsonSerializer<Object> _columnSerializer;
32+
private final TypeSerializer _valueTypeSerializer;
33+
private final JsonSerializer<Object> _valueSerializer;
34+
35+
private final MapSerializer _rowMapSerializer;
36+
private final JsonSerializer<?> _columnAndValueSerializer;
37+
38+
public TableSerializer(final JavaType type)
39+
{
40+
super(type);
41+
_type = type;
42+
_property = null;
43+
_rowSerializer = null;
44+
_columnSerializer = null;
45+
_valueTypeSerializer = null;
46+
_valueSerializer = null;
47+
48+
_rowMapSerializer = null;
49+
_columnAndValueSerializer = null;
50+
}
51+
52+
@SuppressWarnings( "unchecked" )
53+
protected TableSerializer(final TableSerializer src,
54+
final BeanProperty property,
55+
final TypeFactory typeFactory,
56+
final JsonSerializer<?> rowKeySerializer,
57+
final JsonSerializer<?> columnKeySerializer,
58+
final TypeSerializer valueTypeSerializer,
59+
final JsonSerializer<?> valueSerializer)
60+
{
61+
super(src);
62+
_type = src._type;
63+
_property = property;
64+
_rowSerializer = (JsonSerializer<Object>) rowKeySerializer;
65+
_columnSerializer = (JsonSerializer<Object>) columnKeySerializer;
66+
_valueTypeSerializer = valueTypeSerializer;
67+
_valueSerializer = (JsonSerializer<Object>) valueSerializer;
68+
69+
final MapType columnAndValueType = typeFactory.constructMapType(Map.class, _type.containedType(1), _type.containedType(2));
70+
_columnAndValueSerializer =
71+
MapSerializer.construct(null,
72+
columnAndValueType,
73+
false,
74+
_valueTypeSerializer,
75+
_columnSerializer,
76+
_valueSerializer,
77+
null);
78+
79+
final MapType rowMapType = typeFactory.constructMapType(Map.class, _type.containedType(0), columnAndValueType);
80+
_rowMapSerializer =
81+
MapSerializer.construct(null,
82+
rowMapType,
83+
false,
84+
_valueTypeSerializer,
85+
_rowSerializer,
86+
(JsonSerializer<Object>) _columnAndValueSerializer,
87+
null);
88+
89+
}
90+
91+
protected TableSerializer(final TableSerializer src, TypeSerializer typeSer)
92+
{
93+
super(src);
94+
_type = src._type;
95+
_property = src._property;
96+
_rowSerializer = src._rowSerializer;
97+
_columnSerializer = src._columnSerializer;
98+
_valueTypeSerializer = typeSer;
99+
_valueSerializer = src._valueSerializer;
100+
101+
_columnAndValueSerializer = src._columnAndValueSerializer;
102+
_rowMapSerializer = src._rowMapSerializer;
103+
104+
}
105+
106+
protected TableSerializer withResolved(final BeanProperty property,
107+
final TypeFactory typeFactory,
108+
final JsonSerializer<?> rowKeySer,
109+
final JsonSerializer<?> columnKeySer,
110+
final TypeSerializer vts,
111+
final JsonSerializer<?> valueSer )
112+
{
113+
return new TableSerializer(this, property, typeFactory,
114+
rowKeySer, columnKeySer, vts, valueSer);
115+
}
116+
117+
@Override
118+
protected ContainerSerializer<?> _withValueTypeSerializer(final TypeSerializer typeSer)
119+
{
120+
return new TableSerializer(this, typeSer);
121+
}
122+
123+
@Override
124+
public JsonSerializer<?> createContextual(final SerializerProvider provider, final BeanProperty property ) throws JsonMappingException
125+
{
126+
JsonSerializer<?> valueSer = _valueSerializer;
127+
if (valueSer == null) { // if type is final, can actually resolve:
128+
final JavaType valueType = _type.containedType(2);
129+
if (valueType.isFinal()) {
130+
valueSer = provider.findValueSerializer(valueType, property);
131+
}
132+
}
133+
else if (valueSer instanceof ContextualSerializer) {
134+
valueSer = ((ContextualSerializer) valueSer).createContextual(provider, property);
135+
}
136+
JsonSerializer<?> rowKeySer = _rowSerializer;
137+
if (rowKeySer == null) {
138+
rowKeySer = provider.findKeySerializer(_type.containedType(0), property);
139+
}
140+
else if (rowKeySer instanceof ContextualSerializer) {
141+
rowKeySer = ((ContextualSerializer) rowKeySer).createContextual(provider, property);
142+
}
143+
JsonSerializer<?> columnKeySer = _columnSerializer;
144+
if (columnKeySer == null) {
145+
columnKeySer = provider.findKeySerializer(_type.containedType(1), property);
146+
}
147+
else if (columnKeySer instanceof ContextualSerializer) {
148+
columnKeySer = ((ContextualSerializer) columnKeySer).createContextual(provider, property);
149+
}
150+
// finally, TypeSerializers may need contextualization as well
151+
TypeSerializer typeSer = _valueTypeSerializer;
152+
if (typeSer != null) {
153+
typeSer = typeSer.forProperty(property);
154+
}
155+
return withResolved(property, provider.getTypeFactory(), rowKeySer, columnKeySer, typeSer, valueSer);
156+
}
157+
158+
@Override
159+
public JavaType getContentType() {
160+
return _type.getContentType();
161+
}
162+
163+
@Override
164+
public JsonSerializer<?> getContentSerializer() {
165+
return _valueSerializer;
166+
}
167+
168+
@Override
169+
public boolean isEmpty( final Table<?, ?, ?> table )
170+
{
171+
return table.isEmpty();
172+
}
173+
174+
@Override
175+
public boolean hasSingleElement(final Table<?, ?, ?> table )
176+
{
177+
return table.size() == 1;
178+
}
179+
180+
@Override
181+
public void serialize(final Table<?, ?, ?> value,
182+
final JsonGenerator gen, final SerializerProvider provider)
183+
throws IOException
184+
{
185+
gen.writeStartObject();
186+
if ( !value.isEmpty()) {
187+
serializeFields(value, gen, provider);
188+
}
189+
gen.writeEndObject();
190+
}
191+
192+
@Override
193+
public void serializeWithType(final Table<?, ?, ?> value,
194+
final JsonGenerator gen,
195+
final SerializerProvider provider,
196+
final TypeSerializer typeSer ) throws IOException
197+
{
198+
typeSer.writeTypePrefixForObject(value, gen);
199+
serializeFields(value, gen, provider);
200+
typeSer.writeTypeSuffixForObject(value, gen);
201+
}
202+
203+
private final void serializeFields( final Table<?, ?, ?> table, final JsonGenerator jgen, final SerializerProvider provider )
204+
throws IOException
205+
{
206+
_rowMapSerializer.serializeFields(table.rowMap(), jgen, provider);
207+
}
208+
}

0 commit comments

Comments
 (0)