Convert parser-{reactor,spi} classes to JDT annotations
[yangtools.git] / yang / yang-parser-reactor / 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 static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.MoreObjects.ToStringHelper;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
19 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
20
21 abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespace<K, V>>
22         extends NamespaceBehaviour<K, V, N> {
23
24     abstract static class ValueAddedListener<K> {
25         private final NamespaceStorageNode ctxNode;
26
27         ValueAddedListener(final NamespaceStorageNode contextNode) {
28             this.ctxNode = requireNonNull(contextNode);
29         }
30
31         final NamespaceStorageNode getCtxNode() {
32             return ctxNode;
33         }
34     }
35
36     abstract static class KeyedValueAddedListener<K> extends ValueAddedListener<K> {
37         private final K key;
38
39         KeyedValueAddedListener(final NamespaceStorageNode contextNode, final K key) {
40             super(contextNode);
41             this.key = requireNonNull(key);
42         }
43
44         final K getKey() {
45             return key;
46         }
47
48         final <V> boolean isRequestedValue(final NamespaceBehaviour<K, ? , ?> behavior,
49                 final NamespaceStorageNode storage, final V value) {
50             return value == behavior.getFrom(getCtxNode(), key);
51         }
52
53         abstract void onValueAdded(Object value);
54     }
55
56     abstract static class PredicateValueAddedListener<K, V> extends ValueAddedListener<K> {
57         PredicateValueAddedListener(final NamespaceStorageNode contextNode) {
58             super(contextNode);
59         }
60
61         abstract boolean onValueAdded(@NonNull K key, @NonNull V value);
62     }
63
64     protected final NamespaceBehaviour<K, V, N> delegate;
65
66     private List<VirtualNamespaceContext<?, V, ?, K>> derivedNamespaces;
67
68     protected NamespaceBehaviourWithListeners(final NamespaceBehaviour<K, V, N> delegate) {
69         super(delegate.getIdentifier());
70         this.delegate = delegate;
71     }
72
73     abstract void addListener(KeyedValueAddedListener<K> listener);
74
75     abstract void addListener(PredicateValueAddedListener<K, V> listener);
76
77     @Override
78     public abstract void addTo(NamespaceStorageNode storage, K key, V value);
79
80     protected void notifyListeners(final NamespaceStorageNode storage,
81             final Iterator<? extends KeyedValueAddedListener<K>> keyListeners, final V value) {
82         List<KeyedValueAddedListener<K>> toNotify = new ArrayList<>();
83         while (keyListeners.hasNext()) {
84             final KeyedValueAddedListener<K> listener = keyListeners.next();
85             if (listener.isRequestedValue(this, storage, value)) {
86                 keyListeners.remove();
87                 toNotify.add(listener);
88             }
89         }
90         for (KeyedValueAddedListener<K> listener : toNotify) {
91             listener.onValueAdded(value);
92         }
93     }
94
95     protected void notifyDerivedNamespaces(final NamespaceStorageNode storage, final K key, final V value) {
96         if (derivedNamespaces != null) {
97             for (VirtualNamespaceContext<?, V, ?, K> derived : derivedNamespaces) {
98                 derived.addedToSourceNamespace(storage, key, value);
99             }
100         }
101     }
102
103     final void addDerivedNamespace(final VirtualNamespaceContext<?, V, ?, K> namespace) {
104         if (derivedNamespaces == null) {
105             derivedNamespaces = new ArrayList<>();
106         }
107         derivedNamespaces.add(namespace);
108     }
109
110     @Override
111     public V getFrom(final NamespaceStorageNode storage, final K key) {
112         return delegate.getFrom(storage, key);
113     }
114
115     @Override
116     public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
117         return delegate.getAllFrom(storage);
118     }
119
120     @Override
121     protected ToStringHelper addToStringAttributes(final ToStringHelper helper) {
122         return super.addToStringAttributes(helper).add("delegate", delegate);
123     }
124 }