Updated SchemaNodeIdentifier namespace handling.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / NamespaceBehaviourWithListeners.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
9
10 import java.util.ArrayList;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
15 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
16
17 abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespace<K, V>>
18         extends NamespaceBehaviour<K, V, N> {
19
20     abstract static class ValueAddedListener<K> {
21         private final NamespaceStorageNode ctxNode;
22         private K key;
23
24         public ValueAddedListener(final NamespaceStorageNode contextNode, K key) {
25             this.ctxNode = contextNode;
26             this.key = key;
27         }
28
29         public NamespaceStorageNode getCtxNode() {
30             return ctxNode;
31         }
32
33         public K getKey() {
34             return key;
35         }
36
37         abstract void onValueAdded(Object key, Object value);
38     }
39
40     private final NamespaceBehaviour<K, V, N> delegate;
41     private final List<VirtualNamespaceContext<?, V, ?>> derivedNamespaces = new ArrayList<>();
42
43
44     protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V, N> delegate) {
45         super(delegate.getIdentifier());
46         this.delegate = delegate;
47     }
48
49     protected abstract void addListener(K key, ValueAddedListener<K> listener);
50
51     protected abstract Iterator<ValueAddedListener<K>> getMutableListeners(K key);
52
53     protected abstract boolean isRequestedValue(ValueAddedListener<K> listener, NamespaceStorageNode storage, V value);
54
55     @Override
56     public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
57         delegate.addTo(storage, key, value);
58
59         Iterator<ValueAddedListener<K>> keyListeners = getMutableListeners(key);
60         List<ValueAddedListener<K>> toNotify = new ArrayList<>();
61         while (keyListeners.hasNext()) {
62             ValueAddedListener<K> listener = keyListeners.next();
63             if (isRequestedValue(listener, storage, value)) {
64                 keyListeners.remove();
65                 toNotify.add(listener);
66             }
67         }
68         for(ValueAddedListener<K> listener : toNotify) {
69             listener.onValueAdded(key, value);
70         }
71         for (VirtualNamespaceContext<?, V, ?> derived : derivedNamespaces) {
72             derived.addTo(storage, null, value);
73         }
74     }
75
76     final void addValueListener(final ValueAddedListener<K> listener) {
77         addListener(listener.key, listener);
78     }
79
80     final void addDerivedNamespace(VirtualNamespaceContext<?, V, ?> namespace) {
81         derivedNamespaces.add(namespace);
82     }
83
84     @Override
85     public V getFrom(final NamespaceStorageNode storage, final K key) {
86         return delegate.getFrom(storage, key);
87     }
88
89     @Override
90     public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
91         return delegate.getAllFrom(storage);
92     }
93 }