5f77fd4aaf4c3ec9c60ce4a010728621e24499e7
[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         void trigger(Object value) {
38             onValueAdded(key, value);
39         }
40
41         abstract void onValueAdded(Object key, Object value);
42     }
43
44     protected final NamespaceBehaviour<K, V, N> delegate;
45     private final List<VirtualNamespaceContext<?, V, ?, K>> derivedNamespaces = new ArrayList<>();
46
47
48     protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V, N> delegate) {
49         super(delegate.getIdentifier());
50         this.delegate = delegate;
51     }
52
53     protected abstract void addListener(K key, ValueAddedListener<K> listener);
54
55     protected abstract boolean isRequestedValue(ValueAddedListener<K> listener, NamespaceStorageNode storage, V value);
56
57     @Override
58     public abstract void addTo(final NamespaceStorageNode storage, final K key, final V value);
59
60     protected void notifyListeners(final NamespaceStorageNode storage, Iterator<ValueAddedListener<K>> keyListeners,
61             final V value) {
62         List<ValueAddedListener<K>> toNotify = new ArrayList<>();
63         while (keyListeners.hasNext()) {
64             ValueAddedListener<K> listener = keyListeners.next();
65             if (isRequestedValue(listener, storage, value)) {
66                 keyListeners.remove();
67                 toNotify.add(listener);
68             }
69         }
70         for (ValueAddedListener<K> listener : toNotify) {
71             listener.trigger(value);
72         }
73     }
74
75     protected void notifyDerivedNamespaces(final NamespaceStorageNode storage, final K key, final V value) {
76         for (VirtualNamespaceContext<?, V, ?, K> derived : derivedNamespaces) {
77             derived.addedToSourceNamespace(storage, key, value);
78         }
79     }
80
81     final void addValueListener(final ValueAddedListener<K> listener) {
82         addListener(listener.key, listener);
83     }
84
85     final void addDerivedNamespace(VirtualNamespaceContext<?, V, ?, K> namespace) {
86         derivedNamespaces.add(namespace);
87     }
88
89     @Override
90     public V getFrom(final NamespaceStorageNode storage, final K key) {
91         return delegate.getFrom(storage, key);
92     }
93
94     @Override
95     public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
96         return delegate.getAllFrom(storage);
97     }
98 }