Various improvements for the of classes
diff --git a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java
index 8f17845..cdb34e5 100644
--- a/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java
+++ b/java_gen/pre-written/src/main/java/org/openflow/protocol/match/Match.java
@@ -32,20 +32,20 @@
* On prerequisites:<br>
* From the OF1.1 spec, page 28, the OF1.0 spec failed to explicitly specify this, but it
* is the behavior of OF1.0 switches:
- * "Protocol-specific fields within ofp_match will be ignored within a single table when
- * the corresponding protocol is not specified in the match. The MPLS match fields will
- * be ignored unless the Ethertype is specified as MPLS. Likewise, the IP header and
- * transport header fields will be ignored unless the Ethertype is specified as either
- * IPv4 or ARP. The tp_src and tp_dst fields will be ignored unless the network protocol
- * specified is as TCP, UDP or SCTP. Fields that are ignored donÕt need to be wildcarded
+ * "Protocol-specific fields within ofp_match will be ignored within a single table when
+ * the corresponding protocol is not specified in the match. The MPLS match fields will
+ * be ignored unless the Ethertype is specified as MPLS. Likewise, the IP header and
+ * transport header fields will be ignored unless the Ethertype is specified as either
+ * IPv4 or ARP. The tp_src and tp_dst fields will be ignored unless the network protocol
+ * specified is as TCP, UDP or SCTP. Fields that are ignored don�t need to be wildcarded
* and should be set to 0."
* <br><br>
- * This interface uses generics to assure type safety in users code. However, implementing classes may have to suppress
+ * This interface uses generics to assure type safety in users code. However, implementing classes may have to suppress
* 'unchecked cast' warnings while making sure they correctly cast base on their implementation details.
- *
+ *
* @author Yotam Harchol (yotam.harchol@bigswitch.com)
*/
-public interface Match extends OFObject {
+public interface Match extends OFObject {
/**
* Returns a value for the given field if:
@@ -55,7 +55,7 @@
* <li>Prerequisites are ok
* </ul>
* If one of the above conditions does not hold, returns null. Value is returned masked if partially wildcarded.
- *
+ *
* @param field Match field to retrieve
* @return Value of match field (may be masked), or <code>null</code> if field is one of the conditions above does not hold.
* @throws UnsupportedOperationException If field is not supported.
@@ -66,7 +66,7 @@
* Returns the masked value for the given field from this match, along with the mask itself.
* Prerequisite: field is partially masked.
* If prerequisite is not met, a <code>null</code> is returned.
- *
+ *
* @param field Match field to retrieve.
* @return Masked value of match field or null if no mask is set.
* @throws UnsupportedOperationException If field is not supported.
@@ -75,7 +75,7 @@
/**
* Returns true if and only if this match object supports the given match field.
- *
+ *
* @param field Match field
* @return true if field is supported, false otherwise.
*/
@@ -84,7 +84,7 @@
/**
* Returns true if and only if this match object supports partially bitmasking of the given field.
* (note: not all possible values of this bitmask have to be acceptable)
- *
+ *
* @param field Match field.
* @return true if field can be partially masked, false otherwise.
* @throws UnsupportedOperationException If field is not supported.
@@ -94,7 +94,7 @@
/**
* Returns true if and only if this field is currently specified in the match with an exact value and
* no mask. I.e., the specified match will only select packets that match the exact value of getValue(field).
- *
+ *
* @param field Match field.
* @return true if field has a specific exact value, false if not.
* @throws UnsupportedOperationException If field is not supported.
@@ -102,10 +102,10 @@
public boolean isExact(MatchField<?> field) throws UnsupportedOperationException;
/**
- * True if and only if this field is currently logically unspecified in the match, i.e, the
- * value returned by getValue(f) has no impact on whether a packet will be selected
+ * True if and only if this field is currently logically unspecified in the match, i.e, the
+ * value returned by getValue(f) has no impact on whether a packet will be selected
* by the match or not.
- *
+ *
* @param field Match field.
* @return true if field is fully wildcarded, false if not.
* @throws UnsupportedOperationException If field is not supported.
@@ -113,16 +113,16 @@
public boolean isFullyWildcarded(MatchField<?> field) throws UnsupportedOperationException;
/**
- * True if and only if this field is currently partially specified in the match, i.e, the
+ * True if and only if this field is currently partially specified in the match, i.e, the
* match will only select packets that match (p.value & getMask(field)) == getValue(field),
* and getMask(field) != 0.
- *
+ *
* @param field Match field.
* @return true if field is partially masked, false if not.
* @throws UnsupportedOperationException If field is not supported.
*/
public boolean isPartiallyMasked(MatchField<?> field) throws UnsupportedOperationException;
-
+
/**
* Returns a builder to build new instances of this type of match object.
* @return Match builder
@@ -135,17 +135,17 @@
* corresponds to. The builder uses the same notation of wildcards and masks, and can also throw
* <code>UnsupportedOperationException</code> if it is asked to create some matching that is not supported in
* the version it represents.
- *
+ *
* While used, MatchBuilder may not be consistent in terms of field prerequisites. However, user must
* solve these before using the generated Match object as these prerequisites should be enforced in the
- * getters.
- *
+ * getters.
+ *
* @author Yotam Harchol (yotam.harchol@bigswitch.com)
*/
interface Builder extends Match {
/**
* Sets a specific exact value for a field.
- *
+ *
* @param field Match field to set.
* @param value Value of match field.
* @return the Builder instance used.
@@ -155,7 +155,7 @@
/**
* Sets a masked value for a field.
- *
+ *
* @param field Match field to set.
* @param value Value of field.
* @param mask Mask value.
@@ -166,7 +166,7 @@
/**
* Sets a masked value for a field.
- *
+ *
* @param field Match field to set.
* @param valueWithMask Compound Masked object contains the value and the mask.
* @return the Builder instance used.
@@ -176,7 +176,7 @@
/**
* Unsets any value given for the field and wildcards it so that it matches any value.
- *
+ *
* @param field Match field to unset.
* @return the Builder instance used.
* @throws UnsupportedOperationException If field is not supported.
@@ -185,9 +185,9 @@
/**
* Returns the match created by this builder.
- *
+ *
* @return a Match object.
*/
- public Match getMatch();
+ public Match build();
}
}
\ No newline at end of file
diff --git a/java_gen/templates/_field_accessors.java b/java_gen/templates/_field_accessors.java
index e8afe47..b64b29b 100644
--- a/java_gen/templates/_field_accessors.java
+++ b/java_gen/templates/_field_accessors.java
@@ -1,6 +1,6 @@
//:: for prop in msg.interface.members:
@Override
- public ${prop.java_type.public_type} get${prop.title_name}()${ "" if prop in msg.members else "throws UnsupportedOperationException"} {
+ public ${prop.java_type.public_type} ${prop.getter_name}()${ "" if prop in msg.members else "throws UnsupportedOperationException"} {
//:: if prop in msg.members:
//:: version_prop = msg.get_member(prop.name)
//:: if version_prop.is_fixed_value:
@@ -20,7 +20,7 @@
//:: if generate_setters and prop.is_writeable:
@Override
- public ${msg.interface.name}.Builder set${prop.title_name}(${prop.java_type.public_type} ${prop.name})${ "" if prop in msg.members else " throws UnsupportedOperationException"} {
+ public ${msg.interface.name}.Builder ${prop.setter_name}(${prop.java_type.public_type} ${prop.name})${ "" if prop in msg.members else " throws UnsupportedOperationException"} {
//:: if prop in msg.members:
this.${prop.name} = ${prop.name};
this.${prop.name}Set = true;
diff --git a/java_gen/templates/of_class.java b/java_gen/templates/of_class.java
index 43d9893..bcaf961 100644
--- a/java_gen/templates/of_class.java
+++ b/java_gen/templates/of_class.java
@@ -37,7 +37,7 @@
//:: include("_imports.java", msg=msg)
-class ${impl_class} implements ${msg.interface.name} {
+class ${impl_class} implements ${msg.interface.inherited_declaration()} {
// version: ${version}
private final static byte WIRE_VERSION = ${version.int_version};
//:: if msg.is_fixed_length:
@@ -55,20 +55,29 @@
private final ${prop.java_type.public_type} ${prop.name};
//:: #endfor
+ //:: if msg.data_members:
+ // package private constructor - used by readers, builders, and factory
${impl_class}(${
", ".join("%s %s" %(prop.java_type.public_type, prop.name) for prop in msg.data_members) }) {
//:: for prop in msg.data_members:
this.${prop.name} = ${prop.name};
//:: #endfor
}
+ //:: else:
+ final static ${impl_class} INSTANCE = new ${impl_class}();
+ // private empty constructor - use shared instance!
+ private ${impl_class}() {
+ }
+ //:: #endif
// Accessors for OF message fields
-//:: include("_field_accessors.java", msg=msg, generate_setters=False, builder=False)
+ //:: include("_field_accessors.java", msg=msg, generate_setters=False, builder=False)
//:: if os.path.exists("%s/custom/%s.java" % (template_dir, msg.name)):
//:: include("custom/%s.java" % msg.name, msg=msg)
//:: #endif
+ //:: if msg.data_members:
public ${msg.interface.name}.Builder createBuilder() {
return new BuilderWithParent(this);
}
@@ -89,7 +98,7 @@
//:: include("_field_accessors.java", msg=msg, generate_setters=True, builder=True)
@Override
- public ${msg.interface.name} getMessage() {
+ public ${msg.interface.name} build() {
return new ${impl_class}(
${",\n ".join(
[ "this.{0}Set ? this.{0} : parentMessage.{0}".format(prop.name)
@@ -112,7 +121,7 @@
//:: include("_field_accessors.java", msg=msg, generate_setters=True, builder=True)
//
@Override
- public ${msg.interface.name} getMessage() {
+ public ${msg.interface.name} build() {
return new ${impl_class}(
${",\n ".join(
[ "this.{0}Set ? this.{0} : {1}.{2}".format(prop.name, impl_class, prop.default_name)
@@ -124,6 +133,13 @@
//:: #endif
}
+ //:: else:
+ // no data members - do not support builder
+ public ${msg.interface.name}.Builder createBuilder() {
+ throw new UnsupportedOperationException("${impl_class} has no mutable properties -- builder unneeded");
+ }
+ //:: #endif
+
final static Reader READER = new Reader();
static class Reader implements OFMessageReader<${msg.interface.name}> {
@@ -132,7 +148,9 @@
int start = bb.readerIndex();
//:: fields_with_length_member = {}
//:: for prop in msg.members:
-//:: if prop.is_data:
+//:: if prop.is_virtual:
+//:: continue
+//:: elif prop.is_data:
${prop.java_type.public_type} ${prop.name} = ${prop.java_type.read_op(version, pub_type=True,
length=fields_with_length_member[prop.c_name] if prop.c_name in fields_with_length_member else None)};
//:: elif prop.is_pad:
@@ -159,10 +177,14 @@
bb.skipBytes(((length + ${msg.align-1})/${msg.align} * ${msg.align} ) - length );
//:: #endif
+ //:: if msg.data_members:
return new ${impl_class}(
${",\n ".join(
[ prop.name for prop in msg.data_members])}
);
+ //:: else:
+ return INSTANCE;
+ //:: #endif
}
}
@@ -180,7 +202,9 @@
//:: if prop.c_name in fields_with_length_member:
int ${prop.name}StartIndex = bb.writerIndex();
//:: #endif
-//:: if prop.is_data:
+//:: if prop.is_virtual:
+//:: continue
+//:: elif prop.is_data:
${prop.java_type.write_op(version, "message." + prop.name, pub_type=True)};
//:: elif prop.is_pad:
// pad: ${prop.length} bytes