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

Add support for com.google.common.collect.Table #73

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.fasterxml.jackson.datatype.guava;

import com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer;
import com.fasterxml.jackson.datatype.guava.deser.table.MapToArrayTableConverter;
import com.fasterxml.jackson.datatype.guava.deser.table.MapToHashBasedTableConverter;
import com.fasterxml.jackson.datatype.guava.deser.table.MapToImmutableTableConverter;
import com.google.common.base.Optional;
import com.google.common.collect.*;
import com.google.common.hash.HashCode;
Expand Down Expand Up @@ -262,6 +266,18 @@ public JsonDeserializer<?> findBeanDeserializer(final JavaType type, Deserializa
if (raw == HashCode.class) {
return HashCodeDeserializer.std;
}
if (raw == Table.class || raw == ImmutableTable.class) {
return new StdDelegatingDeserializer<Table<Object, Object, Object>>(
new MapToImmutableTableConverter<Object, Object, Object>(type));
}
if (raw == HashBasedTable.class) {
return new StdDelegatingDeserializer<Table<Object, Object, Object>>(
new MapToHashBasedTableConverter<Object, Object, Object>(type));
}
if (raw == ArrayTable.class) {
return new StdDelegatingDeserializer<Table<Object, Object, Object>>(
new MapToArrayTableConverter<Object, Object, Object>(type));
}
return super.findBeanDeserializer(type, config, beanDesc);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.ArrayBuilders;
import com.fasterxml.jackson.databind.util.StdConverter;
import com.fasterxml.jackson.datatype.guava.ser.TableToMapConverter;
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.Table;
import com.google.common.hash.HashCode;
import com.google.common.net.HostAndPort;
import com.google.common.net.InternetDomainName;
Expand Down Expand Up @@ -73,6 +75,9 @@ public JsonSerializer<?> findSerializer(SerializationConfig config, JavaType typ
// JavaType delegate = config.getTypeFactory().constructParametrizedType(FluentIterable.class, Iterable.class, vt);
return new StdDelegatingSerializer(FluentConverter.instance, delegate, null);
}
if (Table.class.isAssignableFrom(raw)) {
return new StdDelegatingSerializer(new TableToMapConverter<Object, Object, Object>(type));
}
return super.findSerializer(config, type, beanDesc);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.fasterxml.jackson.datatype.guava.deser.table;

import com.fasterxml.jackson.databind.JavaType;
import com.google.common.collect.ArrayTable;
import com.google.common.collect.Table;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
* Converts {@link Map} instances into {@link ArrayTable} instances during JSON
* deserialization.
*
* @param <R> the type of the table row keys
* @param <C> the type of the table column keys
* @param <V> the type of the mapped values
*
* @author Michael Hixson
*/
public final class MapToArrayTableConverter<R, C, V>
extends MapToTableConverter<R, C, V>
{
/**
* Constructs a new converter with the provided table type.
*
* @param tableType the type of the table being deserialized
*/
public MapToArrayTableConverter(JavaType tableType)
{
super(tableType);
}

@Override
public Table<R, C, V> convert(Map<R, Map<C, V>> map)
{
Set<R> rowKeys = map.keySet();
Set<C> columnKeys = new LinkedHashSet<C>();
for (Map<C, V> columnMap : map.values())
{
columnKeys.addAll(columnMap.keySet());
}
Table<R, C, V> table = ArrayTable.create(rowKeys, columnKeys);
for (Map.Entry<R, Map<C, V>> rowEntry : map.entrySet())
{
for (Map.Entry<C, V> columnEntry : rowEntry.getValue().entrySet())
{
R rowKey = rowEntry.getKey();
C columnKey = columnEntry.getKey();
V value = columnEntry.getValue();
table.put(rowKey, columnKey, value);
}
}
return table;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.fasterxml.jackson.datatype.guava.deser.table;

import com.fasterxml.jackson.databind.JavaType;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;

import java.util.Map;

/**
* Converts {@link Map} instances into {@link HashBasedTable} instances during
* JSON deserialization.
*
* @param <R> the type of the table row keys
* @param <C> the type of the table column keys
* @param <V> the type of the mapped values
*
* @author Michael Hixson
*/
public final class MapToHashBasedTableConverter<R, C, V>
extends MapToTableConverter<R, C, V>
{
/**
* Constructs a new converter with the provided table type.
*
* @param tableType the type of the table being deserialized
*/
public MapToHashBasedTableConverter(JavaType tableType)
{
super(tableType);
}

@Override
public Table<R, C, V> convert(Map<R, Map<C, V>> map)
{
Table<R, C, V> table = HashBasedTable.create();
for (Map.Entry<R, Map<C, V>> rowEntry : map.entrySet())
{
for (Map.Entry<C, V> columnEntry : rowEntry.getValue().entrySet())
{
R rowKey = rowEntry.getKey();
C columnKey = columnEntry.getKey();
V value = columnEntry.getValue();
table.put(rowKey, columnKey, value);
}
}
return table;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.fasterxml.jackson.datatype.guava.deser.table;

import com.fasterxml.jackson.databind.JavaType;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;

import java.util.Map;

/**
* Converts {@link Map} instances into {@link ImmutableTable} instances during
* JSON deserialization.
*
* @param <R> the type of the table row keys
* @param <C> the type of the table column keys
* @param <V> the type of the mapped values
*
* @author Michael Hixson
*/
public final class MapToImmutableTableConverter<R, C, V>
extends MapToTableConverter<R, C, V>
{
/**
* Constructs a new converter with the provided table type.
*
* @param tableType the type of the table being deserialized
*/
public MapToImmutableTableConverter(JavaType tableType)
{
super(tableType);
}

@Override
public Table<R, C, V> convert(Map<R, Map<C, V>> map)
{
ImmutableTable.Builder<R, C, V> table = ImmutableTable.builder();
for (Map.Entry<R, Map<C, V>> rowEntry : map.entrySet())
{
for (Map.Entry<C, V> columnEntry : rowEntry.getValue().entrySet())
{
R rowKey = rowEntry.getKey();
C columnKey = columnEntry.getKey();
V value = columnEntry.getValue();
table.put(rowKey, columnKey, value);
}
}
return table.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.fasterxml.jackson.datatype.guava.deser.table;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
import com.google.common.collect.Table;

import java.util.LinkedHashMap;
import java.util.Map;

/**
* An abstract base class for converting {@link Map} instances into
* {@link Table} instances during JSON deserialization. This class assumes that
* the maps mirror the structure of {@link Table#rowMap()}. The maps are
* interpreted as {@link LinkedHashMap} to preserve cell ordering, in case the
* table implementation also preserves cell ordering during insertion.
*
* @param <R> the type of the table row keys
* @param <C> the type of the table column keys
* @param <V> the type of the mapped values
*
* @author Michael Hixson
*/
abstract class MapToTableConverter<R, C, V>
implements Converter<Map<R, Map<C, V>>, Table<R, C, V>>
{
private final JavaType tableType;

/**
* Constructs a new converter with the provided table type.
*
* @param tableType the type of the table being deserialized
*/
MapToTableConverter(JavaType tableType)
{
if (tableType == null)
{
throw new NullPointerException("tableType must not be null");
}
this.tableType = tableType;
}

@Override
public JavaType getInputType(TypeFactory typeFactory)
{
JavaType rowKeyType = tableType.containedTypeOrUnknown(0);
JavaType columnKeyType = tableType.containedTypeOrUnknown(1);
JavaType valueType = tableType.containedTypeOrUnknown(2);
return typeFactory.constructMapType(
LinkedHashMap.class,
rowKeyType,
typeFactory.constructMapType(
LinkedHashMap.class,
columnKeyType,
valueType));
}

@Override
public JavaType getOutputType(TypeFactory typeFactory)
{
return tableType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.fasterxml.jackson.datatype.guava.ser;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
import com.google.common.collect.Table;

import java.util.Map;

/**
* Converts {@link Table} instances into {@link Map} instances during JSON
* serialization, using {@link Table#rowMap()}.
*
* @param <R> the type of the table row keys
* @param <C> the type of the table column keys
* @param <V> the type of the mapped values
*/
public final class TableToMapConverter<R, C, V>
implements Converter<Table<R, C, V>, Map<R, Map<C, V>>>
{
private final JavaType tableType;

/**
* Constructs a new converter with the provided table type.
*
* @param tableType the type of the table being serialized
*/
public TableToMapConverter(JavaType tableType)
{
if (tableType == null)
{
throw new NullPointerException("tableType must not be null");
}
this.tableType = tableType;
}

@Override
public Map<R, Map<C, V>> convert(Table<R, C, V> table)
{
return table.rowMap();
}

@Override
public JavaType getInputType(TypeFactory typeFactory)
{
return tableType;
}

@Override
public JavaType getOutputType(TypeFactory typeFactory)
{
return typeFactory.constructRawMapType(Map.class);
}
}
Loading