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 com.google.common.collect.ImmutableMap;
13 import java.io.IOException;
14 import java.util.ArrayDeque;
15 import java.util.Deque;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadata;
19 import org.opendaylight.yangtools.rfc7952.data.api.NormalizedMetadataStreamWriter;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
26 import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
27 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
30 * A simple decorator on top of a NormalizedNodeStreamWriter, which attaches NormalizedMetadata to the event stream,
31 * so that the metadata is emitted along with data.
33 final class NormalizedNodeStreamWriterMetadataDecorator extends ForwardingNormalizedNodeStreamWriter {
34 private final Deque<NormalizedMetadata> stack = new ArrayDeque<>();
35 private final NormalizedMetadataStreamWriter metaWriter;
36 private final NormalizedNodeStreamWriter writer;
37 private final NormalizedMetadata metadata;
39 NormalizedNodeStreamWriterMetadataDecorator(final NormalizedNodeStreamWriter writer,
40 final NormalizedMetadataStreamWriter metaWriter, final NormalizedMetadata metadata) {
41 this.writer = requireNonNull(writer);
42 this.metaWriter = requireNonNull(metaWriter);
43 this.metadata = requireNonNull(metadata);
47 protected NormalizedNodeStreamWriter delegate() {
52 public void startLeafNode(final NodeIdentifier name) throws IOException {
53 super.startLeafNode(name);
54 enterMetadataNode(name);
58 public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
59 super.startLeafSet(name, childSizeHint);
60 enterMetadataNode(name);
64 public void startOrderedLeafSet(final NodeIdentifier name, final int childSizeHint) throws IOException {
65 super.startOrderedLeafSet(name, childSizeHint);
66 enterMetadataNode(name);
70 public void startLeafSetEntryNode(final NodeWithValue<?> name) throws IOException {
71 super.startLeafSetEntryNode(name);
72 enterMetadataNode(name);
76 public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
77 super.startContainerNode(name, childSizeHint);
78 enterMetadataNode(name);
82 public void startUnkeyedList(final NodeIdentifier name, final int childSizeHint) throws IOException {
83 super.startUnkeyedList(name, childSizeHint);
84 enterMetadataNode(name);
88 public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint) throws IOException {
89 super.startUnkeyedListItem(name, childSizeHint);
90 enterMetadataNode(name);
94 public void startMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
95 super.startMapNode(name, childSizeHint);
96 enterMetadataNode(name);
100 public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint)
102 super.startMapEntryNode(identifier, childSizeHint);
103 enterMetadataNode(identifier);
107 public void startOrderedMapNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
108 super.startOrderedMapNode(name, childSizeHint);
109 enterMetadataNode(name);
113 public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
114 super.startChoiceNode(name, childSizeHint);
115 enterMetadataNode(name);
119 public void startAugmentationNode(final AugmentationIdentifier identifier) throws IOException {
120 super.startAugmentationNode(identifier);
121 enterMetadataNode(identifier);
125 public void startAnyxmlNode(final NodeIdentifier name) throws IOException {
126 super.startAnyxmlNode(name);
127 enterMetadataNode(name);
131 public void startYangModeledAnyXmlNode(final NodeIdentifier name, final int childSizeHint) throws IOException {
132 super.startYangModeledAnyXmlNode(name, childSizeHint);
133 enterMetadataNode(name);
137 public void endNode() throws IOException {
142 private void enterMetadataNode(final PathArgument name) throws IOException {
143 final NormalizedMetadata child = findMetadata(name);
145 emitAnnotations(child.getAnnotations());
150 private @Nullable NormalizedMetadata findMetadata(final PathArgument name) {
151 final NormalizedMetadata current = stack.peek();
152 if (current == null) {
153 // This may either be the first entry or unattached metadata nesting
154 return stack.isEmpty() ? metadata : null;
156 return current.getChild(name).orElse(null);
159 private void emitAnnotations(final Map<QName, Object> annotations) throws IOException {
160 if (!annotations.isEmpty()) {
161 metaWriter.metadata(ImmutableMap.copyOf(annotations));