import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.Set;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * NormalizedNodeOutputStreamWriter will be used by distributed datastore to send normalized node in
+ * a stream.
+ * A stream writer wrapper around this class will write node objects to stream in recursive manner.
+ * for example - If you have a ContainerNode which has a two LeafNode as children, then
+ * you will first call
+ * {@link #startContainerNode(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier, int)},
+ * then will call
+ * {@link #leafNode(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier, Object)} twice
+ * and then, {@link #endNode()} to end container node.
+ *
+ * <p>Based on the each node, the node type is also written to the stream, that helps in reconstructing the object,
+ * while reading.
+ */
abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOutput, NormalizedNodeStreamWriter {
private static final Logger LOG = LoggerFactory.getLogger(AbstractNormalizedNodeDataOutput.class);
protected abstract short streamVersion();
- protected abstract void writeString(String string) throws IOException;
+ abstract void writeString(@NonNull String string) throws IOException;
@Override
public final void write(final int value) throws IOException {
writeQName(arg.getNodeType());
}
- private void writeObjSet(final Set<?> set) throws IOException {
+ final void writeObjSet(final Set<?> set) throws IOException {
output.writeInt(set.size());
for (Object o : set) {
checkArgument(o instanceof String, "Expected value type to be String but was %s (%s)", o.getClass(), o);
writeYangInstanceIdentifierInternal(identifier);
}
- private void writeYangInstanceIdentifierInternal(final YangInstanceIdentifier identifier) throws IOException {
+ final void writeYangInstanceIdentifierInternal(final YangInstanceIdentifier identifier) throws IOException {
Collection<PathArgument> pathArguments = identifier.getPathArguments();
output.writeInt(pathArguments.size());
for (PathArgument pathArgument : pathArguments) {
- writePathArgument(pathArgument);
+ writePathArgumentInternal(pathArgument);
}
}
- @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST",
- justification = "The casts in the switch clauses are indirectly confirmed via the determination of 'type'.")
@Override
public void writePathArgument(final PathArgument pathArgument) throws IOException {
+ ensureHeaderWritten();
+ writePathArgumentInternal(pathArgument);
+ }
+
+ @SuppressFBWarnings(value = "BC_UNCONFIRMED_CAST",
+ justification = "The casts in the switch clauses are indirectly confirmed via the determination of 'type'.")
+ final void writePathArgumentInternal(final PathArgument pathArgument) throws IOException {
byte type = PathArgumentTypes.getSerializablePathArgumentType(pathArgument);
}
}
- private void writeObject(final Object value) throws IOException {
+ abstract void writeObject(@NonNull DataOutput output, @NonNull Object value) throws IOException;
- byte type = ValueTypes.getSerializableType(value);
- // Write object type first
- output.writeByte(type);
-
- switch (type) {
- case ValueTypes.BOOL_TYPE:
- output.writeBoolean((Boolean) value);
- break;
- case ValueTypes.QNAME_TYPE:
- writeQName((QName) value);
- break;
- case ValueTypes.INT_TYPE:
- output.writeInt((Integer) value);
- break;
- case ValueTypes.BYTE_TYPE:
- output.writeByte((Byte) value);
- break;
- case ValueTypes.LONG_TYPE:
- output.writeLong((Long) value);
- break;
- case ValueTypes.SHORT_TYPE:
- output.writeShort((Short) value);
- break;
- case ValueTypes.BITS_TYPE:
- writeObjSet((Set<?>) value);
- break;
- case ValueTypes.BINARY_TYPE:
- byte[] bytes = (byte[]) value;
- output.writeInt(bytes.length);
- output.write(bytes);
- break;
- case ValueTypes.YANG_IDENTIFIER_TYPE:
- writeYangInstanceIdentifierInternal((YangInstanceIdentifier) value);
- break;
- case ValueTypes.EMPTY_TYPE:
- break;
- case ValueTypes.STRING_BYTES_TYPE:
- final byte[] valueBytes = value.toString().getBytes(StandardCharsets.UTF_8);
- output.writeInt(valueBytes.length);
- output.write(valueBytes);
- break;
- default:
- output.writeUTF(value.toString());
- break;
- }
+ private void writeObject(final Object value) throws IOException {
+ writeObject(output, value);
}
}