Refactor: Use bidirectional map to make methods easily consistent

Change-Id: I016bb98366351f60e4a6cc36de224a3d3163ac2d
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index ddccd2a..ff80aa3 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -383,7 +383,7 @@
                     mBuilder.setExact(MatchField.OCH_SIGID,
                             new CircuitSignalID(gridType, channelSpacing,
                                     (short) signal.spacingMultiplier(), (short) signal.slotGranularity()));
-                } catch (UnsupportedGridTypeException | UnsupportedChannelSpacingException e) {
+                } catch (UnsupportedConversionException e) {
                     log.warn(e.getMessage());
                 }
                 break;
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderHelper.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderHelper.java
index 19d27b5..8a94400 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderHelper.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderHelper.java
@@ -15,11 +15,11 @@
  */
 package org.onosproject.provider.of.flow.impl;
 
+import com.google.common.collect.BiMap;
+import com.google.common.collect.EnumHashBiMap;
 import org.onosproject.net.ChannelSpacing;
 import org.onosproject.net.GridType;
 import org.onosproject.net.OchSignalType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Collection of helper methods to convert protocol agnostic models to values used in OpenFlow spec.
@@ -27,35 +27,63 @@
 // TODO: Rename to a better name
 final class FlowModBuilderHelper {
 
-    private static final Logger log = LoggerFactory.getLogger(FlowModBuilderHelper.class);
-
     // prohibit instantiation
     private FlowModBuilderHelper() {}
 
+    private static final BiMap<GridType, Byte> GRID_TYPES = EnumHashBiMap.create(GridType.class);
+    static {
+        // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
+        GRID_TYPES.put(GridType.DWDM, (byte) 1); // OFPGRIDT_DWDM of enum ofp_grid_type
+        GRID_TYPES.put(GridType.CWDM, (byte) 2); // OFPGRIDT_CWDM of enum ofp_grid_type
+        GRID_TYPES.put(GridType.FLEX, (byte) 3); // OFPGRIDT_FLEX of enum ofp_grid_type
+    }
+
+    private static final BiMap<ChannelSpacing, Byte> CHANNEL_SPACING = EnumHashBiMap.create(ChannelSpacing.class);
+    static {
+        // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
+        CHANNEL_SPACING.put(ChannelSpacing.CHL_100GHZ, (byte) 1);   // OFPCS_100GHZ of enum ofp_chl_spacing
+        CHANNEL_SPACING.put(ChannelSpacing.CHL_50GHZ, (byte) 2);    // OFPCS_50GHZ of enum ofp_chl_spacing
+        CHANNEL_SPACING.put(ChannelSpacing.CHL_25GHZ, (byte) 3);    // OFPCS_25GHZ of enum ofp_chl_spacing
+        CHANNEL_SPACING.put(ChannelSpacing.CHL_12P5GHZ, (byte) 4);  // OFPCS_12P5GHZ of enum ofp_chl_spacing
+        CHANNEL_SPACING.put(ChannelSpacing.CHL_6P25GHZ, (byte) 5);  // OFPCS_6P25GHZ of enum ofp_chl_spacing
+    }
+
+    private static final BiMap<OchSignalType, Byte> OCH_SIGNAL_TYPES = EnumHashBiMap.create(OchSignalType.class);
+    static {
+        // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
+        OCH_SIGNAL_TYPES.put(OchSignalType.FIXED_GRID, (byte) 1); // OFPOCHT_FIX_GRID of enum ofp_och_signal_type
+        OCH_SIGNAL_TYPES.put(OchSignalType.FLEX_GRID, (byte) 2);  // OFPOCHT_FLEX_GRID of enum ofp_och_signal_type
+    }
+
+    /**
+     * Converts the specified input value to the corresponding value with the specified map.
+     *
+     * @param map bidirectional mapping
+     * @param input input value
+     * @param cls class of output value
+     * @param <I> type of input value
+     * @param <O> type of output value
+     * @return the corresponding value stored in the specified map
+     * @throws UnsupportedConversionException if no corresponding value is found
+     */
+    private static <I, O> O convert(BiMap<I, O> map, I input, Class<O> cls) {
+        if (!map.containsKey(input)) {
+            throw new UnsupportedConversionException(input, cls);
+        }
+
+        return map.get(input);
+    }
+
     /**
      * Converts a {@link GridType} to the corresponding byte value defined in
      * ONF "Optical Transport Protocol Extensions Version 1.0".
      *
      * @param type grid type
      * @return the byte value corresponding to the specified grid type
-     * @throws UnsupportedGridTypeException if the specified grid type is not supported
+     * @throws UnsupportedConversionException if the specified grid type is not supported
      */
     static byte convertGridType(GridType type) {
-        // See ONF "Optical Transport Protocol Extensions Version 1.0"
-        // for the following values
-        switch (type) {
-            case DWDM:
-                // OFPGRIDT_DWDM of enum ofp_grid_type
-                return 1;
-            case CWDM:
-                // OFPGRIDT_CWDM of enum ofp_grid_type
-                return 2;
-            case FLEX:
-                // OFPGRIDT_FLEX of enum ofp_grid_type
-                return 3;
-            default:
-                throw new UnsupportedGridTypeException(type);
-        }
+        return convert(GRID_TYPES, type, Byte.class);
     }
 
     /**
@@ -67,17 +95,7 @@
      * @return the corresponding GridType instance
      */
     static GridType convertGridType(byte type) {
-        switch (type) {
-            case 1:
-                return GridType.DWDM;
-            case 2:
-                return GridType.CWDM;
-            case 3:
-                return GridType.FLEX;
-            default:
-                log.info("The value {} for grid type is not supported");
-                return null;
-        }
+        return convert(GRID_TYPES.inverse(), type, GridType.class);
     }
 
     /**
@@ -86,30 +104,10 @@
      *
      * @param spacing channel spacing
      * @return byte value corresponding to the specified channel spacing
-     * @throws UnsupportedChannelSpacingException if the specified channel spacing is not supported
+     * @throws UnsupportedConversionException if the specified channel spacing is not supported
      */
     static byte convertChannelSpacing(ChannelSpacing spacing) {
-        // See ONF "Optical Transport Protocol Extensions Version 1.0"
-        // for the following values
-        switch (spacing) {
-            case CHL_100GHZ:
-                // OFPCS_100GHZ of enum ofp_chl_spacing
-                return 1;
-            case CHL_50GHZ:
-                // OFPCS_50GHZ of enum ofp_chl_spacing
-                return 2;
-            case CHL_25GHZ:
-                // OFPCS_25GHZ of enum ofp_chl_spacing
-                return 3;
-            case CHL_12P5GHZ:
-                // OFPCS_12P5GHZ of enum ofp_chl_spacing
-                return 4;
-            case CHL_6P25GHZ:
-                // OFPCS_6P25GHZ of enum ofp_chl_spacing
-                return 5;
-            default:
-                throw new UnsupportedChannelSpacingException(spacing);
-        }
+        return convert(CHANNEL_SPACING, spacing, Byte.class);
     }
 
     /**
@@ -121,21 +119,7 @@
      * @return the corresponding ChannelSpacing instance
      */
     static ChannelSpacing convertChannelSpacing(byte spacing) {
-        switch (spacing) {
-            case 1:
-                return ChannelSpacing.CHL_100GHZ;
-            case 2:
-                return ChannelSpacing.CHL_50GHZ;
-            case 3:
-                return ChannelSpacing.CHL_25GHZ;
-            case 4:
-                return ChannelSpacing.CHL_12P5GHZ;
-            case 5:
-                return ChannelSpacing.CHL_6P25GHZ;
-            default:
-                log.info("The value {} for channel spacing is not supported");
-                return null;
-        }
+        return convert(CHANNEL_SPACING.inverse(), spacing, ChannelSpacing.class);
     }
 
     /**
@@ -145,15 +129,7 @@
      * @return byte value corresponding to the specified OCh signal type
      */
     static byte convertOchSignalType(OchSignalType signalType) {
-        switch (signalType) {
-            case FIXED_GRID:
-                return (byte) 1;
-            case FLEX_GRID:
-                return (byte) 2;
-            default:
-                log.info("OchSignalType {} is not supported", signalType);
-                return (byte) 0;
-        }
+        return convert(OCH_SIGNAL_TYPES, signalType, Byte.class);
     }
 
     /**
@@ -165,14 +141,6 @@
      * @return the corresponding OchSignalType instance
      */
     static OchSignalType convertOchSignalType(byte signalType) {
-        switch (signalType) {
-            case 1:
-                return OchSignalType.FIXED_GRID;
-            case 2:
-                return OchSignalType.FLEX_GRID;
-            default:
-                log.info("The value {} for Och signal type is not supported");
-                return null;
-        }
+        return convert(OCH_SIGNAL_TYPES.inverse(), signalType, OchSignalType.class);
     }
 }
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index 67c16fa..413fbd0 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -267,7 +267,7 @@
             case OCH:
                 try {
                     return buildModOchSignalInstruction((ModOchSignalInstruction) i);
-                } catch (UnsupportedGridTypeException | UnsupportedChannelSpacingException e) {
+                } catch (UnsupportedConversionException e) {
                     log.warn(e.getMessage());
                     break;
                 }
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedChannelSpacingException.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedChannelSpacingException.java
deleted file mode 100644
index dac6894..0000000
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedChannelSpacingException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.provider.of.flow.impl;
-
-import org.onosproject.net.ChannelSpacing;
-
-/**
- * Thrown to indicate that unsupported channel spacing is referred.
- */
-public class UnsupportedChannelSpacingException extends RuntimeException {
-
-    /**
-     * Creates an instance with the specified unsupported channel spacing.
-     *
-     * @param unsupported unsupported channel spacing
-     */
-    public UnsupportedChannelSpacingException(ChannelSpacing unsupported) {
-        super("ChannelSpacing " + unsupported + " is not supported");
-    }
-}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedConversionException.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedConversionException.java
new file mode 100644
index 0000000..b3be21e
--- /dev/null
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedConversionException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.of.flow.impl;
+
+/**
+ * Thrown to indicate that unsupported conversion occurs.
+ */
+public class UnsupportedConversionException extends RuntimeException {
+    /**
+     * Creates an instance with the specified values.
+     *
+     * @param input input value of conversion causing this exception
+     * @param output the desired class which the input value is converted to
+     */
+    public UnsupportedConversionException(Object input, Class<?> output) {
+        super(String.format("No mapping found for %s when converting to %s", input, output.getName()));
+    }
+}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedGridTypeException.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedGridTypeException.java
deleted file mode 100644
index b02883d..0000000
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/UnsupportedGridTypeException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.provider.of.flow.impl;
-
-import org.onosproject.net.GridType;
-
-/**
- * Thrown to indicate that unsupported gird type is referred.
- */
-public class UnsupportedGridTypeException extends RuntimeException {
-
-    /**
-     * Creates an instance with the specified unsupported grid type.
-     *
-     * @param unsupported unsupported grid type
-     */
-    public UnsupportedGridTypeException(GridType unsupported) {
-        super("GridType " + unsupported + " is not supported");
-    }
-}