Revert "Revert "Updated SchemaNodeIdentifier namespace handling.""
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / NamespaceBehaviourWithListeners.java
index c4bbb76f004a6417f456a791a49001063e14948c..1f10c18a96bcc33a7d1e00d3f5e49836af7b9bb8 100644 (file)
@@ -7,76 +7,78 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import java.util.Collection;
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
-import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
-import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
 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> {
 
-    abstract static class ValueAddedListener {
+    abstract static class ValueAddedListener<K> {
         private final NamespaceStorageNode ctxNode;
+        private K key;
 
-        public ValueAddedListener(final NamespaceStorageNode contextNode) {
+        public ValueAddedListener(final NamespaceStorageNode contextNode, K key) {
             this.ctxNode = contextNode;
+            this.key = key;
+        }
+
+        public NamespaceStorageNode getCtxNode() {
+            return ctxNode;
+        }
+
+        public K getKey() {
+            return key;
         }
 
         abstract void onValueAdded(Object key, Object value);
     }
 
     private final NamespaceBehaviour<K, V, N> delegate;
-    private final Multimap<K, ValueAddedListener> listeners = HashMultimap.create();
+    private final List<VirtualNamespaceContext<?, V, ?>> derivedNamespaces = new ArrayList<>();
+
 
     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 Iterator<ValueAddedListener<K>> getMutableListeners(K key);
+
+    protected abstract boolean isRequestedValue(ValueAddedListener<K> listener, NamespaceStorageNode storage, V value);
+
     @Override
     public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
         delegate.addTo(storage, key, value);
 
-        Iterator<ValueAddedListener> keyListeners = listeners.get(key).iterator();
+        Iterator<ValueAddedListener<K>> keyListeners = getMutableListeners(key);
+        List<ValueAddedListener<K>> toNotify = new ArrayList<>();
         while (keyListeners.hasNext()) {
-            ValueAddedListener listener = keyListeners.next();
-            if (listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) {
+            ValueAddedListener<K> listener = keyListeners.next();
+            if (isRequestedValue(listener, storage, value)) {
                 keyListeners.remove();
-                listener.onValueAdded(key, value);
+                toNotify.add(listener);
             }
         }
-
-        if (key instanceof ModuleIdentifier && !listeners.isEmpty()) {
-            Collection<ValueAddedListener> defaultImportListeners = getDefaultImportListeners((ModuleIdentifier) key);
-            Iterator<ValueAddedListener> defaultImportsIterator = defaultImportListeners.iterator();
-            while (defaultImportsIterator.hasNext()) {
-                ValueAddedListener listener = defaultImportsIterator.next();
-                if(listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) {
-                    defaultImportsIterator.remove();
-                    listener.onValueAdded(key, value);
-                }
-            }
+        for(ValueAddedListener<K> listener : toNotify) {
+            listener.onValueAdded(key, value);
+        }
+        for (VirtualNamespaceContext<?, V, ?> derived : derivedNamespaces) {
+            derived.addTo(storage, null, value);
         }
     }
 
-    private Collection<ValueAddedListener> getDefaultImportListeners(final ModuleIdentifier key) {
-        ModuleIdentifier defaultImportKey = new ModuleIdentifierImpl(key.getName(),
-            Optional.fromNullable(key.getNamespace()), Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_IMP));
-        return listeners.get((K)defaultImportKey);
-    }
-
-    private boolean hasIdentiticalValue(final NamespaceStorageNode ctxNode, final K key, final V value) {
-        return getFrom(ctxNode, key) == value;
+    final void addValueListener(final ValueAddedListener<K> listener) {
+        addListener(listener.key, listener);
     }
 
-    void addValueListener(final K key, final ValueAddedListener listener) {
-        listeners.put(key, listener);
+    final void addDerivedNamespace(VirtualNamespaceContext<?, V, ?> namespace) {
+        derivedNamespaces.add(namespace);
     }
 
     @Override