3a04347a54faeef7fe74cfedea65ef55a0d8ad42
[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.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
20
21 /**
22  * Provides various utility methods for serialization and de-serialization.
23  *
24  * @author Thomas Pantelis
25  */
26 public final class SerializationUtils {
27     public static final ThreadLocal<NormalizedNodeDataOutput> REUSABLE_WRITER_TL = new ThreadLocal<>();
28     public static final ThreadLocal<NormalizedNodeDataInput> REUSABLE_READER_TL = new ThreadLocal<>();
29
30     private SerializationUtils() {
31     }
32
33     public interface Applier<T> {
34         void apply(T instance, YangInstanceIdentifier path, NormalizedNode<?, ?> node);
35     }
36
37     private static NormalizedNodeDataOutput streamWriter(DataOutput out) {
38         NormalizedNodeDataOutput streamWriter = REUSABLE_WRITER_TL.get();
39         if (streamWriter == null) {
40             streamWriter = NormalizedNodeInputOutput.newDataOutput(out);
41         }
42
43         return streamWriter;
44     }
45
46     private static NormalizedNodeDataInput streamReader(DataInput in) throws IOException {
47         NormalizedNodeDataInput streamReader = REUSABLE_READER_TL.get();
48         if (streamReader == null) {
49             streamReader = NormalizedNodeInputOutput.newDataInput(in);
50         }
51
52         return streamReader;
53     }
54
55     public static void serializePathAndNode(YangInstanceIdentifier path, NormalizedNode<?, ?> node,
56             DataOutput out) {
57         Preconditions.checkNotNull(path);
58         Preconditions.checkNotNull(node);
59         try {
60             NormalizedNodeDataOutput streamWriter = streamWriter(out);
61             streamWriter.writeNormalizedNode(node);
62             streamWriter.writeYangInstanceIdentifier(path);
63         } catch (IOException e) {
64             throw new IllegalArgumentException(String.format("Error serializing path %s and Node %s",
65                     path, node), e);
66         }
67     }
68
69     public static <T> void deserializePathAndNode(DataInput in, T instance, Applier<T> applier) {
70         try {
71             NormalizedNodeDataInput streamReader = streamReader(in);
72             NormalizedNode<?, ?> node = streamReader.readNormalizedNode();
73             YangInstanceIdentifier path = streamReader.readYangInstanceIdentifier();
74             applier.apply(instance, path, node);
75         } catch (IOException e) {
76             throw new IllegalArgumentException("Error deserializing path and Node", e);
77         }
78     }
79
80     private static NormalizedNode<?, ?> tryDeserializeNormalizedNode(DataInput in) throws IOException {
81         boolean present = in.readBoolean();
82         if (present) {
83             NormalizedNodeDataInput streamReader = streamReader(in);
84             return streamReader.readNormalizedNode();
85         }
86
87         return null;
88     }
89
90     public static NormalizedNode<?, ?> deserializeNormalizedNode(DataInput in) {
91         try {
92             return tryDeserializeNormalizedNode(in);
93         } catch (IOException e) {
94             throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
95         }
96     }
97
98     public static NormalizedNode<?, ?> deserializeNormalizedNode(byte [] bytes) {
99         try {
100             return tryDeserializeNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)));
101         } catch (IOException e) {
102             throw new IllegalArgumentException("Error deserializing NormalizedNode", e);
103         }
104     }
105
106     public static void serializeNormalizedNode(NormalizedNode<?, ?> node, DataOutput out) {
107         try {
108             out.writeBoolean(node != null);
109             if (node != null) {
110                 NormalizedNodeDataOutput streamWriter = streamWriter(out);
111                 streamWriter.writeNormalizedNode(node);
112             }
113         } catch (IOException e) {
114             throw new IllegalArgumentException(String.format("Error serializing NormalizedNode %s",
115                     node), e);
116         }
117     }
118
119     public static byte [] serializeNormalizedNode(NormalizedNode<?, ?> node) {
120         ByteArrayOutputStream bos = new ByteArrayOutputStream();
121         serializeNormalizedNode(node, new DataOutputStream(bos));
122         return bos.toByteArray();
123     }
124
125     public static void serializePath(YangInstanceIdentifier path, DataOutput out) {
126         Preconditions.checkNotNull(path);
127         try {
128             NormalizedNodeDataOutput streamWriter = streamWriter(out);
129             streamWriter.writeYangInstanceIdentifier(path);
130         } catch (IOException e) {
131             throw new IllegalArgumentException(String.format("Error serializing path %s", path), e);
132         }
133     }
134
135     public static YangInstanceIdentifier deserializePath(DataInput in) {
136         try {
137             NormalizedNodeDataInput streamReader = streamReader(in);
138             return streamReader.readYangInstanceIdentifier();
139         } catch (IOException e) {
140             throw new IllegalArgumentException("Error deserializing path", e);
141         }
142     }
143 }