Remove use of thread-local output
[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 org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
22
23 /**
24  * Provides various utility methods for serialization and de-serialization.
25  *
26  * @author Thomas Pantelis
27  */
28 public final class SerializationUtils {
29     @Deprecated
30     public static final ThreadLocal<NormalizedNodeDataOutput> REUSABLE_WRITER_TL = new ThreadLocal<>();
31     public static final ThreadLocal<NormalizedNodeDataInput> REUSABLE_READER_TL = new ThreadLocal<>();
32
33     private SerializationUtils() {
34     }
35
36     public interface Applier<T> {
37         void apply(T instance, YangInstanceIdentifier path, NormalizedNode<?, ?> node);
38     }
39
40     @Deprecated
41     private static NormalizedNodeDataOutput streamWriter(final DataOutput out) {
42         NormalizedNodeDataOutput streamWriter = REUSABLE_WRITER_TL.get();
43         if (streamWriter == null) {
44             streamWriter = NormalizedNodeInputOutput.newDataOutput(out);
45         }
46
47         return streamWriter;
48     }
49
50     private static NormalizedNodeDataInput streamReader(final DataInput in) throws IOException {
51         NormalizedNodeDataInput streamReader = REUSABLE_READER_TL.get();
52         if (streamReader == null) {
53             streamReader = NormalizedNodeInputOutput.newDataInput(in);
54         }
55
56         return streamReader;
57     }
58
59     @Deprecated
60     public static void serializePathAndNode(final YangInstanceIdentifier path, final NormalizedNode<?, ?> node,
61             final DataOutput out) {
62         Preconditions.checkNotNull(path);
63         Preconditions.checkNotNull(node);
64         try {
65             NormalizedNodeDataOutput streamWriter = streamWriter(out);
66             streamWriter.writeNormalizedNode(node);
67             streamWriter.writeYangInstanceIdentifier(path);
68         } catch (IOException e) {
69             throw new IllegalArgumentException(String.format("Error serializing path %s and Node %s", path, node), e);
70         }
71     }
72
73     public static <T> void deserializePathAndNode(final DataInput in, final T instance, final Applier<T> applier) {
74         try {
75             NormalizedNodeDataInput streamReader = streamReader(in);
76             NormalizedNode<?, ?> node = streamReader.readNormalizedNode();
77             YangInstanceIdentifier path = streamReader.readYangInstanceIdentifier();
78             applier.apply(instance, path, node);
79         } catch (IOException e) {
80             throw new IllegalArgumentException("Error deserializing path and Node", e);
81         }
82     }
83
84     private static NormalizedNode<?, ?> tryDeserializeNormalizedNode(final DataInput in) throws IOException {
85         boolean present = in.readBoolean();
86         if (present) {
87             NormalizedNodeDataInput streamReader = streamReader(in);
88             return streamReader.readNormalizedNode();
89         }
90
91         return null;
92     }
93
94     public static NormalizedNode<?, ?> deserializeNormalizedNode(final DataInput in) {
95         try {
96             return tryDeserializeNormalizedNode(in);
97         } catch (IOException e) {
98             throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
99         }
100     }
101
102     public static NormalizedNode<?, ?> deserializeNormalizedNode(final byte [] bytes) {
103         try {
104             return tryDeserializeNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)));
105         } catch (IOException e) {
106             throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
107         }
108     }
109
110     @Deprecated
111     public static void serializeNormalizedNode(final NormalizedNode<?, ?> node, final DataOutput out) {
112         try {
113             out.writeBoolean(node != null);
114             if (node != null) {
115                 NormalizedNodeDataOutput streamWriter = streamWriter(out);
116                 streamWriter.writeNormalizedNode(node);
117             }
118         } catch (IOException e) {
119             throw new IllegalArgumentException(String.format("Error serializing NormalizedNode %s", node), e);
120         }
121     }
122
123     public static byte [] serializeNormalizedNode(final NormalizedNode<?, ?> node) {
124         ByteArrayOutputStream bos = new ByteArrayOutputStream();
125         serializeNormalizedNode(node, new DataOutputStream(bos));
126         return bos.toByteArray();
127     }
128
129     public static void writeNormalizedNode(final DataOutput out, final @Nullable NormalizedNode<?, ?> node)
130             throws IOException {
131         if (node != null) {
132             out.writeBoolean(true);
133
134             try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
135                 stream.writeNormalizedNode(node);
136             }
137         } else {
138             out.writeBoolean(false);
139         }
140     }
141
142     @Deprecated
143     public static void serializePath(final YangInstanceIdentifier path, final DataOutput out) {
144         Preconditions.checkNotNull(path);
145         try {
146             NormalizedNodeDataOutput streamWriter = streamWriter(out);
147             streamWriter.writeYangInstanceIdentifier(path);
148         } catch (IOException e) {
149             throw new IllegalArgumentException(String.format("Error serializing path %s", path), e);
150         }
151     }
152
153     public static void writePath(final DataOutput out, final @NonNull YangInstanceIdentifier path)
154             throws IOException {
155         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
156             stream.writeYangInstanceIdentifier(path);
157         }
158     }
159
160     public static void writeNodeAndPath(final DataOutput out, final YangInstanceIdentifier path,
161             final NormalizedNode<?, ?> node) throws IOException {
162         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
163             stream.writeNormalizedNode(node);
164             stream.writeYangInstanceIdentifier(path);
165         }
166     }
167
168     public static void writePathAndNode(final DataOutput out, final YangInstanceIdentifier path,
169             final NormalizedNode<?, ?> node) throws IOException {
170         try (NormalizedNodeDataOutput stream = NormalizedNodeInputOutput.newDataOutput(out)) {
171             stream.writeYangInstanceIdentifier(path);
172             stream.writeNormalizedNode(node);
173         }
174     }
175
176     public static YangInstanceIdentifier deserializePath(final DataInput in) {
177         try {
178             NormalizedNodeDataInput streamReader = streamReader(in);
179             return streamReader.readYangInstanceIdentifier();
180         } catch (IOException e) {
181             throw new IllegalArgumentException("Error deserializing path", e);
182         }
183     }
184 }