2 * Copyright (c) 2014 Brocade Communications 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.controller.cluster.datastore.node.utils.stream;
10 import com.google.common.base.Preconditions;
11 import java.io.ByteArrayInputStream;
12 import java.io.ByteArrayOutputStream;
13 import java.io.DataInput;
14 import java.io.DataInputStream;
15 import java.io.DataOutput;
16 import java.io.DataOutputStream;
17 import java.io.IOException;
18 import java.util.Optional;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 * Provides various utility methods for serialization and de-serialization.
27 * @author Thomas Pantelis
29 public final class SerializationUtils {
31 public static final ThreadLocal<NormalizedNodeDataOutput> REUSABLE_WRITER_TL = new ThreadLocal<>();
33 public static final ThreadLocal<NormalizedNodeDataInput> REUSABLE_READER_TL = new ThreadLocal<>();
35 private SerializationUtils() {
40 public interface Applier<T> {
41 void apply(T instance, YangInstanceIdentifier path, NormalizedNode<?, ?> node);
45 private static NormalizedNodeDataOutput streamWriter(final DataOutput out) {
46 NormalizedNodeDataOutput streamWriter = REUSABLE_WRITER_TL.get();
47 if (streamWriter == null) {
48 streamWriter = NormalizedNodeInputOutput.newDataOutput(out);
55 private static NormalizedNodeDataInput streamReader(final DataInput in) throws IOException {
56 NormalizedNodeDataInput streamReader = REUSABLE_READER_TL.get();
57 if (streamReader == null) {
58 streamReader = NormalizedNodeInputOutput.newDataInput(in);
65 public static void serializePathAndNode(final YangInstanceIdentifier path, final NormalizedNode<?, ?> node,
66 final DataOutput out) {
67 Preconditions.checkNotNull(path);
68 Preconditions.checkNotNull(node);
70 NormalizedNodeDataOutput streamWriter = streamWriter(out);
71 streamWriter.writeNormalizedNode(node);
72 streamWriter.writeYangInstanceIdentifier(path);
73 } catch (IOException e) {
74 throw new IllegalArgumentException(String.format("Error serializing path %s and Node %s", path, node), e);
79 public static <T> void deserializePathAndNode(final DataInput in, final T instance, final Applier<T> applier) {
81 NormalizedNodeDataInput streamReader = streamReader(in);
82 NormalizedNode<?, ?> node = streamReader.readNormalizedNode();
83 YangInstanceIdentifier path = streamReader.readYangInstanceIdentifier();
84 applier.apply(instance, path, node);
85 } catch (IOException e) {
86 throw new IllegalArgumentException("Error deserializing path and Node", e);
90 private static NormalizedNode<?, ?> tryDeserializeNormalizedNode(final DataInput in) throws IOException {
91 boolean present = in.readBoolean();
93 NormalizedNodeDataInput streamReader = streamReader(in);
94 return streamReader.readNormalizedNode();
101 public static NormalizedNode<?, ?> deserializeNormalizedNode(final DataInput in) {
103 return tryDeserializeNormalizedNode(in);
104 } catch (IOException e) {
105 throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
110 public static NormalizedNode<?, ?> deserializeNormalizedNode(final byte [] bytes) {
112 return tryDeserializeNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)));
113 } catch (IOException e) {
114 throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
118 public static Optional<NormalizedNode<?, ?>> readNormalizedNode(final DataInput in) throws IOException {
119 if (!in.readBoolean()) {
120 return Optional.empty();
122 return Optional.of(NormalizedNodeInputOutput.newDataInput(in).readNormalizedNode());
126 public static void serializeNormalizedNode(final NormalizedNode<?, ?> node, final DataOutput out) {
128 out.writeBoolean(node != null);
130 NormalizedNodeDataOutput streamWriter = streamWriter(out);
131 streamWriter.writeNormalizedNode(node);
133 } catch (IOException e) {
134 throw new IllegalArgumentException(String.format("Error serializing NormalizedNode %s", node), e);
138 public static byte [] serializeNormalizedNode(final NormalizedNode<?, ?> node) {
139 ByteArrayOutputStream bos = new ByteArrayOutputStream();
140 serializeNormalizedNode(node, new DataOutputStream(bos));
141 return bos.toByteArray();
144 public static void writeNormalizedNode(final DataOutput out, final @Nullable NormalizedNode<?, ?> node)
147 out.writeBoolean(true);
149 try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
150 stream.writeNormalizedNode(node);
153 out.writeBoolean(false);
158 public static void serializePath(final YangInstanceIdentifier path, final DataOutput out) {
159 Preconditions.checkNotNull(path);
161 NormalizedNodeDataOutput streamWriter = streamWriter(out);
162 streamWriter.writeYangInstanceIdentifier(path);
163 } catch (IOException e) {
164 throw new IllegalArgumentException(String.format("Error serializing path %s", path), e);
168 public static YangInstanceIdentifier readPath(final DataInput in) throws IOException {
169 return NormalizedNodeInputOutput.newDataInput(in).readYangInstanceIdentifier();
172 public static void writePath(final DataOutput out, final @NonNull YangInstanceIdentifier path)
174 try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
175 stream.writeYangInstanceIdentifier(path);
179 public static <T> void readNodeAndPath(final DataInput in, final T instance, final Applier<T> applier)
181 final NormalizedNodeDataInput stream = NormalizedNodeInputOutput.newDataInput(in);
182 NormalizedNode<?, ?> node = stream.readNormalizedNode();
183 YangInstanceIdentifier path = stream.readYangInstanceIdentifier();
184 applier.apply(instance, path, node);
187 public static void writeNodeAndPath(final DataOutput out, final YangInstanceIdentifier path,
188 final NormalizedNode<?, ?> node) throws IOException {
189 try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
190 stream.writeNormalizedNode(node);
191 stream.writeYangInstanceIdentifier(path);
195 public static <T> void readPathAndNode(final DataInput in, final T instance, final Applier<T> applier)
197 final NormalizedNodeDataInput stream = NormalizedNodeInputOutput.newDataInput(in);
198 YangInstanceIdentifier path = stream.readYangInstanceIdentifier();
199 NormalizedNode<?, ?> node = stream.readNormalizedNode();
200 applier.apply(instance, path, node);
203 public static void writePathAndNode(final DataOutput out, final YangInstanceIdentifier path,
204 final NormalizedNode<?, ?> node) throws IOException {
205 try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
206 stream.writeYangInstanceIdentifier(path);
207 stream.writeNormalizedNode(node);
212 public static YangInstanceIdentifier deserializePath(final DataInput in) {
214 NormalizedNodeDataInput streamReader = streamReader(in);
215 return streamReader.readYangInstanceIdentifier();
216 } catch (IOException e) {
217 throw new IllegalArgumentException("Error deserializing path", e);