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;
/**
* 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();
}
}
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;
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<>();
}
@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) {
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;
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);
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);
- }
}
+++ /dev/null
-/*
- * 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);
- }
-}
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;
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;
});
}
+++ /dev/null
-/*
- * 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);
- }
-}
+++ /dev/null
-/*
- * 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);
- }
-}