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.mdsal.binding.dom.codec.api;
10 import com.google.common.annotations.Beta;
11 import java.io.Closeable;
12 import java.io.Flushable;
13 import java.io.IOException;
14 import org.opendaylight.yangtools.yang.binding.Augmentation;
15 import org.opendaylight.yangtools.yang.binding.DataContainer;
16 import org.opendaylight.yangtools.yang.binding.DataObject;
17 import org.opendaylight.yangtools.yang.binding.Identifiable;
18 import org.opendaylight.yangtools.yang.binding.Identifier;
21 * Event Stream Writer for Binding Representation.
23 * <h3>Emmiting Event Stream</h3>
26 * <li><code>container</code> - Container node representation, start event is
27 * emitted using {@link #startContainerNode(Class, int)} and node end event is
28 * emitted using {@link #endNode()}. Container node is implementing
29 * {@link DataObject} interface.
31 * <li><code>list</code> - YANG list statement has two representation in event
32 * stream - unkeyed list and map. Unkeyed list is YANG list which did not
36 * <li><code>Map</code> - Map start event is emitted using
37 * {@link #startMapNode(Class, int)} and is ended using {@link #endNode()}. Each map
38 * entry start is emitted using {@link #startMapEntryNode(Identifier, int)} with Map of keys
39 * 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(Class, int)} list
42 * end is emitted using {@link #endNode()}. Each list item is emitted using
43 * {@link #startUnkeyedListItem(int)} and ended using {@link #endNode()}.</li>
45 * <li><code>leaf</code> - Leaf node event is emitted using
46 * {@link #leafNode(String, Object)}. {@link #endNode()} MUST be not emitted for
48 * <li><code>leaf-list</code> - Leaf list start is emitted using
49 * {@link #startLeafSet(String, int)}. Leaf list end is emitted using
50 * {@link #endNode()}. Leaf list entries are emitted using
51 * {@link #leafSetEntryNode(Object)}.
52 * <li><code>anyxml - Anyxml node event is emitted using
53 * {@link #leafNode(String, Object)}. {@link #endNode()} MUST be not emitted
54 * for anyxml node.</code></li>
55 * <li><code>choice</code> Choice node event is emitted by
56 * {@link #startChoiceNode(Class, int)} event and must be immediately followed by
57 * {@link #startCase(Class, int)} event. Choice node is finished by emitting an
58 * {@link #endNode()} event.</li>
60 * <code>case</code> - Case node may be emitted only inside choice node by
61 * invoking {@link #startCase(Class, int)}. Case node is finished be emitting an
62 * {@link #endNode()} event.</li>
64 * <code>augment</code> - Represents augmentation, augmentation node is started
65 * by invoking {@link #startAugmentationNode(Class)} and
66 * finished by invoking {@link #endNode()}.</li>
69 * <h3>Implementation notes</h3> This interface is not intended to be implemented by users of generated Binding DTOs
70 * but to be used by utilities, which needs to emit NormalizedNode model from Binding DTOs.
73 * This interface is intended as API definition of facade for real Event / Stream Writer, without explicitly requiring
74 * stream writer and related interfaces to be imported by all generated Binding DTOs.
77 * Existence of this interface in base Java Binding package is required to support runtime generation of users of this
78 * interface in OSGI and OSGI-like environment, since this package is only package which is imported by all generated
79 * Binding DTOs and wired in OSGI.
82 public interface BindingStreamEventWriter extends Closeable, Flushable {
85 * Methods in this interface allow users to hint the underlying implementation about the sizing of container-like
86 * constructors (leafLists, containers, etc.). These hints may be taken into account by a particular implementation
87 * to improve performance, but clients are not required to provide hints. This constant should be used by clients
88 * who either do not have the sizing information, or do not wish to divulge it (for whatever reasons).
89 * Implementations are free to ignore these hints completely, but if they do use them, they are expected to be
90 * resilient in face of missing and mismatched hints, which is to say the user can specify startLeafSet(..., 1)
91 * and then call leafNode() 15 times.
94 * The acceptable hint values are non-negative integers and this constant, all other values will result, based on
95 * implementation preference, in the hint being completely ignored or IllegalArgumentException being thrown.
97 int UNKNOWN_SIZE = -1;
100 * Emits a leaf node event with supplied value.
103 * name of node as defined in schema, namespace and revision are
104 * derived from parent node.
106 * Value of leaf node.
107 * @throws IllegalArgumentException
108 * If emitted leaf node has invalid value in current context or
109 * was emitted multiple times.
110 * @throws IllegalStateException
111 * If node was emitted inside <code>map</code>,
112 * <code>choice</code> <code>unkeyed list</code> node.
113 * @throws IOException if an underlying IO error occurs
115 void leafNode(String localName, Object value) throws IOException;
118 * Emits a start of leaf set (leaf-list). Emits start of leaf set, during writing leaf set event, only
119 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is finished by calling {@link #endNode()}.
122 * name of node as defined in schema, namespace and revision are
123 * derived from parent node.
124 * @param childSizeHint
125 * Non-negative count of expected direct child nodes or
126 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
127 * and should not fail writing of child events, if there are more
129 * @throws IllegalArgumentException
130 * If emitted leaf node is invalid in current context or was
131 * emitted multiple times.
132 * @throws IllegalStateException
133 * If node was emitted inside <code>map</code>,
134 * <code>choice</code> <code>unkeyed list</code> node.
135 * @throws IOException if an underlying IO error occurs
137 void startLeafSet(String localName, int childSizeHint) throws IOException;
140 * Emits a start of leaf set (leaf-list).
143 * Emits start of leaf set, during writing leaf set event, only
144 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
145 * finished by calling {@link #endNode()}.
148 * name of node as defined in schema, namespace and revision are
149 * derived from parent node.
150 * @param childSizeHint
151 * Non-negative count of expected direct child nodes or
152 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
153 * and should not fail writing of child events, if there are more
155 * @throws IllegalArgumentException
156 * If emitted leaf node is invalid in current context or was
157 * emitted multiple times.
158 * @throws IllegalStateException
159 * If node was emitted inside <code>map</code>,
160 * <code>choice</code> <code>unkeyed list</code> node.
161 * @throws IOException if an underlying IO error occurs
163 void startOrderedLeafSet(String localName, int childSizeHint) throws IOException;
166 * Emits a leaf set entry node.
169 * Value of leaf set entry node.
170 * @throws IllegalArgumentException
171 * If emitted leaf node has invalid value.
172 * @throws IllegalStateException
173 * If node was emitted outside <code>leaf set</code> node.
174 * @throws IOException if an underlying IO error occurs
176 void leafSetEntryNode(Object value) throws IOException;
179 * Emits start of new container. End of container event is emitted by invoking {@link #endNode()}.
182 * Valid sub-events are:
184 * <li>{@link #leafNode(String, Object)}</li>
185 * <li>{@link #startContainerNode(Class, int)}</li>
186 * <li>{@link #startChoiceNode(Class, int)}</li>
187 * <li>{@link #startLeafSet(String, int)}</li>
188 * <li>{@link #startMapNode(Class, int)}</li>
189 * <li>{@link #startUnkeyedList(Class, int)}</li>
190 * <li>{@link #startAugmentationNode(Class)}</li>
194 * name of node as defined in schema, namespace and revision are
195 * derived from parent node.
196 * @param childSizeHint
197 * Non-negative count of expected direct child nodes or
198 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
199 * and should not fail writing of child events, if there are more
201 * @throws IllegalArgumentException
202 * If emitted node is invalid in current context or was emitted
204 * @throws IllegalStateException
205 * If node was emitted inside <code>map</code>,
206 * <code>choice</code> <code>unkeyed list</code> node.
207 * @throws IOException if an underlying IO error occurs
209 void startContainerNode(Class<? extends DataObject> container, int childSizeHint) throws IOException;
212 * Emits start of unkeyed list node event.
215 * End of unkeyed list event is emitted by invoking {@link #endNode()}.
216 * Valid subevents is only {@link #startUnkeyedListItem(int)}. All other
217 * methods will throw {@link IllegalArgumentException}.
220 * name of node as defined in schema, namespace and revision are
221 * derived from parent node.
222 * @param childSizeHint
223 * Non-negative count of expected direct child nodes or
224 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
225 * and should not fail writing of child events, if there are more
227 * @throws IllegalArgumentException
228 * If emitted node is invalid in current context or was emitted
230 * @throws IllegalStateException
231 * If node was emitted inside <code>map</code>,
232 * <code>choice</code> <code>unkeyed list</code> node.
233 * @throws IOException if an underlying IO error occurs
235 void startUnkeyedList(Class<? extends DataObject> localName, int childSizeHint) throws IOException;
238 * Emits start of new unkeyed list item.
241 * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
244 * <li>{@link #leafNode(String, Object)}</li>
245 * <li>{@link #startContainerNode(Class, int)}</li>
246 * <li>{@link #startChoiceNode(Class, int)}</li>
247 * <li>{@link #startLeafSet(String, int)}</li>
248 * <li>{@link #startMapNode(Class, int)}</li>
249 * <li>{@link #startUnkeyedList(Class, int)}</li>
250 * <li>{@link #startAugmentationNode(Class)}</li>
253 * @param childSizeHint
254 * Non-negative count of expected direct child nodes or
255 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
256 * and should not fail writing of child events, if there are more
258 * @throws IllegalStateException
259 * If node was emitted outside <code>unkeyed list</code> node.
260 * @throws IOException if an underlying IO error occurs
262 void startUnkeyedListItem(int childSizeHint) throws IOException;
265 * Emits start of unordered map node event.
268 * End of map node event is emitted by invoking {@link #endNode()}. Valid
269 * subevent is only {@link #startMapEntryNode(Identifier, int)}. All other methods will
270 * throw {@link IllegalArgumentException}.
272 * @param mapEntryType
273 * Class of list item, which has defined key.
274 * @param childSizeHint
275 * Non-negative count of expected direct child nodes or
276 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
277 * and should not fail writing of child events, if there are more
279 * @throws IllegalArgumentException
280 * If emitted node is invalid in current context or was emitted
282 * @throws IllegalStateException
283 * If node was emitted inside <code>map</code>,
284 * <code>choice</code> <code>unkeyed list</code> node.
285 * @throws IOException if an underlying IO error occurs
287 <T extends DataObject & Identifiable<?>> void startMapNode(Class<T> mapEntryType, int childSizeHint)
291 * Emits start of ordered map node event.
294 * End of map node event is emitted by invoking {@link #endNode()}. Valid
295 * subevent is only {@link #startMapEntryNode(Identifier, int)}. All other methods will
296 * throw {@link IllegalArgumentException}.
298 * @param mapEntryType
299 * Class of list item, which has defined key.
300 * @param childSizeHint
301 * Non-negative count of expected direct child nodes or
302 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
303 * and should not fail writing of child events, if there are more
305 * @throws IllegalArgumentException
306 * If emitted node is invalid in current context or was emitted
308 * @throws IllegalStateException
309 * If node was emitted inside <code>map</code>,
310 * <code>choice</code> <code>unkeyed list</code> node.
311 * @throws IOException if an underlying IO error occurs
313 <T extends DataObject & Identifiable<?>> void startOrderedMapNode(Class<T> mapEntryType, int childSizeHint)
317 * Emits start of map entry.
320 * End of map entry event is emitted by invoking {@link #endNode()}.
323 * Valid sub-events are:
325 * <li>{@link #leafNode(String, Object)}</li>
326 * <li>{@link #startContainerNode(Class, int)}</li>
327 * <li>{@link #startChoiceNode(Class, int)}</li>
328 * <li>{@link #startLeafSet(String, int)}</li>
329 * <li>{@link #startMapNode(Class, int)}</li>
330 * <li>{@link #startUnkeyedList(Class, int)}</li>
331 * <li>{@link #startAugmentationNode(Class)}</li>
335 * Key of map entry node
336 * @param childSizeHint
337 * Non-negative count of expected direct child nodes or
338 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
339 * and should not fail writing of child events, if there are more
341 * @throws IllegalArgumentException
342 * If key contains incorrect value.
343 * @throws IllegalStateException
344 * If node was emitted outside <code>map entry</code> node.
345 * @throws IOException if an underlying IO error occurs
347 void startMapEntryNode(Identifier<?> keyValues, int childSizeHint) throws IOException;
350 * Emits start of choice node.
353 * Valid sub-event in {@link #startCase(Class, int)}, which selects case
354 * which should be written.
358 * @param childSizeHint
359 * Non-negative count of expected direct child nodes or
360 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
361 * and should not fail writing of child events, if there are more
363 * @throws IllegalStateException
364 * If node was emitted inside <code>map</code>, <code>choice</code>,
365 * <code>unkeyed list</code> node.
366 * @throws IOException if an underlying IO error occurs
368 void startChoiceNode(Class<? extends DataContainer> choice, int childSizeHint) throws IOException;
371 * Starts a case node.
374 * Valid sub-events are:
376 * <li>{@link #leafNode(String, Object)}</li>
377 * <li>{@link #startContainerNode(Class, int)}</li>
378 * <li>{@link #startChoiceNode(Class, int)}</li>
379 * <li>{@link #startLeafSet(String, int)}</li>
380 * <li>{@link #startMapNode(Class, int)}</li>
381 * <li>{@link #startUnkeyedList(Class, int)}</li>
382 * <li>{@link #startAugmentationNode(Class)}</li>
385 * @param caze Case class
386 * @throws IOException if an underlying IO error occurs
388 void startCase(Class<? extends DataObject> caze, int childSizeHint) throws IOException;
391 * Emits start of augmentation node.
394 * End of augmentation event is emitted by invoking {@link #endNode()}.
397 * Valid sub-events are:
400 * <li>{@link #leafNode(String, Object)}</li>
401 * <li>{@link #startContainerNode(Class, int)}</li>
402 * <li>{@link #startChoiceNode(Class, int)}</li>
403 * <li>{@link #startLeafSet(String, int)}</li>
404 * <li>{@link #startMapNode(Class, int)}</li>
405 * <li>{@link #startUnkeyedList(Class, int)}</li>
409 * Note this is only method, which does not require childSizeHint, since
410 * maximum value is always size of <code>possibleChildren</code>.
412 * @param augmentationType augmentation class
413 * @throws IllegalArgumentException
414 * If augmentation is invalid in current context.
415 * @throws IOException if an underlying IO error occurs
417 void startAugmentationNode(Class<? extends Augmentation<?>> augmentationType) throws IOException;
420 * Emits anyxml node event.
422 * @param name node name
423 * @param value node value
424 * @throws IllegalStateException
425 * If node was emitted inside <code>map</code>,
426 * <code>choice</code> <code>unkeyed list</code> node.
427 * @throws IOException if an underlying IO error occurs
429 void anyxmlNode(String name, Object value) throws IOException;
432 * Emits end event for node.
434 * @throws IllegalStateException If there is no open node.
435 * @throws IOException if an underlying IO error occurs
437 void endNode() throws IOException;
440 void flush() throws IOException;
443 void close() throws IOException;