From d417276b1c26ab5029b381657fd0be810970e572 Mon Sep 17 00:00:00 2001 From: Peter Kajsa Date: Wed, 2 Sep 2015 13:49:20 +0200 Subject: [PATCH] Bug4231 - Yang tools failing to parse Augmentations under "uses" clause. The problem occurs when uses-augment is nested in another Augment statement. In this case the parent node of uses node is not subclass of SchemaNode but it is AugmentationSchemaNode (it is not subclass of SchemaNode) and in consequence class cast exception occurs. Change-Id: I674392889e561f357297fa220051e8c3728f537d Signed-off-by: Peter Kajsa --- .../parser/builder/impl/BuilderUtils.java | 35 ++++++++++++++ .../yang/parser/impl/YangParserImpl.java | 6 +-- .../yang/parser/impl/Bug4231Test.java | 48 +++++++++++++++++++ .../yangtools/yang/parser/impl/TestUtils.java | 12 +++-- .../src/test/resources/bugs/bug4231/foo.yang | 38 +++++++++++++++ 5 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug4231Test.java create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug4231/foo.yang diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java index 3a17fdeda5..1c202f6100 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java @@ -344,6 +344,41 @@ public final class BuilderUtils { } } + /** + * Find builder of schema node under parent builder (including under + * AugmentationSchemaBuilder). + * + * @param path + * - path of target schema node builder + * @param parent + * - base data node container builder under which the target + * schema node builder should be found + * @return builder of schema node + */ + public static SchemaNodeBuilder findTargetNode(final Iterable path, + final DataNodeContainerBuilder parent) { + + Preconditions.checkNotNull(parent); + Preconditions.checkNotNull(path); + + SchemaNodeBuilder foundNode = null; + + final Iterator pathIterator = path.iterator(); + if (pathIterator.hasNext()) { + String name = pathIterator.next().getLocalName(); + foundNode = parent.getDataChildByName(name); + if (foundNode == null) { + foundNode = findUnknownNode(name, parent); + } + } + + if (pathIterator.hasNext() && foundNode != null) { + return findSchemaNode(Iterables.skip(path, 1), foundNode); + } else { + return foundNode; + } + } + public static SchemaNodeBuilder findSchemaNode(final Iterable path, final SchemaNodeBuilder parentNode) { SchemaNodeBuilder node = null; SchemaNodeBuilder parent = parentNode; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java index 25abb54e83..1aafe20ae4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java @@ -11,8 +11,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.fillAugmentTarget; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findBaseIdentity; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findModuleFromContext; -import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNode; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findSchemaNodeInModule; +import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.findTargetNode; import static org.opendaylight.yangtools.yang.parser.builder.impl.BuilderUtils.processAugmentation; import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveType; import static org.opendaylight.yangtools.yang.parser.builder.impl.TypeUtils.resolveTypeUnion; @@ -957,8 +957,8 @@ public final class YangParserImpl implements YangContextParser { // Conflicting elements in other namespaces are still not present // since resolveUsesAugment occurs before augmenting from external // modules. - potentialTargetNode = Optional. fromNullable(findSchemaNode(augment.getTargetPath() - .getPathFromRoot(), (SchemaNodeBuilder) parentNode)); + potentialTargetNode = Optional. fromNullable(findTargetNode(augment.getTargetPath() + .getPathFromRoot(), parentNode)); } if (potentialTargetNode.isPresent()) { diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug4231Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug4231Test.java new file mode 100644 index 0000000000..1f7ec433a0 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/Bug4231Test.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 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.*; + +import java.text.ParseException; + +import java.net.URI; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; +import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.SchemaPath; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; +import java.io.IOException; +import java.net.URISyntaxException; +import org.junit.Test; + +public class Bug4231Test { + + @Test + public void test() throws IOException, URISyntaxException, ParseException { + SchemaContext context = TestUtils.loadSchemaContext(getClass() + .getResource("/bugs/bug4231").toURI()); + + assertNotNull(context); + + QNameModule foo = QNameModule.create(new URI("foo"), + SimpleDateFormatUtil.getRevisionFormat().parse("2015-09-02")); + + SchemaPath targetPath = SchemaPath + .create(true, QName.create(foo, "augment-target")) + .createChild(QName.create(foo, "my-container-in-grouping")) + .createChild(QName.create(foo, "l2")); + + SchemaNode targetNode = SchemaContextUtil.findNodeInSchemaContext( + context, targetPath.getPathFromRoot()); + assertNotNull(targetNode); + } + +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java index dbf74387ce..dcbaa85a06 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/TestUtils.java @@ -46,8 +46,8 @@ final class TestUtils { private TestUtils() { } - - public static Set loadModules(final URI resourceDirectory) throws IOException { + public static SchemaContext loadSchemaContext(final URI resourceDirectory) + throws IOException { final YangContextParser parser = new YangParserImpl(); final File testDir = new File(resourceDirectory); final String[] fileList = testDir.list(); @@ -58,8 +58,12 @@ final class TestUtils { for (String fileName : fileList) { testFiles.add(new File(testDir, fileName)); } - SchemaContext ctx = parser.parseFiles(testFiles); - return ctx.getModules(); + return parser.parseFiles(testFiles); + } + + public static Set loadModules(final URI resourceDirectory) + throws IOException { + return loadSchemaContext(resourceDirectory).getModules(); } public static Set loadModules(final List input) throws IOException, YangSyntaxErrorException { diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug4231/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug4231/foo.yang new file mode 100644 index 0000000000..d994c037ef --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug4231/foo.yang @@ -0,0 +1,38 @@ +module foo { + namespace "foo"; + prefix "foo"; + yang-version 1; + + revision 2015-09-02 { + description "Test"; + } + + grouping my-grouping { + container my-container-in-grouping { + } + } + + augment /augment-target { + uses my-grouping { + augment my-container-in-grouping { + leaf-list l2 { + type string; + ordered-by "user"; + foo:bar "argument"; + foo:baz "$X(/a/a/a/@@)"; + } + } + } + } + + container augment-target { + } + + extension bar { + argument "arg"; + } + + extension baz { + argument "arg"; + } +} -- 2.36.6