Merge into master from pull request #63:
Improve support for enum_types (https://github.com/floodlight/loxigen/pull/63)
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index bf74d82..9fab422 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -130,14 +130,17 @@
                 "OFOxmMplsTcMasked":        OxmMapEntry("U8", "MPLS_TC", True)
                 }
 
-    class OFEnumMetadata(namedtuple("OFEnumMetadata", ("name", "type", "value"))):
+    class OFEnumPropertyMetadata(namedtuple("OFEnumPropertyMetadata", ("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
+            prefix = "is" if self.type == java_type.boolean else "get"
+            return prefix+self.name
+
+    OFEnumMetadata = namedtuple("OFEnumMetadata", ("properties", "to_string"))
 
     def gen_port_speed(enum_entry):
         splits = enum_entry.name.split("_")
@@ -147,8 +150,16 @@
                 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), )
+    def gen_stp_state(enum_entry):
+        splits = enum_entry.name.split("_")
+        if len(splits)>=1:
+            if splits[0] == "STP":
+                return "true"
+        return "false"
+
+    enum_metadata_map = defaultdict(lambda: JavaModel.OFEnumMetadata((), None),
+            OFPortFeatures = OFEnumMetadata((OFEnumPropertyMetadata("PortSpeed", java_type.port_speed, gen_port_speed),), None),
+            OFPortState = OFEnumMetadata((OFEnumPropertyMetadata("StpState", java_type.boolean, gen_stp_state),), None),
     )
 
     @property
@@ -1053,7 +1064,7 @@
 
     @property
     def constructor_params(self):
-        return [ m.value(self) for m in self.enum.metadata ]
+        return [ m.value(self) for m in self.enum.metadata.properties ]
 
     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 0620df0..d011c96 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -235,8 +235,8 @@
             write='ChannelUtils.writeList(bb, $name)')
 buckets_list = JType('List<OFBucket>') \
         .op(read='ChannelUtils.readList(bb, $length, OFBucketVer$version.READER)', write='ChannelUtils.writeList(bb, $name)')
-port_desc_list = JType('List<OFPhysicalPort>') \
-        .op(read='ChannelUtils.readList(bb, $length, OFPhysicalPort.READER)', write='ChannelUtils.writeList(bb, $name)')
+port_desc_list = JType('List<OFPortDesc>') \
+        .op(read='ChannelUtils.readList(bb, $length, OFPortDescVer$version.READER)', write='ChannelUtils.writeList(bb, $name)')
 port_desc = JType('OFPortDesc') \
         .op(read='OFPortDescVer$version.READER.readFrom(bb)', \
             write='$name.writeTo(bb)')
diff --git a/java_gen/templates/const.java b/java_gen/templates/const.java
index 7542d53..2cd0101 100644
--- a/java_gen/templates/const.java
+++ b/java_gen/templates/const.java
@@ -36,32 +36,42 @@
 //:: include("_imports.java", msg=enum)
 
 public enum ${class_name} {
+
 //:: for i, entry in enumerate(enum.entries):
-//::    if enum.metadata:
+//::    if enum.metadata.properties:
 //::        params = "({})".format(", ".join(entry.constructor_params))
 //::    else:
 //::        params = ""
 //::    #endif
-     ${entry.name}${params}${ ", " if i < len(enum.entries)-1 else ";" }
+//::    delimiter = ", " if i < len(enum.entries)-1 else ";"
+//::    to_string_value = enum.metadata.to_string(entry) if enum.metadata.to_string else None
+//::    if to_string_value:
+     ${entry.name}${params} {
+         @Override
+         public String toString() {
+            return "${to_string_value}";
+         }
+     }${delimiter}
+//::    else:
+     ${entry.name}${params}${delimiter}
+//::    #endif
+//:: #endfor
+//:: if enum.metadata.properties:
+
+//:: for property_metadata in enum.metadata.properties:
+     private final ${property_metadata.type.public_type} ${property_metadata.variable_name};
 //:: #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};
+     private ${class_name}(${", ".join("{} {}".format(m.type.public_type, m.variable_name) for m in enum.metadata.properties)}) {
+     //:: for property_metadata in enum.metadata.properties:
+        this.${property_metadata.variable_name} = ${property_metadata.variable_name};
      //:: #endfor
      }
+//:: for property_metadata in enum.metadata.properties:
 
-//:: for metadata in enum.metadata:
-     public ${metadata.type.public_type} ${metadata.getter_name}() {
-         return ${metadata.variable_name};
+     public ${property_metadata.type.public_type} ${property_metadata.getter_name}() {
+         return ${property_metadata.variable_name};
      }
 //:: #endfor
-
-
 //:: #endif
 }