Use NormalizedNodeStreamWriter to emit JSON data
[netconf.git] / restconf / restconf-nb / src / main / java / org / opendaylight / restconf / nb / rfc8040 / streams / listeners / JsonDataTreeCandidateSerializer.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.listeners;
9
10 import static java.util.Objects.requireNonNull;
11 import static org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter.createNestedWriter;
12
13 import com.google.gson.stream.JsonWriter;
14 import java.io.IOException;
15 import java.util.Collection;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.DataChangedNotification;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.data.changed.notification.DataChangeEvent;
18 import org.opendaylight.yangtools.yang.common.XMLNamespace;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
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.gson.JSONCodecFactorySupplier;
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.api.stmt.SchemaNodeIdentifier.Absolute;
27 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
28
29 final class JsonDataTreeCandidateSerializer extends AbstractWebsocketSerializer<IOException> {
30     private static final XMLNamespace SAL_REMOTE_NS = DataChangedNotification.QNAME.getNamespace();
31     private static final Absolute DATA_CHANGE_EVENT = Absolute.of(DataChangedNotification.QNAME, DataChangeEvent.QNAME);
32
33     private final JSONCodecFactorySupplier codecSupplier;
34     private final JsonWriter jsonWriter;
35
36     JsonDataTreeCandidateSerializer(final EffectiveModelContext context,
37             final JSONCodecFactorySupplier codecSupplier, final JsonWriter jsonWriter) {
38         super(context);
39         this.codecSupplier = requireNonNull(codecSupplier);
40         this.jsonWriter = requireNonNull(jsonWriter);
41     }
42
43     @Override
44     void serializeData(final Inference parent, final Collection<PathArgument> dataPath,
45             final DataTreeCandidateNode candidate, final boolean skipData) throws IOException {
46         jsonWriter.beginObject();
47
48         final var modificationType = candidate.modificationType();
49         if (modificationType != ModificationType.UNMODIFIED) {
50             final var codecs = codecSupplier.getShared(parent.getEffectiveModelContext());
51             try (var writer = createNestedWriter(codecs, DATA_CHANGE_EVENT, SAL_REMOTE_NS, jsonWriter)) {
52                 writer.startLeafNode(PATH_NID);
53                 writer.scalarValue(YangInstanceIdentifier.of(dataPath));
54                 writer.endNode();
55
56                 writer.startLeafNode(OPERATION_NID);
57                 writer.scalarValue(modificationTypeToOperation(candidate));
58                 writer.endNode();
59             }
60
61             if (!skipData) {
62                 final var dataAfter = getDataAfter(candidate);
63                 if (dataAfter != null) {
64                     jsonWriter.name("data").beginObject();
65                     try (var writer = createNestedWriter(codecs, parent, SAL_REMOTE_NS, jsonWriter)) {
66                         NormalizedNodeWriter.forStreamWriter(writer).write(dataAfter).flush();
67                     }
68                     jsonWriter.endObject();
69                 }
70             }
71         }
72
73         jsonWriter.endObject();
74     }
75 }