Expose streams with all supported encodings
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / streams / XmlDataTreeCandidateSerializer.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.restconf.nb.rfc8040.streams;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.Collection;
13 import javax.xml.stream.XMLStreamWriter;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.DataChangedNotification;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.data.changed.notification.DataChangeEvent;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
21 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
22 import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
23 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
24 import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
25 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
26 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
27 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
28
29 final class XmlDataTreeCandidateSerializer extends AbstractWebsocketSerializer<Exception> {
30     private static final @NonNull NodeIdentifier DATA_CHANGE_EVENT_NID = NodeIdentifier.create(DataChangeEvent.QNAME);
31
32     private final XMLStreamWriter xmlWriter;
33
34     XmlDataTreeCandidateSerializer(final EffectiveModelContext context, final XMLStreamWriter xmlWriter) {
35         super(context);
36         this.xmlWriter = requireNonNull(xmlWriter);
37     }
38
39     @Override
40     void serializeData(final Inference parent, final Collection<PathArgument> dataPath,
41             final DataTreeCandidateNode candidate, final boolean skipData) throws Exception {
42         final var modificationType = candidate.modificationType();
43         if (modificationType != ModificationType.UNMODIFIED) {
44             final var stack = SchemaInferenceStack.of(parent.getEffectiveModelContext());
45             stack.enterSchemaTree(DataChangedNotification.QNAME);
46
47             final var writer = XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, stack.toInference());
48             writer.startMapNode(DATA_CHANGE_EVENT_NID, 1);
49
50             final var path = YangInstanceIdentifier.of(dataPath);
51             writer.startMapEntryNode(NodeIdentifierWithPredicates.of(DataChangeEvent.QNAME, PATH_QNAME, path), 4);
52             writer.startLeafNode(PATH_NID);
53             writer.scalarValue(path);
54             writer.endNode();
55
56             writer.startLeafNode(OPERATION_NID);
57             writer.scalarValue(modificationTypeToOperation(candidate));
58             writer.endNode();
59
60             if (!skipData) {
61                 final var dataAfter = getDataAfter(candidate);
62                 if (dataAfter != null) {
63                     writer.flush();
64                     xmlWriter.writeStartElement(DATA_NAME);
65                     final var nnWriter = NormalizedNodeWriter.forStreamWriter(
66                         XMLStreamNormalizedNodeStreamWriter.create(xmlWriter, parent));
67                     nnWriter.write(dataAfter);
68                     nnWriter.flush();
69                     xmlWriter.writeEndElement();
70                 }
71             }
72
73             writer.endNode();
74             writer.endNode();
75         }
76     }
77 }