1168a0b116bf00bb5b14804f8be9734bd0e5dfe8
[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
14 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
15 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
17
18
19 /**
20  * Event Stream Writer based on Normalized Node tree representation
21  *
22  * <h3>Writing Event Stream</h3>
23  *
24  * <ul>
25  * <li><code>container</code> - Container node representation, start event is
26  * emitted using {@link #startContainerNode(NodeIdentifier, int)} and node end event is
27  * emitted using {@link #endNode()}. Container node is implementing
28  * the org.opendaylight.yangtools.yang.binding.DataObject interface.
29  *
30  * <li><code>list</code> - YANG list statement has two representation in event
31  * stream - unkeyed list and map. Unkeyed list is YANG list which did not
32  * specify key.
33  *
34  * <ul>
35  * <li><code>Map</code> - Map start event is emitted using
36  * {@link #startMapNode(NodeIdentifier, int)} and is ended using {@link #endNode()}. Each map
37  * entry start is emitted using {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)} with Map of keys
38  * and finished using {@link #endNode()}.</li>
39  *
40  * <li><code>UnkeyedList</code> - Unkeyed list represent list without keys,
41  * unkeyed list start is emitted using {@link #startUnkeyedList(NodeIdentifier, int)} list
42  * end is emitted using {@link #endNode()}. Each list item is emitted using
43  * {@link #startUnkeyedListItem(NodeIdentifier, int)} and ended using {@link #endNode()}.</li>
44  * </ul></li>
45  *
46  * <li><code>leaf</code> - Leaf node event is emitted using
47  * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted for
48  * leaf node.</li>
49  *
50  * <li><code>leaf-list</code> - Leaf list start is emitted using
51  * {@link #startLeafSet(NodeIdentifier, int)}. Leaf list end is emitted using
52  * {@link #endNode()}. Leaf list entries are emmited using
53  * {@link #leafSetEntryNode(Object)}.
54  *
55  * <li><code>anyxml - Anyxml node event is emitted using
56  * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted
57  * for anyxml node.</code></li>
58  *
59  *
60  * <li><code>choice</code> Choice node event is emmited by
61  * {@link #startChoiceNode(NodeIdentifier, int)} event and
62  * finished by invoking {@link #endNode()}
63  * <li>
64  * <code>augment</code> - Represents augmentation, augmentation node is started
65  * by invoking {@link #startAugmentationNode(AugmentationIdentifier)} and
66  * finished by invoking {@link #endNode()}.</li>
67  *
68  * </ul>
69  *
70  * <h3>Implementation notes</h3>
71  *
72  * <p>
73  * Implementations of this interface must not hold user suppled objects
74  * and resources needlessly.
75  *
76  */
77 public interface NormalizedNodeStreamWriter extends Closeable, Flushable {
78
79     /**
80      * Methods in this interface allow users to hint the underlying
81      * implementation about the sizing of container-like constructors
82      * (leafLists, containers, etc.). These hints may be taken into account by a
83      * particular implementation to improve performance, but clients are not
84      * required to provide hints. This constant should be used by clients who
85      * either do not have the sizing information, or do not wish to divulge it
86      * (for whatever reasons). Implementations are free to ignore these hints
87      * completely, but if they do use them, they are expected to be resilient in
88      * face of missing and mismatched hints, which is to say the user can
89      * specify startLeafSet(..., 1) and then call leafNode() 15 times.
90      * <p>
91      * The acceptable hint values are non-negative integers and this constant,
92      * all other values will result, based on implementation preference, in the
93      * hint being completely ignored or IllegalArgumentException being thrown.
94      */
95     public final int UNKNOWN_SIZE = -1;
96
97     /**
98      *
99      * Emits a leaf node event with supplied value.
100      *
101      * @param name
102      *            name of node as defined in schema, namespace and revision are
103      *            derived from parent node.
104      * @param value
105      *            Value of leaf node. v
106      * @throws IllegalArgumentException
107      *             If emitted leaf node has invalid value in current context or
108      *             was emitted multiple times.
109      * @throws IllegalStateException
110      *             If node was emitted inside <code>map</code>,
111      *             <code>choice</code> <code>unkeyed list</code> node.
112      * @throws IOException if an underlying IO error occurs
113      */
114     void leafNode(NodeIdentifier name, Object value) throws IOException, IllegalArgumentException;
115
116     /**
117      *
118      * Emits a start of leaf set (leaf-list).
119      * <p>
120      * Emits start of leaf set, during writing leaf set event, only
121      * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
122      * finished by calling {@link #endNode()}.
123      *
124      * @param name
125      *            name of node as defined in schema, namespace and revision are
126      *            derived from parent node.
127      * @param childSizeHint
128      *            Non-negative count of expected direct child nodes or
129      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
130      *            and should not fail writing of child events, if there are more
131      *            events than count.
132      * @throws IllegalArgumentException
133      *             If emitted leaf node is invalid in current context or was
134      *             emitted multiple times.
135      * @throws IllegalStateException
136      *             If node was emitted inside <code>map</code>,
137      *             <code>choice</code> <code>unkeyed list</code> node.
138      * @throws IOException if an underlying IO error occurs
139      */
140     void startLeafSet(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
141
142     /**
143      * Emits a leaf set entry node
144      *
145      * @param value
146      *            Value of leaf set entry node. Supplied object MUST BE constant over time.
147      * @throws IllegalArgumentException
148      *             If emitted leaf node has invalid value.
149      * @throws IllegalStateException
150      *             If node was emitted outside <code>leaf set</code> node.
151      * @throws IOException if an underlying IO error occurs
152      */
153     void leafSetEntryNode(Object value) throws IOException, IllegalArgumentException;
154
155     /**
156      *
157      * Emits start of new container.
158      *
159      * <p>
160      * End of container event is emitted by invoking {@link #endNode()}.
161      *
162      * <p>
163      * Valid sub-events are:
164      * <ul>
165      * <li>{@link #leafNode}</li>
166      * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
167      * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
168      * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
169      * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
170      * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
171      * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
172      * </ul>
173      *
174      * @param name
175      *            name of node as defined in schema, namespace and revision are
176      *            derived from parent node.
177      * @param childSizeHint
178      *            Non-negative count of expected direct child nodes or
179      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
180      *            and should not fail writing of child events, if there are more
181      *            events than count.
182      * @throws IllegalArgumentException
183      *             If emitted node is invalid in current context or was emitted
184      *             multiple times.
185      * @throws IllegalStateException
186      *             If node was emitted inside <code>map</code>,
187      *             <code>choice</code> <code>unkeyed list</code> node.
188      * @throws IOException if an underlying IO error occurs
189      */
190     void startContainerNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
191
192     /**
193      *
194      * Emits start of unkeyed list node event.
195      *
196      * <p>
197      * End of unkeyed list event is emitted by invoking {@link #endNode()}.
198      * Valid subevents is only {@link #startUnkeyedListItem(NodeIdentifier, int)}. All other
199      * methods will throw {@link IllegalArgumentException}.
200      *
201      * @param name
202      *            name of node as defined in schema, namespace and revision are
203      *            derived from parent node.
204      * @param childSizeHint
205      *            Non-negative count of expected direct child nodes or
206      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
207      *            and should not fail writing of child events, if there are more
208      *            events than count.
209      * @throws IllegalArgumentException
210      *             If emitted node is invalid in current context or was emitted
211      *             multiple times.
212      * @throws IllegalStateException
213      *             If node was emitted inside <code>map</code>,
214      *             <code>choice</code> <code>unkeyed list</code> node.
215      * @throws IOException if an underlying IO error occurs
216      */
217     void startUnkeyedList(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
218
219     /**
220      * Emits start of new unkeyed list item.
221      *
222      * <p>
223      * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
224      * sub-events are:
225      * <ul>
226      * <li>{@link #leafNode}</li>
227      * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
228      * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
229      * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
230      * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
231      * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
232      * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
233      * </ul>
234      *
235      * @param name Identifier of node
236      * @param childSizeHint
237      *            Non-negative count of expected direct child nodes or
238      *            {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
239      *            and should not fail writing of child events, if there are more
240      *            events than count.
241      * @throws IllegalStateException
242      *             If node was emitted outside <code>unkeyed list</code> node.
243      * @throws IOException if an underlying IO error occurs
244      */
245     void startUnkeyedListItem(NodeIdentifier name, int childSizeHint) throws IOException, IllegalStateException;
246
247     /**
248      *
249      * Emits start of map node event.
250      *
251      * <p>
252      * End of map node event is emitted by invoking {@link #endNode()}. Valid
253      * subevents is only
254      * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
255      * methods will throw {@link IllegalArgumentException}.
256      *
257      * @param name
258      *            name of node as defined in schema, namespace and revision are
259      *            derived from parent node.
260      * @param childSizeHint
261      * @throws IllegalArgumentException
262      * @throws IllegalStateException
263      *             If node was emitted inside <code>map</code>,
264      *             <code>choice</code> <code>unkeyed list</code> node.
265      * @throws IOException if an underlying IO error occurs
266      */
267     void startMapNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
268
269     /**
270      *
271      * Emits start of map entry.
272      *
273      * <p>
274      * End of map entry event is emitted by invoking {@link #endNode()}.
275      *
276      * <p>
277      * Valid sub-events are:
278      * <ul>
279      * <li>{@link #leafNode}</li>
280      * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
281      * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
282      * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
283      * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
284      * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
285      * <li>{@link #startAugmentationNode(AugmentationIdentifier)}</li>
286      * </ul>
287      *
288      *
289      * @param identifier
290      *            QName to value pairs of keys of map entry node. Values  MUST BE constant over time.
291      * @throws IllegalArgumentException
292      *             If key contains incorrect value.
293      * @throws IllegalStateException
294      *             If node was emitted outside <code>map entry</code> node.
295      * @throws IOException if an underlying IO error occurs
296      */
297     void startMapEntryNode(NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException, IllegalArgumentException;
298
299     /**
300      *
301      * Emits start of map node event.
302      *
303      * <p>
304      * End of map node event is emitted by invoking {@link #endNode()}. Valid
305      * subevents is only
306      * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
307      * methods will throw {@link IllegalArgumentException}.
308      *
309      * @param name
310      *            name of node as defined in schema, namespace and revision are
311      *            derived from parent node.
312      * @throws IllegalArgumentException
313      * @throws IllegalStateException
314      *             If node was emitted inside <code>map</code>,
315      *             <code>choice</code> <code>unkeyed list</code> node.
316      * @throws IOException if an underlying IO error occurs
317      */
318     void startOrderedMapNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
319
320     /**
321      *
322      *
323      *
324      * @param name
325      *            name of node as defined in schema, namespace and revision are
326      *            derived from parent node.
327      * @param childSizeHint
328      * @throws IllegalArgumentException
329      * @throws IllegalStateException
330      *             If node was emitted inside <code>map</code>,
331      *             <code>choice</code> <code>unkeyed list</code> node.
332      * @throws IOException if an underlying IO error occurs
333      */
334     void startChoiceNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
335
336     /**
337      * Emits start of augmentation node.
338      *
339      * <p>
340      * End of augmentation event is emitted by invoking {@link #endNode()}.
341      *
342      * <p>
343      * Valid sub-events are:
344      *
345      * <ul>
346      * <li>{@link #leafNode}</li>
347      * <li>{@link #startContainerNode(NodeIdentifier, int)}</li>
348      * <li>{@link #startChoiceNode(NodeIdentifier, int)}</li>
349      * <li>{@link #startLeafSet(NodeIdentifier, int)}</li>
350      * <li>{@link #startMapNode(NodeIdentifier, int)}</li>
351      * <li>{@link #startUnkeyedList(NodeIdentifier, int)}</li>
352      * </ul>
353      *
354      * @param identifier
355      *            Augmentation identifier
356      * @throws IllegalArgumentException
357      *             If augmentation is invalid in current context.
358      * @throws IOException if an underlying IO error occurs
359      */
360     void startAugmentationNode(AugmentationIdentifier identifier) throws IOException, IllegalArgumentException;
361
362     /**
363      * Emits anyxml node event.
364      *
365      * @param name
366      * @param value
367      * @throws IllegalArgumentException
368      * @throws IllegalStateException
369      *             If node was emitted inside <code>map</code>,
370      *             <code>choice</code> <code>unkeyed list</code> node.
371      * @throws IOException if an underlying IO error occurs
372      */
373     void anyxmlNode(NodeIdentifier name, Object value) throws IOException, IllegalArgumentException;
374
375     /**
376      * Emits end event for node.
377      *
378      * @throws IllegalStateException If there is no start* event to be closed.
379      * @throws IOException if an underlying IO error occurs
380      */
381     void endNode() throws IOException, IllegalStateException;
382
383     @Override
384     void close() throws IOException;
385
386     @Override
387     void flush() throws IOException;
388 }