Fix a bug when creating FlowId and FlowBatchId from hex string:

 * Added static methods FlowId.valueOf(String) and FlowBatchId.valueOf(String)
   Implementation-wise, those methods are practically same as
   IntentId.valueOf(String)

 * Used the above methods as appropriate.

This fixes an exception that for some reason only occasionally shows-up
in logs of some of the unit tests, and also does not break those tests.

Also, make the change to accept hex strings starting with either 0x or 0X.

Change-Id: Iaaee529866deb1a89ccc3f306901672f25be6326
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchId.java b/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchId.java
index 219f779..d36ee7c 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchId.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/FlowBatchId.java
@@ -11,9 +11,26 @@
  */
 @Immutable
 public final class FlowBatchId {
+    private static final int DEC = 10;
+    private static final int HEX = 16;
+
     private final long id;
 
     /**
+     * Creates a flow batch identifier from the specified string
+     * representation.
+     *
+     * @param value long value
+     * @return flow batch identifier
+     */
+    public static FlowBatchId valueOf(String value) {
+        long id = value.toLowerCase().startsWith("0x")
+                ? Long.parseLong(value.substring(2), HEX)
+                : Long.parseLong(value, DEC);
+        return new FlowBatchId(id);
+    }
+
+    /**
      * Creates a new FlowBatchId object using long value.
      */
     public FlowBatchId(long id) {
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/FlowId.java b/src/main/java/net/onrc/onos/api/flowmanager/FlowId.java
index 3bf9a30..c72d7cb 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/FlowId.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/FlowId.java
@@ -13,9 +13,25 @@
  */
 @Immutable
 public final class FlowId implements BatchOperationTarget {
+    private static final int DEC = 10;
+    private static final int HEX = 16;
+
     private final long id;
 
     /**
+     * Creates a flow identifier from the specified string representation.
+     *
+     * @param value long value
+     * @return flow identifier
+     */
+    public static FlowId valueOf(String value) {
+        long id = value.toLowerCase().startsWith("0x")
+                ? Long.parseLong(value.substring(2), HEX)
+                : Long.parseLong(value, DEC);
+        return new FlowId(id);
+    }
+
+    /**
      * Default constructor for Kryo deserialization.
      */
     @Deprecated
diff --git a/src/main/java/net/onrc/onos/api/newintent/IntentId.java b/src/main/java/net/onrc/onos/api/newintent/IntentId.java
index ebe1b45..4552187 100644
--- a/src/main/java/net/onrc/onos/api/newintent/IntentId.java
+++ b/src/main/java/net/onrc/onos/api/newintent/IntentId.java
@@ -21,7 +21,7 @@
      * @return intent identifier
      */
     public static IntentId valueOf(String value) {
-        long id = value.startsWith("0x")
+        long id = value.toLowerCase().startsWith("0x")
                 ? Long.parseLong(value.substring(2), HEX)
                 : Long.parseLong(value, DEC);
         return new IntentId(id);
diff --git a/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowBatchMapEventDispatcher.java b/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowBatchMapEventDispatcher.java
index 7107be8..d87defb 100644
--- a/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowBatchMapEventDispatcher.java
+++ b/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowBatchMapEventDispatcher.java
@@ -59,7 +59,7 @@
         if (value instanceof FlowBatchOperation) {
             // Handles events from flowBatchMap.
             final FlowBatchOperation flowOp = (FlowBatchOperation) value;
-            final FlowBatchId id = new FlowBatchId(Long.parseLong(event.getKey()));
+            final FlowBatchId id = FlowBatchId.valueOf(event.getKey());
             log.trace("Flow batch operation ID:{}, {} was added", id, flowOp);
             for (FlowBatchMapEventListener e : listeners) {
                 FlowBatchOperation copiedFlowOp =
@@ -70,7 +70,7 @@
         } else if (value instanceof FlowBatchState) {
             // Handles events from flowBatchStateMap.
             final FlowBatchState state = (FlowBatchState) value;
-            final FlowBatchId id = new FlowBatchId(Long.parseLong(event.getKey()));
+            final FlowBatchId id = FlowBatchId.valueOf(event.getKey());
             log.trace("FlowState of FlowId {} was set to {}", id, state);
             for (FlowBatchMapEventListener e : listeners) {
                 e.flowBatchOperationStateChanged(id, FlowBatchState.SUBMITTED, state);
@@ -86,7 +86,7 @@
         if (value instanceof FlowBatchOperation) {
             // Handles events from flowBatchMap.
             final FlowBatchOperation flowOp = (FlowBatchOperation) value;
-            final FlowBatchId id = new FlowBatchId(Long.parseLong(event.getKey()));
+            final FlowBatchId id = FlowBatchId.valueOf(event.getKey());
             log.trace("Flow batch operation ID:{}, {} was removed", id, flowOp);
             for (FlowBatchMapEventListener e : listeners) {
                 e.flowBatchOperationRemoved(id);
@@ -110,7 +110,7 @@
             Object oldValue = KryoFactory.deserialize(event.getOldValue());
             final FlowBatchState currentState = (FlowBatchState) value;
             final FlowBatchState oldState = (FlowBatchState) oldValue;
-            final FlowBatchId id = new FlowBatchId(Long.parseLong(event.getKey()));
+            final FlowBatchId id = FlowBatchId.valueOf(event.getKey());
             log.trace("Flow batch state of ID:{} was updated from {} to {}",
                     id, oldState, currentState);
             for (FlowBatchMapEventListener e : listeners) {
diff --git a/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowMapEventDispatcher.java b/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowMapEventDispatcher.java
index cc41ce0..9368ac2 100644
--- a/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowMapEventDispatcher.java
+++ b/src/main/java/net/onrc/onos/core/flowmanager/SharedFlowMapEventDispatcher.java
@@ -67,7 +67,7 @@
         } else if (value instanceof FlowState) {
             // Handles events from flowStateMap.
             final FlowState state = (FlowState) value;
-            final FlowId id = new FlowId(Long.parseLong(event.getKey()));
+            final FlowId id = FlowId.valueOf(event.getKey());
             log.trace("FlowState of FlowId {} was set to {}", id, state);
             for (FlowMapEventListener e : listeners) {
                 e.flowStateChanged(id, FlowState.SUBMITTED, state);
@@ -106,7 +106,7 @@
             Object oldValue = KryoFactory.deserialize(event.getOldValue());
             final FlowState state = (FlowState) value;
             final FlowState oldState = (FlowState) oldValue;
-            final FlowId id = new FlowId(Long.parseLong(event.getKey()));
+            final FlowId id = FlowId.valueOf(event.getKey());
             log.trace("FlowState of FlowId {} was updated from {} to {}",
                     id, oldState, state);
             for (FlowMapEventListener e : listeners) {