Remove DerivedNamespaceBehaviour 80/105280/5
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 6 Apr 2023 14:42:35 +0000 (16:42 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 6 Apr 2023 15:13:37 +0000 (17:13 +0200)
DerivedNamespaceBehaviour is not used anywhere and is source of quite a
bit of head-scratching. Remove it, which allows is to solidify
NamespaceAccess to a great extent.

JIRA: YANGTOOLS-1502
Change-Id: Iba43d0f627d5df53f18e9ea4de79f0982b62d837
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BehaviourNamespaceAccess.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceAccess.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SimpleNamespaceContext.java [deleted file]
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java
parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/VirtualNamespaceContext.java [deleted file]
parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedNamespaceBehaviour.java [deleted file]

index 5575912e45a01b8ea75aaab4fcaf72957d5f9d32..367bd367b581727feb9a204e31a08b73540c2fe9 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.base.MoreObjects;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
@@ -21,45 +23,93 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
 /**
  * A {@link NamespaceAccess} backed by a {@link NamespaceBehaviour}. Also holds reference to {@link BuildGlobalContext}.
  */
-abstract class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> implements GlobalStorageAccess {
+final class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> implements GlobalStorageAccess {
     private final @NonNull AbstractNamespaceStorage globalContext;
     private final @NonNull NamespaceBehaviour<K, V> behaviour;
 
+    // FIXME: Change this to Multimap, once issue with modules is resolved.
+    private List<KeyedValueAddedListener<K>> listeners;
+    private List<PredicateValueAddedListener<K, V>> predicateListeners;
+
     BehaviourNamespaceAccess(final AbstractNamespaceStorage globalContext, final NamespaceBehaviour<K, V> behaviour) {
         this.globalContext = requireNonNull(globalContext);
         this.behaviour = requireNonNull(behaviour);
     }
 
     @Override
-    public final AbstractNamespaceStorage getGlobalStorage() {
+    public AbstractNamespaceStorage getGlobalStorage() {
         return globalContext;
     }
 
     @Override
-    final V valueFrom(final NamespaceStorage storage, final K key) {
+    V valueFrom(final NamespaceStorage storage, final K key) {
         return behaviour.getFrom(this, storage, key);
     }
 
     @Override
-    final void valueTo(final NamespaceStorage storage, final K key, final V value) {
+    void valueTo(final NamespaceStorage storage, final K key, final V value) {
         behaviour.addTo(this, storage, key, value);
-        onValueTo(storage, key, value);
-    }
 
-    abstract void onValueTo(NamespaceStorage storage, K key, V value);
+        if (listeners != null) {
+            final var toNotify = new ArrayList<KeyedValueAddedListener<K>>();
+            final var it = listeners.iterator();
+            while (it.hasNext()) {
+                final var listener = it.next();
+                if (listener.isRequestedValue(this, storage, value)) {
+                    it.remove();
+                    toNotify.add(listener);
+                }
+            }
+            for (var listener : toNotify) {
+                listener.onValueAdded(value);
+            }
+
+            if (listeners != null && listeners.isEmpty()) {
+                listeners = null;
+            }
+        }
+
+        if (predicateListeners != null) {
+            final var it = predicateListeners.iterator();
+            while (it.hasNext()) {
+                if (it.next().onValueAdded(key, value)) {
+                    it.remove();
+                }
+            }
+            if (predicateListeners != null && predicateListeners.isEmpty()) {
+                predicateListeners = null;
+            }
+        }
+    }
 
     @Override
-    final Map<K, V> allFrom(final NamespaceStorage storage) {
+    Map<K, V> allFrom(final NamespaceStorage storage) {
         return behaviour.getAllFrom(this, storage);
     }
 
     @Override
-    final Entry<K, V> entryFrom(final NamespaceStorage storage, final NamespaceKeyCriterion<K> criterion) {
+    Entry<K, V> entryFrom(final NamespaceStorage storage, final NamespaceKeyCriterion<K> criterion) {
         return behaviour.getFrom(this, storage, criterion);
     }
 
     @Override
-    public final String toString() {
+    void addListener(final KeyedValueAddedListener<K> listener) {
+        if (listeners == null) {
+            listeners = new ArrayList<>();
+        }
+        listeners.add(listener);
+    }
+
+    @Override
+    void addListener(final PredicateValueAddedListener<K, V> listener) {
+        if (predicateListeners == null) {
+            predicateListeners = new ArrayList<>();
+        }
+        predicateListeners.add(listener);
+    }
+
+    @Override
+    public String toString() {
         return MoreObjects.toStringHelper(this).add("behaviour", behaviour).toString();
     }
 }
index 32ce8cbc5dd8b1ac471f5bddfc4d91d5ad117549..11f246f998d06a44997ea07be65e4caf1bb08c4c 100644 (file)
@@ -41,10 +41,8 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.repo.api.FeatureSet;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.ParserNamespaces;
-import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
@@ -72,7 +70,7 @@ final class BuildGlobalContext extends AbstractNamespaceStorage {
 
     private final Table<YangVersion, QName, StatementDefinitionContext<?, ?, ?>> definitions = HashBasedTable.create();
     private final Map<QName, StatementDefinitionContext<?, ?, ?>> modelDefinedStmtDefs = new HashMap<>();
-    private final Map<ParserNamespace<?, ?>, NamespaceAccess<?, ?>> supportedNamespaces = new HashMap<>();
+    private final Map<ParserNamespace<?, ?>, BehaviourNamespaceAccess<?, ?>> supportedNamespaces = new HashMap<>();
     private final List<MutableStatement> mutableStatementsToSeal = new ArrayList<>();
     private final ImmutableMap<ModelProcessingPhase, StatementSupportBundle> supports;
     private final Set<SourceSpecificContext> sources = new HashSet<>();
@@ -133,30 +131,23 @@ final class BuildGlobalContext extends AbstractNamespaceStorage {
     }
 
     @Override
-    <K, V> NamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> type) {
+    <K, V> BehaviourNamespaceAccess<K, V> accessNamespace(final ParserNamespace<K, V> namespace) {
         @SuppressWarnings("unchecked")
-        var potential = (NamespaceAccess<K, V>) supportedNamespaces.get(type);
-        if (potential == null) {
-            final var potentialRaw = verifyNotNull(supports.get(currentPhase)).namespaceBehaviourOf(type);
-            if (potentialRaw != null) {
-                potential = createNamespaceContext(potentialRaw);
-                supportedNamespaces.put(type, potential);
-            } else {
-                throw new NamespaceNotAvailableException("Namespace " + type + " is not available in phase "
-                        + currentPhase);
-            }
+        final var existing = (BehaviourNamespaceAccess<K, V>) supportedNamespaces.get(namespace);
+        if (existing != null) {
+            return existing;
         }
-        return potential;
-    }
 
-    @SuppressWarnings({ "unchecked", "rawtypes" })
-    private <K, V> @NonNull NamespaceAccess<K, V> createNamespaceContext(final NamespaceBehaviour<K, V> behaviour) {
-        if (behaviour instanceof DerivedNamespaceBehaviour derived) {
-            final VirtualNamespaceContext derivedContext = new VirtualNamespaceContext(this, derived);
-            accessNamespace(derived.getDerivedFrom()).addDerivedNamespace(derivedContext);
-            return derivedContext;
+        final var behaviour = verifyNotNull(supports.get(currentPhase), "No support for phase %s", currentPhase)
+            .namespaceBehaviourOf(namespace);
+        if (behaviour == null) {
+            throw new NamespaceNotAvailableException(
+                "Namespace " + namespace + " is not available in phase " + currentPhase);
         }
-        return new SimpleNamespaceContext<>(this, behaviour);
+
+        final var created = new BehaviourNamespaceAccess<>(this, behaviour);
+        supportedNamespaces.put(namespace, created);
+        return created;
     }
 
     StatementDefinitionContext<?, ?, ?> getStatementDefinition(final YangVersion version, final QName name) {
index bf3e5f4b6c7e4c9e3a887f2abf76e87d8df9a0cb..b55ef40485d6c4470b53c4a4bff23315416d3687 100644 (file)
@@ -9,9 +9,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
 import static java.util.Objects.requireNonNull;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import org.eclipse.jdt.annotation.NonNull;
@@ -20,48 +17,29 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
 
 abstract class NamespaceAccess<K, V> {
-    abstract static class ValueAddedListener<K> {
-        private final NamespaceStorage ctxNode;
-
-        ValueAddedListener(final NamespaceStorage ctxNode) {
-            this.ctxNode = requireNonNull(ctxNode);
-        }
-
-        final NamespaceStorage getCtxNode() {
-            return ctxNode;
-        }
-    }
-
-    abstract static class KeyedValueAddedListener<K> extends ValueAddedListener<K> {
-        private final K key;
+    abstract static class KeyedValueAddedListener<K> {
+        private final @NonNull NamespaceStorage contextNode;
+        private final @NonNull K key;
 
         KeyedValueAddedListener(final NamespaceStorage contextNode, final K key) {
-            super(contextNode);
+            this.contextNode = requireNonNull(contextNode);
             this.key = requireNonNull(key);
         }
 
-        final K getKey() {
-            return key;
-        }
-
         final <V> boolean isRequestedValue(final NamespaceAccess<K, ?> access, final NamespaceStorage storage,
                 final V value) {
-            return value == access.valueFrom(getCtxNode(), key);
+            return value == access.valueFrom(contextNode, key);
         }
 
         abstract void onValueAdded(Object value);
     }
 
-    abstract static class PredicateValueAddedListener<K, V> extends ValueAddedListener<K> {
-        PredicateValueAddedListener(final NamespaceStorage contextNode) {
-            super(contextNode);
-        }
+    @FunctionalInterface
+    interface PredicateValueAddedListener<K, V> {
 
-        abstract boolean onValueAdded(@NonNull K key, @NonNull V value);
+        boolean onValueAdded(@NonNull K key, @NonNull V value);
     }
 
-    private List<VirtualNamespaceContext<?, V, K>> derivedNamespaces;
-
     abstract @Nullable V valueFrom(@NonNull NamespaceStorage storage, K key);
 
     abstract void valueTo(@NonNull NamespaceStorage storage, K key, V value);
@@ -74,34 +52,4 @@ abstract class NamespaceAccess<K, V> {
     abstract void addListener(KeyedValueAddedListener<K> listener);
 
     abstract void addListener(PredicateValueAddedListener<K, V> listener);
-
-    protected void notifyListeners(final NamespaceStorage storage,
-            final Iterator<? extends KeyedValueAddedListener<K>> keyListeners, final V value) {
-        List<KeyedValueAddedListener<K>> toNotify = new ArrayList<>();
-        while (keyListeners.hasNext()) {
-            final KeyedValueAddedListener<K> listener = keyListeners.next();
-            if (listener.isRequestedValue(this, storage, value)) {
-                keyListeners.remove();
-                toNotify.add(listener);
-            }
-        }
-        for (KeyedValueAddedListener<K> listener : toNotify) {
-            listener.onValueAdded(value);
-        }
-    }
-
-    protected void notifyDerivedNamespaces(final NamespaceStorage storage, final K key, final V value) {
-        if (derivedNamespaces != null) {
-            for (VirtualNamespaceContext<?, V, K> derived : derivedNamespaces) {
-                derived.addedToSourceNamespace(storage, key, value);
-            }
-        }
-    }
-
-    final void addDerivedNamespace(final VirtualNamespaceContext<?, V, K> namespace) {
-        if (derivedNamespaces == null) {
-            derivedNamespaces = new ArrayList<>();
-        }
-        derivedNamespaces.add(namespace);
-    }
 }
diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SimpleNamespaceContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SimpleNamespaceContext.java
deleted file mode 100644 (file)
index ce1160a..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.stmt.reactor;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
-
-final class SimpleNamespaceContext<K, V> extends BehaviourNamespaceAccess<K, V> {
-    // FIXME: Change this to Multimap, once issue with modules is resolved.
-    private List<KeyedValueAddedListener<K>> listeners;
-
-    private Collection<PredicateValueAddedListener<K, V>> predicateListeners;
-
-    SimpleNamespaceContext(final AbstractNamespaceStorage globalContext, final NamespaceBehaviour<K, V> behaviour) {
-        super(globalContext, behaviour);
-    }
-
-    @Override
-    void addListener(final KeyedValueAddedListener<K> listener) {
-        if (listeners == null) {
-            listeners = new ArrayList<>();
-        }
-        listeners.add(listener);
-    }
-
-    @Override
-    void addListener(final PredicateValueAddedListener<K, V> listener) {
-        if (predicateListeners == null) {
-            predicateListeners = new ArrayList<>();
-        }
-        predicateListeners.add(listener);
-    }
-
-    @Override
-    void onValueTo(final NamespaceStorage storage, final K key, final V value) {
-        if (listeners != null) {
-            notifyListeners(storage, listeners.iterator(), value);
-            if (listeners != null && listeners.isEmpty()) {
-                listeners = null;
-            }
-        }
-
-        if (predicateListeners != null) {
-            final Iterator<PredicateValueAddedListener<K, V>> it = predicateListeners.iterator();
-            while (it.hasNext()) {
-                if (it.next().onValueAdded(key, value)) {
-                    it.remove();
-                }
-            }
-            if (predicateListeners != null && predicateListeners.isEmpty()) {
-                predicateListeners = null;
-            }
-        }
-
-        notifyDerivedNamespaces(storage, key, value);
-    }
-}
index 0ba6de2e56e417436e88058a98c2d9126def7189..ae3438d67d61da0c390e440856527e1906b04374 100644 (file)
@@ -49,7 +49,6 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceAccess.KeyedValueAddedListener;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceAccess.PredicateValueAddedListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -619,17 +618,13 @@ abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E extends
             return;
         }
 
-        namespaceAccess.addListener(new PredicateValueAddedListener<K, V>(this) {
-            @Override
-            boolean onValueAdded(final K key, final V value) {
-                if (criterion.match(key)) {
-                    LOG.debug("Listener on {} criterion {} matched added key {}", type, criterion, key);
-                    waitForPhase(value, type, phase, criterion, listener);
-                    return true;
-                }
-
-                return false;
+        namespaceAccess.addListener((key, value) -> {
+            if (criterion.match(key)) {
+                LOG.debug("Listener on {} criterion {} matched added key {}", type, criterion, key);
+                waitForPhase(value, type, phase, criterion, listener);
+                return true;
             }
+            return false;
         });
     }
 
diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/VirtualNamespaceContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/VirtualNamespaceContext.java
deleted file mode 100644 (file)
index e6304b7..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.stmt.reactor;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import org.opendaylight.yangtools.yang.parser.spi.meta.DerivedNamespaceBehaviour;
-import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
-
-final class VirtualNamespaceContext<K, V, D> extends BehaviourNamespaceAccess<K, V> {
-    private final Multimap<D, KeyedValueAddedListener<K>> listeners = HashMultimap.create();
-    private final DerivedNamespaceBehaviour<K, V, D, ?> derivedDelegate;
-
-    VirtualNamespaceContext(final AbstractNamespaceStorage globalContext,
-            final DerivedNamespaceBehaviour<K, V, D, ?> behaviour) {
-        super(globalContext, behaviour);
-        derivedDelegate = requireNonNull(behaviour);
-    }
-
-    @Override
-    void addListener(final KeyedValueAddedListener<K> listener) {
-        listeners.put(derivedDelegate.getSignificantKey(listener.getKey()), listener);
-    }
-
-    @Override
-    void addListener(final PredicateValueAddedListener<K, V> listener) {
-        throw new UnsupportedOperationException("Virtual namespaces support only exact lookups");
-    }
-
-    void addedToSourceNamespace(final NamespaceStorage storage, final D key, final V value) {
-        notifyListeners(storage, listeners.get(key).iterator(), value);
-    }
-
-    @Override
-    void onValueTo(final NamespaceStorage storage, final K key, final V value) {
-        notifyListeners(storage, listeners.get(derivedDelegate.getSignificantKey(key)).iterator(), value);
-        notifyDerivedNamespaces(storage, key, value);
-    }
-}
diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedNamespaceBehaviour.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/DerivedNamespaceBehaviour.java
deleted file mode 100644 (file)
index 40aa5f1..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.spi.meta;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.MoreObjects.ToStringHelper;
-import java.util.Map;
-import org.eclipse.jdt.annotation.NonNull;
-
-/**
- * An {@link NamespaceBehaviour} which derives keys from a different namespace.
- *
- * @param <K> Key type
- * @param <V> Value type
- * @param <L> Original key type
- * @param <O> Original namespace type
- */
-public abstract class DerivedNamespaceBehaviour<K, V, L, O extends ParserNamespace<L, ?>>
-        extends NamespaceBehaviour<K, V> {
-
-    private final @NonNull O derivedFrom;
-
-    protected DerivedNamespaceBehaviour(final ParserNamespace<K, V> namespace, final O derivedFrom) {
-        super(namespace);
-        this.derivedFrom = requireNonNull(derivedFrom);
-    }
-
-    public final @NonNull O getDerivedFrom() {
-        return derivedFrom;
-    }
-
-    @Override
-    public Map<K, V> getAllFrom(final GlobalStorageAccess globalAccess, final NamespaceStorage storage) {
-        throw new UnsupportedOperationException("Virtual namespaces does not support provision of all items.");
-    }
-
-    @Override
-    public abstract V getFrom(GlobalStorageAccess globalAccess, NamespaceStorage storage, K key);
-
-    @Override
-    public void addTo(final GlobalStorageAccess globalAccess, final NamespaceStorage storage, final K key,
-            final V value) {
-        // Intentional noop
-    }
-
-    public abstract L getSignificantKey(K key);
-
-    @Override
-    protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
-        return helper.add("derivedFrom", derivedFrom);
-    }
-}