Streaming for Multiset and Iterable.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6512 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -29,9 +29,12 @@ import java.util.Set;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multiset;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
@@ -67,6 +70,8 @@ public class BasicStreamers
|
||||
.put(Collection.class, ListStreamer.INSTANCE)
|
||||
.put(Set.class, SetStreamer.INSTANCE)
|
||||
.put(Map.class, MapStreamer.INSTANCE)
|
||||
.put(Multiset.class, MultisetStreamer.INSTANCE)
|
||||
.put(Iterable.class, IterableStreamer.INSTANCE)
|
||||
.build();
|
||||
|
||||
/** Streams {@link Boolean} instances. */
|
||||
@@ -432,6 +437,15 @@ public class BasicStreamers
|
||||
/** A building-block class for streaming Collections. */
|
||||
protected abstract static class CollectionStreamer extends BasicStreamer
|
||||
{
|
||||
/** The ordering for Collection/Iterable classes, most to least specific. */
|
||||
public static final List<Class<?>> SPECIFICITY_ORDER = ImmutableList.of(
|
||||
/** Pretty specific. */
|
||||
List.class, Map.class, Set.class, Multiset.class,
|
||||
/** General. */
|
||||
Collection.class,
|
||||
/** Last resort. */
|
||||
Iterable.class);
|
||||
|
||||
@Override
|
||||
public Object createObject (ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
@@ -463,6 +477,19 @@ public class BasicStreamers
|
||||
protected abstract Collection<Object> createCollection (int size);
|
||||
}
|
||||
|
||||
/** Streams {@link Set} instances. */
|
||||
public static class SetStreamer extends CollectionStreamer
|
||||
{
|
||||
/** A singleton instance. */
|
||||
public static final SetStreamer INSTANCE = new SetStreamer();
|
||||
|
||||
@Override
|
||||
protected Collection<Object> createCollection (int size)
|
||||
{
|
||||
return Sets.newHashSetWithExpectedSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
/** Streams {@link List} instances. */
|
||||
public static class ListStreamer extends CollectionStreamer
|
||||
{
|
||||
@@ -476,16 +503,18 @@ public class BasicStreamers
|
||||
}
|
||||
}
|
||||
|
||||
/** Streams {@link Set} instances. */
|
||||
public static class SetStreamer extends CollectionStreamer
|
||||
/** Copy a non-Collection {@link Iterable} into a List. */
|
||||
public static class IterableStreamer extends ListStreamer
|
||||
{
|
||||
/** A singleton instance. */
|
||||
public static final SetStreamer INSTANCE = new SetStreamer();
|
||||
public static final IterableStreamer INSTANCE = new IterableStreamer();
|
||||
|
||||
@Override
|
||||
protected Collection<Object> createCollection (int size)
|
||||
public void writeObject (Object object, ObjectOutputStream out, boolean useWriter)
|
||||
throws IOException
|
||||
{
|
||||
return Sets.newHashSetWithExpectedSize(size);
|
||||
// re-wrap the Iterable in a List and let superclass ListStreamer do the rest
|
||||
super.writeObject(Lists.newArrayList((Iterable<?>)object), out, useWriter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,6 +557,49 @@ public class BasicStreamers
|
||||
}
|
||||
}
|
||||
|
||||
/** Streams {@link Multiset} instances. */
|
||||
public static class MultisetStreamer extends BasicStreamer
|
||||
{
|
||||
/** A singleton instance. */
|
||||
public static final MultisetStreamer INSTANCE = new MultisetStreamer();
|
||||
|
||||
@Override
|
||||
public Object createObject (ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
int size = in.readInt();
|
||||
Multiset<Object> set = createMultiset(size);
|
||||
for (int ii = 0; ii < size; ii++) {
|
||||
set.add(in.readObject(), in.readInt());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject (Object object, ObjectOutputStream out, boolean useWriter)
|
||||
throws IOException
|
||||
{
|
||||
// There seems to be a weird bug with the compiler: if I cast to Multiset<?>
|
||||
// then it has a problem assigning the Set<Multiset.Entry<?>>.
|
||||
@SuppressWarnings("unchecked")
|
||||
Multiset<Object> set = (Multiset<Object>)object;
|
||||
Set<Multiset.Entry<Object>> entrySet = set.entrySet();
|
||||
out.writeInt(entrySet.size());
|
||||
for (Multiset.Entry<Object> entry : entrySet) {
|
||||
out.writeObject(entry.getElement());
|
||||
out.writeInt(entry.getCount());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrideable if a subclass is desired to stream a different kind of multiset.
|
||||
*/
|
||||
protected Multiset<Object> createMultiset (int size)
|
||||
{
|
||||
return HashMultiset.create(size);
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO : We can't create an EnumMap of zero size- we need to know the key class
|
||||
// public static class EnumMapStreamer extends MapStreamer
|
||||
// {
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -109,17 +108,10 @@ public class Streamer
|
||||
// the class is natively streamable, let's ignore it
|
||||
return null;
|
||||
}
|
||||
if (Map.class.isAssignableFrom(clazz)) {
|
||||
return Map.class;
|
||||
for (Class<?> collClass : BasicStreamers.CollectionStreamer.SPECIFICITY_ORDER) {
|
||||
if (collClass.isAssignableFrom(clazz)) {
|
||||
return collClass;
|
||||
}
|
||||
if (Set.class.isAssignableFrom(clazz)) {
|
||||
return Set.class;
|
||||
}
|
||||
if (List.class.isAssignableFrom(clazz)) {
|
||||
return List.class;
|
||||
}
|
||||
if (Collection.class.isAssignableFrom(clazz)) {
|
||||
return Collection.class;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user