Adding copy builders for flow objectives.

Adding missing hashCode and equals methods.

Change-Id: I97b2d904eacf0c45a95905c0891dbc6465e18ec6
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
index d325415..4935990 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
@@ -28,7 +28,7 @@
     /**
      * Installs the filtering rules onto the specified device.
      *
-     * @param deviceId            device identifier
+     * @param deviceId           device identifier
      * @param filteringObjective the filtering objective
      */
     void filter(DeviceId deviceId, FilteringObjective filteringObjective);
@@ -36,7 +36,7 @@
     /**
      * Installs the forwarding rules onto the specified device.
      *
-     * @param deviceId             device identifier
+     * @param deviceId            device identifier
      * @param forwardingObjective the forwarding objective
      */
     void forward(DeviceId deviceId, ForwardingObjective forwardingObjective);
@@ -44,7 +44,7 @@
     /**
      * Installs the next hop elements into the specified device.
      *
-     * @param deviceId       device identifier
+     * @param deviceId      device identifier
      * @param nextObjective a next objective
      */
     void next(DeviceId deviceId, NextObjective nextObjective);
@@ -59,7 +59,25 @@
     /**
      * Installs the filtering rules onto the specified device.
      *
-     * @param policy            policy expression
+     * @param policy policy expression
      */
     void initPolicy(String policy);
+
+    /**
+     * Installs the objective onto the specified device.
+     *
+     * @param deviceId  device identifier
+     * @param objective the objective
+     */
+    default void apply(DeviceId deviceId, Objective objective) {
+        if (ForwardingObjective.class.isAssignableFrom(objective.getClass())) {
+            forward(deviceId, (ForwardingObjective) objective);
+        } else if (FilteringObjective.class.isAssignableFrom(objective.getClass())) {
+            filter(deviceId, (FilteringObjective) objective);
+        } else if (NextObjective.class.isAssignableFrom(objective.getClass())) {
+            next(deviceId, (NextObjective) objective);
+        } else {
+            throw new UnsupportedOperationException("Unsupported objective of type " + objective.getClass());
+        }
+    }
 }