Add support for incremental Prerequisites 71/73971/3
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 12 Jul 2018 09:14:45 +0000 (11:14 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 12 Jul 2018 10:35:44 +0000 (12:35 +0200)
We really need a method which would allow us to follow a path,
hooking incrementally to each of the elements as they appear.

This patch adds the mechanics to support that lookup, rendering
SchemaNodeIdentifierBuildNamespace largely superfluous, as we
can perform equivalent lookups on ChildSchemaNodeNamespace.

JIRA: YANGTOOLS-859
Change-Id: I7dae9559555ee6ddc95faf1f874cebac9f915c1b
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/ModifierImpl.java
yang/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java

index bf77d868050dcfb44e2a8e653dd8f447eb94eae0..3b7972b26fabc8891d8538bd1dfefcecb399b99f 100644 (file)
@@ -128,9 +128,7 @@ final class ModifierImpl implements ModelActionBuilder {
                     final K key, final ModelProcessingPhase phase) {
         checkNotRegistered();
 
-        PhaseModificationInNamespace<C> mod = new PhaseModificationInNamespace<>(phase);
-        addReq(mod);
-        addMutation(mod);
+        PhaseModificationInNamespace<C> mod = createModification(phase);
         contextImpl(context).onNamespaceItemAddedAction((Class) namespace, key, mod);
         return mod;
     }
@@ -246,6 +244,54 @@ final class ModifierImpl implements ModelActionBuilder {
         return mutatesCtxImpl(context, namespace, key, EFFECTIVE_MODEL);
     }
 
+    @Nonnull
+    @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
+            AbstractPrerequisite<Mutable<?, ?, E>> mutatesEffectiveCtxPath(final StmtContext<?, ?, ?> context,
+                    final Class<N> namespace, final Iterable<K> keys) {
+        final Iterator<K> it = keys.iterator();
+        Preconditions.checkArgument(it.hasNext(), "Namespace %s keys may not be empty", namespace);
+        checkNotRegistered();
+
+        final PhaseModificationInNamespace<Mutable<?, ?, E>> ret = createModification(EFFECTIVE_MODEL);
+        contextImpl(context).onNamespaceItemAddedAction((Class) namespace, it.next(),
+            (parent, ns, foundKey, foundValue) -> {
+                checkResult((Mutable<?, ?, E>)foundValue, namespace, it, ret);
+            });
+        return ret;
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    private <K, C extends Mutable<?, ?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
+            void mutateNextKey(final StmtContext<?, ?, ?> context, final Class<N> namespace,
+                    final Iterator<K> it, final AbstractPrerequisite<C> result) {
+        final PhaseModificationInNamespace<C> mod = createModification(EFFECTIVE_MODEL);
+        contextImpl(context).onNamespaceItemAddedAction((Class) namespace, it.next(),
+            (parent, ns, foundKey, foundValue) -> {
+                checkResult((C) foundValue, namespace, it, result);
+                mod.resolvePrereq((C) foundValue);
+            });
+    }
+
+    private <C extends Mutable<?, ?, ?>> PhaseModificationInNamespace<C> createModification(
+            final ModelProcessingPhase phase) {
+        final PhaseModificationInNamespace<C> ret = new PhaseModificationInNamespace<>(EFFECTIVE_MODEL);
+        addReq(ret);
+        addMutation(ret);
+        return ret;
+    }
+
+    private <K, C extends Mutable<?, ?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
+            void checkResult(final C context, final Class<N> namespace, final Iterator<K> it,
+                    final AbstractPrerequisite<C> result) {
+        if (it.hasNext()) {
+            mutateNextKey(context, namespace, it, result);
+        } else {
+            result.resolvePrereq(context);
+        }
+    }
+
     @Override
     @SuppressWarnings("checkstyle:hiddenField")
     public void apply(final InferenceAction action) {
index 08d01cb9f1b90247bab6edeef6b0ee541dae4554..2e674d02ef882332a545f2c83e9988179f39d4a9 100644 (file)
@@ -174,6 +174,12 @@ public interface ModelActionBuilder {
     @Nonnull <K, E extends EffectiveStatement<?, ?>, N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>>
         Prerequisite<Mutable<?, ?, E>> mutatesEffectiveCtx(StmtContext<?, ?, ?> context, Class<N> namespace, K key);
 
+    default @Nonnull <K, E extends EffectiveStatement<?, ?>,
+            N extends IdentifierNamespace<K, ? extends StmtContext<?, ?, ?>>> Prerequisite<Mutable<?, ?, E>>
+                mutatesEffectiveCtxPath(StmtContext<?, ?, ?> context, Class<N> namespace, Iterable<K> keys) {
+        throw new UnsupportedOperationException(getClass() + " does not implement mutatesEffectiveCtxPath()");
+    }
+
     /**
      * Action mutates the specified statement in the specified phase. Target statement cannot complete specified
      * phase before this action is applier.