2 * Copyright (c) 2020 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.restconf.common.serializer;
10 import java.util.ArrayDeque;
11 import java.util.Collection;
12 import java.util.Deque;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
18 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
19 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
20 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
22 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 public abstract class AbstractWebsocketSerializer<T extends Exception> {
29 private static final Logger LOG = LoggerFactory.getLogger(AbstractWebsocketSerializer.class);
31 public void serialize(DataTreeCandidate candidate, boolean leafNodesOnly, boolean skipData) throws T {
32 final Deque<PathArgument> path = new ArrayDeque<>();
33 path.addAll(candidate.getRootPath().getPathArguments());
35 serializeLeafNodesOnly(path, candidate.getRootNode(), skipData);
39 serializeData(path, candidate.getRootNode(), skipData);
42 void serializeLeafNodesOnly(Deque<PathArgument> path, DataTreeCandidateNode candidate, boolean skipData)
44 NormalizedNode<?, ?> node = null;
45 switch (candidate.getModificationType()) {
47 // no reason to do anything with an unmodified node
48 LOG.debug("DataTreeCandidate for a notification is unmodified, not serializing leaves. Candidate: {}",
51 case SUBTREE_MODIFIED:
54 node = candidate.getDataAfter().get();
58 node = candidate.getDataBefore().get();
61 LOG.error("DataTreeCandidate modification has unknown type: {}", candidate.getModificationType());
68 if (node instanceof LeafNode<?> || node instanceof LeafSetNode) {
69 serializeData(path, candidate, skipData);
73 for (DataTreeCandidateNode childNode : candidate.getChildNodes()) {
74 path.add(childNode.getIdentifier());
75 serializeLeafNodesOnly(path, childNode, skipData);
80 abstract void serializeData(Collection<PathArgument> path, DataTreeCandidateNode candidate, boolean skipData)
83 abstract void serializePath(Collection<PathArgument> pathArguments) throws T;
85 abstract void serializeOperation(DataTreeCandidateNode candidate) throws T;
87 String convertPath(Collection<PathArgument> path) {
88 final StringBuilder pathBuilder = new StringBuilder();
90 for (PathArgument pathArgument : path) {
91 pathBuilder.append("/");
92 pathBuilder.append(pathArgument.getNodeType().getNamespace().toString().replaceAll(":", "-"));
93 pathBuilder.append(":");
94 pathBuilder.append(pathArgument.getNodeType().getLocalName());
96 if (pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
97 pathBuilder.append("[");
98 final Set<Map.Entry<QName, Object>> keys =
99 ((YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument).entrySet();
100 for (Map.Entry<QName, Object> key : keys) {
101 pathBuilder.append(key.getKey().getNamespace().toString().replaceAll(":", "-"));
102 pathBuilder.append(":");
103 pathBuilder.append(key.getKey().getLocalName());
104 pathBuilder.append("='");
105 pathBuilder.append(key.getValue().toString());
106 pathBuilder.append("'");
108 pathBuilder.append("]");
112 return pathBuilder.toString();
115 String modificationTypeToOperation(DataTreeCandidateNode candidate, ModificationType modificationType) {
116 switch (modificationType) {
118 // shouldn't ever happen since the root of a modification is only triggered by some event
119 LOG.warn("DataTreeCandidate for a notification is unmodified. Candidate: {}", candidate);
121 case SUBTREE_MODIFIED:
124 if (candidate.getDataBefore().isPresent()) {
133 LOG.error("DataTreeCandidate modification has unknown type: {}",
134 candidate.getModificationType());
135 throw new IllegalStateException("Unknown modification type");