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.Key;
18 import org.opendaylight.yangtools.yang.binding.KeyAware;
21 * Event Stream Writer for Binding Representation.
23 * <h2>Emitting Event Stream</h2>
25 * <li>{@code container} - Container node representation, start event is emitted using
26 * {@link #startContainerNode(Class, int)} and node end event is emitted using {@link #endNode()}. Container node
27 * is implementing {@link DataObject} interface.
29 * <li>{@code list} - YANG list statement has two representation in event stream - unkeyed list and map. Unkeyed list
30 * is YANG list which did not specify key.
32 * <li>{@code Map} - Map start event is emitted using {@link #startMapNode(Class, int)} and is ended using
33 * {@link #endNode()}. Each map entry start is emitted using {@link #startMapEntryNode(Identifier, int)} with Map
34 * of keys and finished using {@link #endNode()}.
36 * <li>{@code UnkeyedList} - Unkeyed list represent list without keys, unkeyed list start is emitted using
37 * {@link #startUnkeyedList(Class, int)} list end is emitted using {@link #endNode()}. Each list item is emitted
38 * using {@link #startUnkeyedListItem(int)} and ended using {@link #endNode()}.
40 * <li>{@code leaf} - Leaf node event is emitted using {@link #leafNode(String, Object)}. {@link #endNode()} MUST be
41 * not emitted for leaf node.
43 * <li>{@code leaf-list} - Leaf list start is emitted using {@link #startLeafSet(String, int)}. Leaf list end is
44 * emitted using {@link #endNode()}. Leaf list entries are emitted using {@link #leafSetEntryNode(Object)}.
46 * <li>{@code anyxml} - Anyxml node event is emitted using {@link #leafNode(String, Object)}. {@link #endNode()} MUST
47 * be not emitted for anyxml node.
49 * <li>{@code choice} Choice node event is emitted by {@link #startChoiceNode(Class, int)} event and must be
50 * immediately followed by {@link #startCase(Class, int)} event. Choice node is finished by emitting an
51 * {@link #endNode()} event.
53 * <li>{@code case} - Case node may be emitted only inside choice node by invoking {@link #startCase(Class, int)}.
54 * Case node is finished be emitting an {@link #endNode()} event.
56 * <li>{@code augment} - Represents augmentation, augmentation node is started by invoking
57 * {@link #startAugmentationNode(Class)} and finished by invoking {@link #endNode()}.
61 * <h3>Implementation notes</h3>
62 * This interface is not intended to be implemented by users of generated Binding DTOs but to be used by utilities,
63 * which needs to emit NormalizedNode model from Binding DTOs.
66 * This interface is intended as API definition of facade for real Event / Stream Writer, without explicitly requiring
67 * stream writer and related interfaces to be imported by all generated Binding DTOs.
70 * Existence of this interface in base Java Binding package is required to support runtime generation of users of this
71 * interface in OSGI and OSGI-like environment, since this package is only package which is imported by all generated
72 * Binding DTOs and wired in OSGI.
75 public interface BindingStreamEventWriter extends Closeable, Flushable {
78 * Methods in this interface allow users to hint the underlying implementation about the sizing of container-like
79 * constructors (leafLists, containers, etc.). These hints may be taken into account by a particular implementation
80 * to improve performance, but clients are not required to provide hints. This constant should be used by clients
81 * who either do not have the sizing information, or do not wish to divulge it (for whatever reasons).
82 * Implementations are free to ignore these hints completely, but if they do use them, they are expected to be
83 * resilient in face of missing and mismatched hints, which is to say the user can specify startLeafSet(..., 1)
84 * and then call leafNode() 15 times.
87 * The acceptable hint values are non-negative integers and this constant, all other values will result, based on
88 * implementation preference, in the hint being completely ignored or IllegalArgumentException being thrown.
90 int UNKNOWN_SIZE = -1;
93 * Emits a leaf node event with supplied value.
96 * name of node as defined in schema, namespace and revision are
97 * derived from parent node.
100 * @throws IllegalArgumentException
101 * If emitted leaf node has invalid value in current context or
102 * was emitted multiple times.
103 * @throws IllegalStateException
104 * If node was emitted inside <code>map</code>,
105 * <code>choice</code> <code>unkeyed list</code> node.
106 * @throws IOException if an underlying IO error occurs
108 void leafNode(String localName, Object value) throws IOException;
111 * Emits a start of leaf set (leaf-list). Emits start of leaf set, during writing leaf set event, only
112 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is finished by calling {@link #endNode()}.
115 * name of node as defined in schema, namespace and revision are
116 * derived from parent node.
117 * @param childSizeHint
118 * Non-negative count of expected direct child nodes or
119 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
120 * and should not fail writing of child events, if there are more
122 * @throws IllegalArgumentException
123 * If emitted leaf node is invalid in current context or was
124 * emitted multiple times.
125 * @throws IllegalStateException
126 * If node was emitted inside <code>map</code>,
127 * <code>choice</code> <code>unkeyed list</code> node.
128 * @throws IOException if an underlying IO error occurs
130 void startLeafSet(String localName, int childSizeHint) throws IOException;
133 * Emits a start of leaf set (leaf-list).
136 * Emits start of leaf set, during writing leaf set event, only
137 * {@link #leafSetEntryNode(Object)} calls are valid. Leaf set event is
138 * finished by calling {@link #endNode()}.
141 * name of node as defined in schema, namespace and revision are
142 * derived from parent node.
143 * @param childSizeHint
144 * Non-negative count of expected direct child nodes or
145 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
146 * and should not fail writing of child events, if there are more
148 * @throws IllegalArgumentException
149 * If emitted leaf node is invalid in current context or was
150 * emitted multiple times.
151 * @throws IllegalStateException
152 * If node was emitted inside <code>map</code>,
153 * <code>choice</code> <code>unkeyed list</code> node.
154 * @throws IOException if an underlying IO error occurs
156 void startOrderedLeafSet(String localName, int childSizeHint) throws IOException;
159 * Emits a leaf set entry node.
162 * Value of leaf set entry node.
163 * @throws IllegalArgumentException
164 * If emitted leaf node has invalid value.
165 * @throws IllegalStateException
166 * If node was emitted outside <code>leaf set</code> node.
167 * @throws IOException if an underlying IO error occurs
169 void leafSetEntryNode(Object value) throws IOException;
172 * Emits start of new container. End of container event is emitted by invoking {@link #endNode()}.
175 * Valid sub-events are:
177 * <li>{@link #leafNode(String, Object)}</li>
178 * <li>{@link #startContainerNode(Class, int)}</li>
179 * <li>{@link #startChoiceNode(Class, int)}</li>
180 * <li>{@link #startLeafSet(String, int)}</li>
181 * <li>{@link #startMapNode(Class, int)}</li>
182 * <li>{@link #startUnkeyedList(Class, int)}</li>
183 * <li>{@link #startAugmentationNode(Class)}</li>
187 * name of node as defined in schema, namespace and revision are
188 * derived from parent node.
189 * @param childSizeHint
190 * Non-negative count of expected direct child nodes or
191 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
192 * and should not fail writing of child events, if there are more
194 * @throws IllegalArgumentException
195 * If emitted node is invalid in current context or was emitted
197 * @throws IllegalStateException
198 * If node was emitted inside <code>map</code>,
199 * <code>choice</code> <code>unkeyed list</code> node.
200 * @throws IOException if an underlying IO error occurs
202 void startContainerNode(Class<? extends DataObject> container, int childSizeHint) throws IOException;
205 * Emits start of unkeyed list node event.
208 * End of unkeyed list event is emitted by invoking {@link #endNode()}.
209 * Valid subevents is only {@link #startUnkeyedListItem(int)}. All other
210 * methods will throw {@link IllegalArgumentException}.
213 * name of node as defined in schema, namespace and revision are
214 * derived from parent node.
215 * @param childSizeHint
216 * Non-negative count of expected direct child nodes or
217 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
218 * and should not fail writing of child events, if there are more
220 * @throws IllegalArgumentException
221 * If emitted node is invalid in current context or was emitted
223 * @throws IllegalStateException
224 * If node was emitted inside <code>map</code>,
225 * <code>choice</code> <code>unkeyed list</code> node.
226 * @throws IOException if an underlying IO error occurs
228 void startUnkeyedList(Class<? extends DataObject> localName, int childSizeHint) throws IOException;
231 * Emits start of new unkeyed list item.
234 * Unkeyed list item event is finished by invoking {@link #endNode()}. Valid
237 * <li>{@link #leafNode(String, Object)}</li>
238 * <li>{@link #startContainerNode(Class, int)}</li>
239 * <li>{@link #startChoiceNode(Class, int)}</li>
240 * <li>{@link #startLeafSet(String, int)}</li>
241 * <li>{@link #startMapNode(Class, int)}</li>
242 * <li>{@link #startUnkeyedList(Class, int)}</li>
243 * <li>{@link #startAugmentationNode(Class)}</li>
246 * @param childSizeHint
247 * Non-negative count of expected direct child nodes or
248 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
249 * and should not fail writing of child events, if there are more
251 * @throws IllegalStateException
252 * If node was emitted outside <code>unkeyed list</code> node.
253 * @throws IOException if an underlying IO error occurs
255 void startUnkeyedListItem(int childSizeHint) throws IOException;
258 * Emits start of unordered map node event.
261 * End of map node event is emitted by invoking {@link #endNode()}. Valid
262 * subevent is only {@link #startMapEntryNode(Identifier, int)}. All other methods will
263 * throw {@link IllegalArgumentException}.
265 * @param mapEntryType
266 * Class of list item, which has defined key.
267 * @param childSizeHint
268 * Non-negative count of expected direct child nodes or
269 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
270 * and should not fail writing of child events, if there are more
272 * @throws IllegalArgumentException
273 * If emitted node is invalid in current context or was emitted
275 * @throws IllegalStateException
276 * If node was emitted inside <code>map</code>,
277 * <code>choice</code> <code>unkeyed list</code> node.
278 * @throws IOException if an underlying IO error occurs
280 <T extends DataObject & KeyAware<?>> void startMapNode(Class<T> mapEntryType, int childSizeHint) throws IOException;
283 * Emits start of ordered map node event.
286 * End of map node event is emitted by invoking {@link #endNode()}. Valid
287 * subevent is only {@link #startMapEntryNode(Identifier, int)}. All other methods will
288 * throw {@link IllegalArgumentException}.
290 * @param mapEntryType
291 * Class of list item, which has defined key.
292 * @param childSizeHint
293 * Non-negative count of expected direct child nodes or
294 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
295 * and should not fail writing of child events, if there are more
297 * @throws IllegalArgumentException
298 * If emitted node is invalid in current context or was emitted
300 * @throws IllegalStateException
301 * If node was emitted inside <code>map</code>,
302 * <code>choice</code> <code>unkeyed list</code> node.
303 * @throws IOException if an underlying IO error occurs
305 <T extends DataObject & KeyAware<?>> void startOrderedMapNode(Class<T> mapEntryType, int childSizeHint)
309 * Emits start of map entry.
312 * End of map entry event is emitted by invoking {@link #endNode()}.
315 * Valid sub-events are:
317 * <li>{@link #leafNode(String, Object)}</li>
318 * <li>{@link #startContainerNode(Class, int)}</li>
319 * <li>{@link #startChoiceNode(Class, int)}</li>
320 * <li>{@link #startLeafSet(String, int)}</li>
321 * <li>{@link #startMapNode(Class, int)}</li>
322 * <li>{@link #startUnkeyedList(Class, int)}</li>
323 * <li>{@link #startAugmentationNode(Class)}</li>
327 * Key of map entry node
328 * @param childSizeHint
329 * Non-negative count of expected direct child nodes or
330 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
331 * and should not fail writing of child events, if there are more
333 * @throws IllegalArgumentException
334 * If key contains incorrect value.
335 * @throws IllegalStateException
336 * If node was emitted outside <code>map entry</code> node.
337 * @throws IOException if an underlying IO error occurs
339 void startMapEntryNode(Key<?> keyValues, int childSizeHint) throws IOException;
342 * Emits start of choice node.
345 * Valid sub-event in {@link #startCase(Class, int)}, which selects case
346 * which should be written.
350 * @param childSizeHint
351 * Non-negative count of expected direct child nodes or
352 * {@link #UNKNOWN_SIZE} if count is unknown. This is only hint
353 * and should not fail writing of child events, if there are more
355 * @throws IllegalStateException
356 * If node was emitted inside <code>map</code>, <code>choice</code>,
357 * <code>unkeyed list</code> node.
358 * @throws IOException if an underlying IO error occurs
360 void startChoiceNode(Class<? extends DataContainer> choice, int childSizeHint) throws IOException;
363 * Starts a case node.
366 * Valid sub-events are:
368 * <li>{@link #leafNode(String, Object)}</li>
369 * <li>{@link #startContainerNode(Class, int)}</li>
370 * <li>{@link #startChoiceNode(Class, int)}</li>
371 * <li>{@link #startLeafSet(String, int)}</li>
372 * <li>{@link #startMapNode(Class, int)}</li>
373 * <li>{@link #startUnkeyedList(Class, int)}</li>
374 * <li>{@link #startAugmentationNode(Class)}</li>
377 * @param caze Case class
378 * @throws IOException if an underlying IO error occurs
380 void startCase(Class<? extends DataObject> caze, int childSizeHint) throws IOException;
383 * Emits start of augmentation node.
386 * End of augmentation event is emitted by invoking {@link #endNode()}.
389 * Valid sub-events are:
392 * <li>{@link #leafNode(String, Object)}</li>
393 * <li>{@link #startContainerNode(Class, int)}</li>
394 * <li>{@link #startChoiceNode(Class, int)}</li>
395 * <li>{@link #startLeafSet(String, int)}</li>
396 * <li>{@link #startMapNode(Class, int)}</li>
397 * <li>{@link #startUnkeyedList(Class, int)}</li>
401 * Note this is only method, which does not require childSizeHint, since
402 * maximum value is always size of <code>possibleChildren</code>.
404 * @param augmentationType augmentation class
405 * @throws IllegalArgumentException
406 * If augmentation is invalid in current context.
407 * @throws IOException if an underlying IO error occurs
409 void startAugmentationNode(Class<? extends Augmentation<?>> augmentationType) throws IOException;
412 * Emits anyxml node event.
414 * @param name node name
415 * @param value node value
416 * @throws IllegalStateException
417 * If node was emitted inside <code>map</code>,
418 * <code>choice</code> <code>unkeyed list</code> node.
419 * @throws IOException if an underlying IO error occurs
421 void anyxmlNode(String name, Object value) throws IOException;
424 * Emits end event for node.
426 * @throws IllegalStateException If there is no open node.
427 * @throws IOException if an underlying IO error occurs
429 void endNode() throws IOException;
432 void flush() throws IOException;
435 void close() throws IOException;