Do not use SchemaNodeIdentifierBuildNamespace prerequisites 16/75516/1
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 12 Jul 2018 09:26:35 +0000 (11:26 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 27 Aug 2018 23:50:11 +0000 (01:50 +0200)
Incremental lookups on ChildSchemaNodeNamespace allow us to react
to childen being created, hence we do not have an assumption that
the target node must be instantiated by someone else (like eager
instantiation).

This will also allow us better recovery if the target node is not
going to appear due to being disabled by if-feature.

JIRA: YANGTOOLS-694
Change-Id: Ibc05e18037bb85d42ed7123293e7f83f896aad5d
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 509988128ed9d5fe314a14906114f53778200e47)

yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/namespace/ChildSchemaNodeNamespace.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/namespace/SchemaNodeIdentifierBuildNamespace.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/augment/AbstractAugmentStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/deviate/AbstractDeviateStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesStatementImpl.java

index 7685e93cf2ad342cd5b7c747363f46c0fdbb5692..7968cd4a6d958b604eae77d047e2338dfaee66e1 100644 (file)
@@ -8,14 +8,21 @@
 package org.opendaylight.yangtools.yang.parser.rfc7950.namespace;
 
 import com.google.common.annotations.Beta;
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.common.QName;
 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.stmt.SchemaNodeIdentifier;
+import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 /**
@@ -61,6 +68,54 @@ public final class ChildSchemaNodeNamespace<D extends DeclaredStatement<QName>,
         }
     }
 
+    /**
+     * Find statement context identified by interpreting specified {@link SchemaNodeIdentifier} starting at specified
+     * {@link StmtContext}.
+     *
+     * @param root Search root context
+     * @param identifier {@link SchemaNodeIdentifier} relative to search root
+     * @return Matching statement context, if present.
+     * @throws NullPointerException if any of the arguments is null
+     */
+    public static Optional<StmtContext<?, ?, ?>> findNode(final StmtContext<?, ?, ?> root,
+            final SchemaNodeIdentifier identifier) {
+        final Iterator<QName> iterator = identifier.getPathFromRoot().iterator();
+        if (!iterator.hasNext()) {
+            return Optional.of((Mutable<?, ?, EffectiveStatement<?, ?>>) root);
+        }
+
+        QName nextPath = iterator.next();
+        Mutable<?, ?, EffectiveStatement<?, ?>> current = root.getFromNamespace(ChildSchemaNodeNamespace.class,
+            nextPath);
+        if (current == null) {
+            return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(),
+                (Mutable<?, ?, EffectiveStatement<?, ?>>) root));
+        }
+        while (current != null && iterator.hasNext()) {
+            nextPath = iterator.next();
+            final Mutable<?, ?, EffectiveStatement<?, ?>> nextNodeCtx = current.getFromNamespace(
+                ChildSchemaNodeNamespace.class,nextPath);
+            if (nextNodeCtx == null) {
+                return Optional.ofNullable(tryToFindUnknownStatement(nextPath.getLocalName(), current));
+            }
+            current = nextNodeCtx;
+        }
+        return Optional.ofNullable(current);
+    }
+
+    @SuppressWarnings("unchecked")
+    static Mutable<?, ?, EffectiveStatement<?, ?>> tryToFindUnknownStatement(final String localName,
+            final Mutable<?, ?, EffectiveStatement<?, ?>> current) {
+        final Collection<? extends StmtContext<?, ?, ?>> unknownSubstatements = StmtContextUtils.findAllSubstatements(
+            current, UnknownStatement.class);
+        for (final StmtContext<?, ?, ?> unknownSubstatement : unknownSubstatements) {
+            if (localName.equals(unknownSubstatement.rawStatementArgument())) {
+                return (Mutable<?, ?, EffectiveStatement<?, ?>>) unknownSubstatement;
+            }
+        }
+        return null;
+    }
+
     private static NamespaceStorageNode globalOrStatementSpecific(final NamespaceStorageNode storage) {
         NamespaceStorageNode current = storage;
         while (!isLocalOrGlobal(current.getStorageNodeType())) {
index c26b9f7403c7a64c0b7b6d835debede513b8c566..708fb016981a57790aafe0197272007ca001c1fa 100644 (file)
@@ -7,10 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.namespace;
 
-import static java.util.Objects.requireNonNull;
-
 import com.google.common.annotations.Beta;
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.Optional;
 import javax.annotation.Nonnull;
@@ -18,14 +15,18 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
-import org.opendaylight.yangtools.yang.model.api.stmt.UnknownStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 
+/**
+ * Legacy namespace for looking up nodes by their Schema Tree identifier.
+ *
+ * @deprecated Use path-based utilities provided around {@link ChildSchemaNodeNamespace} instead.
+ */
 @Beta
+@Deprecated
 public final class SchemaNodeIdentifierBuildNamespace
         extends DerivedNamespaceBehaviour<SchemaNodeIdentifier, Mutable<?, ?, EffectiveStatement<?, ?>>, QName,
                 SchemaNodeIdentifierBuildNamespace, ChildSchemaNodeNamespace<?, ?>>
@@ -44,11 +45,12 @@ public final class SchemaNodeIdentifierBuildNamespace
      * @param identifier {@link SchemaNodeIdentifier} relative to search root
      * @return Matching statement context, if present.
      * @throws NullPointerException if any of the arguments is null
+     * @deprecated Use {@link ChildSchemaNodeNamespace#findNode(StmtContext, SchemaNodeIdentifier)} instead.
      */
+    @Deprecated
     public static Optional<StmtContext<?, ?, ?>> findNode(final StmtContext<?, ?, ?> root,
             final SchemaNodeIdentifier identifier) {
-        return Optional.ofNullable(root.getFromNamespace(SchemaNodeIdentifierBuildNamespace.class,
-            requireNonNull(identifier)));
+        return ChildSchemaNodeNamespace.findNode(root, identifier);
     }
 
     @Override
@@ -77,7 +79,7 @@ public final class SchemaNodeIdentifierBuildNamespace
         Mutable<?, ?, EffectiveStatement<?, ?>> current = lookupStartStorage.getFromLocalStorage(
             ChildSchemaNodeNamespace.class,nextPath);
         if (current == null && lookupStartStorage instanceof StmtContext<?, ?, ?>) {
-            return tryToFindUnknownStatement(nextPath.getLocalName(),
+            return ChildSchemaNodeNamespace.tryToFindUnknownStatement(nextPath.getLocalName(),
                 (Mutable<?, ?, EffectiveStatement<?, ?>>) lookupStartStorage);
         }
         while (current != null && iterator.hasNext()) {
@@ -85,26 +87,13 @@ public final class SchemaNodeIdentifierBuildNamespace
             final Mutable<?, ?, EffectiveStatement<?, ?>> nextNodeCtx = current.getFromNamespace(
                 ChildSchemaNodeNamespace.class,nextPath);
             if (nextNodeCtx == null) {
-                return tryToFindUnknownStatement(nextPath.getLocalName(), current);
+                return ChildSchemaNodeNamespace.tryToFindUnknownStatement(nextPath.getLocalName(), current);
             }
             current = nextNodeCtx;
         }
         return current;
     }
 
-    @SuppressWarnings("unchecked")
-    private static Mutable<?, ?, EffectiveStatement<?, ?>> tryToFindUnknownStatement(final String localName,
-            final Mutable<?, ?, EffectiveStatement<?, ?>> current) {
-        final Collection<? extends StmtContext<?, ?, ?>> unknownSubstatements = StmtContextUtils.findAllSubstatements(
-            current, UnknownStatement.class);
-        for (final StmtContext<?, ?, ?> unknownSubstatement : unknownSubstatements) {
-            if (localName.equals(unknownSubstatement.rawStatementArgument())) {
-                return (Mutable<?, ?, EffectiveStatement<?, ?>>) unknownSubstatement;
-            }
-        }
-        return null;
-    }
-
     @Override
     public QName getSignificantKey(final SchemaNodeIdentifier key) {
         return key.getLastComponent();
index d4e5881171cc028daee11c9567b3512bc4ea364c..18093dc432d9bf111c5e698d4357683d3e638f03 100644 (file)
@@ -24,7 +24,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.DataDefinitionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.SchemaNodeIdentifierBuildNamespace;
+import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.ArgumentUtils;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
@@ -95,8 +95,8 @@ abstract class AbstractAugmentStatementSupport extends AbstractStatementSupport<
             EffectiveStatement<SchemaNodeIdentifier, AugmentStatement>>> sourceCtxPrereq =
                 augmentAction.requiresCtx(augmentNode, ModelProcessingPhase.EFFECTIVE_MODEL);
         final Prerequisite<Mutable<?, ?, EffectiveStatement<?, ?>>> target =
-                augmentAction.mutatesEffectiveCtx(getSearchRoot(augmentNode),
-                    SchemaNodeIdentifierBuildNamespace.class, augmentNode.getStatementArgument());
+                augmentAction.mutatesEffectiveCtxPath(getSearchRoot(augmentNode),
+                    ChildSchemaNodeNamespace.class, augmentNode.getStatementArgument().getPathFromRoot());
 
         augmentAction.apply(new ModelActionBuilder.InferenceAction() {
             @Override
@@ -147,7 +147,7 @@ abstract class AbstractAugmentStatementSupport extends AbstractStatementSupport<
                  * Do not fail, if it is an uses-augment to an unknown node.
                  */
                 if (YangStmtMapping.USES == augmentNode.getParentContext().getPublicDefinition()) {
-                    final Optional<StmtContext<?, ?, ?>> targetNode = SchemaNodeIdentifierBuildNamespace.findNode(
+                    final Optional<StmtContext<?, ?, ?>> targetNode = ChildSchemaNodeNamespace.findNode(
                         getSearchRoot(augmentNode), augmentNode.getStatementArgument());
                     if (targetNode.isPresent() && StmtContextUtils.isUnknownStatement(targetNode.get())) {
                         augmentNode.setIsSupportedToBuildEffective(false);
index 0ba89b617454f8fa7d19df9f6fc206e16587a3b9..02bf56941344e1459d1019f2327708f631daccc7 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.DeviateStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
-import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.SchemaNodeIdentifierBuildNamespace;
+import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace;
 import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.YangValidationBundles;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
@@ -143,8 +143,8 @@ abstract class AbstractDeviateStatementSupport extends AbstractStatementSupport<
                 deviateAction.requiresCtx(deviateStmtCtx, ModelProcessingPhase.EFFECTIVE_MODEL);
 
         final Prerequisite<Mutable<?, ?, EffectiveStatement<?, ?>>> targetCtxPrerequisite =
-                deviateAction.mutatesEffectiveCtx(deviateStmtCtx.getRoot(),
-                    SchemaNodeIdentifierBuildNamespace.class,  deviationTarget);
+                deviateAction.mutatesEffectiveCtxPath(deviateStmtCtx.getRoot(),
+                    ChildSchemaNodeNamespace.class, deviationTarget.getPathFromRoot());
 
         deviateAction.apply(new InferenceAction() {
             @Override
index 1357a5754e05f4a23dc6ec8c7db8fb8ca54c51d2..3a6cab552bbccc76dd8ca66b09dedc24692e58f5 100644 (file)
@@ -22,7 +22,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.SchemaNodeIdentifierBuildNamespace;
+import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace;
 import org.opendaylight.yangtools.yang.parser.rfc7950.reactor.YangValidationBundles;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
@@ -145,7 +145,7 @@ final class UsesStatementImpl extends AbstractDeclaredStatement<QName> implement
             subStmtCtx.getStatementSourceReference(),
             "Invalid refine argument %s. It must be instance of SchemaNodeIdentifier.", refineArgument);
 
-        final Optional<StmtContext<?, ?, ?>> optRefineTargetCtx = SchemaNodeIdentifierBuildNamespace.findNode(
+        final Optional<StmtContext<?, ?, ?>> optRefineTargetCtx = ChildSchemaNodeNamespace.findNode(
             usesParentCtx, (SchemaNodeIdentifier) refineArgument);
         InferenceException.throwIf(!optRefineTargetCtx.isPresent(), subStmtCtx.getStatementSourceReference(),
             "Refine target node %s not found.", refineArgument);