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.yangtools.yang.data.api.schema.stream;
10 import java.io.Closeable;
11 import java.io.Flushable;
12 import java.io.IOException;
13 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
14 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
19 * Event Stream Writer based on Normalized Node tree representation
21 * <h3>Writing Event Stream</h3>
24 * <li><code>container</code> - Container node representation, start event is
25 * emitted using {@link #startContainerNode(NodeIdentifier, int)} and node end event is
26 * emitted using {@link #endNode()}. Container node is implementing
27 * the org.opendaylight.yangtools.yang.binding.DataObject interface.
29 * <li><code>list</code> - YANG list statement has two representation in event
30 * stream - unkeyed list and map. Unkeyed list is YANG list which did not
34 * <li><code>Map</code> - Map start event is emitted using
35 * {@link #startMapNode(NodeIdentifier, int)} and is ended using {@link #endNode()}. Each map
36 * entry start is emitted using {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)} with Map of keys
37 * and finished using {@link #endNode()}.</li>
39 * <li><code>UnkeyedList</code> - Unkeyed list represent list without keys,
40 * unkeyed list start is emitted using {@link #startUnkeyedList(NodeIdentifier, int)} list
41 * end is emitted using {@link #endNode()}. Each list item is emitted using
42 * {@link #startUnkeyedListItem(NodeIdentifier, int)} and ended using {@link #endNode()}.</li>
45 * <li><code>leaf</code> - Leaf node event is emitted using
46 * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted for
49 * <li><code>leaf-list</code> - Leaf list start is emitted using
50 * {@link #startLeafSet(NodeIdentifier, int)}. Leaf list end is emitted using
51 * {@link #endNode()}. Leaf list entries are emmited using
52 * {@link #leafSetEntryNode(Object)}.
54 * <li><code>anyxml - AN node event is emitted using
55 * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted
56 * for anyxml node.</code></li>
59 * <li><code>choice</code> Choice node event is emmited by
60 * {@link #startChoiceNode(NodeIdentifier, int)} event and
61 * finished by invoking {@link #endNode()}
63 * <code>augment</code> - Represents augmentation, augmentation node is started
64 * by invoking {@link #startAugmentationNode(AugmentationIdentifier)} and
65 * finished by invoking {@link #endNode()}.</li>
69 * <h3>Implementation notes</h3>
72 * Implementations of this interface must not hold user suppled objects
73 * and resources needlessly.
76 public interface NormalizedNodeStreamWriter extends Closeable, Flushable {
79 * Methods in this interface allow users to hint the underlying
80 * implementation about the sizing of container-like constructors
81 * (leafLists, containers, etc.). These hints may be taken into account by a
82 * particular implementation to improve performance, but clients are not
83 * required to provide hints. This constant should be used by clients who
84 * either do not have the sizing information, or do not wish to divulge it
85 * (for whatever reasons). Implementations are free to ignore these hints
86 * completely, but if they do use them, they are expected to be resilient in
87 * face of missing and mismatched hints, which is to say the user can
88 * specify startLeafSet(..., 1) and then call leafNode() 15 times.
90 * The acceptable hint values are non-negative integers and this constant,
91 * all other values will result, based on implementation preference, in the
92 * hint being completely ignored or IllegalArgumentException being thrown.
94 int UNKNOWN_SIZE = -1;
98 * Emits a leaf node event with supplied value.
101 * name of node as defined in schema, namespace and revision are
102 * derived from parent node.
104 * Value of leaf node. v
105 * @throws IllegalArgumentException
106 * If emitted leaf node has invalid value in current context or
107 * was emitted multiple times.
108 * @throws IllegalStateException
109 * If node was emitted inside <code>map</code>,
110 * <code>choice</code> <code>unkeyed list</code> node.
111 * @throws IOException if an underlying IO error occurs
113 void leafNode(NodeIdentifier name, Object value) throws IOException;
117 * Emits a start of leaf set (leaf-list).
119 * Emits start of leaf set, during writing leaf set event, only
120 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
121 * finished by calling {@link #endNode()}.
124 * name of node as defined in schema, namespace and revision are
125 * derived from parent node.
126 * @param childSizeHint
127 * Non-negative count of expected direct child nodes or
128 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
129 * and should not fail writing of child events, if there are more
131 * @throws IllegalArgumentException
132 * If emitted leaf node is invalid in current context or was
133 * emitted multiple times.
134 * @throws IllegalStateException
135 * If node was emitted inside <code>map</code>,
136 * <code>choice</code> <code>unkeyed list</code> node.
137 * @throws IOException if an underlying IO error occurs
139 void startLeafSet(NodeIdentifier name, int childSizeHint) throws IOException;
142 * Emits a leaf set entry node
145 * Value of leaf set entry node. Supplied object MUST BE constant over time.
146 * @throws IllegalArgumentException
147 * If emitted leaf node has invalid value.
148 * @throws IllegalStateException
149 * If node was emitted outside <code>leaf set</code> node.
150 * @throws IOException if an underlying IO error occurs
152 void leafSetEntryNode(Object value) throws IOException;
156 * Emits start of new container.
159 * End of container event is emitted by invoking {@link #endNode()}.
162 * Valid sub-events are:
164 * <li>{@link #leafNode}</li>
165 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
166 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
167 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
168 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
169 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
170 * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
174 * name of node as defined in schema, namespace and revision are
175 * derived from parent node.
176 * @param childSizeHint
177 * Non-negative count of expected direct child nodes or
178 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
179 * and should not fail writing of child events, if there are more
181 * @throws IllegalArgumentException
182 * If emitted node is invalid in current context or was emitted
184 * @throws IllegalStateException
185 * If node was emitted inside <code>map</code>,
186 * <code>choice</code> <code>unkeyed list</code> node.
187 * @throws IOException if an underlying IO error occurs
189 void startContainerNode(NodeIdentifier name, int childSizeHint) throws IOException;
193 * Emits start of unkeyed list node event.
196 * End of unkeyed list event is emitted by invoking {@link #endNode()}.
197 * Valid subevents is only {@link #startUnkeyedListItem(NodeIdentifier, int)}. All other
198 * methods will throw {@link IllegalArgumentException}.
201 * name of node as defined in schema, namespace and revision are
202 * derived from parent node.
203 * @param childSizeHint
204 * Non-negative count of expected direct child nodes or
205 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
206 * and should not fail writing of child events, if there are more
208 * @throws IllegalArgumentException
209 * If emitted node is invalid in current context or was emitted
211 * @throws IllegalStateException
212 * If node was emitted inside <code>map</code>,
213 * <code>choice</code> <code>unkeyed list</code> node.
214 * @throws IOException if an underlying IO error occurs
216 void startUnkeyedList(NodeIdentifier name, int childSizeHint) throws IOException;
219 * Emits start of new unkeyed list item.
222 * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
225 * <li>{@link #leafNode}</li>
226 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
227 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
228 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
229 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
230 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
231 * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
234 * @param name Identifier of node
235 * @param childSizeHint
236 * Non-negative count of expected direct child nodes or
237 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
238 * and should not fail writing of child events, if there are more
240 * @throws IllegalStateException
241 * If node was emitted outside <code>unkeyed list</code> node.
242 * @throws IOException if an underlying IO error occurs
244 void startUnkeyedListItem(NodeIdentifier name, int childSizeHint) throws IOException;
248 * Emits start of map node event.
251 * End of map node event is emitted by invoking {@link #endNode()}. Valid
253 * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
254 * methods will throw {@link IllegalArgumentException}.
257 * name of node as defined in schema, namespace and revision are
258 * derived from parent node.
259 * @param childSizeHint
260 * Non-negative count of expected direct child nodes or
261 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
262 * and should not fail writing of child events, if there are more
264 * @throws IllegalArgumentException
265 * If emitted node is invalid in current context or was emitted
267 * @throws IllegalStateException
268 * If node was emitted inside <code>map</code>,
269 * <code>choice</code> <code>unkeyed list</code> node.
270 * @throws IOException if an underlying IO error occurs
272 void startMapNode(NodeIdentifier name, int childSizeHint) throws IOException;
276 * Emits start of map entry.
279 * End of map entry event is emitted by invoking {@link #endNode()}.
282 * Valid sub-events are:
284 * <li>{@link #leafNode}</li>
285 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
286 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
287 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
288 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
289 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
290 * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
295 * QName to value pairs of keys of map entry node. Values MUST BE constant over time.
296 * @param childSizeHint
297 * Non-negative count of expected direct child nodes or
298 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
299 * and should not fail writing of child events, if there are more
301 * @throws IllegalArgumentException
302 * If key contains incorrect value.
303 * @throws IllegalStateException
304 * If node was emitted outside <code>map entry</code> node.
305 * @throws IOException if an underlying IO error occurs
307 void startMapEntryNode(NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException;
311 * Emits start of map node event.
314 * End of map node event is emitted by invoking {@link #endNode()}. Valid
316 * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
317 * methods will throw {@link IllegalArgumentException}.
320 * name of node as defined in schema, namespace and revision are
321 * derived from parent node.
322 * @param childSizeHint
323 * Non-negative count of expected direct child nodes or
324 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
325 * and should not fail writing of child events, if there are more
327 * @throws IllegalArgumentException
328 * If emitted node is invalid in current context or was emitted
330 * @throws IllegalStateException
331 * If node was emitted inside <code>map</code>,
332 * <code>choice</code> <code>unkeyed list</code> node.
333 * @throws IOException if an underlying IO error occurs
335 void startOrderedMapNode(NodeIdentifier name, int childSizeHint) throws IOException;
342 * name of node as defined in schema, namespace and revision are
343 * derived from parent node.
344 * @param childSizeHint
345 * Non-negative count of expected direct child nodes or
346 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
347 * and should not fail writing of child events, if there are more
349 * @throws IllegalArgumentException
350 * If emitted node is invalid in current context or was emitted
352 * @throws IllegalStateException
353 * If node was emitted inside <code>map</code>,
354 * <code>choice</code> <code>unkeyed list</code> node.
355 * @throws IOException if an underlying IO error occurs
357 void startChoiceNode(NodeIdentifier name, int childSizeHint) throws IOException;
360 * Emits start of augmentation node.
363 * End of augmentation event is emitted by invoking {@link #endNode()}.
366 * Valid sub-events are:
369 * <li>{@link #leafNode}</li>
370 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
371 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
372 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
373 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
374 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
378 * Augmentation identifier
379 * @throws IllegalArgumentException
380 * If augmentation is invalid in current context.
381 * @throws IOException if an underlying IO error occurs
383 void startAugmentationNode(AugmentationIdentifier identifier) throws IOException;
386 * Emits anyxml node event.
389 * name of node as defined in schema, namespace and revision are
390 * derived from parent node.
392 * Value of AnyXml node.
393 * @throws IllegalArgumentException
394 * If emitted node is invalid in current context or was emitted
396 * @throws IllegalStateException
397 * If node was emitted inside <code>map</code>,
398 * <code>choice</code> <code>unkeyed list</code> node.
399 * @throws IOException if an underlying IO error occurs
401 void anyxmlNode(NodeIdentifier name, Object value) throws IOException;
405 * Emits start of new yang modeled anyXml node.
408 * End of yang modeled anyXml node event is emitted by invoking {@link #endNode()}.
411 * Valid sub-events are:
413 * <li>{@link #leafNode}</li>
414 * <li>{@link #startContainerNode}</li>
415 * <li>{@link #startLeafSet}</li>
416 * <li>{@link #startMapNode}</li>
417 * <li>{@link #startUnkeyedList}</li>
421 * name of node as defined in schema, namespace and revision are
422 * derived from parent node.
423 * @param childSizeHint
424 * Non-negative count of expected direct child nodes or
425 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
426 * and should not fail writing of child events, if there are more
428 * @throws IllegalArgumentException
429 * If emitted node is invalid in current context or was emitted
431 * @throws IllegalStateException
432 * If node was emitted inside <code>map</code>,
433 * <code>choice</code> <code>unkeyed list</code> node.
434 * @throws IOException if an underlying IO error occurs
436 void startYangModeledAnyXmlNode(NodeIdentifier name, int childSizeHint) throws IOException;
439 * Emits end event for node.
441 * @throws IllegalStateException If there is no start* event to be closed.
442 * @throws IOException if an underlying IO error occurs
444 void endNode() throws IOException;
447 void close() throws IOException;
450 void flush() throws IOException;