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.yang.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.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
23 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedMetadata;
24 import org.opendaylight.yangtools.yang.data.api.schema.stream.ForwardingNormalizedNodeStreamWriter;
25 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
28 * A simple decorator on top of a NormalizedNodeStreamWriter, which attaches NormalizedMetadata to the event stream,
29 * so that the metadata is emitted along with data.
31 final class NormalizedNodeStreamWriterMetadataDecorator extends ForwardingNormalizedNodeStreamWriter {
32 private final Deque<NormalizedMetadata> stack = new ArrayDeque<>();
33 private final NormalizedNodeStreamWriter writer;
34 private final MetadataExtension metaWriter;
35 private final NormalizedMetadata metadata;
37 private int absentDepth = 0;
39 NormalizedNodeStreamWriterMetadataDecorator(final NormalizedNodeStreamWriter writer,
40 final MetadataExtension 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 boolean startAnyxmlNode(final NodeIdentifier name, final Class<?> objectModel) throws IOException {
126 final boolean ret = super.startAnyxmlNode(name, objectModel);
128 enterMetadataNode(name);
134 public void endNode() throws IOException {
137 if (absentDepth > 0) {
144 private void enterMetadataNode(final PathArgument name) throws IOException {
145 if (absentDepth > 0) {
150 final NormalizedMetadata current = stack.peek();
151 if (current != null) {
152 final NormalizedMetadata child = current.getChildren().get(name);
159 // Empty stack: enter first entry
160 enterChild(metadata);
164 private void enterChild(final NormalizedMetadata child) throws IOException {
165 final Map<QName, Object> annotations = child.getAnnotations();
166 if (!annotations.isEmpty()) {
167 metaWriter.metadata(ImmutableMap.copyOf(annotations));