Bug 6240: Entities of imported module's submodule are not visible 12/42312/2
authorPeter Kajsa <pkajsa@cisco.com>
Thu, 21 Jul 2016 10:46:22 +0000 (12:46 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Mon, 25 Jul 2016 13:11:24 +0000 (13:11 +0000)
Yang statement parser didn't lookup yang elements in submodules of imported module.
Therefore each submodule element was always invisible to other modules even if they
imported parent module of the submodule.

This patch adds IncludeContext to the each RootStatementContext in order to allow
lookup of yang elements also in included submodules.

Change-Id: I9993b9fe110a5e80e9a61258a40841af13c18320
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6240Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/sub-bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/sub-foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/foo-imp.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/sub-foo.yang [new file with mode: 0644]

index 045be493784c639bcffac5043deb1d6b9f0520e3..54f93ebe8ac36b35dfd991454c771db90cb92663 100644 (file)
@@ -8,16 +8,21 @@
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
 import com.google.common.base.Optional;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Map;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IncludedModuleContext;
 
 /**
  * root statement class for a Yang source
@@ -26,6 +31,7 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
         StatementContextBase<A, D, E> {
 
     private final SourceSpecificContext sourceContext;
+    private final Collection<NamespaceStorageNode> includedContexts = new ArrayList<>();
     private final A argument;
 
     RootStatementContext(final ContextBuilder<A, D, E> builder, final SourceSpecificContext sourceContext) {
@@ -180,4 +186,44 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
     public boolean isEnabledSemanticVersioning() {
         return sourceContext.isEnabledSemanticVersioning();
     }
+
+    @Override
+    public <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(final Class<N> type, final K key,
+            final V value) {
+        if (IncludedModuleContext.class.isAssignableFrom(type)) {
+            includedContexts.add((NamespaceStorageNode) value);
+        }
+        super.addToLocalStorage(type, key, value);
+    }
+
+    @Override
+    public <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(final Class<N> type, final K key) {
+        final V potentialLocal = super.getFromLocalStorage(type, key);
+        if (potentialLocal != null) {
+            return potentialLocal;
+        }
+        for (final NamespaceStorageNode includedSource : includedContexts) {
+            final V potential = includedSource.getFromLocalStorage(type, key);
+            if (potential != null) {
+                return potential;
+            }
+        }
+        return null;
+    }
+
+    @Nullable
+    @Override
+    public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(final Class<N> type) {
+        final Map<K, V> potentialLocal = super.getAllFromLocalStorage(type);
+        if (potentialLocal != null) {
+            return potentialLocal;
+        }
+        for (final NamespaceStorageNode includedSource : includedContexts) {
+            final Map<K, V> potential = includedSource.getAllFromLocalStorage(type);
+            if (potential != null) {
+                return potential;
+            }
+        }
+        return null;
+    }
 }
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6240Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6240Test.java
new file mode 100644 (file)
index 0000000..dda220c
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.stmt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.FileNotFoundException;
+import java.net.URISyntaxException;
+import java.util.Set;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+public class Bug6240Test {
+    private static final String NS = "bar";
+    private static final String REV = "2016-07-19";
+
+    @Test
+    public void testModels() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException {
+        final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug6240/correct");
+        assertNotNull(context);
+
+        final Set<Module> modules = context.getModules();
+        assertEquals(2, modules.size());
+
+        Module bar = null;
+        for (final Module module : modules) {
+            if ("bar".equals(module.getName())) {
+                bar = module;
+                break;
+            }
+        }
+
+        assertNotNull(bar);
+        assertTrue(bar.getDataChildByName(QName.create(NS, REV, "foo-grp-con")) instanceof ContainerSchemaNode);
+        assertTrue(bar.getDataChildByName(QName.create(NS, REV, "sub-foo-grp-con")) instanceof ContainerSchemaNode);
+
+        assertEquals(1, bar.getSubmodules().size());
+
+        final DataSchemaNode dataChildByName = bar.getDataChildByName(QName.create(NS, REV, "sub-bar-con"));
+        assertTrue(dataChildByName instanceof ContainerSchemaNode);
+        final ContainerSchemaNode subBarCon = (ContainerSchemaNode) dataChildByName;
+
+        assertTrue(subBarCon.getDataChildByName(QName.create(NS, REV, "foo-grp-con")) instanceof ContainerSchemaNode);
+        assertTrue(subBarCon.getDataChildByName(QName.create(NS, REV, "sub-foo-grp-con")) instanceof ContainerSchemaNode);
+    }
+
+    @Test
+    public void testInvalidModels() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException {
+        try {
+            StmtTestUtils.parseYangSources("/bugs/bug6240/incorrect");
+        } catch (final SomeModifiersUnresolvedException e) {
+            assertTrue(e.getCause().getCause().getMessage()
+                    .startsWith("Grouping '(bar?revision=2016-07-19)foo-imp-grp' was not resolved."));
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/bar.yang
new file mode 100644 (file)
index 0000000..0136d58
--- /dev/null
@@ -0,0 +1,14 @@
+module bar {
+    namespace "bar";
+    prefix "bar";
+
+    include sub-bar {
+        revision-date 2016-07-19;
+    }
+    import foo { prefix foo; revision-date 2016-07-19; }
+
+    revision "2016-07-19";
+
+    uses foo:sub-foo-grp;
+    uses foo:foo-grp;
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/foo.yang
new file mode 100644 (file)
index 0000000..7fe73c4
--- /dev/null
@@ -0,0 +1,15 @@
+module foo {
+    namespace "foo";
+    prefix foo;
+
+    include sub-foo {
+        revision-date 2016-07-19;
+    }
+
+    revision 2016-07-19;
+    
+    grouping foo-grp {
+        container foo-grp-con {
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/sub-bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/sub-bar.yang
new file mode 100644 (file)
index 0000000..1b21c45
--- /dev/null
@@ -0,0 +1,14 @@
+submodule sub-bar {
+    belongs-to bar {
+        prefix bar;
+    }
+    
+    import foo { prefix foo; revision-date 2016-07-19; }
+    
+    revision 2016-07-19;
+
+    container sub-bar-con {
+        uses foo:sub-foo-grp;
+        uses foo:foo-grp;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/sub-foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/correct/sub-foo.yang
new file mode 100644 (file)
index 0000000..d3e858b
--- /dev/null
@@ -0,0 +1,12 @@
+submodule sub-foo {
+    belongs-to foo {
+        prefix foo;
+    }
+
+    revision 2016-07-19;
+
+    grouping sub-foo-grp {
+        container sub-foo-grp-con {
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/bar.yang
new file mode 100644 (file)
index 0000000..9ece862
--- /dev/null
@@ -0,0 +1,12 @@
+module bar {
+    namespace "bar";
+    prefix "bar";
+
+    import foo { prefix foo; revision-date 2016-07-19; }
+
+    revision "2016-07-19";
+
+    uses foo:sub-foo-grp;
+    uses foo:foo-grp;
+    uses foo-imp-grp;
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/foo-imp.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/foo-imp.yang
new file mode 100644 (file)
index 0000000..e524961
--- /dev/null
@@ -0,0 +1,11 @@
+module foo-imp {
+    namespace "foo-imp";
+    prefix foo-imp;
+
+    revision 2016-07-19;
+
+    grouping foo-imp-grp {
+        container foo-imp-grp-con {
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/foo.yang
new file mode 100644 (file)
index 0000000..7fe73c4
--- /dev/null
@@ -0,0 +1,15 @@
+module foo {
+    namespace "foo";
+    prefix foo;
+
+    include sub-foo {
+        revision-date 2016-07-19;
+    }
+
+    revision 2016-07-19;
+    
+    grouping foo-grp {
+        container foo-grp-con {
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/sub-foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug6240/incorrect/sub-foo.yang
new file mode 100644 (file)
index 0000000..d3e858b
--- /dev/null
@@ -0,0 +1,12 @@
+submodule sub-foo {
+    belongs-to foo {
+        prefix foo;
+    }
+
+    revision 2016-07-19;
+
+    grouping sub-foo-grp {
+        container sub-foo-grp-con {
+        }
+    }
+}