Tolerate empty instance identifier in ImmutableNodes.fromInstanceId() 81/77481/1
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 4 Nov 2018 20:24:28 +0000 (21:24 +0100)
committerRobert Varga <nite@hq.sk>
Sun, 4 Nov 2018 20:29:21 +0000 (20:29 +0000)
If the user specifies an empty InstanceIdentifier, we fail with an
undocumented NoSuchElementException. Make sure we properly handle
this case by returning a container which matches SchemaContext.NAME.

JIRA: YANGTOOLS-914
Change-Id: I0b503d3bed99d73d88e037d35979c503215f3b52
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ImmutableNodes.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToNodesTest.java

index 3a559b277c5f56fb04222b4ba1287f1cc1cb6e50..754a87047bafd4b0fbc57a8e3876b8d5e7f512d9 100644 (file)
@@ -39,6 +39,7 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 public final class ImmutableNodes {
+    private static final NodeIdentifier SCHEMACONTEXT_NAME = NodeIdentifier.create(SchemaContext.NAME);
 
     private ImmutableNodes() {
         throw new UnsupportedOperationException("Utilities class should not be instantiated");
@@ -195,13 +196,20 @@ public final class ImmutableNodes {
      */
     public static NormalizedNode<?, ?> fromInstanceId(final SchemaContext ctx, final YangInstanceIdentifier id,
             final Optional<NormalizedNode<?, ?>> deepestElement, final Optional<Entry<QName, ModifyAction>> operation) {
+        final PathArgument topLevelElement;
+        final InstanceIdToNodes<?> instanceIdToNodes;
         final Iterator<PathArgument> it = id.getPathArguments().iterator();
-        final PathArgument topLevelElement = it.next();
-        final DataSchemaNode dataChildByName = ctx.getDataChildByName(topLevelElement.getNodeType());
-        checkNotNull(dataChildByName,
-            "Cannot find %s node in schema context. Instance identifier has to start from root", topLevelElement);
-        final InstanceIdToNodes<?> instanceIdToNodes = InstanceIdToNodes.fromSchemaAndQNameChecked(ctx,
-            topLevelElement.getNodeType());
+        if (it.hasNext()) {
+            topLevelElement = it.next();
+            final DataSchemaNode dataChildByName = ctx.getDataChildByName(topLevelElement.getNodeType());
+            checkNotNull(dataChildByName,
+                "Cannot find %s node in schema context. Instance identifier has to start from root", topLevelElement);
+            instanceIdToNodes = InstanceIdToNodes.fromSchemaAndQNameChecked(ctx, topLevelElement.getNodeType());
+        } else {
+            topLevelElement = SCHEMACONTEXT_NAME;
+            instanceIdToNodes = InstanceIdToNodes.fromDataSchemaNode(ctx);
+        }
+
         return instanceIdToNodes.create(topLevelElement, it, deepestElement, operation);
     }
 }
index 778a0945d1d5a6698df977cd4a4fcf39045a9be2..ca75650f941cc812f2eab59ac4cc6c89ccdca826 100644 (file)
@@ -200,4 +200,10 @@ public class InstanceIdToNodesTest {
                 YangInstanceIdentifier.create(rootContainer, leafList, leafListWithValue));
         assertEquals(expectedFilter, filter);
     }
+
+    @Test
+    public void testEmptyInstanceIdentifier() {
+        assertEquals(ImmutableNodes.containerNode(SchemaContext.NAME),
+            ImmutableNodes.fromInstanceId(ctx, YangInstanceIdentifier.EMPTY));
+    }
 }