1 package org.opendaylight.controller.cluster.datastore.node;
3 import com.google.common.base.Preconditions;
4 import org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils;
5 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
6 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
7 import org.opendaylight.yangtools.yang.common.QName;
8 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
9 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
10 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
11 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
12 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
13 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
14 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
15 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
18 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
22 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
27 * NormalizedNodeToProtocolBufferNode walks the NormalizedNode tree converting it to the
28 * NormalizedMessage.Node
30 * {@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
58 containerBuilder.setParentPath(parentPath).setNormalizedNode(
59 builderRoot.build()).build();
61 //this can happen when an attempt was made to read from datastore and normalized node was null.
62 container = containerBuilder.setParentPath(parentPath).build();
69 private void navigateDataContainerNode(int level, final String parentPath,
70 final DataContainerNode<?> dataContainerNode,
71 Node.Builder builderParent) {
73 String newParentPath =
74 parentPath + "/" + dataContainerNode.getIdentifier().toString();
75 String type = getDataContainerType(dataContainerNode).getSimpleName();
76 builderParent.setPath(dataContainerNode.getIdentifier().toString())
79 final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>>
81 dataContainerNode.getValue();
82 for (NormalizedNode<?, ?> node : value) {
83 Node.Builder builderChild = Node.newBuilder();
84 if (node instanceof MixinNode
85 && node instanceof NormalizedNodeContainer) {
87 navigateNormalizedNodeContainerMixin(level, newParentPath,
88 (NormalizedNodeContainer<?, ?, ?>) node, builderChild);
90 navigateNormalizedNode(level, newParentPath, node,
93 builderParent.addChild(builderChild);
97 private Class getDataContainerType(
98 NormalizedNodeContainer<?, ?, ?> dataContainerNode) {
99 if (dataContainerNode instanceof ChoiceNode) {
100 return ChoiceNode.class;
101 } else if (dataContainerNode instanceof AugmentationNode) {
102 return AugmentationNode.class;
103 } else if (dataContainerNode instanceof ContainerNode) {
104 return ContainerNode.class;
105 } else if (dataContainerNode instanceof MapEntryNode) {
106 return MapEntryNode.class;
107 } else if (dataContainerNode instanceof UnkeyedListEntryNode) {
108 return UnkeyedListEntryNode.class;
109 } else if (dataContainerNode instanceof MapNode) {
110 return MapNode.class;
111 } else if (dataContainerNode instanceof LeafSetNode) {
112 return LeafSetNode.class;
114 throw new IllegalArgumentException(
115 "could not find the data container node type "
116 + dataContainerNode.toString()
120 private void navigateNormalizedNodeContainerMixin(int level,
121 final String parentPath,
122 NormalizedNodeContainer<?, ?, ?> node, Node.Builder builderParent) {
123 String newParentPath =
124 parentPath + "/" + node.getIdentifier().toString();
126 builderParent.setPath(node.getIdentifier().toString()).setType(
127 this.getDataContainerType(node).getSimpleName());
128 final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
129 for (NormalizedNode normalizedNode : value) {
130 // child node builder
131 Node.Builder builderChild = Node.newBuilder();
132 if (normalizedNode instanceof MixinNode
133 && normalizedNode instanceof NormalizedNodeContainer) {
134 navigateNormalizedNodeContainerMixin(level + 1, newParentPath,
135 (NormalizedNodeContainer) normalizedNode, builderChild);
137 navigateNormalizedNode(level, newParentPath, normalizedNode,
140 builderParent.addChild(builderChild);
149 private void navigateNormalizedNode(int level,
150 String parentPath, NormalizedNode<?, ?> normalizedNode,
151 Node.Builder builderParent) {
153 if (normalizedNode instanceof DataContainerNode) {
155 final DataContainerNode<?> dataContainerNode =
156 (DataContainerNode) normalizedNode;
158 navigateDataContainerNode(level + 1, parentPath, dataContainerNode,
160 } else if (normalizedNode instanceof MixinNode
161 && normalizedNode instanceof NormalizedNodeContainer) {
163 navigateNormalizedNodeContainerMixin(level, parentPath,
164 (NormalizedNodeContainer<?, ?, ?>) normalizedNode,
167 if (normalizedNode instanceof LeafNode) {
168 buildLeafNode(parentPath, normalizedNode, builderParent);
169 } else if (normalizedNode instanceof LeafSetEntryNode) {
170 buildLeafSetEntryNode(parentPath, normalizedNode,
178 private void buildLeafSetEntryNode(String parentPath,
179 NormalizedNode<?, ?> normalizedNode,
180 Node.Builder builderParent) {
182 parentPath + "/" + normalizedNode.getIdentifier().toString();
183 LeafSetEntryNode leafSetEntryNode = (LeafSetEntryNode) normalizedNode;
184 Map<QName, String> attributes = leafSetEntryNode.getAttributes();
185 if (!attributes.isEmpty()) {
186 NormalizedNodeMessages.Attribute.Builder builder = null;
187 for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
188 builder = NormalizedNodeMessages.Attribute.newBuilder();
191 .setName(attribute.getKey().toString())
192 .setValue(normalizedNode.getValue().toString());
194 builderParent.addAttributes(builder.build());
197 buildNodeValue(normalizedNode, builderParent);
200 private void buildLeafNode(String parentPath,
201 NormalizedNode<?, ?> normalizedNode,
202 Node.Builder builderParent) {
203 Preconditions.checkNotNull(parentPath);
204 Preconditions.checkNotNull(normalizedNode);
206 parentPath + "/" + normalizedNode.getIdentifier().toString();
207 LeafNode leafNode = (LeafNode) normalizedNode;
208 Map<QName, String> attributes = leafNode.getAttributes();
209 if (!attributes.isEmpty()) {
210 NormalizedNodeMessages.Attribute.Builder builder = null;
211 for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
212 builder = NormalizedNodeMessages.Attribute.newBuilder();
214 .setName(attribute.getKey().toString())
215 .setValue(attribute.getValue().toString());
217 builderParent.addAttributes(builder.build());
221 Object value = normalizedNode.getValue();
224 .setPath(normalizedNode.getIdentifier().toString())
225 .setType(LeafNode.class.getSimpleName())
226 .setValueType(String.class.getSimpleName())
229 buildNodeValue(normalizedNode, builderParent);
233 private void buildNodeValue(NormalizedNode<?, ?> normalizedNode,
234 Node.Builder builderParent) {
236 Object value = normalizedNode.getValue();
239 .setPath(normalizedNode.getIdentifier().toString())
240 .setType(LeafNode.class.getSimpleName())
241 .setValueType((value.getClass().getSimpleName()))
242 .setValue(value.toString());
244 if(value.getClass().equals(YangInstanceIdentifier.class)){
245 builderParent.setInstanceIdentifierValue(
246 InstanceIdentifierUtils
247 .toSerializable((YangInstanceIdentifier) value));
251 public NormalizedNodeMessages.Container getContainer() {