2 * Copyright (c) 2017 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
9 package org.opendaylight.mdsal.binding.javav2.spec.runtime;
11 import com.google.common.annotations.Beta;
12 import java.io.Closeable;
13 import java.io.Flushable;
14 import java.io.IOException;
15 import org.opendaylight.mdsal.binding.javav2.spec.base.IdentifiableItem;
16 import org.opendaylight.mdsal.binding.javav2.spec.base.Item;
17 import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
18 import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
19 import org.opendaylight.yangtools.concepts.Identifiable;
22 * Event Stream Writer for Binding version 2 Representation
25 * <h3>Emitting Event Stream</h3>
28 * <li><code>container</code> - Container node representation, start event is
29 * emitted using {@link #startContainerNode(Class, int)} and node end event is
30 * emitted using {@link #endNode()}. Container node is implementing
31 * {@link TreeNode} interface.
33 * <li><code>list</code> - YANG list statement has two representations in event
34 * stream - un-keyed list and map. Un-keyed list is YANG list which didn't
38 * <li><code>Map</code> - Map start event is emitted using
39 * {@link #startMapNode(Class, int)} and is ended using {@link #endNode()}. Each map
40 * entry start is emitted using {@link #startMapEntryNode(IdentifiableItem, int)} with Map of keys
41 * and finished using {@link #endNode()}.</li>
43 * <li><code>UnkeyedList</code> - Un-keyed list represents list without keys,
44 * un-keyed list start is emitted using {@link #startUnkeyedList(Class, int)}, list
45 * end is emitted using {@link #endNode()}. Each list item is emitted using
46 * {@link #startUnkeyedListItem(int)} and ended using {@link #endNode()}.</li>
49 * <li><code>leaf</code> - Leaf node event is emitted using
50 * {@link #leafNode(String, Object)}. {@link #endNode()} MUST NOT be emitted for
53 * <li><code>leaf-list</code> - Leaf list start is emitted using
54 * {@link #startLeafSet(String, int)}. Leaf list end is emitted using
55 * {@link #endNode()}. Leaf list entries are emitted using
56 * {@link #leafSetEntryNode(Object)}.
58 * <li><code>anyxml - Anyxml node event is emitted using
59 * {@link #anyxmlNode(String, Object)}. {@link #endNode()} MUST NOT be emitted
60 * for anyxml node.</code></li>
62 * <li><code>anydata - Anydata node event is emitted using
63 * {@link #startAnydataNode(String, Object)}. {@link #endNode()} MUST NOT be emitted
64 * for anydata node.</code></li>
66 * <li><code>choice</code> Choice node event is emitted by
67 * {@link #startChoiceNode(Item, int)} event and must be immediately followed by
68 * {@link #startCase(Class, int)} event. Choice node is finished by emitting an
69 * {@link #endNode()} event.</li>
72 * <code>case</code> - Case node may be emitted only inside choice node by
73 * invoking {@link #startCase(Class, int)}. Case node is finished be emitting an
74 * {@link #endNode()} event.</li>
77 * <code>augment</code> - Represents augmentation, augmentation node is started
78 * by invoking {@link #startAugmentationNode(Class)} and
79 * finished by invoking {@link #endNode()}.</li>
83 * <h3>Implementation notes</h3> This interface is not intended to be
84 * implemented by users of generated Binding2 DTOs but to be used by utilities,
85 * which needs to emit NormalizedNode model from Binding2 DTOs.
87 * This interface is intended as API definition of facade for real Event /
88 * Stream Writer, without explicitly requiring stream writer and related
89 * interfaces to be imported by all generated Binding2 DTOs.
91 * Existence of this interface in runtime Java Binding2 package is required to
92 * support runtime generation of users of this interface in OSGI and OSGI-like
93 * environment, since this package is only package which is imported by all
94 * generated Binding2 DTOs and wired in OSGI.
99 public interface BindingStreamEventWriter extends Closeable, Flushable {
102 * Methods in this interface allow users to hint the underlying
103 * implementation about the sizing of container-like constructors
104 * (leafLists, containers, etc.). These hints may be taken into account by a
105 * particular implementation to improve performance, but clients are not
106 * required to provide hints. This constant should be used by clients who
107 * either do not have the sizing information, or do not wish to divulge it
108 * (for whatever reasons). Implementations are free to ignore these hints
109 * completely, but if they do use them, they are expected to be resilient in
110 * face of missing and mismatched hints, which is to say the user can
111 * specify startLeafSet(..., 1) and then call leafNode() 15 times.
113 * The acceptable hint values are non-negative integers and this constant,
114 * all other values will result, based on implementation preference, in the
115 * hint being completely ignored or IllegalArgumentException being thrown.
117 int UNKNOWN_SIZE = -1;
121 * Emits a leaf node event with supplied value.
124 * name of node as defined in schema, namespace and revision are
125 * derived from parent node.
127 * Value of leaf node.
128 * @throws IllegalArgumentException
129 * If emitted leaf node has invalid value in current context or
130 * was emitted multiple times.
131 * @throws IllegalStateException
132 * If node was emitted inside <code>map</code>,
133 * <code>choice</code> <code>unkeyed list</code> node.
134 * @throws IOException if an underlying IO error occurs
136 void leafNode(String localName, Object value) throws IOException;
140 * Emits a start of leaf set (leaf-list).
142 * Emits start of leaf set, during writing leaf set event, only
143 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
144 * finished by calling {@link #endNode()}.
147 * name of node as defined in schema, namespace and revision are
148 * derived from parent node.
149 * @param childSizeHint
150 * Non-negative count of expected direct child nodes or
151 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
152 * and should not fail writing of child events, if there are more
154 * @throws IllegalArgumentException
155 * If emitted leaf node is invalid in current context or was
156 * emitted multiple times.
157 * @throws IllegalStateException
158 * If node was emitted inside <code>map</code>,
159 * <code>choice</code> <code>unkeyed list</code> node.
160 * @throws IOException if an underlying IO error occurs
162 void startLeafSet(String localName, int childSizeHint) throws IOException;
166 * Emits a start of leaf set (leaf-list).
168 * Emits start of leaf set, during writing leaf set event, only
169 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
170 * finished by calling {@link #endNode()}.
173 * name of node as defined in schema, namespace and revision are
174 * derived from parent node.
175 * @param childSizeHint
176 * Non-negative count of expected direct child nodes or
177 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
178 * and should not fail writing of child events, if there are more
180 * @throws IllegalArgumentException
181 * If emitted leaf node is invalid in current context or was
182 * emitted multiple times.
183 * @throws IllegalStateException
184 * If node was emitted inside <code>map</code>,
185 * <code>choice</code> <code>unkeyed list</code> node.
186 * @throws IOException if an underlying IO error occurs
188 void startOrderedLeafSet(String localName, int childSizeHint) throws IOException;
191 * Emits a leaf set entry node
194 * Value of leaf set entry node.
195 * @throws IllegalArgumentException
196 * If emitted leaf node has invalid value.
197 * @throws IllegalStateException
198 * If node was emitted outside <code>leaf set</code> node.
199 * @throws IOException if an underlying IO error occurs
201 void leafSetEntryNode(Object value) throws IOException;
205 * Emits start of new container.
208 * End of container event is emitted by invoking {@link #endNode()}.
211 * Valid sub-events are:
213 * <li>{@link #leafNode(String, Object)}</li>
214 * <li>{@link #startContainerNode(Class, int)}</li>
215 * <li>{@link #startChoiceNode(Item, int)}</li>
216 * <li>{@link #startLeafSet(String, int)}</li>
217 * <li>{@link #startMapNode(Class, int)}</li>
218 * <li>{@link #startUnkeyedList(Class, int)}</li>
219 * <li>{@link #startAugmentationNode(Class)}</li>
223 * name of node as defined in schema, namespace and revision are
224 * derived from parent node.
225 * @param childSizeHint
226 * Non-negative count of expected direct child nodes or
227 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
228 * and should not fail writing of child events, if there are more
230 * @throws IllegalArgumentException
231 * If emitted node is invalid in current context or was emitted
233 * @throws IllegalStateException
234 * If node was emitted inside <code>map</code>,
235 * <code>choice</code> <code>unkeyed list</code> node.
236 * @throws IOException if an underlying IO error occurs
238 void startContainerNode(Class<? extends TreeNode> container, int childSizeHint) throws IOException;
242 * Emits start of unkeyed list node event.
245 * End of unkeyed list event is emitted by invoking {@link #endNode()}.
246 * Valid sub-event is only {@link #startUnkeyedListItem(int)}. All other
247 * methods will throw {@link IllegalArgumentException}.
250 * name of node as defined in schema, namespace and revision are
251 * derived from parent node.
252 * @param childSizeHint
253 * Non-negative count of expected direct child nodes or
254 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
255 * and should not fail writing of child events, if there are more
257 * @throws IllegalArgumentException
258 * If emitted node is invalid in current context or was emitted
260 * @throws IllegalStateException
261 * If node was emitted inside <code>map</code>,
262 * <code>choice</code> <code>unkeyed list</code> node.
263 * @throws IOException if an underlying IO error occurs
265 void startUnkeyedList(Class<? extends TreeNode> localName, int childSizeHint) throws IOException;
268 * Emits start of new unkeyed list item.
271 * Un-keyed list item event is finished by invoking {@link #endNode()}.
273 * Valid sub-events are:
276 * <li>{@link #leafNode(String, Object)}</li>
277 * <li>{@link #startContainerNode(Class, int)}</li>
278 * <li>{@link #startChoiceNode(Item, int)}</li>
279 * <li>{@link #startLeafSet(String, int)}</li>
280 * <li>{@link #startMapNode(Class, int)}</li>
281 * <li>{@link #startUnkeyedList(Class, int)}</li>
282 * <li>{@link #startAugmentationNode(Class)}</li>
286 * @param childSizeHint
287 * Non-negative count of expected direct child nodes or
288 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
289 * and should not fail writing of child events, if there are more
291 * @throws IllegalStateException
292 * If node was emitted outside <code>unkeyed list</code> node.
293 * @throws IOException if an underlying IO error occurs
295 void startUnkeyedListItem(int childSizeHint) throws IOException;
299 * Emits start of unordered map node event.
302 * End of map node event is emitted by invoking {@link #endNode()}. Valid
303 * subevents is only {@link #startMapEntryNode(IdentifiableItem, int)}. All other methods will
304 * throw {@link IllegalArgumentException}.
306 * @param mapEntryType
308 * @param childSizeHint
309 * Non-negative count of expected direct child nodes or
310 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
311 * and should not fail writing of child events, if there are more
313 * @throws IllegalArgumentException
314 * @throws IllegalStateException
315 * If node was emitted inside <code>map</code>,
316 * <code>choice</code> <code>unkeyed list</code> node.
317 * @throws IOException if an underlying IO error occurs
319 <T extends TreeNode & Identifiable<?>> void startMapNode(Class<T> mapEntryType, int childSizeHint)
324 * Emits start of ordered map node event.
327 * End of map node event is emitted by invoking {@link #endNode()}. Valid
328 * sub-event is only {@link #startMapEntryNode(IdentifiableItem, int)}. All other methods will
329 * throw {@link IllegalArgumentException}.
331 * @param mapEntryType
332 * Class of list item, which has defined key.
333 * @param childSizeHint
334 * Non-negative count of expected direct child nodes or
335 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
336 * and should not fail writing of child events, if there are more
338 * @throws IllegalArgumentException
339 * @throws IllegalStateException
340 * If node was emitted inside <code>map</code>,
341 * <code>choice</code> <code>unkeyed list</code> node.
342 * @throws IOException if an underlying IO error occurs
344 <T extends TreeNode & Identifiable<?>> void startOrderedMapNode(Class<T> mapEntryType, int childSizeHint)
349 * Emits start of map entry.
352 * End of map entry event is emitted by invoking {@link #endNode()}.
355 * Valid sub-events are:
357 * <li>{@link #leafNode(String, Object)}</li>
358 * <li>{@link #startContainerNode(Class, int)}</li>
359 * <li>{@link #startChoiceNode(Item, int)}</li>
360 * <li>{@link #startLeafSet(String, int)}</li>
361 * <li>{@link #startMapNode(Class, int)}</li>
362 * <li>{@link #startUnkeyedList(Class, int)}</li>
363 * <li>{@link #startAugmentationNode(Class)}</li>
367 * Key of map entry node
368 * @param childSizeHint
369 * Non-negative count of expected direct child nodes or
370 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
371 * and should not fail writing of child events, if there are more
373 * @throws IllegalArgumentException
374 * If key contains incorrect value.
375 * @throws IllegalStateException
376 * If node was emitted outside <code>map entry</code> node.
377 * @throws IOException if an underlying IO error occurs
379 <I extends TreeNode, T> void startMapEntryNode(IdentifiableItem<I, T> keyValues, int childSizeHint)
383 * Emits start of choice node.
386 * Valid sub-event is {@link #startCase(Class, int)}, which selects case
387 * which should be written.
391 * @param childSizeHint
392 * Non-negative count of expected direct child nodes or
393 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
394 * and should not fail writing of child events, if there are more
396 * @throws IllegalArgumentException
397 * @throws IllegalStateException
398 * If node was emitted inside <code>map</code>, <code>choice</code>,
399 * <code>unkeyed list</code> node.
400 * @throws IOException if an underlying IO error occurs
402 <T extends TreeNode> void startChoiceNode(Item<T> choice, int childSizeHint) throws IOException;
406 * Starts a case node.
409 * Valid sub-events are:
411 * <li>{@link #leafNode(String, Object)}</li>
412 * <li>{@link #startContainerNode(Class, int)}</li>
413 * <li>{@link #startChoiceNode(Item, int)}</li>
414 * <li>{@link #startLeafSet(String, int)}</li>
415 * <li>{@link #startMapNode(Class, int)}</li>
416 * <li>{@link #startUnkeyedList(Class, int)}</li>
417 * <li>{@link #startAugmentationNode(Class)}</li>
420 * @param caze Case class
421 * @throws IllegalArgumentException
422 * @throws IOException if an underlying IO error occurs
424 void startCase(Class<? extends TreeNode> caze, int childSizeHint) throws IOException;
427 * Emits start of augmentation node.
430 * End of augmentation event is emitted by invoking {@link #endNode()}.
433 * Valid sub-events are:
436 * <li>{@link #leafNode(String, Object)}</li>
437 * <li>{@link #startContainerNode(Class, int)}</li>
438 * <li>{@link #startChoiceNode(Item, int)}</li>
439 * <li>{@link #startLeafSet(String, int)}</li>
440 * <li>{@link #startMapNode(Class, int)}</li>
441 * <li>{@link #startUnkeyedList(Class, int)}</li>
445 * Note this is only method, which does not require childSizeHint, since
446 * maximum value is always size of <code>possibleChildren</code>.
448 * @param augmentationType augmentation class
449 * @throws IllegalArgumentException
450 * If augmentation is invalid in current context.
451 * @throws IOException if an underlying IO error occurs
453 void startAugmentationNode(Class<? extends Augmentation<?>> augmentationType) throws IOException;
456 * Emits anyxml node event.
460 * @throws IllegalArgumentException
461 * @throws IllegalStateException
462 * If node was emitted inside <code>map</code>,
463 * <code>choice</code> <code>unkeyed list</code> node.
464 * @throws IOException if an underlying IO error occurs
466 void anyxmlNode(String name, Object value) throws IOException;
469 * Emits anydata node event.
473 * @throws IllegalStateException
474 * If node was emitted inside <code>map</code>,
475 * <code>choice</code> <code>unkeyed list</code> node.
476 * @throws IOException if an underlying IO error occurs
478 void startAnydataNode(String name, Object value) throws IOException;
481 * Emits end event for node.
483 * @throws IllegalStateException If there is no open node.
484 * @throws IOException if an underlying IO error occurs
486 void endNode() throws IOException;
489 void flush() throws IOException;
492 void close() throws IOException;