Merge into master from pull request #175:
java_type: remove hard coded superclass information (https://github.com/floodlight/loxigen/pull/175)
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 6f86706..8726632 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -47,6 +47,10 @@
logger = logging.getLogger(__name__)
+
+def java_class_name(c_name):
+ return java_type.name_c_to_caps_camel(c_name) if c_name != "of_header" else "OFMessage"
+
class JavaModel(object):
# registry for enums that should not be generated
# set(${java_enum_name})
@@ -54,7 +58,6 @@
# registry for enum *entry* that should not be generated
# map: ${java_enum_name} -> set(${java_entry_entry_name})
enum_entry_blacklist = defaultdict(lambda: set(), OFFlowWildcards=set([ "NW_DST_BITS", "NW_SRC_BITS", "NW_SRC_SHIFT", "NW_DST_SHIFT" ]))
-
# registry of interfaces that should not be generated
# set(java_names)
# OFUint structs are there for god-knows what in loci. We certainly don't need them.
@@ -370,7 +373,7 @@
self.c_name = ir_class.name
self.version_map = { JavaOFVersion(v): c for v,c in ir_class.version_classes.items() }
# name: the Java Type name, e.g., OFFlowAdd
- self.name = java_type.name_c_to_caps_camel(self.c_name) if self.c_name != "of_header" else "OFMessage"
+ self.name = java_class_name(self.c_name)
# variable_name name to use for variables of this type. i.e., flowAdd
self.variable_name = self.name[2].lower() + self.name[3:]
self.title_name = self.variable_name[0].upper() + self.variable_name[1:]
@@ -434,99 +437,66 @@
def class_info(self):
""" return tuple of (package_prefix, parent_class) for the current JavaOFInterface"""
- # FIXME: This duplicates inheritance information that is now available in the loxi_ir
- # model (note, that the loxi model is on versioned classes). Should check/infer the
- # inheritance information from the versioned lox_ir classes.
- if re.match(r'OFStatsRequest$', self.name):
- return ("", "OFMessage", "T extends OFStatsReply")
+ # FIXME: This code could be cleaned up further. Maybe some of the exceptions
+ # here could be folded into ir, or the type arithmetic specified in a more general
+ # fashion
+ def calc_package(i):
+ if i.is_subclassof("of_error_msg"):
+ return "errormsg"
+ elif i.is_instanceof("of_action"):
+ return "action"
+ elif i.is_instanceof("of_action_id"):
+ return "actionid"
+ elif i.is_instanceof("of_instruction"):
+ return "instruction"
+ elif i.is_instanceof("of_instruction_id"):
+ return "instructionid"
+ elif i.is_instanceof("of_oxm"):
+ return "oxm"
+ elif i.is_instanceof("of_meter_band"):
+ return "meterband"
+ elif i.is_instanceof("of_queue_prop"):
+ return "queueprop"
+ elif i.is_instanceof("of_bsn_tlv"):
+ return "bsntlv"
+ else:
+ return ""
+
+ def calc_super_name(i):
+ if re.match('of_match_.*', i.name):
+ return "Match"
+ else:
+ ir_super_class = self.ir_class.superclass
+ return java_class_name(ir_super_class.name) if ir_super_class else ""
+
+ package = calc_package(self.ir_class)
+ super_name = calc_super_name(self.ir_class)
+
+ if self.name == "OFStatsRequest":
+ # stats_requests are special because of their type annotation
+ return (package, "OFMessage", "T extends OFStatsReply")
elif self.ir_class.is_subclassof('of_stats_request'):
- if self.ir_class.is_subclassof('of_bsn_stats_request'):
- return ("", "OFBsnStatsRequest", None)
- elif self.ir_class.is_subclassof('of_experimenter_stats_request'):
- return ("", "OFExperimenterStatsRequest", None)
- else:
- return ("", "OFStatsRequest<{}>".format(re.sub(r'Request$', 'Reply', self.name)), None)
- elif self.ir_class.is_subclassof('of_stats_reply'):
- if self.ir_class.is_subclassof('of_bsn_stats_reply'):
- return ("", "OFBsnStatsReply", None)
- elif self.ir_class.is_subclassof('of_experimenter_stats_reply'):
- return ("", "OFExperimenterStatsReply", None)
- else:
- return ("", "OFStatsReply", None)
- elif self.ir_class.is_subclassof('of_error_msg'):
- return ("errormsg", "OFErrorMsg", None)
- elif self.ir_class.is_subclassof('of_flow_mod'):
- return ("", "OFFlowMod", None)
- elif self.ir_class.is_subclassof('of_group_mod'):
- return ("", "OFGroupMod", None)
- elif self.ir_class.is_subclassof('of_bsn_header'):
- return ("", "OFBsnHeader", None)
- elif self.ir_class.is_subclassof('of_nicira_header'):
- return ("", "OFNiciraHeader", None)
- elif self.ir_class.is_subclassof('of_experimenter'):
- return ("", "OFExperimenter", None)
- elif re.match(r'OFMatch.*', self.name):
- return ("", "Match", None)
- elif self.ir_class.is_message:
- return ("", "OFMessage", None)
- elif self.ir_class.is_action:
- if self.ir_class.is_subclassof('of_action_bsn'):
- return ("action", "OFActionBsn", None)
- elif self.ir_class.is_subclassof('of_action_nicira'):
- return ("action", "OFActionNicira", None)
- elif self.ir_class.is_subclassof('of_action_experimenter'):
- return ("action", "OFActionExperimenter", None)
- else:
- return ("action", "OFAction", None)
- elif self.ir_class.is_instanceof("of_action_id"):
- if self.ir_class.is_subclassof('of_action_id_bsn'):
- return ("actionid", "OFActionIdBsn", None)
- elif self.ir_class.is_subclassof('of_action_id_nicira'):
- return ("actionid", "OFActionIdNicira", None)
- elif self.ir_class.is_subclassof('of_action_id_experimenter'):
- return ("actionid", "OFActionIdExperimenter", None)
- else:
- return ("actionid", "OFActionId", None)
- elif self.ir_class.is_instruction:
- if self.ir_class.is_subclassof('of_instruction_bsn'):
- return ("instruction", "OFInstructionBsn", None)
- elif self.ir_class.is_subclassof('of_instruction_experimenter'):
- return ("instruction", "OFInstructionExperimenter", None)
- else:
- return ("instruction", "OFInstruction", None)
- elif self.ir_class.is_instanceof('of_instruction_id'):
- if self.ir_class.is_subclassof('of_instruction_id_bsn'):
- return ("instructionid", "OFInstructionIdBsn", None)
- elif self.ir_class.is_subclassof('of_instruction_id_experimenter'):
- return ("instructionid", "OFInstructionIdExperimenter", None)
- else:
- return ("instructionid", "OFInstructionId", None)
- elif re.match(r'OFBsnVport.+$', self.name):
- return ("", "OFBsnVport", None)
+ # stats_request subclasses are special because of their type annotation
+ reply_name = re.sub(r'Request$', 'Reply', self.name)
+ super_type_annotation = "T" if self.ir_class.virtual else reply_name
+
+ type_annotation = "T extends {}".format(reply_name) if self.ir_class.virtual \
+ else ""
+
+ return (package, "{}<{}>".format(super_name, super_type_annotation),
+ type_annotation)
elif self.name == "OFOxm":
- return ("oxm", None, "T extends OFValueType<T>")
+ return (package, None, "T extends OFValueType<T>")
elif loxi_utils.class_is_oxm(self.c_name):
+ # look up type from member value for OFValueType type annotation
if self.member_by_name("value") is not None:
- return ("oxm", "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None)
+ return (package, "OFOxm<%s>" % self.member_by_name("value").java_type.public_type, None)
else:
- return ("oxm", "OFOxm", None)
- elif loxi_utils.class_is_instruction(self.c_name):
- return ("instruction", "OFInstruction", None)
- elif loxi_utils.class_is_meter_band(self.c_name):
- return ("meterband", "OFMeterBand", None)
- elif loxi_utils.class_is_queue_prop(self.c_name):
- return ("queueprop", "OFQueueProp", None)
- elif loxi_utils.class_is_hello_elem(self.c_name):
- return ("", "OFHelloElem", None)
- elif loxi_utils.class_is_table_feature_prop(self.c_name):
- return ("", "OFTableFeatureProp", None)
- elif loxi_utils.class_is_bsn_tlv(self.c_name):
- return ("bsntlv", "OFBsnTlv", None)
+ return (package, "OFOxm", None)
else:
- return ("", None, None)
+ return (package, super_name, None)
@property
-
@memoize
def writeable_members(self):
return [ m for m in self.members if m.is_writeable ]