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;
143 * Emits a start of leaf set (leaf-list).
145 * Emits start of leaf set, during writing leaf set event, only
146 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
147 * finished by calling {@link #endNode()}.
150 * name of node as defined in schema, namespace and revision are
151 * derived from parent node.
152 * @param childSizeHint
153 * Non-negative count of expected direct child nodes or
154 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
155 * and should not fail writing of child events, if there are more
157 * @throws IllegalArgumentException
158 * If emitted leaf node is invalid in current context or was
159 * emitted multiple times.
160 * @throws IllegalStateException
161 * If node was emitted inside <code>map</code>,
162 * <code>choice</code> <code>unkeyed list</code> node.
163 * @throws IOException if an underlying IO error occurs
165 void startOrderedLeafSet(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
168 * Emits a leaf set entry node
171 * Value of leaf set entry node. Supplied object MUST BE constant over time.
172 * @throws IllegalArgumentException
173 * If emitted leaf node has invalid value.
174 * @throws IllegalStateException
175 * If node was emitted outside <code>leaf set</code> node.
176 * @throws IOException if an underlying IO error occurs
178 void leafSetEntryNode(Object value) throws IOException;
182 * Emits start of new container.
185 * End of container event is emitted by invoking {@link #endNode()}.
188 * Valid sub-events are:
190 * <li>{@link #leafNode}</li>
191 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
192 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
193 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
194 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
195 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
196 * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
200 * name of node as defined in schema, namespace and revision are
201 * derived from parent node.
202 * @param childSizeHint
203 * Non-negative count of expected direct child nodes or
204 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
205 * and should not fail writing of child events, if there are more
207 * @throws IllegalArgumentException
208 * If emitted node is invalid in current context or was emitted
210 * @throws IllegalStateException
211 * If node was emitted inside <code>map</code>,
212 * <code>choice</code> <code>unkeyed list</code> node.
213 * @throws IOException if an underlying IO error occurs
215 void startContainerNode(NodeIdentifier name, int childSizeHint) throws IOException;
219 * Emits start of unkeyed list node event.
222 * End of unkeyed list event is emitted by invoking {@link #endNode()}.
223 * Valid subevents is only {@link #startUnkeyedListItem(NodeIdentifier, int)}. All other
224 * methods will throw {@link IllegalArgumentException}.
227 * name of node as defined in schema, namespace and revision are
228 * derived from parent node.
229 * @param childSizeHint
230 * Non-negative count of expected direct child nodes or
231 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
232 * and should not fail writing of child events, if there are more
234 * @throws IllegalArgumentException
235 * If emitted node is invalid in current context or was emitted
237 * @throws IllegalStateException
238 * If node was emitted inside <code>map</code>,
239 * <code>choice</code> <code>unkeyed list</code> node.
240 * @throws IOException if an underlying IO error occurs
242 void startUnkeyedList(NodeIdentifier name, int childSizeHint) throws IOException;
245 * Emits start of new unkeyed list item.
248 * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
251 * <li>{@link #leafNode}</li>
252 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
253 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
254 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
255 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
256 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
257 * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
260 * @param name Identifier of node
261 * @param childSizeHint
262 * Non-negative count of expected direct child nodes or
263 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
264 * and should not fail writing of child events, if there are more
266 * @throws IllegalStateException
267 * If node was emitted outside <code>unkeyed list</code> node.
268 * @throws IOException if an underlying IO error occurs
270 void startUnkeyedListItem(NodeIdentifier name, int childSizeHint) throws IOException;
274 * Emits start of map node event.
277 * End of map node event is emitted by invoking {@link #endNode()}. Valid
279 * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
280 * methods will throw {@link IllegalArgumentException}.
283 * name of node as defined in schema, namespace and revision are
284 * derived from parent node.
285 * @param childSizeHint
286 * Non-negative count of expected direct child nodes or
287 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
288 * and should not fail writing of child events, if there are more
290 * @throws IllegalArgumentException
291 * If emitted node is invalid in current context or was emitted
293 * @throws IllegalStateException
294 * If node was emitted inside <code>map</code>,
295 * <code>choice</code> <code>unkeyed list</code> node.
296 * @throws IOException if an underlying IO error occurs
298 void startMapNode(NodeIdentifier name, int childSizeHint) throws IOException;
302 * Emits start of map entry.
305 * End of map entry event is emitted by invoking {@link #endNode()}.
308 * Valid sub-events are:
310 * <li>{@link #leafNode}</li>
311 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
312 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
313 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
314 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
315 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
316 * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
321 * QName to value pairs of keys of map entry node. Values MUST BE constant over time.
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 key contains incorrect value.
329 * @throws IllegalStateException
330 * If node was emitted outside <code>map entry</code> node.
331 * @throws IOException if an underlying IO error occurs
333 void startMapEntryNode(NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException;
337 * Emits start of map node event.
340 * End of map node event is emitted by invoking {@link #endNode()}. Valid
342 * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
343 * methods will throw {@link IllegalArgumentException}.
346 * name of node as defined in schema, namespace and revision are
347 * derived from parent node.
348 * @param childSizeHint
349 * Non-negative count of expected direct child nodes or
350 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
351 * and should not fail writing of child events, if there are more
353 * @throws IllegalArgumentException
354 * If emitted node is invalid in current context or was emitted
356 * @throws IllegalStateException
357 * If node was emitted inside <code>map</code>,
358 * <code>choice</code> <code>unkeyed list</code> node.
359 * @throws IOException if an underlying IO error occurs
361 void startOrderedMapNode(NodeIdentifier name, int childSizeHint) throws IOException;
368 * name of node as defined in schema, namespace and revision are
369 * derived from parent node.
370 * @param childSizeHint
371 * Non-negative count of expected direct child nodes or
372 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
373 * and should not fail writing of child events, if there are more
375 * @throws IllegalArgumentException
376 * If emitted node is invalid in current context or was emitted
378 * @throws IllegalStateException
379 * If node was emitted inside <code>map</code>,
380 * <code>choice</code> <code>unkeyed list</code> node.
381 * @throws IOException if an underlying IO error occurs
383 void startChoiceNode(NodeIdentifier name, int childSizeHint) throws IOException;
386 * Emits start of augmentation node.
389 * End of augmentation event is emitted by invoking {@link #endNode()}.
392 * Valid sub-events are:
395 * <li>{@link #leafNode}</li>
396 * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
397 * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
398 * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
399 * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
400 * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
404 * Augmentation identifier
405 * @throws IllegalArgumentException
406 * If augmentation is invalid in current context.
407 * @throws IOException if an underlying IO error occurs
409 void startAugmentationNode(AugmentationIdentifier identifier) throws IOException;
412 * Emits anyxml node event.
415 * name of node as defined in schema, namespace and revision are
416 * derived from parent node.
418 * Value of AnyXml node.
419 * @throws IllegalArgumentException
420 * If emitted node is invalid in current context or was emitted
422 * @throws IllegalStateException
423 * If node was emitted inside <code>map</code>,
424 * <code>choice</code> <code>unkeyed list</code> node.
425 * @throws IOException if an underlying IO error occurs
427 void anyxmlNode(NodeIdentifier name, Object value) throws IOException;
431 * Emits start of new yang modeled anyXml node.
434 * End of yang modeled anyXml node event is emitted by invoking {@link #endNode()}.
437 * Valid sub-events are:
439 * <li>{@link #leafNode}</li>
440 * <li>{@link #startContainerNode}</li>
441 * <li>{@link #startLeafSet}</li>
442 * <li>{@link #startMapNode}</li>
443 * <li>{@link #startUnkeyedList}</li>
447 * name of node as defined in schema, namespace and revision are
448 * derived from parent node.
449 * @param childSizeHint
450 * Non-negative count of expected direct child nodes or
451 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
452 * and should not fail writing of child events, if there are more
454 * @throws IllegalArgumentException
455 * If emitted node is invalid in current context or was emitted
457 * @throws IllegalStateException
458 * If node was emitted inside <code>map</code>,
459 * <code>choice</code> <code>unkeyed list</code> node.
460 * @throws IOException if an underlying IO error occurs
462 void startYangModeledAnyXmlNode(NodeIdentifier name, int childSizeHint) throws IOException;
465 * Emits end event for node.
467 * @throws IllegalStateException If there is no start* event to be closed.
468 * @throws IOException if an underlying IO error occurs
470 void endNode() throws IOException;
473 void close() throws IOException;
476 void flush() throws IOException;