Fix path namespace resolution 21/87021/1
authormiroslav.kovac <miroslav.kovac@pantheon.tech>
Mon, 16 Dec 2019 15:57:22 +0000 (16:57 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 17 Jan 2020 06:57:00 +0000 (07:57 +0100)
If a path is defined in terms of a submodule-local import,
SchemaContextUtil.findDataSchemaNode() breaks down because
it's reparse attempt fails to find the import in the actual
module.

SchemaContextUtil is providing findDataTreeSchemaNode() which
works properly on parsed PathExpression, use that instead.

JIRA: MDSAL-499
Change-Id: Ifa8a8958d7118d851d27fcc2c70c6d8382e3e3c0
Signed-off-by: miroslav.kovac <miroslav.kovac@pantheon.tech>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/yang/types/AbstractTypeProvider.java
binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal499Test.java [new file with mode: 0644]
binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/child.yang [new file with mode: 0644]
binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/imported.yang [new file with mode: 0644]
binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/parent.yang [new file with mode: 0644]

index 4f422cb04e817e90be95aef9fed4b0461eec98b8..ce3f1f6d173e383b2ae4ff746bc488e9f95807ff 100644 (file)
@@ -9,8 +9,8 @@ package org.opendaylight.mdsal.binding.yang.types;
 
 import static java.util.Objects.requireNonNull;
 import static org.opendaylight.mdsal.binding.model.util.BindingTypes.TYPE_OBJECT;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataTreeSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
 
 import com.google.common.annotations.Beta;
@@ -269,16 +269,17 @@ public abstract class AbstractTypeProvider implements TypeProvider {
 
         // Then try to look up the expression.
         final PathExpression leafRefXPath = leafref.getPathStatement();
-        final PathExpression leafRefStrippedXPath = new PathExpressionImpl(
-            GROUPS_PATTERN.matcher(leafRefXPath.getOriginalString()).replaceAll(""), leafRefXPath.isAbsolute());
         final Module parentModule = getParentModule(parentNode);
         final SchemaNode leafRefValueNode;
-        if (!leafRefStrippedXPath.isAbsolute()) {
-            leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
-                    parentNode, leafRefStrippedXPath);
+        if (leafRefXPath.isAbsolute()) {
+            leafRefValueNode = SchemaContextUtil.findDataTreeSchemaNode(schemaContext, parentModule.getQNameModule(),
+                leafRefXPath);
         } else {
-            leafRefValueNode = SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, leafRefStrippedXPath);
+            leafRefValueNode = SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule,
+                parentNode, new PathExpressionImpl(
+                    GROUPS_PATTERN.matcher(leafRefXPath.getOriginalString()).replaceAll(""), false));
         }
+
         return leafRefValueNode != null && leafRefValueNode.equals(parentNode);
     }
 
@@ -513,7 +514,7 @@ public abstract class AbstractTypeProvider implements TypeProvider {
 
         final SchemaNode dataNode;
         if (xpath.isAbsolute()) {
-            dataNode = findDataSchemaNode(schemaContext, module, xpath);
+            dataNode = findDataTreeSchemaNode(schemaContext, module.getQNameModule(), xpath);
         } else {
             dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
             if (dataNode == null && inGrouping) {
@@ -1531,7 +1532,7 @@ public abstract class AbstractTypeProvider implements TypeProvider {
                 if (module != null) {
                     final SchemaNode dataNode;
                     if (xpath.isAbsolute()) {
-                        dataNode = findDataSchemaNode(schemaContext, module, xpath);
+                        dataNode = findDataTreeSchemaNode(schemaContext, module.getQNameModule(), xpath);
                     } else {
                         dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
                     }
diff --git a/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal499Test.java b/binding/mdsal-binding-generator-impl/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal499Test.java
new file mode 100644 (file)
index 0000000..a60c918
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019 PANTHEON.tech, s.r.o. 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.mdsal.binding.generator.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.model.api.Type;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public class Mdsal499Test {
+
+    @Test
+    public void testSubmoduleImport() {
+        SchemaContext context = YangParserTestUtils.parseYangResourceDirectory("/mdsal-499");
+
+        List<Type> generateTypes = new BindingGeneratorImpl().generateTypes(context);
+        assertNotNull(generateTypes);
+        assertEquals(5, generateTypes.size());
+    }
+}
diff --git a/binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/child.yang b/binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/child.yang
new file mode 100644 (file)
index 0000000..4240bf4
--- /dev/null
@@ -0,0 +1,20 @@
+submodule child {
+  belongs-to parent {
+    prefix par;
+  }
+
+  import imported {
+    prefix imp;
+  }
+
+  container cont {
+    leaf leaf1 {
+      type leafref {
+        path "/imp:root/imp:leaf1";
+      }
+    }
+    leaf leaf2 {
+      type imp:foo;
+    }
+  }
+}
diff --git a/binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/imported.yang b/binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/imported.yang
new file mode 100644 (file)
index 0000000..e8681ff
--- /dev/null
@@ -0,0 +1,16 @@
+module imported {
+  namespace "http://foo/bar/yang/imported";
+  prefix imp;
+
+  typedef foo {
+    type string {
+      pattern 'S(\d+G)?(\d+M)?';
+    }
+  }
+
+  container root {
+    leaf leaf1 {
+      type string;
+    }
+  }
+}
diff --git a/binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/parent.yang b/binding/mdsal-binding-generator-impl/src/test/resources/mdsal-499/parent.yang
new file mode 100644 (file)
index 0000000..41334d9
--- /dev/null
@@ -0,0 +1,6 @@
+module parent {
+  namespace "https://foo/bar/parent";
+  prefix par;
+
+  include child;
+}