Bug 3670 (part 3/5): Use of new statement parser in yang-maven-plugin
[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 org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
11
12 import com.google.common.base.Optional;
13 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
14 import java.util.Collection;
15 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
16 import com.google.common.collect.HashMultimap;
17 import com.google.common.collect.Multimap;
18 import java.util.Iterator;
19 import java.util.Map;
20 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
22
23 final class NamespaceBehaviourWithListeners<K,V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
24
25     static abstract class ValueAddedListener {
26
27         private org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode ctxNode;
28
29         public ValueAddedListener(NamespaceStorageNode contextNode) {
30             this.ctxNode = contextNode;
31         }
32
33         abstract void onValueAdded(Object key, Object value);
34
35     }
36
37     private final NamespaceBehaviour<K, V, N> delegate;
38     private final Multimap<K, ValueAddedListener> listeners = HashMultimap.create();
39
40     protected NamespaceBehaviourWithListeners(NamespaceBehaviour<K, V, N> delegate) {
41         super(delegate.getIdentifier());
42         this.delegate = delegate;
43     }
44
45     @Override
46     public void addTo(NamespaceBehaviour.NamespaceStorageNode storage,
47             K key, V value) {
48         delegate.addTo(storage, key, value);
49
50         Iterator<ValueAddedListener> keyListeners = listeners.get(key).iterator();
51         while(keyListeners.hasNext()) {
52             ValueAddedListener listener = keyListeners.next();
53             if(listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) {
54                 keyListeners.remove();
55                 listener.onValueAdded(key, value);
56             }
57         }
58
59         if(key instanceof ModuleIdentifier && !listeners.isEmpty()) {
60             Collection<ValueAddedListener> defaultImportListeners = getDefaultImportListeners((ModuleIdentifier) key);
61             Iterator<ValueAddedListener> defaultImportsIterator = defaultImportListeners.iterator();
62             while(defaultImportsIterator.hasNext()) {
63                 ValueAddedListener listener = defaultImportsIterator.next();
64                 if(listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) {
65                     defaultImportsIterator.remove();
66                     listener.onValueAdded(key, value);
67                 }
68             }
69         }
70     }
71
72     private Collection<ValueAddedListener> getDefaultImportListeners(
73             ModuleIdentifier key) {
74         ModuleIdentifier defaultImportKey = new ModuleIdentifierImpl(
75                 key.getName(), Optional.fromNullable(key.getNamespace()),
76                 Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_IMP));
77         return listeners.get((K)defaultImportKey);
78     }
79
80     private boolean hasIdentiticalValue(NamespaceBehaviour.NamespaceStorageNode ctxNode, K key, V value) {
81         return getFrom(ctxNode, key) == value;
82     }
83
84     void addValueListener(K key, ValueAddedListener listener) {
85         listeners.put(key, listener);
86     }
87
88     @Override
89     public V getFrom(NamespaceBehaviour.NamespaceStorageNode storage,
90             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 }