Use instanceof patterns in netconf-util
[netconf.git] / netconf / netconf-util / src / main / java / org / opendaylight / netconf / util / StreamingContext.java
index 82172f2c9b7e1d11a0acb368e2aa33055738bb4d..7283841ef914ce3583e0cfa1b7a5c267253528d8 100644 (file)
@@ -8,11 +8,11 @@
 package org.opendaylight.netconf.util;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter.UNKNOWN_SIZE;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import java.io.IOException;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -23,6 +23,7 @@ import java.util.Optional;
 import java.util.stream.Collectors;
 import javax.xml.transform.dom.DOMSource;
 import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.yang.common.Empty;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
@@ -62,7 +63,7 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         // We try to look up if this node was added by augmentation
         if (schema instanceof DataSchemaNode && result.isAugmenting()) {
             for (final AugmentationSchemaNode aug : ((AugmentationTarget)schema).getAvailableAugmentations()) {
-                if (aug.findDataChildByName(result.getQName()).isPresent()) {
+                if (aug.dataChildByName(result.getQName()) != null) {
                     return new Augmentation(aug, schema);
                 }
             }
@@ -71,19 +72,20 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
     }
 
     static StreamingContext<?> fromDataSchemaNode(final DataSchemaNode potential) {
-        if (potential instanceof ContainerSchemaNode) {
-            return new Container((ContainerSchemaNode) potential);
-        } else if (potential instanceof ListSchemaNode) {
-            return fromListSchemaNode((ListSchemaNode) potential);
-        } else if (potential instanceof LeafSchemaNode) {
-            return new Leaf((LeafSchemaNode) potential);
-        } else if (potential instanceof ChoiceSchemaNode) {
-            return new Choice((ChoiceSchemaNode) potential);
-        } else if (potential instanceof LeafListSchemaNode) {
-            return fromLeafListSchemaNode((LeafListSchemaNode) potential);
-        } else if (potential instanceof AnyxmlSchemaNode) {
-            return new AnyXml((AnyxmlSchemaNode) potential);
-        }
+        if (potential instanceof ContainerSchemaNode container) {
+            return new Container(container);
+        } else if (potential instanceof ListSchemaNode list) {
+            return fromListSchemaNode(list);
+        } else if (potential instanceof LeafSchemaNode leaf) {
+            return new Leaf(leaf);
+        } else if (potential instanceof ChoiceSchemaNode choice) {
+            return new Choice(choice);
+        } else if (potential instanceof LeafListSchemaNode leafList) {
+            return fromLeafListSchemaNode(leafList);
+        } else if (potential instanceof AnyxmlSchemaNode anyxml) {
+            return new AnyXml(anyxml);
+        }
+        // FIXME: unhandled anydata!
         return null;
     }
 
@@ -160,7 +162,7 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
                 final Iterator<PathArgument> others) throws IOException {
             verifyActualPathArgument(first);
 
-            emitElementStart(writer, first);
+            emitElementStart(writer, first, others.hasNext() ? 1 : 0);
             if (others.hasNext()) {
                 final PathArgument childPath = others.next();
                 final StreamingContext<?> childOp = getChildOperation(childPath);
@@ -174,7 +176,8 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
                                   final PathNode subtree) throws IOException {
             verifyActualPathArgument(first);
 
-            emitElementStart(writer, first);
+            final Collection<PathNode> children = subtree.children();
+            emitElementStart(writer, first, children.size());
             for (final PathNode node : subtree.children()) {
                 emitChildTreeNode(writer, node);
             }
@@ -194,7 +197,8 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
             }
         }
 
-        abstract void emitElementStart(NormalizedNodeStreamWriter writer, PathArgument arg) throws IOException;
+        abstract void emitElementStart(NormalizedNodeStreamWriter writer, PathArgument arg,
+                                       int childSizeHint) throws IOException;
 
         @SuppressWarnings("checkstyle:illegalCatch")
         StreamingContext<?> getChildOperation(final PathArgument childPath) {
@@ -232,9 +236,8 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         private StreamingContext<?> fromLocalSchema(final PathArgument child) {
-            if (child instanceof AugmentationIdentifier) {
-                return fromSchemaAndQNameChecked(schema, ((AugmentationIdentifier) child).getPossibleChildNames()
-                        .iterator().next());
+            if (child instanceof AugmentationIdentifier aid) {
+                return fromSchemaAndQNameChecked(schema, aid.getPossibleChildNames().iterator().next());
             }
             return fromSchemaAndQNameChecked(schema, child.getNodeType());
         }
@@ -246,8 +249,8 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
 
         AbstractMapMixin(final ListSchemaNode list) {
             super(NodeIdentifier.create(list.getQName()));
-            this.innerNode = new ListEntry(NodeIdentifierWithPredicates.of(list.getQName()), list);
-            this.keyLeaves = list.getKeyDefinition();
+            innerNode = new ListEntry(NodeIdentifierWithPredicates.of(list.getQName()), list);
+            keyLeaves = list.getKeyDefinition();
         }
 
         @Override
@@ -262,7 +265,11 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
 
         @Override
         final void emitChildTreeNode(final NormalizedNodeStreamWriter writer, final PathNode node) throws IOException {
-            final NodeIdentifierWithPredicates childPath = (NodeIdentifierWithPredicates) node.element();
+            final PathArgument element = node.element();
+            if (!(element instanceof NodeIdentifierWithPredicates childPath)) {
+                throw new IOException("Child identifier " + element + " is invalid in parent " + getIdentifier());
+            }
+
             final StreamingContext<?> childOp = getChildOperation(childPath);
             if (childPath.size() == 0 && node.isEmpty() || childPath.keySet().containsAll(keyLeaves)) {
                 // This is a query for the entire list, or the query specifies everything we need
@@ -342,8 +349,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startChoiceNode(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startChoiceNode(getIdentifier(), childSizeHint);
         }
     }
 
@@ -363,7 +371,7 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
 
     private static final class LeafListEntry extends AbstractSimple<NodeWithValue<?>> {
         LeafListEntry(final LeafListSchemaNode potential) {
-            super(new NodeWithValue<>(potential.getQName(), null));
+            super(new NodeWithValue<>(potential.getQName(), Empty.value()));
         }
 
         @Override
@@ -388,9 +396,10 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
             final NodeIdentifierWithPredicates identifier = (NodeIdentifierWithPredicates) arg;
-            writer.startMapEntryNode(identifier, UNKNOWN_SIZE);
+            writer.startMapEntryNode(identifier, childSizeHint);
 
             for (Entry<QName, Object> entry : identifier.entrySet()) {
                 writer.startLeafNode(new NodeIdentifier(entry.getKey()));
@@ -411,8 +420,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startUnkeyedListItem(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startUnkeyedListItem(getIdentifier(), childSizeHint);
         }
     }
 
@@ -427,8 +437,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startContainerNode(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startContainerNode(getIdentifier(), childSizeHint);
         }
     }
 
@@ -457,8 +468,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startOrderedLeafSet(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startOrderedLeafSet(getIdentifier(), childSizeHint);
         }
     }
 
@@ -468,15 +480,16 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startLeafSet(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startLeafSet(getIdentifier(), childSizeHint);
         }
     }
 
     private static final class Augmentation extends AbstractDataContainer<AugmentationIdentifier> {
         Augmentation(final AugmentationSchemaNode augmentation, final DataNodeContainer schema) {
             super(DataSchemaContextNode.augmentationIdentifierFrom(augmentation),
-                    EffectiveAugmentationSchema.create(augmentation, schema));
+                    new EffectiveAugmentationSchema(augmentation, schema));
         }
 
         @Override
@@ -485,7 +498,8 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
             writer.startAugmentationNode(getIdentifier());
         }
     }
@@ -496,8 +510,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startMapNode(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startMapNode(getIdentifier(), childSizeHint);
         }
     }
 
@@ -507,8 +522,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startOrderedMapNode(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startOrderedMapNode(getIdentifier(), childSizeHint);
         }
     }
 
@@ -517,7 +533,7 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
 
         UnkeyedListMixin(final ListSchemaNode list) {
             super(NodeIdentifier.create(list.getQName()));
-            this.innerNode = new UnkeyedListItem(list);
+            innerNode = new UnkeyedListItem(list);
         }
 
         @Override
@@ -531,8 +547,9 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         }
 
         @Override
-        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg) throws IOException {
-            writer.startUnkeyedList(getIdentifier(), UNKNOWN_SIZE);
+        void emitElementStart(final NormalizedNodeStreamWriter writer, final PathArgument arg,
+                              final int childSizeHint) throws IOException {
+            writer.startUnkeyedList(getIdentifier(), childSizeHint);
         }
     }
 }