Separate out AbstractNormalizedNodeDataInput
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / main / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / AbstractNormalizedNodeDataOutput.java
1 /*
2  * Copyright (c) 2015 Cisco 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 static java.util.Objects.requireNonNull;
11
12 import java.io.DataOutput;
13 import java.io.IOException;
14 import java.io.OutputStream;
15 import java.util.List;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
20 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
21 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
22 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
23 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
24
25 /**
26  * Abstract base class for implementing {@link NormalizedNodeDataOutput} contract. This class uses
27  * {@link NormalizedNodeStreamWriter} as an internal interface for performing the actual NormalizedNode writeout,
28  * i.e. it will defer to a {@link NormalizedNodeWriter} instance.
29  *
30  * <p>
31  * As such, this is an implementation detail not exposed from this package, hence implementations can rely on the
32  * stream being initialized with a header and version.
33  */
34 abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOutput, NormalizedNodeStreamWriter {
35     // Visible for subclasses
36     final DataOutput output;
37
38     private NormalizedNodeWriter normalizedNodeWriter;
39     private boolean headerWritten;
40
41     AbstractNormalizedNodeDataOutput(final DataOutput output) {
42         this.output = requireNonNull(output);
43     }
44
45
46     private void ensureHeaderWritten() throws IOException {
47         if (!headerWritten) {
48             output.writeByte(TokenTypes.SIGNATURE_MARKER);
49             output.writeShort(streamVersion());
50             headerWritten = true;
51         }
52     }
53
54     @Override
55     public final void write(final int value) throws IOException {
56         ensureHeaderWritten();
57         output.write(value);
58     }
59
60     @Override
61     public final void write(final byte[] bytes) throws IOException {
62         ensureHeaderWritten();
63         output.write(bytes);
64     }
65
66     @Override
67     public final void write(final byte[] bytes, final int off, final int len) throws IOException {
68         ensureHeaderWritten();
69         output.write(bytes, off, len);
70     }
71
72     @Override
73     public final void writeBoolean(final boolean value) throws IOException {
74         ensureHeaderWritten();
75         output.writeBoolean(value);
76     }
77
78     @Override
79     public final void writeByte(final int value) throws IOException {
80         ensureHeaderWritten();
81         output.writeByte(value);
82     }
83
84     @Override
85     public final void writeShort(final int value) throws IOException {
86         ensureHeaderWritten();
87         output.writeShort(value);
88     }
89
90     @Override
91     public final void writeChar(final int value) throws IOException {
92         ensureHeaderWritten();
93         output.writeChar(value);
94     }
95
96     @Override
97     public final void writeInt(final int value) throws IOException {
98         ensureHeaderWritten();
99         output.writeInt(value);
100     }
101
102     @Override
103     public final void writeLong(final long value) throws IOException {
104         ensureHeaderWritten();
105         output.writeLong(value);
106     }
107
108     @Override
109     public final void writeFloat(final float value) throws IOException {
110         ensureHeaderWritten();
111         output.writeFloat(value);
112     }
113
114     @Override
115     public final void writeDouble(final double value) throws IOException {
116         ensureHeaderWritten();
117         output.writeDouble(value);
118     }
119
120     @Override
121     public final void writeBytes(final String str) throws IOException {
122         ensureHeaderWritten();
123         output.writeBytes(str);
124     }
125
126     @Override
127     public final void writeChars(final String str) throws IOException {
128         ensureHeaderWritten();
129         output.writeChars(str);
130     }
131
132     @Override
133     public final void writeUTF(final String str) throws IOException {
134         ensureHeaderWritten();
135         output.writeUTF(str);
136     }
137
138     @Override
139     public final void writeQName(final QName qname) throws IOException {
140         ensureHeaderWritten();
141         writeQNameInternal(qname);
142     }
143
144     @Override
145     public final void writeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
146         ensureHeaderWritten();
147         if (normalizedNodeWriter == null) {
148             normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(this);
149         }
150         normalizedNodeWriter.write(node);
151     }
152
153     @Override
154     public final void writePathArgument(final PathArgument pathArgument) throws IOException {
155         ensureHeaderWritten();
156         writePathArgumentInternal(pathArgument);
157     }
158
159     @Override
160     public final void writeYangInstanceIdentifier(final YangInstanceIdentifier identifier) throws IOException {
161         ensureHeaderWritten();
162         writeYangInstanceIdentifierInternal(identifier);
163     }
164
165     @Override
166     public final void writeSchemaPath(final SchemaPath path) throws IOException {
167         ensureHeaderWritten();
168
169         output.writeBoolean(path.isAbsolute());
170         final List<QName> qnames = path.getPath();
171         output.writeInt(qnames.size());
172         for (QName qname : qnames) {
173             writeQNameInternal(qname);
174         }
175     }
176
177     @Override
178     public final void close() throws IOException {
179         flush();
180     }
181
182     @Override
183     public void flush() throws IOException {
184         if (output instanceof OutputStream) {
185             ((OutputStream)output).flush();
186         }
187     }
188
189     abstract short streamVersion();
190
191     abstract void writeQNameInternal(@NonNull QName qname) throws IOException;
192
193     abstract void writePathArgumentInternal(PathArgument pathArgument) throws IOException;
194
195     abstract void writeYangInstanceIdentifierInternal(YangInstanceIdentifier identifier) throws IOException;
196 }