fc4bfa36f4205238a7ef75278d4b6072690e347a
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / SerializationUtils.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. 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.controller.cluster.datastore.node.utils.stream;
9
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;
23
24 /**
25  * Provides various utility methods for serialization and de-serialization.
26  *
27  * @author Thomas Pantelis
28  */
29 public final class SerializationUtils {
30     @Deprecated
31     public static final ThreadLocal<NormalizedNodeDataOutput> REUSABLE_WRITER_TL = new ThreadLocal<>();
32     @Deprecated
33     public static final ThreadLocal<NormalizedNodeDataInput> REUSABLE_READER_TL = new ThreadLocal<>();
34
35     private SerializationUtils() {
36
37     }
38
39     @FunctionalInterface
40     public interface Applier<T> {
41         void apply(T instance, YangInstanceIdentifier path, NormalizedNode<?, ?> node);
42     }
43
44     @Deprecated
45     private static NormalizedNodeDataOutput streamWriter(final DataOutput out) {
46         NormalizedNodeDataOutput streamWriter = REUSABLE_WRITER_TL.get();
47         if (streamWriter == null) {
48             streamWriter = NormalizedNodeInputOutput.newDataOutput(out);
49         }
50
51         return streamWriter;
52     }
53
54     @Deprecated
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);
59         }
60
61         return streamReader;
62     }
63
64     @Deprecated
65     public static void serializePathAndNode(final YangInstanceIdentifier path, final NormalizedNode<?, ?> node,
66             final DataOutput out) {
67         Preconditions.checkNotNull(path);
68         Preconditions.checkNotNull(node);
69         try {
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);
75         }
76     }
77
78     @Deprecated
79     public static <T> void deserializePathAndNode(final DataInput in, final T instance, final Applier<T> applier) {
80         try {
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);
87         }
88     }
89
90     private static NormalizedNode<?, ?> tryDeserializeNormalizedNode(final DataInput in) throws IOException {
91         boolean present = in.readBoolean();
92         if (present) {
93             NormalizedNodeDataInput streamReader = streamReader(in);
94             return streamReader.readNormalizedNode();
95         }
96
97         return null;
98     }
99
100     @Deprecated
101     public static NormalizedNode<?, ?> deserializeNormalizedNode(final DataInput in) {
102         try {
103             return tryDeserializeNormalizedNode(in);
104         } catch (IOException e) {
105             throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
106         }
107     }
108
109     @Deprecated
110     public static NormalizedNode<?, ?> deserializeNormalizedNode(final byte [] bytes) {
111         try {
112             return tryDeserializeNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)));
113         } catch (IOException e) {
114             throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
115         }
116     }
117
118     public static Optional<NormalizedNode<?, ?>> readNormalizedNode(final DataInput in) throws IOException {
119         if (!in.readBoolean()) {
120             return Optional.empty();
121         }
122         return Optional.of(NormalizedNodeInputOutput.newDataInput(in).readNormalizedNode());
123     }
124
125     @Deprecated
126     public static void serializeNormalizedNode(final NormalizedNode<?, ?> node, final DataOutput out) {
127         try {
128             out.writeBoolean(node != null);
129             if (node != null) {
130                 NormalizedNodeDataOutput streamWriter = streamWriter(out);
131                 streamWriter.writeNormalizedNode(node);
132             }
133         } catch (IOException e) {
134             throw new IllegalArgumentException(String.format("Error serializing NormalizedNode %s", node), e);
135         }
136     }
137
138     public static byte [] serializeNormalizedNode(final NormalizedNode<?, ?> node) {
139         ByteArrayOutputStream bos = new ByteArrayOutputStream();
140         serializeNormalizedNode(node, new DataOutputStream(bos));
141         return bos.toByteArray();
142     }
143
144     public static void writeNormalizedNode(final DataOutput out, final @Nullable NormalizedNode<?, ?> node)
145             throws IOException {
146         if (node != null) {
147             out.writeBoolean(true);
148
149             try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
150                 stream.writeNormalizedNode(node);
151             }
152         } else {
153             out.writeBoolean(false);
154         }
155     }
156
157     public static void writeNormalizedNode(final DataOutput out, final NormalizedNodeStreamVersion version,
158             final @Nullable NormalizedNode<?, ?> node) throws IOException {
159         if (node != null) {
160             out.writeBoolean(true);
161
162             try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out, version)) {
163                 stream.writeNormalizedNode(node);
164             }
165         } else {
166             out.writeBoolean(false);
167         }
168     }
169
170     @Deprecated
171     public static void serializePath(final YangInstanceIdentifier path, final DataOutput out) {
172         Preconditions.checkNotNull(path);
173         try {
174             NormalizedNodeDataOutput streamWriter = streamWriter(out);
175             streamWriter.writeYangInstanceIdentifier(path);
176         } catch (IOException e) {
177             throw new IllegalArgumentException(String.format("Error serializing path %s", path), e);
178         }
179     }
180
181     public static YangInstanceIdentifier readPath(final DataInput in) throws IOException {
182         return NormalizedNodeInputOutput.newDataInput(in).readYangInstanceIdentifier();
183     }
184
185     public static void writePath(final DataOutput out, final @NonNull YangInstanceIdentifier path)
186             throws IOException {
187         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
188             stream.writeYangInstanceIdentifier(path);
189         }
190     }
191
192     public static void writePath(final DataOutput out, final NormalizedNodeStreamVersion version,
193             final @NonNull YangInstanceIdentifier path) throws IOException {
194         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out, version)) {
195             stream.writeYangInstanceIdentifier(path);
196         }
197     }
198
199     public static <T> void readNodeAndPath(final DataInput in, final T instance, final Applier<T> applier)
200             throws IOException {
201         final NormalizedNodeDataInput stream = NormalizedNodeInputOutput.newDataInput(in);
202         NormalizedNode<?, ?> node = stream.readNormalizedNode();
203         YangInstanceIdentifier path = stream.readYangInstanceIdentifier();
204         applier.apply(instance, path, node);
205     }
206
207     public static void writeNodeAndPath(final DataOutput out, final YangInstanceIdentifier path,
208             final NormalizedNode<?, ?> node) throws IOException {
209         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
210             stream.writeNormalizedNode(node);
211             stream.writeYangInstanceIdentifier(path);
212         }
213     }
214
215     public static <T> void readPathAndNode(final DataInput in, final T instance, final Applier<T> applier)
216             throws IOException {
217         final NormalizedNodeDataInput stream = NormalizedNodeInputOutput.newDataInput(in);
218         YangInstanceIdentifier path = stream.readYangInstanceIdentifier();
219         NormalizedNode<?, ?> node = stream.readNormalizedNode();
220         applier.apply(instance, path, node);
221     }
222
223     public static void writePathAndNode(final DataOutput out, final YangInstanceIdentifier path,
224             final NormalizedNode<?, ?> node) throws IOException {
225         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
226             stream.writeYangInstanceIdentifier(path);
227             stream.writeNormalizedNode(node);
228         }
229     }
230
231     @Deprecated
232     public static YangInstanceIdentifier deserializePath(final DataInput in) {
233         try {
234             NormalizedNodeDataInput streamReader = streamReader(in);
235             return streamReader.readYangInstanceIdentifier();
236         } catch (IOException e) {
237             throw new IllegalArgumentException("Error deserializing path", e);
238         }
239     }
240 }