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