java_gen: add support for object hashing via the guava hash API
diff --git a/java_gen/templates/_imports.java b/java_gen/templates/_imports.java
index 7fd0719..55e9a2d 100644
--- a/java_gen/templates/_imports.java
+++ b/java_gen/templates/_imports.java
@@ -1,5 +1,6 @@
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
 import java.util.Map;
@@ -18,3 +19,5 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
+import com.google.common.hash.Funnel;
+import com.google.common.hash.PrimitiveSink;
diff --git a/java_gen/templates/const_serializer.java b/java_gen/templates/const_serializer.java
index 5710f9c..12ff28a 100644
--- a/java_gen/templates/const_serializer.java
+++ b/java_gen/templates/const_serializer.java
@@ -33,10 +33,7 @@
 
 package ${package};
 
-import org.projectfloodlight.openflow.types.*;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.projectfloodlight.openflow.exceptions.OFParseError;
-import org.projectfloodlight.openflow.protocol.OFVersion;
+//:: include('_imports.java')
 import ${enum.package}.${enum.name};
 
 public class ${class_name} {
@@ -60,6 +57,10 @@
         ${wire_type.write_op(version=version, name="toWireValue(e)")};
     }
 
+    public static void putTo(${enum.name} e, PrimitiveSink sink) {
+        ${wire_type.funnel_op(version=version, name="toWireValue(e)")};
+    }
+
     public static ${enum.name} ofWireValue(${int_wire_type} val) {
         switch(val) {
         //:: for entry, _ in entries:
@@ -71,6 +72,7 @@
         }
     }
 
+
     public static ${int_wire_type} toWireValue(${enum.name} e) {
         switch(e) {
         //:: for entry, _ in entries:
diff --git a/java_gen/templates/const_set_serializer.java b/java_gen/templates/const_set_serializer.java
index 4fcff22..4c624ee 100644
--- a/java_gen/templates/const_set_serializer.java
+++ b/java_gen/templates/const_set_serializer.java
@@ -33,14 +33,8 @@
 
 package ${package};
 
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Set;
+//:: include('_imports.java')
 
-import org.projectfloodlight.openflow.types.*;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.projectfloodlight.openflow.exceptions.OFParseError;
-import org.projectfloodlight.openflow.protocol.OFVersion;
 import ${enum.package}.${enum.name};
 
 public class ${class_name} {
@@ -64,6 +58,11 @@
         ${wire_type.write_op(version=version, name="toWireValue(set)")};
     }
 
+    public static void putTo(Set<${enum.name}> set, PrimitiveSink sink) {
+        ${wire_type.funnel_op(version=version, name="toWireValue(set)")};
+    }
+
+
     public static Set<${enum.name}> ofWireValue(${int_wire_type} val) {
         EnumSet<${enum.name}> set = EnumSet.noneOf(${enum.name}.class);
 
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 829d257..8014ee7 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -247,6 +247,33 @@
         }
     }
 
+    public void putTo(PrimitiveSink sink) {
+        FUNNEL.funnel(this, sink);
+    }
+
+    final static ${impl_class}Funnel FUNNEL = new ${impl_class}Funnel();
+    static class ${impl_class}Funnel implements Funnel<${impl_class}> {
+        private static final long serialVersionUID = 1L;
+        @Override
+        public void funnel(${impl_class} message, PrimitiveSink sink) {
+//:: for prop in msg.members:
+//:: if prop.is_virtual:
+//::    continue
+//:: elif prop.is_data:
+            ${prop.java_type.funnel_op(version, "message." + prop.name, pub_type=True)};
+//:: elif prop.is_pad:
+            // skip pad (${prop.length} bytes)
+//:: elif prop.is_fixed_value:
+            // fixed value property ${prop.name} = ${prop.value}
+            ${prop.java_type.funnel_op(version, prop.priv_value, pub_type=False)};
+//:: else:
+            // FIXME: skip funnel of ${prop.name}
+//:: #endif
+//:: #endfor
+        }
+    }
+
+
     public void writeTo(ChannelBuffer bb) {
         WRITER.write(bb, this);
     }