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;
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;
20 * Event Stream Writer based on Normalized Node tree representation
22 * <h3>Writing Event Stream</h3>
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.
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
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>
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>
46 * <li><code>leaf</code> - Leaf node event is emitted using
47 * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted for
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)}.
55 * <li><code>anyxml - AN node event is emitted using
56 * {@link #leafNode(NodeIdentifier, Object)}. {@link #endNode()} MUST NOT BE emitted
57 * for anyxml node.</code></li>
60 * <li><code>choice</code> Choice node event is emmited by
61 * {@link #startChoiceNode(NodeIdentifier, int)} event and
62 * finished by invoking {@link #endNode()}
64 * <code>augment</code> - Represents augmentation, augmentation node is started
65 * by invoking {@link #startAugmentationNode(AugmentationIdentifier)} and
66 * finished by invoking {@link #endNode()}.</li>
70 * <h3>Implementation notes</h3>
73 * Implementations of this interface must not hold user suppled objects
74 * and resources needlessly.
77 public interface NormalizedNodeStreamWriter extends Closeable, Flushable {
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.
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.
95 int UNKNOWN_SIZE = -1;
99 * Emits a leaf node event with supplied value.
102 * name of node as defined in schema, namespace and revision are
103 * derived from parent node.
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
114 void leafNode(NodeIdentifier name, Object value) throws IOException, IllegalArgumentException;
118 * Emits a start of leaf set (leaf-list).
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()}.
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
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
140 void startLeafSet(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
143 * Emits a leaf set entry node
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
153 void leafSetEntryNode(Object value) throws IOException, IllegalArgumentException;
157 * Emits start of new container.
160 * End of container event is emitted by invoking {@link #endNode()}.
163 * Valid sub-events are:
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>
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
182 * @throws IllegalArgumentException
183 * If emitted node is invalid in current context or was emitted
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
190 void startContainerNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
194 * Emits start of unkeyed list node event.
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}.
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
209 * @throws IllegalArgumentException
210 * If emitted node is invalid in current context or was emitted
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
217 void startUnkeyedList(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
220 * Emits start of new unkeyed list item.
223 * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
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>
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
241 * @throws IllegalStateException
242 * If node was emitted outside <code>unkeyed list</code> node.
243 * @throws IOException if an underlying IO error occurs
245 void startUnkeyedListItem(NodeIdentifier name, int childSizeHint) throws IOException, IllegalStateException;
249 * Emits start of map node event.
252 * End of map node event is emitted by invoking {@link #endNode()}. Valid
254 * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
255 * methods will throw {@link IllegalArgumentException}.
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
267 void startMapNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
271 * Emits start of map entry.
274 * End of map entry event is emitted by invoking {@link #endNode()}.
277 * Valid sub-events are:
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>
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
297 void startMapEntryNode(NodeIdentifierWithPredicates identifier, int childSizeHint) throws IOException, IllegalArgumentException;
301 * Emits start of map node event.
304 * End of map node event is emitted by invoking {@link #endNode()}. Valid
306 * {@link #startMapEntryNode(NodeIdentifierWithPredicates, int)}. All other
307 * methods will throw {@link IllegalArgumentException}.
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
318 void startOrderedMapNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
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
334 void startChoiceNode(NodeIdentifier name, int childSizeHint) throws IOException, IllegalArgumentException;
337 * Emits start of augmentation node.
340 * End of augmentation event is emitted by invoking {@link #endNode()}.
343 * Valid sub-events are:
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>
355 * Augmentation identifier
356 * @throws IllegalArgumentException
357 * If augmentation is invalid in current context.
358 * @throws IOException if an underlying IO error occurs
360 void startAugmentationNode(AugmentationIdentifier identifier) throws IOException, IllegalArgumentException;
363 * Emits anyxml node event.
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
373 void anyxmlNode(NodeIdentifier name, Object value) throws IOException, IllegalArgumentException;
376 * Emits end event for node.
378 * @throws IllegalStateException If there is no start* event to be closed.
379 * @throws IOException if an underlying IO error occurs
381 void endNode() throws IOException, IllegalStateException;
384 void close() throws IOException;
387 void flush() throws IOException;