Implement subtree filtering using fields
[netconf.git] / netconf / netconf-util / src / main / java / org / opendaylight / netconf / util / StreamingContext.java
index 52ce54fd6ecfa0c45cff658dc3298889b08bf826..5cf6a7e732cc3e124a8c574822ee4ff47c11cca3 100644 (file)
@@ -13,6 +13,7 @@ import static org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedN
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -27,6 +28,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
 import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
@@ -91,9 +93,29 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
 
     abstract StreamingContext<?> getChild(PathArgument child);
 
+    /**
+     * Writing node structure that is described by series of {@link PathArgument}
+     * into {@link NormalizedNodeStreamWriter}.
+     *
+     * @param writer output {@link NormalizedNode} writer
+     * @param first  the first {@link PathArgument}
+     * @param others iterator that points to next path arguments
+     * @throws IOException failed to write a stream of path arguments into {@link NormalizedNodeStreamWriter}
+     */
     abstract void streamToWriter(NormalizedNodeStreamWriter writer, PathArgument first, Iterator<PathArgument> others)
             throws IOException;
 
+    /**
+     * Writing node structure that is described by provided {@link PathNode} into {@link NormalizedNodeStreamWriter}.
+     *
+     * @param writer output {@link NormalizedNode} writer
+     * @param first  the first {@link PathArgument}
+     * @param tree   subtree of path arguments that starts with the first path argument
+     * @throws IOException failed to write a stream of path arguments into {@link NormalizedNodeStreamWriter}
+     */
+    abstract void streamToWriter(NormalizedNodeStreamWriter writer, PathArgument first, PathNode tree)
+            throws IOException;
+
     abstract boolean isMixin();
 
     private static Optional<DataSchemaNode> findChildSchemaNode(final DataNodeContainer parent, final QName child) {
@@ -135,13 +157,7 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         @Override
         final void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first,
                 final Iterator<PathArgument> others) throws IOException {
-            if (!isMixin()) {
-                final QName type = getIdentifier().getNodeType();
-                if (type != null) {
-                    final QName firstType = first.getNodeType();
-                    checkArgument(type.equals(firstType), "Node QName must be %s was %s", type, firstType);
-                }
-            }
+            verifyActualPathArgument(first);
 
             emitElementStart(writer, first);
             if (others.hasNext()) {
@@ -152,6 +168,28 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
             writer.endNode();
         }
 
+        @Override
+        void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first,
+                            final PathNode subtree) throws IOException {
+            verifyActualPathArgument(first);
+
+            emitElementStart(writer, first);
+            for (final PathNode node : subtree.children()) {
+                final PathArgument childPath = node.element();
+                final StreamingContext<?> childOp = getChildOperation(childPath);
+                childOp.streamToWriter(writer, childPath, node);
+            }
+            writer.endNode();
+        }
+
+        private void verifyActualPathArgument(final PathArgument first) {
+            if (!isMixin()) {
+                final QName type = getIdentifier().getNodeType();
+                final QName firstType = first.getNodeType();
+                checkArgument(type.equals(firstType), "Node QName must be %s was %s", type, firstType);
+            }
+        }
+
         abstract void emitElementStart(NormalizedNodeStreamWriter writer, PathArgument arg) throws IOException;
 
         @SuppressWarnings("checkstyle:illegalCatch")
@@ -231,6 +269,12 @@ abstract class StreamingContext<T extends PathArgument> implements Identifiable<
         final boolean isMixin() {
             return false;
         }
+
+        @Override
+        void streamToWriter(final NormalizedNodeStreamWriter writer, final PathArgument first,
+                            final PathNode tree) throws IOException {
+            streamToWriter(writer, first, Collections.emptyIterator());
+        }
     }
 
     private static final class AnyXml extends AbstractSimple<NodeIdentifier> {