Serialization/Deserialization and a host of other fixes
[controller.git] / opendaylight / md-sal / sal-protocolbuffer-encoding / src / main / java / org / opendaylight / controller / cluster / datastore / node / NormalizedNodeToProtocolBufferNode.java
index f8ec57be8fd553fb240846628c513ff3061846a1..fb153126650bd55ee07f188c1b5ea900a80aef6b 100644 (file)
@@ -1,5 +1,7 @@
 package org.opendaylight.controller.cluster.datastore.node;
 
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils;
 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -24,177 +26,229 @@ import java.util.Map;
 /**
  * NormalizedNodeToProtocolBufferNode walks the NormalizedNode tree converting it to the
  * NormalizedMessage.Node
- *
+ * <p/>
  * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode } is a tree like structure that provides a generic structure for a yang data
  * model
- *
- *
  */
 public class NormalizedNodeToProtocolBufferNode {
 
 
-  private final Node.Builder builderRoot;
-  private NormalizedNodeMessages.Container container;
+    private final Node.Builder builderRoot;
+    private NormalizedNodeMessages.Container container;
 
-  public NormalizedNodeToProtocolBufferNode() {
+    public NormalizedNodeToProtocolBufferNode() {
 
-    builderRoot = Node.newBuilder();
-  }
-
-  public void encode(String parentPath, NormalizedNode<?, ?> normalizedNode) {
-    if (parentPath == null) {
-      parentPath = "";
+        builderRoot = Node.newBuilder();
     }
 
-    NormalizedNodeMessages.Container.Builder containerBuilder =
-        NormalizedNodeMessages.Container.newBuilder();
+    public void encode(String parentPath, NormalizedNode<?, ?> normalizedNode) {
+        if (parentPath == null) {
+            parentPath = "";
+        }
+
+        NormalizedNodeMessages.Container.Builder containerBuilder =
+            NormalizedNodeMessages.Container.newBuilder();
 
-    if(normalizedNode != null) {
+        if (normalizedNode != null) {
 
-      navigateNormalizedNode(0, parentPath, normalizedNode, builderRoot);
-      // here we need to put back the Node Tree in Container
+            navigateNormalizedNode(0, parentPath, normalizedNode, builderRoot);
+            // here we need to put back the Node Tree in Container
 
-      container= containerBuilder.setParentPath(parentPath).setNormalizedNode(
-          builderRoot.build()).build();
-    }else {
-      //this can happen when an attempt was made to read from datastore and normalized node was null.
-      container = containerBuilder.setParentPath(parentPath).build();
+            container =
+                containerBuilder.setParentPath(parentPath).setNormalizedNode(
+                    builderRoot.build()).build();
+        } else {
+            //this can happen when an attempt was made to read from datastore and normalized node was null.
+            container = containerBuilder.setParentPath(parentPath).build();
+
+        }
 
     }
 
-  }
 
+    private void navigateDataContainerNode(int level, final String parentPath,
+        final DataContainerNode<?> dataContainerNode,
+        Node.Builder builderParent) {
+
+        String newParentPath =
+            parentPath + "/" + dataContainerNode.getIdentifier().toString();
+        String type = getDataContainerType(dataContainerNode).getSimpleName();
+        builderParent.setPath(dataContainerNode.getIdentifier().toString())
+            .setType(type);
+
+        final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>>
+            value =
+            dataContainerNode.getValue();
+        for (NormalizedNode<?, ?> node : value) {
+            Node.Builder builderChild = Node.newBuilder();
+            if (node instanceof MixinNode
+                && node instanceof NormalizedNodeContainer) {
+
+                navigateNormalizedNodeContainerMixin(level, newParentPath,
+                    (NormalizedNodeContainer<?, ?, ?>) node, builderChild);
+            } else {
+                navigateNormalizedNode(level, newParentPath, node,
+                    builderChild);
+            }
+            builderParent.addChild(builderChild);
+        }
+    }
 
-  private void navigateDataContainerNode(int level,final String parentPath,
-      final DataContainerNode<?> dataContainerNode, Node.Builder builderParent) {
+    private Class getDataContainerType(
+        NormalizedNodeContainer<?, ?, ?> dataContainerNode) {
+        if (dataContainerNode instanceof ChoiceNode) {
+            return ChoiceNode.class;
+        } else if (dataContainerNode instanceof AugmentationNode) {
+            return AugmentationNode.class;
+        } else if (dataContainerNode instanceof ContainerNode) {
+            return ContainerNode.class;
+        } else if (dataContainerNode instanceof MapEntryNode) {
+            return MapEntryNode.class;
+        } else if (dataContainerNode instanceof UnkeyedListEntryNode) {
+            return UnkeyedListEntryNode.class;
+        } else if (dataContainerNode instanceof MapNode) {
+            return MapNode.class;
+        } else if (dataContainerNode instanceof LeafSetNode) {
+            return LeafSetNode.class;
+        }
+        throw new IllegalArgumentException(
+            "could not find the data container node type "
+                + dataContainerNode.toString()
+        );
+    }
 
-    String newParentPath = parentPath + "/" + dataContainerNode.getIdentifier().toString();
-    String type = getDataContainerType(dataContainerNode).getSimpleName();
-    builderParent.setPath(dataContainerNode.getIdentifier().toString())
-        .setType(type);
+    private void navigateNormalizedNodeContainerMixin(int level,
+        final String parentPath,
+        NormalizedNodeContainer<?, ?, ?> node, Node.Builder builderParent) {
+        String newParentPath =
+            parentPath + "/" + node.getIdentifier().toString();
 
-    final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> value =
-        dataContainerNode.getValue();
-    for (NormalizedNode<?, ?> node : value) {
-      Node.Builder builderChild = Node.newBuilder();
-      if (node instanceof MixinNode && node instanceof NormalizedNodeContainer) {
+        builderParent.setPath(node.getIdentifier().toString()).setType(
+            this.getDataContainerType(node).getSimpleName());
+        final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
+        for (NormalizedNode normalizedNode : value) {
+            // child node builder
+            Node.Builder builderChild = Node.newBuilder();
+            if (normalizedNode instanceof MixinNode
+                && normalizedNode instanceof NormalizedNodeContainer) {
+                navigateNormalizedNodeContainerMixin(level + 1, newParentPath,
+                    (NormalizedNodeContainer) normalizedNode, builderChild);
+            } else {
+                navigateNormalizedNode(level, newParentPath, normalizedNode,
+                    builderChild);
+            }
+            builderParent.addChild(builderChild);
 
-        navigateNormalizedNodeContainerMixin(level, newParentPath,
-            (NormalizedNodeContainer<?, ?, ?>) node, builderChild);
-      } else {
-        navigateNormalizedNode(level, newParentPath,node, builderChild);
-      }
-      builderParent.addChild(builderChild);
-    }
+        }
 
-  }
-
-  private Class getDataContainerType(
-      NormalizedNodeContainer<?, ?, ?> dataContainerNode) {
-    if (dataContainerNode instanceof ChoiceNode) {
-      return ChoiceNode.class;
-    } else if (dataContainerNode instanceof AugmentationNode) {
-      return AugmentationNode.class;
-    } else if (dataContainerNode instanceof ContainerNode) {
-      return ContainerNode.class;
-    } else if (dataContainerNode instanceof MapEntryNode) {
-      return MapEntryNode.class;
-    } else if (dataContainerNode instanceof UnkeyedListEntryNode) {
-      return UnkeyedListEntryNode.class;
-    } else if (dataContainerNode instanceof MapNode) {
-      return MapNode.class;
-    } else if (dataContainerNode instanceof LeafSetNode){
-      return LeafSetNode.class;
-    }
-    throw new IllegalArgumentException(
-        "could not find the data container node type "
-            + dataContainerNode.toString());
-  }
-
-  private void navigateNormalizedNodeContainerMixin(int level, final String parentPath,
-      NormalizedNodeContainer<?, ?, ?> node, Node.Builder builderParent) {
-    String newParentPath = parentPath + "/" + node.getIdentifier().toString();
-
-    builderParent.setPath(node.getIdentifier().toString()).setType(
-        this.getDataContainerType(node).getSimpleName());
-    final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
-    for (NormalizedNode normalizedNode : value) {
-      // child node builder
-      Node.Builder builderChild = Node.newBuilder();
-      if (normalizedNode instanceof MixinNode
-          && normalizedNode instanceof NormalizedNodeContainer) {
-        navigateNormalizedNodeContainerMixin(level + 1,newParentPath,
-            (NormalizedNodeContainer) normalizedNode, builderChild);
-      } else {
-        navigateNormalizedNode(level,newParentPath, normalizedNode, builderChild);
-      }
-      builderParent.addChild(builderChild);
 
-    }
 
+    }
 
 
-  }
+    private void navigateNormalizedNode(int level,
+        String parentPath, NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
 
+        if (normalizedNode instanceof DataContainerNode) {
 
-  private void navigateNormalizedNode(int level,
-      String parentPath,NormalizedNode<?, ?> normalizedNode, Node.Builder builderParent) {
+            final DataContainerNode<?> dataContainerNode =
+                (DataContainerNode) normalizedNode;
 
-    if (normalizedNode instanceof DataContainerNode) {
+            navigateDataContainerNode(level + 1, parentPath, dataContainerNode,
+                builderParent);
+        } else if (normalizedNode instanceof MixinNode
+            && normalizedNode instanceof NormalizedNodeContainer) {
 
-      final DataContainerNode<?> dataContainerNode =
-          (DataContainerNode) normalizedNode;
+            navigateNormalizedNodeContainerMixin(level, parentPath,
+                (NormalizedNodeContainer<?, ?, ?>) normalizedNode,
+                builderParent);
+        } else {
+            if (normalizedNode instanceof LeafNode) {
+                buildLeafNode(parentPath, normalizedNode, builderParent);
+            } else if (normalizedNode instanceof LeafSetEntryNode) {
+                buildLeafSetEntryNode(parentPath, normalizedNode,
+                    builderParent);
+            }
 
-      navigateDataContainerNode(level + 1, parentPath,dataContainerNode, builderParent);
-    } else {
+        }
 
-      if (normalizedNode instanceof LeafNode) {
-        buildLeafNode(parentPath,normalizedNode, builderParent);
-      } else if (normalizedNode instanceof LeafSetEntryNode) {
-        buildLeafSetEntryNode(parentPath,normalizedNode,builderParent);
-      }
+    }
 
+    private void buildLeafSetEntryNode(String parentPath,
+        NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+        String path =
+            parentPath + "/" + normalizedNode.getIdentifier().toString();
+        LeafSetEntryNode leafSetEntryNode = (LeafSetEntryNode) normalizedNode;
+        Map<QName, String> attributes = leafSetEntryNode.getAttributes();
+        if (!attributes.isEmpty()) {
+            NormalizedNodeMessages.Attribute.Builder builder = null;
+            for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
+                builder = NormalizedNodeMessages.Attribute.newBuilder();
+
+                builder
+                    .setName(attribute.getKey().toString())
+                    .setValue(normalizedNode.getValue().toString());
+
+                builderParent.addAttributes(builder.build());
+            }
+        }
+        buildNodeValue(normalizedNode, builderParent);
     }
 
-  }
-
-  private void buildLeafSetEntryNode(String parentPath,NormalizedNode<?, ?> normalizedNode,
-      Node.Builder builderParent) {
-    String path = parentPath + "/" + normalizedNode.getIdentifier().toString();
-    LeafSetEntryNode leafSetEntryNode = (LeafSetEntryNode) normalizedNode;
-    Map<QName, String> attributes = leafSetEntryNode.getAttributes();
-    if (!attributes.isEmpty()) {
-      NormalizedNodeMessages.Attribute.Builder builder = null;
-      for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
-        builder = NormalizedNodeMessages.Attribute.newBuilder();
-        builder.setName(attribute.getKey().toString()).setValue(
-            normalizedNode.getValue().toString());
-        builderParent.addAttributes(builder.build());
-      }
+    private void buildLeafNode(String parentPath,
+        NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+        Preconditions.checkNotNull(parentPath);
+        Preconditions.checkNotNull(normalizedNode);
+        String path =
+            parentPath + "/" + normalizedNode.getIdentifier().toString();
+        LeafNode leafNode = (LeafNode) normalizedNode;
+        Map<QName, String> attributes = leafNode.getAttributes();
+        if (!attributes.isEmpty()) {
+            NormalizedNodeMessages.Attribute.Builder builder = null;
+            for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
+                builder = NormalizedNodeMessages.Attribute.newBuilder();
+                builder
+                    .setName(attribute.getKey().toString())
+                    .setValue(attribute.getValue().toString());
+
+                builderParent.addAttributes(builder.build());
+            }
+        }
+
+        Object value = normalizedNode.getValue();
+        if (value == null) {
+            builderParent
+                .setPath(normalizedNode.getIdentifier().toString())
+                .setType(LeafNode.class.getSimpleName())
+                .setValueType(String.class.getSimpleName())
+                .setValue("");
+        } else {
+            buildNodeValue(normalizedNode, builderParent);
+        }
     }
-    builderParent.setPath(normalizedNode.getIdentifier().toString()).setType(
-        LeafSetEntryNode.class.getSimpleName()).setValue(normalizedNode.getValue().toString());
-  }
-
-  private void buildLeafNode(String parentPath,NormalizedNode<?, ?> normalizedNode,
-      Node.Builder builderParent) {
-    String path = parentPath + "/" + normalizedNode.getIdentifier().toString();
-    LeafNode leafNode = (LeafNode) normalizedNode;
-    Map<QName, String> attributes = leafNode.getAttributes();
-    if (!attributes.isEmpty()) {
-      NormalizedNodeMessages.Attribute.Builder builder = null;
-      for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
-        builder = NormalizedNodeMessages.Attribute.newBuilder();
-        builder.setName(attribute.getKey().toString()).setValue(
-            normalizedNode.getValue().toString());
-        builderParent.addAttributes(builder.build());
-      }
+
+    private void buildNodeValue(NormalizedNode<?, ?> normalizedNode,
+        Node.Builder builderParent) {
+
+        Object value = normalizedNode.getValue();
+
+        builderParent
+            .setPath(normalizedNode.getIdentifier().toString())
+            .setType(LeafNode.class.getSimpleName())
+            .setValueType((value.getClass().getSimpleName()))
+            .setValue(value.toString());
+
+        if(value.getClass().equals(YangInstanceIdentifier.class)){
+            builderParent.setInstanceIdentifierValue(
+                InstanceIdentifierUtils
+                    .toSerializable((YangInstanceIdentifier) value));
+        }
     }
-    builderParent.setPath(normalizedNode.getIdentifier().toString()).setType(
-        LeafNode.class.getSimpleName()).setValue(normalizedNode.getValue().toString());
-  }
 
-  public NormalizedNodeMessages.Container getContainer() {
-    return container;
-  }
+    public NormalizedNodeMessages.Container getContainer() {
+        return container;
+    }
 }