Reorganize AbstractNormalizedNodeDataOutput 90/84590/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 11 Sep 2019 15:44:47 +0000 (17:44 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 23 Sep 2019 03:38:04 +0000 (05:38 +0200)
This reorganizes AbstractNormalizedNodeDataOutput so that it
implements all NormalizedNodeDataOutput with final methods,
deferring implementation as need to abstract methods.

This way we have precisely one implementation of public methods,
making it easy to audit for correctness. Furthermore it eliminates
writeAugmentationIdentifier() override in NeonSR2 writer.

It also introduces writeQNameInternal(), which skips header checks,
as the call sites have already performed those checks.

Change-Id: Icb4a7e994c04e3d52bd561d99c7743dfdfd88738
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 5f03268912870fdffe366074e581ff18c805216f)

opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractLithiumDataOutput.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/LithiumNormalizedNodeOutputStreamWriter.java
opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NeonSR2NormalizedNodeOutputStreamWriter.java

index 2c3d0959a48b81b88d788d46ca0b8b34697f7023..07960dd3f6a1d9f87874b152c106bd48a5f01133 100644 (file)
@@ -70,7 +70,7 @@ abstract class AbstractLithiumDataOutput extends AbstractNormalizedNodeDataOutpu
                 rawOuput.writeBoolean((Boolean) value);
                 break;
             case ValueTypes.QNAME_TYPE:
-                writeQName((QName) value);
+                writeQNameInternal((QName) value);
                 break;
             case ValueTypes.INT_TYPE:
                 rawOuput.writeInt((Integer) value);
index d54baf92fc43538be2c11ab2c23c945d16c41cb5..fb677a33df7ec4a34174f34f317d74837cd98a18 100755 (executable)
@@ -75,10 +75,6 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         }
     }
 
-    protected abstract short streamVersion();
-
-    abstract void writeString(@NonNull String string) throws IOException;
-
     @Override
     public final void write(final int value) throws IOException {
         ensureHeaderWritten();
@@ -163,18 +159,48 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         output.writeUTF(str);
     }
 
-    private NormalizedNodeWriter normalizedNodeWriter() {
+    @Override
+    public final void writeQName(final QName qname) throws IOException {
+        ensureHeaderWritten();
+        writeQNameInternal(qname);
+    }
+
+    @Override
+    public final void writeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
+        ensureHeaderWritten();
         if (normalizedNodeWriter == null) {
             normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(this);
         }
+        normalizedNodeWriter.write(node);
+    }
 
-        return normalizedNodeWriter;
+    @Override
+    public final void writePathArgument(final PathArgument pathArgument) throws IOException {
+        ensureHeaderWritten();
+        writePathArgumentInternal(pathArgument);
     }
 
     @Override
-    public void writeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
+    public final void writeYangInstanceIdentifier(final YangInstanceIdentifier identifier) throws IOException {
         ensureHeaderWritten();
-        normalizedNodeWriter().write(node);
+        writeYangInstanceIdentifierInternal(identifier);
+    }
+
+    @Override
+    public final void writeSchemaPath(final SchemaPath path) throws IOException {
+        ensureHeaderWritten();
+        output.writeBoolean(path.isAbsolute());
+
+        final Collection<QName> qnames = path.getPath();
+        output.writeInt(qnames.size());
+        for (QName qname : qnames) {
+            writeQNameInternal(qname);
+        }
+    }
+
+    @Override
+    public final void close() throws IOException {
+        flush();
     }
 
     @Override
@@ -210,7 +236,7 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         // lastLeafSetQName is set if the parent LeafSetNode was previously written. Otherwise this is a
         // stand alone LeafSetEntryNode so write out it's name here.
         if (lastLeafSetQName == null) {
-            writeQName(name.getNodeType());
+            writeQNameInternal(name.getNodeType());
         }
         inSimple = true;
     }
@@ -307,11 +333,6 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         inSimple = false;
     }
 
-    @Override
-    public void close() throws IOException {
-        flush();
-    }
-
     @Override
     public void flush() throws IOException {
         if (output instanceof OutputStream) {
@@ -328,7 +349,7 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         // First write the type of node
         output.writeByte(nodeType);
         // Write Start Tag
-        writeQName(arg.getNodeType());
+        writeQNameInternal(arg.getNodeType());
     }
 
     final void writeObjSet(final Set<?> set) throws IOException {
@@ -339,24 +360,6 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         }
     }
 
-    @Override
-    public void writeSchemaPath(final SchemaPath path) throws IOException {
-        ensureHeaderWritten();
-        output.writeBoolean(path.isAbsolute());
-
-        final Collection<QName> qnames = path.getPath();
-        output.writeInt(qnames.size());
-        for (QName qname : qnames) {
-            writeQName(qname);
-        }
-    }
-
-    @Override
-    public void writeYangInstanceIdentifier(final YangInstanceIdentifier identifier) throws IOException {
-        ensureHeaderWritten();
-        writeYangInstanceIdentifierInternal(identifier);
-    }
-
     final void writeYangInstanceIdentifierInternal(final YangInstanceIdentifier identifier) throws IOException {
         Collection<PathArgument> pathArguments = identifier.getPathArguments();
         output.writeInt(pathArguments.size());
@@ -366,51 +369,33 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         }
     }
 
-    @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);
-
+        final byte type = PathArgumentTypes.getSerializablePathArgumentType(pathArgument);
         output.writeByte(type);
 
         switch (type) {
             case PathArgumentTypes.NODE_IDENTIFIER:
-
                 NodeIdentifier nodeIdentifier = (NodeIdentifier) pathArgument;
-
-                writeQName(nodeIdentifier.getNodeType());
+                writeQNameInternal(nodeIdentifier.getNodeType());
                 break;
-
             case PathArgumentTypes.NODE_IDENTIFIER_WITH_PREDICATES:
-
                 NodeIdentifierWithPredicates nodeIdentifierWithPredicates =
                     (NodeIdentifierWithPredicates) pathArgument;
-                writeQName(nodeIdentifierWithPredicates.getNodeType());
-
+                writeQNameInternal(nodeIdentifierWithPredicates.getNodeType());
                 writeKeyValueMap(nodeIdentifierWithPredicates.entrySet());
                 break;
-
-            case PathArgumentTypes.NODE_IDENTIFIER_WITH_VALUE :
-
+            case PathArgumentTypes.NODE_IDENTIFIER_WITH_VALUE:
                 NodeWithValue<?> nodeWithValue = (NodeWithValue<?>) pathArgument;
-
-                writeQName(nodeWithValue.getNodeType());
+                writeQNameInternal(nodeWithValue.getNodeType());
                 writeObject(nodeWithValue.getValue());
                 break;
-
-            case PathArgumentTypes.AUGMENTATION_IDENTIFIER :
-
+            case PathArgumentTypes.AUGMENTATION_IDENTIFIER:
                 // No Qname in augmentation identifier
                 writeAugmentationIdentifier((AugmentationIdentifier) pathArgument);
                 break;
-            default :
+            default:
                 throw new IllegalStateException("Unknown node identifier type is found : "
                         + pathArgument.getClass().toString());
         }
@@ -420,7 +405,7 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         if (!entrySet.isEmpty()) {
             output.writeInt(entrySet.size());
             for (Entry<QName, Object> entry : entrySet) {
-                writeQName(entry.getKey());
+                writeQNameInternal(entry.getKey());
                 writeObject(entry.getValue());
             }
         } else {
@@ -428,13 +413,13 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         }
     }
 
-    void writeAugmentationIdentifier(final AugmentationIdentifier aid) throws IOException {
+    final void defaultWriteAugmentationIdentifier(final @NonNull AugmentationIdentifier aid) throws IOException {
         final Set<QName> qnames = aid.getPossibleChildNames();
         // Write each child's qname separately, if list is empty send count as 0
         if (!qnames.isEmpty()) {
             output.writeInt(qnames.size());
             for (QName qname : qnames) {
-                writeQName(qname);
+                writeQNameInternal(qname);
             }
         } else {
             LOG.debug("augmentation node does not have any child");
@@ -442,6 +427,14 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut
         }
     }
 
+    abstract short streamVersion();
+
+    abstract void writeString(@NonNull String string) throws IOException;
+
+    abstract void writeQNameInternal(@NonNull QName qname) throws IOException;
+
+    abstract void writeAugmentationIdentifier(@NonNull AugmentationIdentifier aid) throws IOException;
+
     abstract void writeObject(@NonNull DataOutput output, @NonNull Object value) throws IOException;
 
     private void writeObject(final Object value) throws IOException {
index 3f7fb3b290895910dba9a41de1cec5e521c49b22..b14bc1904ac8c59e49f7d68e83cee34429caec9b 100644 (file)
@@ -11,6 +11,7 @@ import java.io.DataOutput;
 import java.io.IOException;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 
 /**
  * NormalizedNodeOutputStreamWriter will be used by distributed datastore to send normalized node in
@@ -32,12 +33,12 @@ final class LithiumNormalizedNodeOutputStreamWriter extends AbstractLithiumDataO
     }
 
     @Override
-    protected short streamVersion() {
+    short streamVersion() {
         return TokenTypes.LITHIUM_VERSION;
     }
 
     @Override
-    public void writeQName(final QName qname) throws IOException {
+    void writeQNameInternal(final QName qname) throws IOException {
         defaultWriteQName(qname);
     }
 
@@ -45,4 +46,9 @@ final class LithiumNormalizedNodeOutputStreamWriter extends AbstractLithiumDataO
     void writeModule(final QNameModule module) throws IOException {
         defaultWriteModule(module);
     }
+
+    @Override
+    void writeAugmentationIdentifier(final AugmentationIdentifier aid) throws IOException {
+        defaultWriteAugmentationIdentifier(aid);
+    }
 }
index b3183a3d95ee93fbcf7194bca6cb19223923a666..43bcc3452369ced145ec1d363cf672f2022c506b 100644 (file)
@@ -39,12 +39,12 @@ final class NeonSR2NormalizedNodeOutputStreamWriter extends AbstractLithiumDataO
     }
 
     @Override
-    protected short streamVersion() {
+    short streamVersion() {
         return TokenTypes.NEON_SR2_VERSION;
     }
 
     @Override
-    public void writeQName(final QName qname) throws IOException {
+    void writeQNameInternal(final QName qname) throws IOException {
         final Integer value = qnameCodeMap.get(qname);
         if (value == null) {
             // Fresh QName, remember it and emit as three strings
@@ -65,7 +65,7 @@ final class NeonSR2NormalizedNodeOutputStreamWriter extends AbstractLithiumDataO
             // Fresh AugmentationIdentifier, remember it and emit as three strings
             aidCodeMap.put(aid, aidCodeMap.size());
             writeByte(TokenTypes.IS_AUGMENT_VALUE);
-            super.writeAugmentationIdentifier(aid);
+            defaultWriteAugmentationIdentifier(aid);
         } else {
             // We have already seen this AugmentationIdentifier: write its code
             writeByte(TokenTypes.IS_AUGMENT_CODE);