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(final DataTreeCandidate candidate, final boolean leafNodesOnly, final boolean skipData)
33 final Deque<PathArgument> path = new ArrayDeque<>();
34 path.addAll(candidate.getRootPath().getPathArguments());
36 serializeLeafNodesOnly(path, candidate.getRootNode(), skipData);
40 serializeData(path, candidate.getRootNode(), skipData);
43 void serializeLeafNodesOnly(final Deque<PathArgument> path, final DataTreeCandidateNode candidate,
44 final boolean skipData) throws T {
45 NormalizedNode node = null;
46 switch (candidate.getModificationType()) {
48 // no reason to do anything with an unmodified node
49 LOG.debug("DataTreeCandidate for a notification is unmodified, not serializing leaves. Candidate: {}",
52 case SUBTREE_MODIFIED:
55 node = candidate.getDataAfter().get();
59 node = candidate.getDataBefore().get();
62 LOG.error("DataTreeCandidate modification has unknown type: {}", candidate.getModificationType());
69 if (node instanceof LeafNode<?> || node instanceof LeafSetNode) {
70 serializeData(path, candidate, skipData);
74 for (DataTreeCandidateNode childNode : candidate.getChildNodes()) {
75 path.add(childNode.getIdentifier());
76 serializeLeafNodesOnly(path, childNode, skipData);
81 abstract void serializeData(Collection<PathArgument> path, DataTreeCandidateNode candidate, boolean skipData)
84 abstract void serializePath(Collection<PathArgument> pathArguments) throws T;
86 abstract void serializeOperation(DataTreeCandidateNode candidate) throws T;
88 String convertPath(final Collection<PathArgument> path) {
89 final StringBuilder pathBuilder = new StringBuilder();
91 for (PathArgument pathArgument : path) {
92 pathBuilder.append("/");
93 pathBuilder.append(pathArgument.getNodeType().getNamespace().toString().replaceAll(":", "-"));
94 pathBuilder.append(":");
95 pathBuilder.append(pathArgument.getNodeType().getLocalName());
97 if (pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) {
98 pathBuilder.append("[");
99 final Set<Map.Entry<QName, Object>> keys =
100 ((YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument).entrySet();
101 for (Map.Entry<QName, Object> key : keys) {
102 pathBuilder.append(key.getKey().getNamespace().toString().replaceAll(":", "-"));
103 pathBuilder.append(":");
104 pathBuilder.append(key.getKey().getLocalName());
105 pathBuilder.append("='");
106 pathBuilder.append(key.getValue().toString());
107 pathBuilder.append("'");
109 pathBuilder.append("]");
113 return pathBuilder.toString();
116 String modificationTypeToOperation(final DataTreeCandidateNode candidate, final ModificationType modificationType) {
117 switch (modificationType) {
119 // shouldn't ever happen since the root of a modification is only triggered by some event
120 LOG.warn("DataTreeCandidate for a notification is unmodified. Candidate: {}", candidate);
122 case SUBTREE_MODIFIED:
125 if (candidate.getDataBefore().isPresent()) {
134 LOG.error("DataTreeCandidate modification has unknown type: {}",
135 candidate.getModificationType());
136 throw new IllegalStateException("Unknown modification type");