ONOS-5976 Added CodecContext service to UiMessageHandler to allow
handlers to use JsonCodecs.

Modified the DeviceView to utilize the JSON Codec context capability
for demonstration purposes.   Functionality should be identical.

Change-Id: Ic6d25b4be6fc634dfa88277f17f93287af4c331c
diff --git a/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java b/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java
index 609c28b..c38d741 100644
--- a/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java
+++ b/core/api/src/main/java/org/onosproject/ui/UiMessageHandler.java
@@ -19,6 +19,9 @@
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.JsonCodec;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -51,6 +54,11 @@
  * the <em>event-type</em> is determined, and the message dispatched to the
  * corresponding <em>RequestHandler</em>'s
  * {@link RequestHandler#process process} method.
+ * <p>
+ * For convenience the implementation includes methods to obtain JSON
+ * generating objects (mapper, objectNode, arrayNode) as well as a
+ * JsonCodecContext for preparing and digesting messages to the UI
+ * client.
  */
 public abstract class UiMessageHandler {
 
@@ -62,6 +70,7 @@
     private UiConnection connection;
     private ServiceDirectory directory;
 
+    private MessageCodecContext codecContext;
 
     /**
      * Subclasses must create and return the collection of request handlers
@@ -202,4 +211,40 @@
             connection.sendMessage(data);
         }
     }
+
+    /**
+     * Obtain a CodecContext to be used in encoding and decoding objects
+     * that have a registered JsonCodec for their class.  This method
+     * instantiates a private inner class which is returned on
+     * subsequent calls.
+     *
+     * @return a CodecContext.
+     */
+    protected CodecContext getJsonCodecContext() {
+        if (codecContext != null) {
+            return codecContext;
+        }
+        codecContext = new MessageCodecContext();
+        return codecContext;
+    }
+
+    private class MessageCodecContext implements CodecContext {
+
+        CodecService cs = get(CodecService.class);
+
+        @Override
+        public ObjectMapper mapper() {
+            return mapper;
+        }
+
+        @Override
+        public <T> JsonCodec<T> codec(Class<T> entityClass) {
+            return cs.getCodec(entityClass);
+        }
+
+        @Override
+        public <T> T getService(Class<T> serviceClass) {
+            return get(serviceClass);
+        }
+    }
 }