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;
21 * Event Stream Writer for Binding version 2 Representation
24 * <h3>Emitting Event Stream</h3>
27 * <li><code>container</code> - Container node representation, start event is
28 * emitted using {@link #startContainerNode(Class, int)} and node end event is
29 * emitted using {@link #endNode()}. Container node is implementing
30 * {@link TreeNode} interface.
32 * <li><code>list</code> - YANG list statement has two representations in event
33 * stream - un-keyed list and map. Un-keyed list is YANG list which didn't
37 * <li><code>Map</code> - Map start event is emitted using
38 * {@link #startMapNode(IdentifiableItem, int)} and is ended using {@link #endNode()}. Each map
39 * entry start is emitted using {@link #startMapEntryNode(IdentifiableItem, int)} with Map of keys
40 * and finished using {@link #endNode()}.</li>
42 * <li><code>UnkeyedList</code> - Un-keyed list represents list without keys,
43 * un-keyed list start is emitted using {@link #startUnkeyedList(Class, int)}, list
44 * end is emitted using {@link #endNode()}. Each list item is emitted using
45 * {@link #startUnkeyedListItem(int)} and ended using {@link #endNode()}.</li>
48 * <li><code>leaf</code> - Leaf node event is emitted using
49 * {@link #leafNode(String, Object)}. {@link #endNode()} MUST NOT be emitted for
52 * <li><code>leaf-list</code> - Leaf list start is emitted using
53 * {@link #startLeafSet(String, int)}. Leaf list end is emitted using
54 * {@link #endNode()}. Leaf list entries are emitted using
55 * {@link #leafSetEntryNode(Object)}.
57 * <li><code>anyxml - Anyxml node event is emitted using
58 * {@link #startAnyxmlNode(String, Object)}. {@link #endNode()} MUST NOT be emitted
59 * for anyxml node.</code></li>
61 * <li><code>anydata - Anydata node event is emitted using
62 * {@link #startAnydataNode(String, Object)}. {@link #endNode()} MUST NOT be emitted
63 * for anydata node.</code></li>
65 * <li><code>choice</code> Choice node event is emitted by
66 * {@link #startChoiceNode(Item, int)} event and must be immediately followed by
67 * {@link #startCase(Class, int)} event. Choice node is finished by emitting an
68 * {@link #endNode()} event.</li>
71 * <code>case</code> - Case node may be emitted only inside choice node by
72 * invoking {@link #startCase(Class, int)}. Case node is finished be emitting an
73 * {@link #endNode()} event.</li>
76 * <code>augment</code> - Represents augmentation, augmentation node is started
77 * by invoking {@link #startAugmentationNode(Class)} and
78 * finished by invoking {@link #endNode()}.</li>
82 * <h3>Implementation notes</h3> This interface is not intended to be
83 * implemented by users of generated Binding2 DTOs but to be used by utilities,
84 * which needs to emit NormalizedNode model from Binding2 DTOs.
86 * This interface is intended as API definition of facade for real Event /
87 * Stream Writer, without explicitly requiring stream writer and related
88 * interfaces to be imported by all generated Binding2 DTOs.
90 * Existence of this interface in runtime Java Binding2 package is required to
91 * support runtime generation of users of this interface in OSGI and OSGI-like
92 * environment, since this package is only package which is imported by all
93 * generated Binding2 DTOs and wired in OSGI.
98 public interface BindingStreamEventWriter extends Closeable, Flushable {
101 * Methods in this interface allow users to hint the underlying
102 * implementation about the sizing of container-like constructors
103 * (leafLists, containers, etc.). These hints may be taken into account by a
104 * particular implementation to improve performance, but clients are not
105 * required to provide hints. This constant should be used by clients who
106 * either do not have the sizing information, or do not wish to divulge it
107 * (for whatever reasons). Implementations are free to ignore these hints
108 * completely, but if they do use them, they are expected to be resilient in
109 * face of missing and mismatched hints, which is to say the user can
110 * specify startLeafSet(..., 1) and then call leafNode() 15 times.
112 * The acceptable hint values are non-negative integers and this constant,
113 * all other values will result, based on implementation preference, in the
114 * hint being completely ignored or IllegalArgumentException being thrown.
116 int UNKNOWN_SIZE = -1;
120 * Emits a leaf node event with supplied value.
123 * name of node as defined in schema, namespace and revision are
124 * derived from parent node.
126 * Value of leaf node.
127 * @throws IllegalArgumentException
128 * If emitted leaf node has invalid value in current context or
129 * was emitted multiple times.
130 * @throws IllegalStateException
131 * If node was emitted inside <code>map</code>,
132 * <code>choice</code> <code>unkeyed list</code> node.
133 * @throws IOException if an underlying IO error occurs
135 void leafNode(String localName, Object value) throws IOException;
139 * Emits a start of leaf set (leaf-list).
141 * Emits start of leaf set, during writing leaf set event, only
142 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
143 * finished by calling {@link #endNode()}.
146 * name of node as defined in schema, namespace and revision are
147 * derived from parent node.
148 * @param childSizeHint
149 * Non-negative count of expected direct child nodes or
150 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
151 * and should not fail writing of child events, if there are more
153 * @throws IllegalArgumentException
154 * If emitted leaf node is invalid in current context or was
155 * emitted multiple times.
156 * @throws IllegalStateException
157 * If node was emitted inside <code>map</code>,
158 * <code>choice</code> <code>unkeyed list</code> node.
159 * @throws IOException if an underlying IO error occurs
161 void startLeafSet(String localName, int childSizeHint) throws IOException;
165 * Emits a start of leaf set (leaf-list).
167 * Emits start of leaf set, during writing leaf set event, only
168 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
169 * finished by calling {@link #endNode()}.
172 * name of node as defined in schema, namespace and revision are
173 * derived from parent node.
174 * @param childSizeHint
175 * Non-negative count of expected direct child nodes or
176 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
177 * and should not fail writing of child events, if there are more
179 * @throws IllegalArgumentException
180 * If emitted leaf node is invalid in current context or was
181 * emitted multiple times.
182 * @throws IllegalStateException
183 * If node was emitted inside <code>map</code>,
184 * <code>choice</code> <code>unkeyed list</code> node.
185 * @throws IOException if an underlying IO error occurs
187 void startOrderedLeafSet(String localName, int childSizeHint) throws IOException;
190 * Emits a leaf set entry node
193 * Value of leaf set entry node.
194 * @throws IllegalArgumentException
195 * If emitted leaf node has invalid value.
196 * @throws IllegalStateException
197 * If node was emitted outside <code>leaf set</code> node.
198 * @throws IOException if an underlying IO error occurs
200 void leafSetEntryNode(Object value) throws IOException;
204 * Emits start of new container.
207 * End of container event is emitted by invoking {@link #endNode()}.
210 * Valid sub-events are:
212 * <li>{@link #leafNode(String, Object)}</li>
213 * <li>{@link #startContainerNode(Class, int)}</li>
214 * <li>{@link #startChoiceNode(Item, int)}</li>
215 * <li>{@link #startLeafSet(String, int)}</li>
216 * <li>{@link #startMapNode(IdentifiableItem, int)}</li>
217 * <li>{@link #startUnkeyedList(Class, int)}</li>
218 * <li>{@link #startAugmentationNode(Class)}</li>
222 * name of node as defined in schema, namespace and revision are
223 * derived from parent node.
224 * @param childSizeHint
225 * Non-negative count of expected direct child nodes or
226 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
227 * and should not fail writing of child events, if there are more
229 * @throws IllegalArgumentException
230 * If emitted node is invalid in current context or was emitted
232 * @throws IllegalStateException
233 * If node was emitted inside <code>map</code>,
234 * <code>choice</code> <code>unkeyed list</code> node.
235 * @throws IOException if an underlying IO error occurs
237 void startContainerNode(Class<? extends TreeNode> container, int childSizeHint) throws IOException;
241 * Emits start of unkeyed list node event.
244 * End of unkeyed list event is emitted by invoking {@link #endNode()}.
245 * Valid sub-event is only {@link #startUnkeyedListItem(int)}. All other
246 * methods will throw {@link IllegalArgumentException}.
249 * name of node as defined in schema, namespace and revision are
250 * derived from parent node.
251 * @param childSizeHint
252 * Non-negative count of expected direct child nodes or
253 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
254 * and should not fail writing of child events, if there are more
256 * @throws IllegalArgumentException
257 * If emitted node is invalid in current context or was emitted
259 * @throws IllegalStateException
260 * If node was emitted inside <code>map</code>,
261 * <code>choice</code> <code>unkeyed list</code> node.
262 * @throws IOException if an underlying IO error occurs
264 void startUnkeyedList(Class<? extends TreeNode> localName, int childSizeHint) throws IOException;
267 * Emits start of new unkeyed list item.
270 * Un-keyed list item event is finished by invoking {@link #endNode()}.
272 * Valid sub-events are:
275 * <li>{@link #leafNode(String, Object)}</li>
276 * <li>{@link #startContainerNode(Class, int)}</li>
277 * <li>{@link #startChoiceNode(Item, int)}</li>
278 * <li>{@link #startLeafSet(String, int)}</li>
279 * <li>{@link #startMapNode(IdentifiableItem, int)}</li>
280 * <li>{@link #startUnkeyedList(Class, int)}</li>
281 * <li>{@link #startAugmentationNode(Class)}</li>
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 IllegalStateException
291 * If node was emitted outside <code>unkeyed list</code> node.
292 * @throws IOException if an underlying IO error occurs
294 void startUnkeyedListItem(int childSizeHint) throws IOException;
298 * Emits start of unordered map node event.
301 * End of map node event is emitted by invoking {@link #endNode()}. Valid
302 * subevents is only {@link #startMapEntryNode(IdentifiableItem, int)}. All other methods will
303 * throw {@link IllegalArgumentException}.
305 * @param mapEntryType
306 * Class of list item, which has defined key.
307 * @param childSizeHint
308 * Non-negative count of expected direct child nodes or
309 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
310 * and should not fail writing of child events, if there are more
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 <I extends TreeNode, T> void startMapNode(IdentifiableItem<I, T> mapEntryType, int childSizeHint)
323 * Emits start of ordered map node event.
326 * End of map node event is emitted by invoking {@link #endNode()}. Valid
327 * sub-event is only {@link #startMapEntryNode(IdentifiableItem, int)}. All other methods will
328 * throw {@link IllegalArgumentException}.
330 * @param mapEntryType
331 * Class of list item, which has defined key.
332 * @param childSizeHint
333 * Non-negative count of expected direct child nodes or
334 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
335 * and should not fail writing of child events, if there are more
337 * @throws IllegalArgumentException
338 * @throws IllegalStateException
339 * If node was emitted inside <code>map</code>,
340 * <code>choice</code> <code>unkeyed list</code> node.
341 * @throws IOException if an underlying IO error occurs
343 <I extends TreeNode, T> void startOrderedMapNode(IdentifiableItem<I, T> mapEntryType, int childSizeHint)
348 * Emits start of map entry.
351 * End of map entry event is emitted by invoking {@link #endNode()}.
354 * Valid sub-events are:
356 * <li>{@link #leafNode(String, Object)}</li>
357 * <li>{@link #startContainerNode(Class, int)}</li>
358 * <li>{@link #startChoiceNode(Item, int)}</li>
359 * <li>{@link #startLeafSet(String, int)}</li>
360 * <li>{@link #startMapNode(IdentifiableItem, int)}</li>
361 * <li>{@link #startUnkeyedList(Class, int)}</li>
362 * <li>{@link #startAugmentationNode(Class)}</li>
366 * Key of map entry node
367 * @param childSizeHint
368 * Non-negative count of expected direct child nodes or
369 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
370 * and should not fail writing of child events, if there are more
372 * @throws IllegalArgumentException
373 * If key contains incorrect value.
374 * @throws IllegalStateException
375 * If node was emitted outside <code>map entry</code> node.
376 * @throws IOException if an underlying IO error occurs
378 <I extends TreeNode, T> void startMapEntryNode(IdentifiableItem<I, T> keyValues, int childSizeHint)
382 * Emits start of choice node.
385 * Valid sub-event is {@link #startCase(Class, int)}, which selects case
386 * which should be written.
390 * @param childSizeHint
391 * Non-negative count of expected direct child nodes or
392 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
393 * and should not fail writing of child events, if there are more
395 * @throws IllegalArgumentException
396 * @throws IllegalStateException
397 * If node was emitted inside <code>map</code>, <code>choice</code>,
398 * <code>unkeyed list</code> node.
399 * @throws IOException if an underlying IO error occurs
401 <T extends TreeNode> void startChoiceNode(Item<T> choice, int childSizeHint) throws IOException;
405 * Starts a case node.
408 * Valid sub-events are:
410 * <li>{@link #leafNode(String, Object)}</li>
411 * <li>{@link #startContainerNode(Class, int)}</li>
412 * <li>{@link #startChoiceNode(Item, int)}</li>
413 * <li>{@link #startLeafSet(String, int)}</li>
414 * <li>{@link #startMapNode(IdentifiableItem, int)}</li>
415 * <li>{@link #startUnkeyedList(Class, int)}</li>
416 * <li>{@link #startAugmentationNode(Class)}</li>
419 * @param caze Case class
420 * @throws IllegalArgumentException
421 * @throws IOException if an underlying IO error occurs
423 void startCase(Class<? extends TreeNode> caze, int childSizeHint) throws IOException;
426 * Emits start of augmentation node.
429 * End of augmentation event is emitted by invoking {@link #endNode()}.
432 * Valid sub-events are:
435 * <li>{@link #leafNode(String, Object)}</li>
436 * <li>{@link #startContainerNode(Class, int)}</li>
437 * <li>{@link #startChoiceNode(Item, int)}</li>
438 * <li>{@link #startLeafSet(String, int)}</li>
439 * <li>{@link #startMapNode(IdentifiableItem, int)}</li>
440 * <li>{@link #startUnkeyedList(Class, int)}</li>
444 * Note this is only method, which does not require childSizeHint, since
445 * maximum value is always size of <code>possibleChildren</code>.
447 * @param augmentationType augmentation class
448 * @throws IllegalArgumentException
449 * If augmentation is invalid in current context.
450 * @throws IOException if an underlying IO error occurs
452 void startAugmentationNode(Class<? extends Augmentation<?>> augmentationType) throws IOException;
455 * Emits anyxml node event.
459 * @throws IllegalArgumentException
460 * @throws IllegalStateException
461 * If node was emitted inside <code>map</code>,
462 * <code>choice</code> <code>unkeyed list</code> node.
463 * @throws IOException if an underlying IO error occurs
465 void startAnyxmlNode(String name, Object value) throws IOException;
468 * Emits anydata node event.
472 * @throws IllegalStateException
473 * If node was emitted inside <code>map</code>,
474 * <code>choice</code> <code>unkeyed list</code> node.
475 * @throws IOException if an underlying IO error occurs
477 void startAnydataNode(String name, Object value) throws IOException;
480 * Emits end event for node.
482 * @throws IllegalStateException If there is no open node.
483 * @throws IOException if an underlying IO error occurs
485 void endNode() throws IOException;
488 void flush() throws IOException;
491 void close() throws IOException;