3 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
11 package org.opendaylight.controller.cluster.datastore.node;
13 import com.google.common.base.Preconditions;
14 import org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils;
15 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
16 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
23 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
25 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
26 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
27 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
28 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
29 import org.opendaylight.yangtools.yang.data.api.schema.MixinNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
32 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
37 * NormalizedNodeToProtocolBufferNode walks the NormalizedNode tree converting it to the
38 * NormalizedMessage.Node
40 * {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode } is a tree like structure that provides a generic structure for a yang data
43 public class NormalizedNodeToProtocolBufferNode {
46 private final Node.Builder builderRoot;
47 private NormalizedNodeMessages.Container container;
49 public NormalizedNodeToProtocolBufferNode() {
51 builderRoot = Node.newBuilder();
54 public void encode(String parentPath, NormalizedNode<?, ?> normalizedNode) {
55 if (parentPath == null) {
59 NormalizedNodeMessages.Container.Builder containerBuilder =
60 NormalizedNodeMessages.Container.newBuilder();
62 if (normalizedNode != null) {
64 navigateNormalizedNode(0, parentPath, normalizedNode, builderRoot);
65 // here we need to put back the Node Tree in Container
68 containerBuilder.setParentPath(parentPath).setNormalizedNode(
69 builderRoot.build()).build();
71 //this can happen when an attempt was made to read from datastore and normalized node was null.
72 container = containerBuilder.setParentPath(parentPath).build();
79 private void navigateDataContainerNode(int level, final String parentPath,
80 final DataContainerNode<?> dataContainerNode,
81 Node.Builder builderParent) {
83 String newParentPath =
84 parentPath + "/" + dataContainerNode.getIdentifier().toString();
85 String type = getDataContainerType(dataContainerNode).getSimpleName();
86 builderParent.setPath(dataContainerNode.getIdentifier().toString())
89 final Iterable<DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>>
91 dataContainerNode.getValue();
92 for (NormalizedNode<?, ?> node : value) {
93 Node.Builder builderChild = Node.newBuilder();
94 if (node instanceof MixinNode
95 && node instanceof NormalizedNodeContainer) {
97 navigateNormalizedNodeContainerMixin(level, newParentPath,
98 (NormalizedNodeContainer<?, ?, ?>) node, builderChild);
100 navigateNormalizedNode(level, newParentPath, node,
103 builderParent.addChild(builderChild);
107 private Class getDataContainerType(
108 NormalizedNodeContainer<?, ?, ?> dataContainerNode) {
109 if (dataContainerNode instanceof ChoiceNode) {
110 return ChoiceNode.class;
111 } else if (dataContainerNode instanceof AugmentationNode) {
112 return AugmentationNode.class;
113 } else if (dataContainerNode instanceof ContainerNode) {
114 return ContainerNode.class;
115 } else if (dataContainerNode instanceof MapEntryNode) {
116 return MapEntryNode.class;
117 } else if (dataContainerNode instanceof UnkeyedListEntryNode) {
118 return UnkeyedListEntryNode.class;
119 } else if (dataContainerNode instanceof MapNode) {
120 return MapNode.class;
121 } else if (dataContainerNode instanceof LeafSetNode) {
122 return LeafSetNode.class;
124 throw new IllegalArgumentException(
125 "could not find the data container node type "
126 + dataContainerNode.toString()
130 private void navigateNormalizedNodeContainerMixin(int level,
131 final String parentPath,
132 NormalizedNodeContainer<?, ?, ?> node, Node.Builder builderParent) {
133 String newParentPath =
134 parentPath + "/" + node.getIdentifier().toString();
136 builderParent.setPath(node.getIdentifier().toString()).setType(
137 this.getDataContainerType(node).getSimpleName());
138 final Iterable<? extends NormalizedNode<?, ?>> value = node.getValue();
139 for (NormalizedNode normalizedNode : value) {
140 // child node builder
141 Node.Builder builderChild = Node.newBuilder();
142 if (normalizedNode instanceof MixinNode
143 && normalizedNode instanceof NormalizedNodeContainer) {
144 navigateNormalizedNodeContainerMixin(level + 1, newParentPath,
145 (NormalizedNodeContainer) normalizedNode, builderChild);
147 navigateNormalizedNode(level, newParentPath, normalizedNode,
150 builderParent.addChild(builderChild);
159 private void navigateNormalizedNode(int level,
160 String parentPath, NormalizedNode<?, ?> normalizedNode,
161 Node.Builder builderParent) {
163 if (normalizedNode instanceof DataContainerNode) {
165 final DataContainerNode<?> dataContainerNode =
166 (DataContainerNode) normalizedNode;
168 navigateDataContainerNode(level + 1, parentPath, dataContainerNode,
170 } else if (normalizedNode instanceof MixinNode
171 && normalizedNode instanceof NormalizedNodeContainer) {
173 navigateNormalizedNodeContainerMixin(level, parentPath,
174 (NormalizedNodeContainer<?, ?, ?>) normalizedNode,
177 if (normalizedNode instanceof LeafNode) {
178 buildLeafNode(parentPath, normalizedNode, builderParent);
179 } else if (normalizedNode instanceof LeafSetEntryNode) {
180 buildLeafSetEntryNode(parentPath, normalizedNode,
188 private void buildLeafSetEntryNode(String parentPath,
189 NormalizedNode<?, ?> normalizedNode,
190 Node.Builder builderParent) {
192 parentPath + "/" + normalizedNode.getIdentifier().toString();
193 LeafSetEntryNode leafSetEntryNode = (LeafSetEntryNode) normalizedNode;
194 Map<QName, String> attributes = leafSetEntryNode.getAttributes();
195 if (!attributes.isEmpty()) {
196 NormalizedNodeMessages.Attribute.Builder builder = null;
197 for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
198 builder = NormalizedNodeMessages.Attribute.newBuilder();
201 .setName(attribute.getKey().toString())
202 .setValue(normalizedNode.getValue().toString());
204 builderParent.addAttributes(builder.build());
207 buildNodeValue(normalizedNode, builderParent);
210 private void buildLeafNode(String parentPath,
211 NormalizedNode<?, ?> normalizedNode,
212 Node.Builder builderParent) {
213 Preconditions.checkNotNull(parentPath);
214 Preconditions.checkNotNull(normalizedNode);
216 parentPath + "/" + normalizedNode.getIdentifier().toString();
217 LeafNode leafNode = (LeafNode) normalizedNode;
218 Map<QName, String> attributes = leafNode.getAttributes();
219 if (!attributes.isEmpty()) {
220 NormalizedNodeMessages.Attribute.Builder builder = null;
221 for (Map.Entry<QName, String> attribute : attributes.entrySet()) {
222 builder = NormalizedNodeMessages.Attribute.newBuilder();
224 .setName(attribute.getKey().toString())
225 .setValue(attribute.getValue().toString());
227 builderParent.addAttributes(builder.build());
231 Object value = normalizedNode.getValue();
234 .setPath(normalizedNode.getIdentifier().toString())
235 .setType(LeafNode.class.getSimpleName())
236 .setValueType(String.class.getSimpleName())
239 buildNodeValue(normalizedNode, builderParent);
243 private void buildNodeValue(NormalizedNode<?, ?> normalizedNode,
244 Node.Builder builderParent) {
246 Object value = normalizedNode.getValue();
249 .setPath(normalizedNode.getIdentifier().toString())
250 .setType(LeafNode.class.getSimpleName())
251 .setValueType((value.getClass().getSimpleName()))
252 .setValue(value.toString());
254 if(value.getClass().equals(YangInstanceIdentifier.class)){
255 builderParent.setInstanceIdentifierValue(
256 InstanceIdentifierUtils
257 .toSerializable((YangInstanceIdentifier) value));
261 public NormalizedNodeMessages.Container getContainer() {