1 package org.opendaylight.controller.cluster.datastore.node;
3 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
4 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
5 import org.opendaylight.yangtools.yang.common.QName;
6 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
7 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
8 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
9 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
10 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
11 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
12 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
13 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
14 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
15 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
18 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
20 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
25 * NormalizedNodeToProtocolBufferNode walks the NormalizedNode tree converting it to the
26 * NormalizedMessage.Node
28 * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode } is a tree like structure that provides a generic structure for a yang data
33 public class NormalizedNodeToProtocolBufferNode {
36 private final Node.Builder builderRoot;
37 private NormalizedNodeMessages.Container container;
39 public NormalizedNodeToProtocolBufferNode() {
41 builderRoot = Node.newBuilder();
44 public void encode(String parentPath, NormalizedNode<?, ?> normalizedNode) {
45 if (parentPath == null) {
49 NormalizedNodeMessages.Container.Builder containerBuilder =
50 NormalizedNodeMessages.Container.newBuilder();
52 if(normalizedNode != null) {
54 navigateNormalizedNode(0, parentPath, normalizedNode, builderRoot);
55 // here we need to put back the Node Tree in Container
57 container= containerBuilder.setParentPath(parentPath).setNormalizedNode(
58 builderRoot.build()).build();
60 //this can happen when an attempt was made to read from datastore and normalized node was null.
61 container = containerBuilder.setParentPath(parentPath).build();
68 private void navigateDataContainerNode(int level,final String parentPath,
69 final DataContainerNode<?> dataContainerNode, Node.Builder builderParent) {
71 String newParentPath = parentPath + "/" + dataContainerNode.getIdentifier().toString();
72 String type = getDataContainerType(dataContainerNode).getSimpleName();
73 builderParent.setPath(dataContainerNode.getIdentifier().toString())
76 final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> value =
77 dataContainerNode.getValue();
78 for (NormalizedNode<?, ?> node : value) {
79 Node.Builder builderChild = Node.newBuilder();
80 if (node instanceof MixinNode && node instanceof NormalizedNodeContainer) {
82 navigateNormalizedNodeContainerMixin(level, newParentPath,
83 (NormalizedNodeContainer<?, ?, ?>) node, builderChild);
85 navigateNormalizedNode(level, newParentPath,node, builderChild);
87 builderParent.addChild(builderChild);
92 private Class getDataContainerType(
93 NormalizedNodeContainer<?, ?, ?> dataContainerNode) {
94 if (dataContainerNode instanceof ChoiceNode) {
95 return ChoiceNode.class;
96 } else if (dataContainerNode instanceof AugmentationNode) {
97 return AugmentationNode.class;
98 } else if (dataContainerNode instanceof ContainerNode) {
99 return ContainerNode.class;
100 } else if (dataContainerNode instanceof MapEntryNode) {
101 return MapEntryNode.class;
102 } else if (dataContainerNode instanceof UnkeyedListEntryNode) {
103 return UnkeyedListEntryNode.class;
104 } else if (dataContainerNode instanceof MapNode) {
105 return MapNode.class;
106 } else if (dataContainerNode instanceof LeafSetNode){
107 return LeafSetNode.class;
109 throw new IllegalArgumentException(
110 "could not find the data container node type "
111 + dataContainerNode.toString());
114 private void navigateNormalizedNodeContainerMixin(int level, final String parentPath,
115 NormalizedNodeContainer<?, ?, ?> node, Node.Builder builderParent) {
116 String newParentPath = parentPath + "/" + node.getIdentifier().toString();
118 builderParent.setPath(node.getIdentifier().toString()).setType(
119 this.getDataContainerType(node).getSimpleName());
120 final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
121 for (NormalizedNode normalizedNode : value) {
122 // child node builder
123 Node.Builder builderChild = Node.newBuilder();
124 if (normalizedNode instanceof MixinNode
125 && normalizedNode instanceof NormalizedNodeContainer) {
126 navigateNormalizedNodeContainerMixin(level + 1,newParentPath,
127 (NormalizedNodeContainer) normalizedNode, builderChild);
129 navigateNormalizedNode(level,newParentPath, normalizedNode, builderChild);
131 builderParent.addChild(builderChild);
140 private void navigateNormalizedNode(int level,
141 String parentPath,NormalizedNode<?, ?> normalizedNode, Node.Builder builderParent) {
143 if (normalizedNode instanceof DataContainerNode) {
145 final DataContainerNode<?> dataContainerNode =
146 (DataContainerNode) normalizedNode;
148 navigateDataContainerNode(level + 1, parentPath,dataContainerNode, builderParent);
151 if (normalizedNode instanceof LeafNode) {
152 buildLeafNode(parentPath,normalizedNode, builderParent);
153 } else if (normalizedNode instanceof LeafSetEntryNode) {
154 buildLeafSetEntryNode(parentPath,normalizedNode,builderParent);
161 private void buildLeafSetEntryNode(String parentPath,NormalizedNode<?, ?> normalizedNode,
162 Node.Builder builderParent) {
163 String path = parentPath + "/" + normalizedNode.getIdentifier().toString();
164 LeafSetEntryNode leafSetEntryNode = (LeafSetEntryNode) normalizedNode;
165 Map<QName, String> attributes = leafSetEntryNode.getAttributes();
166 if (!attributes.isEmpty()) {
167 NormalizedNodeMessages.Attribute.Builder builder = null;
168 for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
169 builder = NormalizedNodeMessages.Attribute.newBuilder();
170 builder.setName(attribute.getKey().toString()).setValue(
171 normalizedNode.getValue().toString());
172 builderParent.addAttributes(builder.build());
175 builderParent.setPath(normalizedNode.getIdentifier().toString()).setType(
176 LeafSetEntryNode.class.getSimpleName()).setValue(normalizedNode.getValue().toString());
179 private void buildLeafNode(String parentPath,NormalizedNode<?, ?> normalizedNode,
180 Node.Builder builderParent) {
181 String path = parentPath + "/" + normalizedNode.getIdentifier().toString();
182 LeafNode leafNode = (LeafNode) normalizedNode;
183 Map<QName, String> attributes = leafNode.getAttributes();
184 if (!attributes.isEmpty()) {
185 NormalizedNodeMessages.Attribute.Builder builder = null;
186 for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
187 builder = NormalizedNodeMessages.Attribute.newBuilder();
188 builder.setName(attribute.getKey().toString()).setValue(
189 normalizedNode.getValue().toString());
190 builderParent.addAttributes(builder.build());
193 builderParent.setPath(normalizedNode.getIdentifier().toString()).setType(
194 LeafNode.class.getSimpleName()).setValue(normalizedNode.getValue().toString());
197 public NormalizedNodeMessages.Container getContainer() {