Improve ImmutableAugmentationNodeBuilder defensiveness
[yangtools.git] / yang / yang-data-impl / src / main / java / org / opendaylight / yangtools / yang / data / impl / schema / SchemaOrderedNormalizedNodeWriter.java
index e92f0dd7286f9d3a0e743c1390fab0bbbdabe817..6cb35a5dbb61e77094c9c3574ea9771e11ecd164 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ArrayListMultimap;
 import java.io.IOException;
 import java.util.Collection;
@@ -18,49 +19,59 @@ import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 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.api.schema.stream.NormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * This is an iterator over a {@link NormalizedNode}. Unlike {@link NormalizedNodeWriter},
- * this iterates over elements in order as they are defined in .yang file.
+ * This is an iterator over a {@link NormalizedNode}. Unlike {@link NormalizedNodeWriter}, this iterates over elements
+ * in the order as they are defined in YANG file.
  */
 public class SchemaOrderedNormalizedNodeWriter extends NormalizedNodeWriter {
-
-    private final SchemaContext schemaContext;
+    private static final Logger LOG = LoggerFactory.getLogger(SchemaOrderedNormalizedNodeWriter.class);
+    private final EffectiveModelContext schemaContext;
     private final SchemaNode root;
-    private final NormalizedNodeStreamWriter writer;
 
     private SchemaNode currentSchemaNode;
 
     /**
      * Create a new writer backed by a {@link NormalizedNodeStreamWriter}.
-     * @param writer Back-end writer
-     * @param schemaContext Schema context
-     * @param path path
+     *
+     * @param writer
+     *            Back-end writer
+     * @param schemaContext
+     *            Schema context
+     * @param path
+     *            path
      */
-    public SchemaOrderedNormalizedNodeWriter(final NormalizedNodeStreamWriter writer, final SchemaContext schemaContext, final SchemaPath path) {
+    public SchemaOrderedNormalizedNodeWriter(final NormalizedNodeStreamWriter writer,
+            final EffectiveModelContext schemaContext, final SchemaPath path) {
         super(writer);
-        this.writer = writer;
         this.schemaContext = schemaContext;
-        this.root = SchemaUtils.findParentSchemaOnPath(schemaContext, path);
+        final Collection<SchemaNode> schemaNodes = SchemaUtils.findParentSchemaNodesOnPath(schemaContext, path);
+        Preconditions.checkArgument(!schemaNodes.isEmpty(), "Unable to find schema node for supplied schema path: %s",
+                path);
+        if (schemaNodes.size() > 1) {
+            LOG.warn("More possible schema nodes {} for supplied schema path {}", schemaNodes, path);
+        }
+        this.root = schemaNodes.iterator().next();
     }
 
     @Override
     public SchemaOrderedNormalizedNodeWriter write(final NormalizedNode<?, ?> node) throws IOException {
         if (Objects.equals(root, schemaContext)) {
-            currentSchemaNode = schemaContext.getDataChildByName(node.getNodeType());
+            currentSchemaNode = schemaContext.dataChildByName(node.getNodeType());
         } else {
             currentSchemaNode = root;
         }
         return write(node, currentSchemaNode);
-
     }
 
     /**
@@ -78,10 +89,10 @@ public class SchemaOrderedNormalizedNodeWriter extends NormalizedNodeWriter {
         }
 
         throw new IllegalStateException("It wasn't possible to serialize nodes " + nodes);
-
     }
 
-    private SchemaOrderedNormalizedNodeWriter write(final NormalizedNode<?, ?> node, final SchemaNode dataSchemaNode) throws IOException {
+    private SchemaOrderedNormalizedNodeWriter write(final NormalizedNode<?, ?> node, final SchemaNode dataSchemaNode)
+            throws IOException {
 
         //Set current schemaNode
         try (SchemaNodeSetter sns = new SchemaNodeSetter(dataSchemaNode)) {
@@ -102,19 +113,21 @@ public class SchemaOrderedNormalizedNodeWriter extends NormalizedNodeWriter {
     }
 
     private void write(final List<NormalizedNode<?, ?>> nodes, final SchemaNode dataSchemaNode) throws IOException {
-        for (NormalizedNode<?, ?> node : nodes) {
+        for (final NormalizedNode<?, ?> node : nodes) {
             write(node, dataSchemaNode);
         }
     }
 
+    @Override
     protected boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children) throws IOException {
         return writeChildren(children, currentSchemaNode, true);
     }
 
-    private boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children, final SchemaNode parentSchemaNode, boolean endParent) throws IOException {
+    private boolean writeChildren(final Iterable<? extends NormalizedNode<?, ?>> children,
+            final SchemaNode parentSchemaNode, final boolean endParent) throws IOException {
         //Augmentations cannot be gotten with node.getChild so create our own structure with augmentations resolved
-        ArrayListMultimap<QName, NormalizedNode<?, ?>> qNameToNodes = ArrayListMultimap.create();
-        for (NormalizedNode<?, ?> child : children) {
+        final ArrayListMultimap<QName, NormalizedNode<?, ?>> qNameToNodes = ArrayListMultimap.create();
+        for (final NormalizedNode<?, ?> child : children) {
             if (child instanceof AugmentationNode) {
                 qNameToNodes.putAll(resolveAugmentations(child));
             } else {
@@ -126,25 +139,25 @@ public class SchemaOrderedNormalizedNodeWriter extends NormalizedNodeWriter {
             if (parentSchemaNode instanceof ListSchemaNode && qNameToNodes.containsKey(parentSchemaNode.getQName())) {
                 write(qNameToNodes.get(parentSchemaNode.getQName()), parentSchemaNode);
             } else {
-                for (DataSchemaNode schemaNode : ((DataNodeContainer) parentSchemaNode).getChildNodes()) {
+                for (final DataSchemaNode schemaNode : ((DataNodeContainer) parentSchemaNode).getChildNodes()) {
                     write(qNameToNodes.get(schemaNode.getQName()), schemaNode);
                 }
             }
-        } else if(parentSchemaNode instanceof ChoiceSchemaNode) {
-            for (ChoiceCaseNode ccNode : ((ChoiceSchemaNode) parentSchemaNode).getCases()) {
-                for (DataSchemaNode dsn : ccNode.getChildNodes()) {
+        } else if (parentSchemaNode instanceof ChoiceSchemaNode) {
+            for (final CaseSchemaNode ccNode : ((ChoiceSchemaNode) parentSchemaNode).getCases()) {
+                for (final DataSchemaNode dsn : ccNode.getChildNodes()) {
                     if (qNameToNodes.containsKey(dsn.getQName())) {
                         write(qNameToNodes.get(dsn.getQName()), dsn);
                     }
                 }
             }
         } else {
-            for (NormalizedNode<?, ?> child : children) {
+            for (final NormalizedNode<?, ?> child : children) {
                 writeLeaf(child);
             }
         }
         if (endParent) {
-            writer.endNode();
+            getWriter().endNode();
         }
         return true;
     }
@@ -159,7 +172,7 @@ public class SchemaOrderedNormalizedNodeWriter extends NormalizedNodeWriter {
 
     private ArrayListMultimap<QName, NormalizedNode<?, ?>> resolveAugmentations(final NormalizedNode<?, ?> child) {
         final ArrayListMultimap<QName, NormalizedNode<?, ?>> resolvedAugs = ArrayListMultimap.create();
-        for (NormalizedNode<?, ?> node : ((AugmentationNode) child).getValue()) {
+        for (final NormalizedNode<?, ?> node : ((AugmentationNode) child).getValue()) {
             if (node instanceof AugmentationNode) {
                 resolvedAugs.putAll(resolveAugmentations(node));
             } else {
@@ -169,26 +182,24 @@ public class SchemaOrderedNormalizedNodeWriter extends NormalizedNodeWriter {
         return resolvedAugs;
     }
 
-
-    private class SchemaNodeSetter implements AutoCloseable {
+    private final class SchemaNodeSetter implements AutoCloseable {
 
         private final SchemaNode previousSchemaNode;
 
         /**
-         * Sets current schema node new value and store old value for later restore
+         * Sets current schema node new value and store old value for later restore.
          */
-        public SchemaNodeSetter(final SchemaNode schemaNode) {
+        SchemaNodeSetter(final SchemaNode schemaNode) {
             previousSchemaNode = SchemaOrderedNormalizedNodeWriter.this.currentSchemaNode;
             SchemaOrderedNormalizedNodeWriter.this.currentSchemaNode = schemaNode;
         }
 
         /**
-         * Restore previous schema node
+         * Restore previous schema node.
          */
         @Override
         public void close() {
             SchemaOrderedNormalizedNodeWriter.this.currentSchemaNode = previousSchemaNode;
         }
     }
-
 }
\ No newline at end of file