Bugfix: Resolving of extension arguments. 08/9808/3
authorLukas Sedlak <lsedlak@cisco.com>
Fri, 8 Aug 2014 12:33:38 +0000 (14:33 +0200)
committerLukas Sedlak <lsedlak@cisco.com>
Wed, 13 Aug 2014 08:44:55 +0000 (10:44 +0200)
Fixed methods parseQName and handleUnknownNode in YangParserListenerImpl class. Now if extension contains ":"
as argument value and string before ":" doesn't represent prefix for import the argument will be parsed as ordinary
string and will not throw exception.
Log level in parseQName has been changed from warn to debug.

Tests in yang-parser-impl has been modified since they're lacked of import definitions of extensions in yang modules.

Change-Id: I84debed2bef1a0694a7019c296433b8b089e6d80
Signed-off-by: Lukas Sedlak <lsedlak@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserListenerImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug1412Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug1413Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/ParsingExtensionValueTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug1412/bug1412.yang
yang/yang-parser-impl/src/test/resources/bugs/bug1412/extensions.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug1413/bug1413.yang
yang/yang-parser-impl/src/test/resources/bugs/bug1413/extensions.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/extensions/ext-typedef.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/extensions/ext-use.yang [new file with mode: 0644]

index 417747a07ef0cfb8e14d0e0108dc8dd4ecb2cd05..f5071ede5b70bea4d1463a49cec757fa6dc6eeaf 100644 (file)
@@ -532,6 +532,20 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         }
     }
 
+    /**
+     * Method transforms string representation of yang element (i.e. leaf name, container name etc.) into QName.
+     * The namespace of QName is assigned from parent module same as revision date of module. If String qname parameter
+     * contains ":" the string is evaluated as prefix:name of element. In this case method will look into import map
+     * and extract correct ModuleImport. If such import is not present in import map the method will throw {@link YangParseException}
+     * <br>
+     * If ModuleImport is present but the value of namespace in ModuleImport is <code>null</code> the method wil throw {@link YangParseException}
+     *
+     * @param qnameString QName value as String
+     * @param line line in Yang model document where QName occur.
+     * @return transformed string qname parameter as QName structure.
+     *
+     * @throws YangParseException
+     */
     private QName parseQName(final String qnameString, final int line) {
         final QName qname;
         if (qnameString.indexOf(':') == -1) {
@@ -545,8 +559,9 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
             } else {
                 ModuleImport imp = moduleBuilder.getImport(prefix);
                 if (imp == null) {
-                    LOG.warn("Error in module {} at line {}: No import found with prefix {}", moduleName, line, prefix);
-                    return QName.create(name);
+                    LOG.debug("Error in module {} at line {}: No import found with prefix {}", moduleName, line, prefix);
+                    throw new YangParseException(moduleName, line, "Error in module " + moduleName
+                        + " No import found with prefix " + prefix + " not found.");
                 }
                 Date revision = imp.getRevision();
                 TreeMap<Date, URI> namespaces = namespaceContext.get(imp.getModuleName());
@@ -1121,6 +1136,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
 
         QName qname = null;
         try {
+            //FIXME: rewrite whole method to handle unknown nodes properly.
+            // This should be bugfix for bug https://bugs.opendaylight.org/show_bug.cgi?id=1539
+            // After this fix bug https://bugs.opendaylight.org/show_bug.cgi?id=1538 MUST be fixed since
+            // they are dependent!!!
             if (Strings.isNullOrEmpty(nodeParameter)) {
                 qname = nodeType;
             } else {
@@ -1132,7 +1151,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                     qname = QName.create(moduleQName, it.next());
                 }
             }
-        } catch (IllegalArgumentException e) {
+        } catch (IllegalArgumentException | YangParseException ex) {
             qname = nodeType;
         }
 
index da54e9488d41bbd358bb63e42527805ef428106d..1ff22d94549a2a93e8b3e6d18b04b7a523f4ea8f 100644 (file)
@@ -23,9 +23,9 @@ import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 
 /**
- * Test antlr grammar capability to parse description statement in unknown node.
+ * Test ANTLR4 grammar capability to parse description statement in unknown node.
  *
- * Not that everything under unknown node is unknown node.
+ * Note: Everything under unknown node is unknown node.
  */
 public class Bug1412Test {
 
@@ -42,8 +42,8 @@ public class Bug1412Test {
 
         Date revision = new SimpleDateFormat("yyyy-MM-dd").parse("2014-07-25");
         QNameModule qm = QNameModule.create(URI.create("urn:test:bug1412"), revision);
-        QName expectedNodeType = new QName(null, null, null, "action");
-        assertEquals(QName.create(null, (Date) null, "action"), action.getNodeType());
+        QName expectedNodeType = QName.create("urn:test:bug1412:ext:definitions", "2014-07-25", "action");
+        assertEquals(expectedNodeType, action.getNodeType());
         assertEquals("hello", action.getNodeParameter());
         QName expectedQName = QName.create(qm, "hello");
         assertEquals(expectedQName, action.getQName());
@@ -70,7 +70,7 @@ public class Bug1412Test {
         assertNotNull(actionPoint);
         assertNotNull(output);
 
-        expectedNodeType = new QName(null, null, null, "info");
+        expectedNodeType = QName.create("urn:test:bug1412:ext:definitions", "2014-07-25", "info");
         assertEquals(expectedNodeType, info.getNodeType());
         assertEquals("greeting", info.getNodeParameter());
 
@@ -78,7 +78,7 @@ public class Bug1412Test {
         assertEquals(expectedNodeType, description.getNodeType());
         assertEquals("say greeting", description.getNodeParameter());
 
-        expectedNodeType = new QName(null, null, null, "actionpoint");
+        expectedNodeType = QName.create("urn:test:bug1412:ext:definitions", "2014-07-25", "actionpoint");
         assertEquals(expectedNodeType, actionPoint.getNodeType());
         assertEquals("entry", actionPoint.getNodeParameter());
 
index 42414141d69a326ae639fe94a60d86c743ee4e55..e9f09bb0cd6531a506ecc531f509298d14dacb87 100644 (file)
@@ -18,10 +18,10 @@ import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
 /**
- * Test antlr grammar capability to parse unknown node in extension argument
+ * Test ANTLR4 grammar capability to parse unknown node in extension argument
  * declaration.
  *
- * Not that everything under unknown node is unknown node.
+ * Note: Everything under unknown node is unknown node.
  */
 public class Bug1413Test {
 
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/ParsingExtensionValueTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/ParsingExtensionValueTest.java
new file mode 100644 (file)
index 0000000..07b008d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 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.parser.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+/**
+ * Test for testing of extensions and their arguments.
+ *
+ * @author Lukas Sedlak <lsedlak@cisco.com>
+ */
+public class ParsingExtensionValueTest {
+
+    private Set<Module> modules;
+
+    @Before
+    public void init() throws Exception {
+        DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+        modules = TestUtils.loadModules(getClass().getResource("/extensions").toURI());
+        assertEquals(2, modules.size());
+    }
+
+    @Test
+    public void parsingExtensionArgsTest() {
+
+    }
+}
index 605cc46bb9c48664e153a7d7dbf70f8b77923da4..7a65967768657185f223acbcc3d21c234a0440a6 100644 (file)
@@ -3,6 +3,11 @@ module bug1412 {
     namespace "urn:test:bug1412";
     prefix "b1412";
 
+    import extensions {
+        prefix ext;
+        revision-date "2014-07-25";
+    }
+
     revision "2014-07-25" {
     }
 
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug1412/extensions.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug1412/extensions.yang
new file mode 100644 (file)
index 0000000..0a2c123
--- /dev/null
@@ -0,0 +1,28 @@
+module extensions {
+    yang-version 1;
+    namespace "urn:test:bug1412:ext:definitions";
+    prefix "ext";
+
+    revision "2014-07-25" {
+    }
+
+    extension action {
+        argument hello {
+
+        }
+    }
+
+    extension info {
+        argument string;
+    }
+
+    extension actionpoint {
+        argument entry {
+
+        }
+    }
+
+    extension internal {
+
+    }
+}
\ No newline at end of file
index b691ef867b1e61dc369e3a5514c9e7aac0d003c6..f2297f6e3aefd20771b52eae42676b8644c37f54 100644 (file)
@@ -3,9 +3,13 @@ module bug1413 {
     namespace "odl:test:bug1413";
     prefix "b1413";
 
-    revision "2014-07-25" {
+    import extensions {
+        prefix ext;
+        revision-date "2014-07-25";
     }
 
+    revision "2014-07-25" {
+    }
 
     extension info {
         argument text {
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug1413/extensions.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug1413/extensions.yang
new file mode 100644 (file)
index 0000000..679a113
--- /dev/null
@@ -0,0 +1,12 @@
+module extensions {
+    yang-version 1;
+    namespace "urn:test:bug1412:ext:definitions";
+    prefix "ext";
+
+    revision "2014-07-25" {
+    }
+
+    extension arg-type {
+
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/extensions/ext-typedef.yang b/yang/yang-parser-impl/src/test/resources/extensions/ext-typedef.yang
new file mode 100644 (file)
index 0000000..36046f8
--- /dev/null
@@ -0,0 +1,19 @@
+module ext-typedef {
+    yang-version 1;
+    namespace "urn:simple.extension.typedefs";
+    prefix "ext";
+
+    organization "opendaylight";
+    contact "http://www.opendaylight.org/";
+
+    description "Model for testing and resolving of extension typedefs.";
+
+    revision "2014-08-07" {
+        reference "Initial revision.";
+    }
+
+    extension simple-ext-w-arg {
+        argument "ext-arg";
+        description "Extension with single argument definition.";
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/extensions/ext-use.yang b/yang/yang-parser-impl/src/test/resources/extensions/ext-use.yang
new file mode 100644 (file)
index 0000000..f36fc15
--- /dev/null
@@ -0,0 +1,41 @@
+module ext-use {
+    yang-version 1;
+    namespace "urn:simple.extension.use";
+    prefix "ext-use";
+
+    import ext-typedef { prefix "ext"; }
+
+    organization "opendaylight";
+    contact "http://www.opendaylight.org/";
+
+    description "Model for testing of used extensions across model.";
+
+    revision "2014-08-07" {
+        reference "Initial revision.";
+    }
+
+    leaf value {
+      ext:simple-ext-w-arg "key:value";
+      type uint32;
+      description "value";
+    }
+
+    grouping inner-ext {
+        ext:simple-ext-w-arg "value:test";
+
+        leaf inner-value {
+          ext:simple-ext-w-arg "key:inner-value";
+          type uint32;
+          description "value";
+        }
+    }
+
+    container cont-ext {
+        ext:simple-ext-w-arg "value:test";
+
+        leaf inner-value {
+            ext:simple-ext-w-arg "value:test";
+            type string;
+        }
+    }
+}
\ No newline at end of file