adba2b6572f7cf81952626eafbb2e8d51bdf7a48
[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 final K key;
23
24         ValueAddedListener(final NamespaceStorageNode contextNode, final K key) {
25             this.ctxNode = contextNode;
26             this.key = key;
27         }
28
29         NamespaceStorageNode getCtxNode() {
30             return ctxNode;
31         }
32
33         final <V> boolean isRequestedValue(final NamespaceBehaviour<K, ? , ?> behavior,
34                 final NamespaceStorageNode storage, final V value) {
35             return value == behavior.getFrom(ctxNode, key);
36         }
37
38         abstract void onValueAdded(Object value);
39     }
40
41     protected final NamespaceBehaviour<K, V, N> delegate;
42     private final List<VirtualNamespaceContext<?, V, ?, K>> derivedNamespaces = new ArrayList<>();
43
44     protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V, N> delegate) {
45         super(delegate.getIdentifier());
46         this.delegate = delegate;
47     }
48
49     abstract void addListener(K key, ValueAddedListener<K> listener);
50
51     @Override
52     public abstract void addTo(NamespaceStorageNode storage, K key, V value);
53
54     protected void notifyListeners(final NamespaceStorageNode storage,
55             final Iterator<ValueAddedListener<K>> keyListeners, final V value) {
56         List<ValueAddedListener<K>> toNotify = new ArrayList<>();
57         while (keyListeners.hasNext()) {
58             final ValueAddedListener<K> listener = keyListeners.next();
59             if (listener.isRequestedValue(this, storage, value)) {
60                 keyListeners.remove();
61                 toNotify.add(listener);
62             }
63         }
64         for (ValueAddedListener<K> listener : toNotify) {
65             listener.onValueAdded(value);
66         }
67     }
68
69     protected void notifyDerivedNamespaces(final NamespaceStorageNode storage, final K key, final V value) {
70         for (VirtualNamespaceContext<?, V, ?, K> derived : derivedNamespaces) {
71             derived.addedToSourceNamespace(storage, key, value);
72         }
73     }
74
75     final void addDerivedNamespace(final VirtualNamespaceContext<?, V, ?, K> namespace) {
76         derivedNamespaces.add(namespace);
77     }
78
79     @Override
80     public V getFrom(final NamespaceStorageNode storage, final K key) {
81         return delegate.getFrom(storage, key);
82     }
83
84     @Override
85     public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
86         return delegate.getAllFrom(storage);
87     }
88 }