2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.rfc7952.data.util;
10 import static java.util.Objects.requireNonNull;
12 import java.io.IOException;
13 import java.util.ArrayDeque;
14 import java.util.Deque;
16 import java.util.Map.Entry;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadata;
19 import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadataContainer;
20 import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadataStreamWriter;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
27 import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
28 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
31 * A simple decorator on top of a NormalizedNodeStreamWriter, which attaches NormalizedMetadata to the event stream,
32 * so that the metadata is emitted along with data.
34 final class NormalizedNodeStreamWriterMetadataDecorator extends ForwardingNormalizedNodeStreamWriter {
35 private final Deque<NormalizedMetadata> stack = new ArrayDeque<>();
36 private final NormalizedMetadataStreamWriter metaWriter;
37 private final NormalizedNodeStreamWriter writer;
38 private final NormalizedMetadata metadata;
40 NormalizedNodeStreamWriterMetadataDecorator(final NormalizedNodeStreamWriter writer,
41 final NormalizedMetadataStreamWriter metaWriter, final NormalizedMetadata metadata) {
42 this.writer = requireNonNull(writer);
43 this.metaWriter = requireNonNull(metaWriter);
44 this.metadata = requireNonNull(metadata);
48 protected NormalizedNodeStreamWriter delegate() {
53 public void startLeafNode(final NodeIdentifier name) throws IOException {
54 super.startLeafNode(name);
55 enterMetadataNode(name);
59 public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
60 super.startLeafSet(name, childSizeHint);
61 enterMetadataNode(name);
65 public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
66 super.startOrderedLeafSet(name, childSizeHint);
67 enterMetadataNode(name);
71 public void startLeafSetEntryNode(final NodeWithValue<?> name) throws IOException {
72 super.startLeafSetEntryNode(name);
73 enterMetadataNode(name);
77 public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
78 super.startContainerNode(name, childSizeHint);
79 enterMetadataNode(name);
83 public void startUnkeyedList(final NodeIdentifier name, final int childSizeHint) throws IOException {
84 super.startUnkeyedList(name, childSizeHint);
85 enterMetadataNode(name);
89 public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint) throws IOException {
90 super.startUnkeyedListItem(name, childSizeHint);
91 enterMetadataNode(name);
95 public void startMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
96 super.startMapNode(name, childSizeHint);
97 enterMetadataNode(name);
101 public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint)
103 super.startMapEntryNode(identifier, childSizeHint);
104 enterMetadataNode(identifier);
108 public void startOrderedMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
109 super.startOrderedMapNode(name, childSizeHint);
110 enterMetadataNode(name);
114 public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
115 super.startChoiceNode(name, childSizeHint);
116 enterMetadataNode(name);
120 public void startAugmentationNode(final AugmentationIdentifier identifier) throws IOException {
121 super.startAugmentationNode(identifier);
122 enterMetadataNode(identifier);
126 public void startAnyxmlNode(final NodeIdentifier name) throws IOException {
127 super.startAnyxmlNode(name);
128 enterMetadataNode(name);
132 public void startYangModeledAnyXmlNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
133 super.startYangModeledAnyXmlNode(name, childSizeHint);
134 enterMetadataNode(name);
138 public void endNode() throws IOException {
143 private void enterMetadataNode(final PathArgument name) throws IOException {
144 final NormalizedMetadata child = findMetadata(name);
146 emitAnnotations(child.getAnnotations());
151 private @Nullable NormalizedMetadata findMetadata(final PathArgument name) {
152 final NormalizedMetadata current = stack.peek();
153 if (current instanceof NormalizedMetadataContainer) {
154 return ((NormalizedMetadataContainer) current).getChild(name).orElse(null);
157 // This may either be the first entry or unattached metadata nesting
158 return stack.isEmpty() ? metadata : null;
161 private void emitAnnotations(final Map<QName, Object> annotations) throws IOException {
162 if (!annotations.isEmpty()) {
163 metaWriter.startMetadata(annotations.size());
164 for (Entry<QName, Object> entry : annotations.entrySet()) {
165 metaWriter.startMetadataEntry(entry.getKey(), null);
166 writer.nodeValue(entry.getValue());