983378703e57f72694db34748f7011b008484fd6
[yangtools.git] / yang / yang-data-api / src / main / java / org / opendaylight / yangtools / yang / data / api / schema / stream / NormalizedNodeStreamWriter.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.data.api.schema.stream;
9
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;
16
17
18 /**
19  * Event Stream Writer based on Normalized Node tree representation
20  *
21  * <h3>Writing Event Stream</h3>
22  *
23  * <ul>
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.
28  *
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
31  * specify key.
32  *
33  * <ul>
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>
38  *
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>
43  * </ul></li>
44  *
45  * <li><code>leaf</code> - Leaf node event is emitted using
46  * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted for
47  * leaf node.</li>
48  *
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)}.
53  *
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>
57  *
58  *
59  * <li><code>choice</code> Choice node event is emmited by
60  * {@link #startChoiceNode(NodeIdentifier, int)} event and
61  * finished by invoking {@link #endNode()}
62  * <li>
63  * <code>augment</code> - Represents augmentation, augmentation node is started
64  * by invoking {@link #startAugmentationNode(AugmentationIdentifier)} and
65  * finished by invoking {@link #endNode()}.</li>
66  *
67  * </ul>
68  *
69  * <h3>Implementation notes</h3>
70  *
71  * <p>
72  * Implementations of this interface must not hold user suppled objects
73  * and resources needlessly.
74  *
75  */
76 public interface NormalizedNodeStreamWriter extends Closeable, Flushable {
77
78     /**
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.
89      * <p>
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.
93      */
94     int UNKNOWN_SIZE = -1;
95
96     /**
97      *
98      * Emits a leaf node event with supplied value.
99      *
100      * @param name
101      *            name of node as defined in schema, namespace and revision are
102      *            derived from parent node.
103      * @param value
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
112      */
113     void leafNode(NodeIdentifier name, Object value) throws IOException;
114
115     /**
116      *
117      * Emits a start of leaf set (leaf-list).
118      * <p>
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()}.
122      *
123      * @param name
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
130      *            events than count.
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
138      */
139     void startLeafSet(NodeIdentifier name, int childSizeHint) throws IOException;
140
141     /**
142      * Emits a leaf set entry node
143      *
144      * @param value
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
151      */
152     void leafSetEntryNode(Object value) throws IOException;
153
154     /**
155      *
156      * Emits start of new container.
157      *
158      * <p>
159      * End of container event is emitted by invoking {@link #endNode()}.
160      *
161      * <p>
162      * Valid sub-events are:
163      * <ul>
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>
171      * </ul>
172      *
173      * @param name
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
180      *            events than count.
181      * @throws IllegalArgumentException
182      *             If emitted node is invalid in current context or was emitted
183      *             multiple times.
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
188      */
189     void startContainerNode(NodeIdentifier name, int childSizeHint) throws IOException;
190
191     /**
192      *
193      * Emits start of unkeyed list node event.
194      *
195      * <p>
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}.
199      *
200      * @param name
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
207      *            events than count.
208      * @throws IllegalArgumentException
209      *             If emitted node is invalid in current context or was emitted
210      *             multiple times.
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
215      */
216     void startUnkeyedList(NodeIdentifier name, int childSizeHint) throws IOException;
217
218     /**
219      * Emits start of new unkeyed list item.
220      *
221      * <p>
222      * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
223      * sub-events are:
224      * <ul>
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>
232      * </ul>
233      *
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
239      *            events than count.
240      * @throws IllegalStateException
241      *             If node was emitted outside <code>unkeyed list</code> node.
242      * @throws IOException if an underlying IO error occurs
243      */
244     void startUnkeyedListItem(NodeIdentifier name, int childSizeHint) throws IOException;
245
246     /**
247      *
248      * Emits start of map node event.
249      *
250      * <p>
251      * End of map node event is emitted by invoking {@link #endNode()}. Valid
252      * subevents is only
253      * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
254      * methods will throw {@link IllegalArgumentException}.
255      *
256      * @param name
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
263      *            events than count.
264      * @throws IllegalArgumentException
265      *             If emitted node is invalid in current context or was emitted
266      *             multiple times.
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
271      */
272     void startMapNode(NodeIdentifier name, int childSizeHint) throws IOException;
273
274     /**
275      *
276      * Emits start of map entry.
277      *
278      * <p>
279      * End of map entry event is emitted by invoking {@link #endNode()}.
280      *
281      * <p>
282      * Valid sub-events are:
283      * <ul>
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>
291      * </ul>
292      *
293      *
294      * @param identifier
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
300      *            events than count.
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
306      */
307     void startMapEntryNode(NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException;
308
309     /**
310      *
311      * Emits start of map node event.
312      *
313      * <p>
314      * End of map node event is emitted by invoking {@link #endNode()}. Valid
315      * subevents is only
316      * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
317      * methods will throw {@link IllegalArgumentException}.
318      *
319      * @param name
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
326      *            events than count.
327      * @throws IllegalArgumentException
328      *             If emitted node is invalid in current context or was emitted
329      *             multiple times.
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
334      */
335     void startOrderedMapNode(NodeIdentifier name, int childSizeHint) throws IOException;
336
337     /**
338      *
339      *
340      *
341      * @param name
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
348      *            events than count.
349      * @throws IllegalArgumentException
350      *             If emitted node is invalid in current context or was emitted
351      *             multiple times.
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
356      */
357     void startChoiceNode(NodeIdentifier name, int childSizeHint) throws IOException;
358
359     /**
360      * Emits start of augmentation node.
361      *
362      * <p>
363      * End of augmentation event is emitted by invoking {@link #endNode()}.
364      *
365      * <p>
366      * Valid sub-events are:
367      *
368      * <ul>
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>
375      * </ul>
376      *
377      * @param identifier
378      *            Augmentation identifier
379      * @throws IllegalArgumentException
380      *             If augmentation is invalid in current context.
381      * @throws IOException if an underlying IO error occurs
382      */
383     void startAugmentationNode(AugmentationIdentifier identifier) throws IOException;
384
385     /**
386      * Emits anyxml node event.
387      *
388      * @param name
389      *            name of node as defined in schema, namespace and revision are
390      *            derived from parent node.
391      * @param value
392      *             Value of AnyXml node.
393      * @throws IllegalArgumentException
394      *             If emitted node is invalid in current context or was emitted
395      *             multiple times.
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
400      */
401     void anyxmlNode(NodeIdentifier name, Object value) throws IOException;
402
403     /**
404     *
405     * Emits start of new yang modeled anyXml node.
406     *
407     * <p>
408     * End of yang modeled anyXml node event is emitted by invoking {@link #endNode()}.
409     *
410     * <p>
411     * Valid sub-events are:
412     * <ul>
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>
418     * </ul>
419     *
420     * @param name
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
427     *            events than count.
428     * @throws IllegalArgumentException
429     *             If emitted node is invalid in current context or was emitted
430     *             multiple times.
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
435     */
436     void startYangModeledAnyXmlNode(NodeIdentifier name, int childSizeHint) throws IOException;
437
438     /**
439      * Emits end event for node.
440      *
441      * @throws IllegalStateException If there is no start* event to be closed.
442      * @throws IOException if an underlying IO error occurs
443      */
444     void endNode() throws IOException;
445
446     @Override
447     void close() throws IOException;
448
449     @Override
450     void flush() throws IOException;
451 }