2 * Copyright (c) 2016 Cisco Systems, Inc. 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.codec.binfmt;
10 import com.google.common.annotations.Beta;
11 import com.google.common.collect.ImmutableList;
12 import java.io.IOException;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import org.eclipse.jdt.annotation.NonNull;
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.stream.ReusableStreamReceiver;
19 import org.opendaylight.yangtools.yang.data.impl.schema.ReusableImmutableNormalizedNodeStreamWriter;
20 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate;
21 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
22 import org.opendaylight.yangtools.yang.data.tree.api.ModificationType;
23 import org.opendaylight.yangtools.yang.data.tree.spi.DataTreeCandidateNodes;
24 import org.opendaylight.yangtools.yang.data.tree.spi.DataTreeCandidates;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Utility serialization/deserialization for {@link DataTreeCandidate}. Note that this utility does not maintain
30 * before-image information across serialization.
33 public final class DataTreeCandidateInputOutput {
34 private static final Logger LOG = LoggerFactory.getLogger(DataTreeCandidateInputOutput.class);
35 private static final byte DELETE = 0;
36 private static final byte SUBTREE_MODIFIED = 1;
37 private static final byte UNMODIFIED = 2;
38 private static final byte WRITE = 3;
39 private static final byte APPEARED = 4;
40 private static final byte DISAPPEARED = 5;
42 private DataTreeCandidateInputOutput() {
46 public static @NonNull DataTreeCandidate readDataTreeCandidate(final NormalizedNodeDataInput in)
48 return readDataTreeCandidate(in, ReusableImmutableNormalizedNodeStreamWriter.create());
51 public static @NonNull DataTreeCandidate readDataTreeCandidate(final NormalizedNodeDataInput in,
52 final ReusableStreamReceiver receiver) throws IOException {
53 final YangInstanceIdentifier rootPath = in.readYangInstanceIdentifier();
54 final byte type = in.readByte();
56 final DataTreeCandidateNode rootNode;
59 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED, readChildren(in, receiver));
62 rootNode = DeletedDataTreeCandidateNode.create();
65 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED,
66 readChildren(in, receiver));
68 case SUBTREE_MODIFIED:
69 rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
70 readChildren(in, receiver));
73 rootNode = DataTreeCandidateNodes.written(in.readNormalizedNode(receiver));
76 rootNode = UnmodifiedRootDataTreeCandidateNode.INSTANCE;
79 throw unhandledNodeType(type);
82 return DataTreeCandidates.newDataTreeCandidate(rootPath, rootNode);
85 public static void writeDataTreeCandidate(final NormalizedNodeDataOutput out, final DataTreeCandidate candidate)
87 out.writeYangInstanceIdentifier(candidate.getRootPath());
89 final DataTreeCandidateNode node = candidate.getRootNode();
90 switch (node.getModificationType()) {
92 out.writeByte(APPEARED);
93 writeChildren(out, node.getChildNodes());
96 out.writeByte(DELETE);
99 out.writeByte(DISAPPEARED);
100 writeChildren(out, node.getChildNodes());
102 case SUBTREE_MODIFIED:
103 out.writeByte(SUBTREE_MODIFIED);
104 writeChildren(out, node.getChildNodes());
107 out.writeByte(UNMODIFIED);
110 out.writeByte(WRITE);
111 out.writeNormalizedNode(node.getDataAfter().get());
114 throw unhandledNodeType(node);
118 private static DataTreeCandidateNode readModifiedNode(final ModificationType type, final NormalizedNodeDataInput in,
119 final ReusableStreamReceiver receiver) throws IOException {
120 final PathArgument identifier = in.readPathArgument();
121 final Collection<DataTreeCandidateNode> children = readChildren(in, receiver);
122 if (children.isEmpty()) {
123 LOG.debug("Modified node {} does not have any children, not instantiating it", identifier);
127 return ModifiedDataTreeCandidateNode.create(identifier, type, children);
130 private static Collection<DataTreeCandidateNode> readChildren(final NormalizedNodeDataInput in,
131 final ReusableStreamReceiver receiver) throws IOException {
132 final int size = in.readInt();
134 return ImmutableList.of();
137 final Collection<DataTreeCandidateNode> ret = new ArrayList<>(size);
138 for (int i = 0; i < size; ++i) {
139 final DataTreeCandidateNode child = readNode(in, receiver);
147 private static DataTreeCandidateNode readNode(final NormalizedNodeDataInput in,
148 final ReusableStreamReceiver receiver) throws IOException {
149 final byte type = in.readByte();
152 return readModifiedNode(ModificationType.APPEARED, in, receiver);
154 return DeletedDataTreeCandidateNode.create(in.readPathArgument());
156 return readModifiedNode(ModificationType.DISAPPEARED, in, receiver);
157 case SUBTREE_MODIFIED:
158 return readModifiedNode(ModificationType.SUBTREE_MODIFIED, in, receiver);
162 return DataTreeCandidateNodes.written(in.readNormalizedNode(receiver));
164 throw unhandledNodeType(type);
168 private static void writeChildren(final NormalizedNodeDataOutput out,
169 final Collection<DataTreeCandidateNode> children) throws IOException {
170 out.writeInt(children.size());
171 for (DataTreeCandidateNode child : children) {
172 writeNode(out, child);
176 private static void writeNode(final NormalizedNodeDataOutput out, final DataTreeCandidateNode node)
178 switch (node.getModificationType()) {
180 out.writeByte(APPEARED);
181 out.writePathArgument(node.getIdentifier());
182 writeChildren(out, node.getChildNodes());
185 out.writeByte(DELETE);
186 out.writePathArgument(node.getIdentifier());
189 out.writeByte(DISAPPEARED);
190 out.writePathArgument(node.getIdentifier());
191 writeChildren(out, node.getChildNodes());
193 case SUBTREE_MODIFIED:
194 out.writeByte(SUBTREE_MODIFIED);
195 out.writePathArgument(node.getIdentifier());
196 writeChildren(out, node.getChildNodes());
199 out.writeByte(WRITE);
200 out.writeNormalizedNode(node.getDataAfter().get());
203 out.writeByte(UNMODIFIED);
206 throw unhandledNodeType(node);
210 private static IllegalArgumentException unhandledNodeType(final byte type) {
211 return new IllegalArgumentException("Unhandled node type " + type);
214 private static IllegalArgumentException unhandledNodeType(final DataTreeCandidateNode node) {
215 return new IllegalArgumentException("Unhandled node type " + node.getModificationType());