2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.datastore.node.utils.stream;
10 import com.google.common.base.Preconditions;
11 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
12 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
13 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
14 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
15 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
16 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
17 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
18 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
25 import java.io.Closeable;
26 import java.io.Flushable;
27 import java.io.IOException;
28 import java.util.Collection;
30 import static org.opendaylight.controller.cluster.datastore.node.utils.stream.NormalizedNodeStreamWriter.UNKNOWN_SIZE;
34 * This class is used only for testing purpose for now, we may use similar logic while integrating
38 public class NormalizedNodeWriter implements Closeable, Flushable {
39 private final NormalizedNodeStreamWriter writer;
41 private NormalizedNodeWriter(final NormalizedNodeStreamWriter writer) {
42 this.writer = Preconditions.checkNotNull(writer);
45 protected final NormalizedNodeStreamWriter getWriter() {
50 * Create a new writer backed by a {@link org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter}.
52 * @param writer Back-end writer
53 * @return A new instance.
55 public static NormalizedNodeWriter forStreamWriter(final NormalizedNodeStreamWriter writer) {
56 return new NormalizedNodeWriter(writer);
61 * Iterate over the provided {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} and emit write
62 * events to the encapsulated {@link org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter}.
66 * @throws java.io.IOException when thrown from the backing writer.
68 public final NormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
69 if (wasProcessedAsComplexNode(node)) {
73 if (wasProcessAsSimpleNode(node)) {
77 throw new IllegalStateException("It wasn't possible to serialize node " + node);
81 public void flush() throws IOException {
86 public void close() throws IOException {
92 * Emit a best guess of a hint for a particular set of children. It evaluates the
93 * iterable to see if the size can be easily gotten to. If it is, we hint at the
94 * real number of child nodes. Otherwise we emit UNKNOWN_SIZE.
96 * @param children Child nodes
97 * @return Best estimate of the collection size required to hold all the children.
99 static final int childSizeHint(final Iterable<?> children) {
100 return (children instanceof Collection) ? ((Collection<?>) children).size() : UNKNOWN_SIZE;
103 private boolean wasProcessAsSimpleNode(final NormalizedNode<?, ?> node) throws IOException {
104 if (node instanceof LeafSetEntryNode) {
105 final LeafSetEntryNode<?> nodeAsLeafList = (LeafSetEntryNode<?>)node;
106 writer.leafSetEntryNode(nodeAsLeafList.getIdentifier(), nodeAsLeafList.getValue());
108 } else if (node instanceof LeafNode) {
109 final LeafNode<?> nodeAsLeaf = (LeafNode<?>)node;
110 writer.leafNode(nodeAsLeaf.getIdentifier(), nodeAsLeaf.getValue());
112 } else if (node instanceof AnyXmlNode) {
113 final AnyXmlNode anyXmlNode = (AnyXmlNode)node;
114 writer.anyxmlNode(anyXmlNode.getIdentifier(), anyXmlNode.getValue());
122 * Emit events for all children and then emit an endNode() event.
124 * @param children Child iterable
126 * @throws java.io.IOException when the writer reports it
128 protected final boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children) throws IOException {
129 for (NormalizedNode<?, ?> child : children) {
137 protected boolean writeMapEntryNode(final MapEntryNode node) throws IOException {
138 writer.startMapEntryNode(node.getIdentifier(), childSizeHint(node.getValue()));
139 return writeChildren(node.getValue());
142 private boolean wasProcessedAsComplexNode(final NormalizedNode<?, ?> node) throws IOException {
143 if (node instanceof ContainerNode) {
144 final ContainerNode n = (ContainerNode) node;
145 writer.startContainerNode(n.getIdentifier(), childSizeHint(n.getValue()));
146 return writeChildren(n.getValue());
148 if (node instanceof MapEntryNode) {
149 return writeMapEntryNode((MapEntryNode) node);
151 if (node instanceof UnkeyedListEntryNode) {
152 final UnkeyedListEntryNode n = (UnkeyedListEntryNode) node;
153 writer.startUnkeyedListItem(n.getIdentifier(), childSizeHint(n.getValue()));
154 return writeChildren(n.getValue());
156 if (node instanceof ChoiceNode) {
157 final ChoiceNode n = (ChoiceNode) node;
158 writer.startChoiceNode(n.getIdentifier(), childSizeHint(n.getValue()));
159 return writeChildren(n.getValue());
161 if (node instanceof AugmentationNode) {
162 final AugmentationNode n = (AugmentationNode) node;
163 writer.startAugmentationNode(n.getIdentifier());
164 return writeChildren(n.getValue());
166 if (node instanceof UnkeyedListNode) {
167 final UnkeyedListNode n = (UnkeyedListNode) node;
168 writer.startUnkeyedList(n.getIdentifier(), childSizeHint(n.getValue()));
169 return writeChildren(n.getValue());
171 if (node instanceof OrderedMapNode) {
172 final OrderedMapNode n = (OrderedMapNode) node;
173 writer.startOrderedMapNode(n.getIdentifier(), childSizeHint(n.getValue()));
174 return writeChildren(n.getValue());
176 if (node instanceof MapNode) {
177 final MapNode n = (MapNode) node;
178 writer.startMapNode(n.getIdentifier(), childSizeHint(n.getValue()));
179 return writeChildren(n.getValue());
181 if (node instanceof LeafSetNode) {
182 //covers also OrderedLeafSetNode for which doesn't exist start* method
183 final LeafSetNode<?> n = (LeafSetNode<?>) node;
184 writer.startLeafSet(n.getIdentifier(), childSizeHint(n.getValue()));
185 return writeChildren(n.getValue());