java_gen: added ability to define metadata for enums

added metadata PortSpeed to OFPortFeatures
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 4f77390..12fe0b4 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -130,6 +130,27 @@
                 "OFOxmMplsTcMasked":        OxmMapEntry("U8", "MPLS_TC", True)
                 }
 
+    class OFEnumMetadata(namedtuple("OFEnumMetadata", ("name", "type", "value"))):
+        @property
+        def variable_name(self):
+            return self.name[0].lower() + self.name[1:]
+
+        @property
+        def getter_name(self):
+            return "get"+self.name
+
+    def gen_port_speed(enum_entry):
+        splits = enum_entry.name.split("_")
+        if len(splits)>=2:
+            m = re.match(r'\d+[MGTP]B', splits[1])
+            if m:
+                return "PortSpeed.SPEED_{}".format(splits[1])
+        return "PortSpeed.SPEED_NONE";
+
+    enum_metadata_map = defaultdict(lambda: (),
+            OFPortFeatures = ( OFEnumMetadata("PortSpeed", java_type.port_speed, gen_port_speed), )
+    )
+
     @property
     @memoize
     def versions(self):
@@ -979,6 +1000,8 @@
         self.entries = [ e for e in self.entries if e.name not in model.enum_entry_blacklist[self.name] ]
         self.package = "org.projectfloodlight.openflow.protocol"
 
+        self.metadata = model.enum_metadata_map[self.name]
+
     def wire_type(self, version):
         ir_enum = self.version_enums[version]
         if "wire_type" in ir_enum.params:
@@ -1021,6 +1044,10 @@
         self.name = enum.name_prefix + "_".join(name.split("_")[1:]).upper()
         self.values = values
 
+    @property
+    def constructor_params(self):
+        return [ m.value(self) for m in self.enum.metadata ]
+
     def has_value(self, version):
         return version in self.values
 
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index e7f2201..0844686 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -305,6 +305,7 @@
 meter_features = JType("OFMeterFeatures")\
         .op(read="OFMeterFeaturesVer$version.READER.readFrom(bb)", write="$name.writeTo(bb)")
 
+port_speed = JType("PortSpeed")
 boolean = JType("boolean")
 
 generic_t = JType("T")
diff --git a/java_gen/templates/const.java b/java_gen/templates/const.java
index b5c7ed0..7542d53 100644
--- a/java_gen/templates/const.java
+++ b/java_gen/templates/const.java
@@ -33,11 +33,35 @@
 
 package ${package};
 
-import org.projectfloodlight.openflow.protocol.OFVersion;
+//:: include("_imports.java", msg=enum)
 
 public enum ${class_name} {
 //:: for i, entry in enumerate(enum.entries):
-     ${entry.name}${ ", " if i < len(enum.entries)-1 else ";" }
+//::    if enum.metadata:
+//::        params = "({})".format(", ".join(entry.constructor_params))
+//::    else:
+//::        params = ""
+//::    #endif
+     ${entry.name}${params}${ ", " if i < len(enum.entries)-1 else ";" }
 //:: #endfor
 
+//:: if enum.metadata:
+//:: for metadata in enum.metadata:
+     private final ${metadata.type.public_type} ${metadata.variable_name};
+//:: #endfor
+
+     private ${class_name}(${", ".join("{} {}".format(m.type.public_type, m.variable_name) for m in enum.metadata)}) {
+     //:: for metadata in enum.metadata:
+        this.${metadata.variable_name} = ${metadata.variable_name};
+     //:: #endfor
+     }
+
+//:: for metadata in enum.metadata:
+     public ${metadata.type.public_type} ${metadata.getter_name}() {
+         return ${metadata.variable_name};
+     }
+//:: #endfor
+
+
+//:: #endif
 }