From: Robert Varga Date: Mon, 30 Dec 2019 08:11:16 +0000 (+0100) Subject: Add another alternative SchemaContextUtil.findDataSchemaNode() X-Git-Tag: v3.0.8~25 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=6b321f387f45d9a5850224d591d4edbb483eda9a;p=yangtools.git Add another alternative SchemaContextUtil.findDataSchemaNode() We have a number of call sites which are using the XPath variant of SchemaContextUtil.findDataSchemaNode() in context where the complexity is not warranted. Introduce utility methods to migrate those callers to a simplified version which takes resolved QNames (but does not use SchemaPath), reducing proliferation of PathExpressionImpl. JIRA: YANGTOOLS-1060 Change-Id: Id645563733af448f42ecdc62b26205c1a97a2216 Signed-off-by: Robert Varga (cherry picked from commit 0c48f313a0e06974816cf0d114a83ad1139219b4) --- diff --git a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java index a8323182f6..93fc7dd3ed 100644 --- a/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java +++ b/yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java @@ -18,6 +18,7 @@ import com.google.common.base.Splitter; import com.google.common.collect.Iterables; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Arrays; import java.util.Deque; import java.util.HashSet; import java.util.Iterator; @@ -25,6 +26,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.common.AbstractQName; @@ -84,20 +86,17 @@ public final class SchemaContextUtil { } /** - * Method attempts to find DataSchemaNode in Schema Context via specified - * Schema Path. The returned DataSchemaNode from method will be the node at - * the end of the SchemaPath. If the DataSchemaNode is not present in the - * Schema Context the method will return null.
- * In case that Schema Context or Schema Path are not specified correctly - * (i.e. contains null values) the method will throw - * IllegalArgumentException. + * Method attempts to find DataSchemaNode in Schema Context via specified Schema Path. The returned DataSchemaNode + * from method will be the node at the end of the SchemaPath. If the DataSchemaNode is not present in the Schema + * Context the method will return {@code null}. * - * @param context - * Schema Context - * @param schemaPath - * Schema Path to search for - * @return SchemaNode from the end of the Schema Path or null - * if the Node is not present. + *

+ * In case that Schema Context or Schema Path are not specified correctly (i.e. contains {@code null} values) the + * method will throw IllegalArgumentException. + * + * @param context Schema Context + * @param schemaPath Schema Path to search for + * @return SchemaNode from the end of the Schema Path or {@code null} if the Node is not present. * @throws NullPointerException if context or schemaPath is null */ public static SchemaNode findDataSchemaNode(final SchemaContext context, final SchemaPath schemaPath) { @@ -111,6 +110,35 @@ public final class SchemaContextUtil { return findNodeInSchemaContext(context, prefixedPath); } + /** + * Attempt to find a DataSchemaNode based on its path from root, similar to + * {@link #findDataSchemaNode(SchemaContext, Module, PathExpression)} without requiring an expression. + * + * @param context Schema Context + * @param path Path to search for + * @return SchemaNode from the end of the Schema Path or {@code null} if the Node is not present. + * @throws NullPointerException if a any argument is null or if the path contains a null element + */ + @Beta + public static SchemaNode findDataSchemaNode(final SchemaContext context, final List path) { + return findTargetNode(context, null, YangLocationPath.absolute( + path.stream().map(YangXPathAxis.CHILD::asStep).collect(Collectors.toList()))); + } + + /** + * Attempt to find a DataSchemaNode based on its path from root, similar to + * {@link #findDataSchemaNode(SchemaContext, Module, PathExpression)} without requiring an expression. + * + * @param context Schema Context + * @param path Path to search for + * @return SchemaNode from the end of the Schema Path or {@code null} if the Node is not present. + * @throws NullPointerException if a any argument is null or if the path contains a null element + */ + @Beta + public static SchemaNode findDataSchemaNode(final SchemaContext context, final QName... path) { + return findDataSchemaNode(context, Arrays.asList(path)); + } + /** * Method attempts to find DataSchemaNode inside of provided Schema Context * and Yang Module accordingly to Non-conditional Revision Aware XPath. The @@ -209,7 +237,7 @@ public final class SchemaContextUtil { // // which would then be passed in to a method similar to this one. In static contexts, like MD-SAL codegen, // that feels like an overkill. - // FIXME: YANGTOOLS-1052: this is a static analysis util, move it to yang-model-sa + // FIXME: YANGTOOLS-1052: this is a static analysis util, move it to a dedicated class public static SchemaNode findDataSchemaNodeForRelativeXPath(final SchemaContext context, final Module module, final SchemaNode actualSchemaNode, final PathExpression relativeXPath) { checkState(!relativeXPath.isAbsolute(), "Revision Aware XPath MUST be relative i.e. MUST contains ../, " @@ -655,7 +683,7 @@ public final class SchemaContextUtil { LOG.debug("Derefencing path {}", targetPath); final SchemaNode deref = targetPath.isAbsolute() - ? findTargetNode(context, actualSchemaNode, + ? findTargetNode(context, actualSchemaNode.getQName().getModule(), ((LocationPathSteps) targetPath.getSteps()).getLocationPath()) : findDataSchemaNodeForRelativeXPath(context, module, actualSchemaNode, targetPath); if (deref == null) { @@ -669,9 +697,8 @@ public final class SchemaContextUtil { return findTargetNode(context, resolveRelativePath(context, module, deref, qnames)); } - private static @Nullable SchemaNode findTargetNode(final SchemaContext context, final SchemaNode actualSchemaNode, + private static @Nullable SchemaNode findTargetNode(final SchemaContext context, final QNameModule defaultModule, final YangLocationPath path) { - final QNameModule defaultModule = actualSchemaNode.getQName().getModule(); final Deque ret = new ArrayDeque<>(); for (Step step : path.getSteps()) { if (step instanceof AxisStep) { diff --git a/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtilTest.java b/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtilTest.java index 8aa887641e..b47e541232 100644 --- a/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtilTest.java +++ b/yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtilTest.java @@ -131,7 +131,7 @@ public class SchemaContextUtilTest { @Test(expected = NullPointerException.class) public void findDataSchemaNodeIllegalArgumentTest() { - SchemaContextUtil.findDataSchemaNode(mock(SchemaContext.class), null); + SchemaContextUtil.findDataSchemaNode(mock(SchemaContext.class), (SchemaPath) null); } @Test(expected = NullPointerException.class) diff --git a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/openconfigver/OpenconfigVersionComplexTest.java b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/openconfigver/OpenconfigVersionComplexTest.java index 1c047dd361..3ebbcb0c88 100644 --- a/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/openconfigver/OpenconfigVersionComplexTest.java +++ b/yang/yang-parser-rfc7950/src/test/java/org/opendaylight/yangtools/yang/stmt/openconfigver/OpenconfigVersionComplexTest.java @@ -14,10 +14,10 @@ import static org.junit.Assert.assertNull; import java.net.URI; import org.junit.Test; import org.opendaylight.yangtools.concepts.SemVer; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; -import org.opendaylight.yangtools.yang.model.util.PathExpressionImpl; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.opendaylight.yangtools.yang.stmt.StmtTestUtils; @@ -55,18 +55,22 @@ public class OpenconfigVersionComplexTest { assertEquals(SemVer.valueOf("2.26.465"), foobar.getSemanticVersion().get()); // check imported components - assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, foo, - new PathExpressionImpl("/bar:root/bar:test-container/bar:number", true))); + assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(bar.getQNameModule(), "root"), + QName.create(bar.getQNameModule(), "test-container"), + QName.create(bar.getQNameModule(), "number"))); - assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, foo, - new PathExpressionImpl("/bar:should-present", true))); + assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(bar.getQNameModule(), "should-present"))); // check not imported components - assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, foo, - new PathExpressionImpl("/bar:root/bar:test-container/bar:oldnumber", true))); + assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(bar.getQNameModule(), "root"), + QName.create(bar.getQNameModule(), "test-container"), + QName.create(bar.getQNameModule(), "oldnumber"))); - assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, foo, - new PathExpressionImpl("/bar:should-not-be-present", true))); + assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(bar.getQNameModule(), "should-not-be-present"))); } @Test @@ -101,26 +105,33 @@ public class OpenconfigVersionComplexTest { assertEquals(SemVer.valueOf("7.13.99"), foobar.getSemanticVersion().get()); // check used augmentations - assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, bar, - new PathExpressionImpl("/foobar:root/foobar:test-container/bar:should-present-leaf-1", true))); + assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(foobar.getQNameModule(), "root"), + QName.create(foobar.getQNameModule(), "test-container"), + QName.create(bar.getQNameModule(), "should-present-leaf-1"))); - assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, bar, - new PathExpressionImpl("/foobar:root/foobar:test-container/bar:should-present-leaf-2", true))); + assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(foobar.getQNameModule(), "root"), + QName.create(foobar.getQNameModule(), "test-container"), + QName.create(bar.getQNameModule(), "should-present-leaf-2"))); // check not used augmentations - assertNull("This component should not be present", - SchemaContextUtil.findDataSchemaNode(context, bar, new PathExpressionImpl( - "/foobar:root/foobar:test-container/bar:should-not-be-present-leaf-1", true))); - - assertNull("This component should not be present", - SchemaContextUtil.findDataSchemaNode(context, bar, new PathExpressionImpl( - "/foobar:root/foobar:test-container/bar:should-not-be-present-leaf-2", true))); + assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(foobar.getQNameModule(), "root"), + QName.create(foobar.getQNameModule(), "test-container"), + QName.create(bar.getQNameModule(), "should-not-be-present-leaf-1"))); + assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(foobar.getQNameModule(), "root"), + QName.create(foobar.getQNameModule(), "test-container"), + QName.create(bar.getQNameModule(), "should-not-be-present-leaf-2"))); // check if correct foobar module was included - assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, bar, - new PathExpressionImpl("/foobar:root/foobar:included-correct-mark", true))); + assertNotNull("This component should be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(foobar.getQNameModule(), "root"), + QName.create(foobar.getQNameModule(), "included-correct-mark"))); - assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, bar, - new PathExpressionImpl("/foobar:root/foobar:included-not-correct-mark", true))); + assertNull("This component should not be present", SchemaContextUtil.findDataSchemaNode(context, + QName.create(foobar.getQNameModule(), "root"), + QName.create(foobar.getQNameModule(), "included-not-correct-mark"))); } }