*/
package org.opendaylight.yangtools.yang.parser.stmt.reactor;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
-final class NamespaceBehaviourWithListeners<K,V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
+abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespace<K, V>>
+ extends NamespaceBehaviour<K, V, N> {
- static abstract class ValueAddedListener {
+ abstract static class ValueAddedListener<K> {
+ private final NamespaceStorageNode ctxNode;
+ private K key;
- private org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode ctxNode;
-
- public ValueAddedListener(NamespaceStorageNode contextNode) {
+ public ValueAddedListener(final NamespaceStorageNode contextNode, K key) {
this.ctxNode = contextNode;
+ this.key = key;
}
- abstract void onValueAdded(Object key, Object value);
+ public NamespaceStorageNode getCtxNode() {
+ return ctxNode;
+ }
+
+ public K getKey() {
+ return key;
+ }
+ void trigger(Object value) {
+ onValueAdded(key, value);
+ }
+
+ abstract void onValueAdded(Object key, Object value);
}
- private final NamespaceBehaviour<K, V, N> delegate;
- private final Multimap<K, ValueAddedListener> listeners = HashMultimap.create();
+ protected final NamespaceBehaviour<K, V, N> delegate;
+ private final List<VirtualNamespaceContext<?, V, ?, K>> derivedNamespaces = new ArrayList<>();
- protected NamespaceBehaviourWithListeners(NamespaceBehaviour<K, V, N> delegate) {
+
+ protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V, N> delegate) {
super(delegate.getIdentifier());
this.delegate = delegate;
}
+ protected abstract void addListener(K key, ValueAddedListener<K> listener);
+
+ protected abstract boolean isRequestedValue(ValueAddedListener<K> listener, NamespaceStorageNode storage, V value);
+
@Override
- public void addTo(NamespaceBehaviour.NamespaceStorageNode storage,
- K key, V value) {
- delegate.addTo(storage, key, value);
-
- Iterator<ValueAddedListener> keyListeners = listeners.get(key).iterator();
- while(keyListeners.hasNext()) {
- ValueAddedListener listener = keyListeners.next();
- if(listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) {
+ public abstract void addTo(final NamespaceStorageNode storage, final K key, final V value);
+
+ protected void notifyListeners(final NamespaceStorageNode storage, Iterator<ValueAddedListener<K>> keyListeners,
+ final V value) {
+ List<ValueAddedListener<K>> toNotify = new ArrayList<>();
+ while (keyListeners.hasNext()) {
+ ValueAddedListener<K> listener = keyListeners.next();
+ if (isRequestedValue(listener, storage, value)) {
keyListeners.remove();
- listener.onValueAdded(key, value);
+ toNotify.add(listener);
}
}
+ for (ValueAddedListener<K> listener : toNotify) {
+ listener.trigger(value);
+ }
}
- private boolean hasIdentiticalValue(NamespaceBehaviour.NamespaceStorageNode ctxNode, K key, V value) {
- return getFrom(ctxNode, key) == value;
+ protected void notifyDerivedNamespaces(final NamespaceStorageNode storage, final K key, final V value) {
+ for (VirtualNamespaceContext<?, V, ?, K> derived : derivedNamespaces) {
+ derived.addedToSourceNamespace(storage, key, value);
+ }
}
- void addValueListener(K key, ValueAddedListener listener) {
- listeners.put(key, listener);
+ final void addValueListener(final ValueAddedListener<K> listener) {
+ addListener(listener.key, listener);
+ }
+
+ final void addDerivedNamespace(VirtualNamespaceContext<?, V, ?, K> namespace) {
+ derivedNamespaces.add(namespace);
}
@Override
- public V getFrom(NamespaceBehaviour.NamespaceStorageNode storage,
- K key) {
+ public V getFrom(final NamespaceStorageNode storage, final K key) {
return delegate.getFrom(storage, key);
}
+
+ @Override
+ public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
+ return delegate.getAllFrom(storage);
+ }
}