Another round of checkstyle fixes
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / stmt / reactor / NamespaceStorageSupport.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 com.google.common.collect.ImmutableMap;
11 import java.util.Date;
12 import java.util.HashMap;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import java.util.Set;
16 import javax.annotation.Nonnull;
17 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
18 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
19 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.NamespaceStorageNode;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Registry;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
25 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
26
27 abstract class NamespaceStorageSupport implements NamespaceStorageNode {
28
29     private Map<Class<?>, Map<?,?>> namespaces = ImmutableMap.of();
30
31     @Override
32     public abstract NamespaceStorageNode getParentNamespaceStorage();
33
34     /**
35      * Return the registry of a source context.
36      *
37      * @return registry of source context
38      */
39     public abstract Registry getBehaviourRegistry();
40
41     protected void checkLocalNamespaceAllowed(final Class<? extends IdentifierNamespace<?, ?>> type) {
42         // NOOP
43     }
44
45     /**
46      * Occurs when an item is added to model namespace.
47      *
48      * @throws SourceException instance of SourceException
49      */
50     protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(final Class<N> type, final K key,
51             final V value) {
52         // NOOP
53     }
54
55     @Nonnull
56     public final <K,V, KT extends K, N extends IdentifierNamespace<K, V>> V getFromNamespace(final Class<N> type,
57             final KT key) throws NamespaceNotAvailableException {
58         return getBehaviourRegistry().getNamespaceBehaviour(type).getFrom(this, key);
59     }
60
61     public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromNamespace(final Class<N> type) {
62         return getBehaviourRegistry().getNamespaceBehaviour(type).getAllFrom(this);
63     }
64
65     @SuppressWarnings("unchecked")
66     public final <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromCurrentStmtCtxNamespace(
67             final Class<N> type) {
68         return (Map<K, V>) namespaces.get(type);
69     }
70
71     public final <K,V, KT extends K, VT extends V,N extends IdentifierNamespace<K, V>> void addToNs(final Class<N> type,
72             final KT key, final VT value) throws NamespaceNotAvailableException {
73         getBehaviourRegistry().getNamespaceBehaviour(type).addTo(this,key,value);
74     }
75
76     @SuppressWarnings({ "unchecked", "rawtypes" })
77     public final <K, N extends StatementNamespace<K, ?,?>> void addContextToNamespace(final Class<N> type, final K key,
78             final StmtContext<?, ?, ?> value) throws NamespaceNotAvailableException {
79         getBehaviourRegistry().getNamespaceBehaviour((Class)type).addTo(this, key, value);
80     }
81
82     @SuppressWarnings("unchecked")
83     @Override
84     public <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(final Class<N> type, final K key) {
85         final Map<K, V> localNamespace = (Map<K,V>) namespaces.get(type);
86
87         V potential = null;
88         if (localNamespace != null) {
89             potential = localNamespace.get(key);
90         }
91
92         if (potential == null && isModuleIdentifierWithoutSpecifiedRevision(key)) {
93             potential = getRegardlessOfRevision((ModuleIdentifier)key,(Map<ModuleIdentifier,V>)localNamespace);
94         }
95
96         return potential;
97     }
98
99     private static boolean isModuleIdentifierWithoutSpecifiedRevision(final Object obj) {
100         if (!(obj instanceof ModuleIdentifier)) {
101             return false;
102         }
103
104         final Date rev = ((ModuleIdentifier) obj).getRevision();
105         return rev == SimpleDateFormatUtil.DEFAULT_DATE_IMP || rev == SimpleDateFormatUtil.DEFAULT_BELONGS_TO_DATE;
106     }
107
108     private static <K, V, N extends IdentifierNamespace<K, V>> V getRegardlessOfRevision(final ModuleIdentifier key,
109             final Map<ModuleIdentifier, V> localNamespace) {
110
111         if (localNamespace == null) {
112             return null;
113         }
114
115         final Set<Entry<ModuleIdentifier, V>> entrySet = localNamespace.entrySet();
116         for (final Entry<ModuleIdentifier, V> entry : entrySet) {
117             final ModuleIdentifier moduleIdentifierInMap = entry.getKey();
118             if (moduleIdentifierInMap.getName().equals(key.getName())) {
119                 return entry.getValue();
120             }
121         }
122
123         return null;
124     }
125
126     @Override
127     public <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(final Class<N> type) {
128         @SuppressWarnings("unchecked")
129         final Map<K, V> localNamespace = (Map<K, V>) namespaces.get(type);
130         return localNamespace;
131     }
132
133     private <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> ensureLocalNamespace(final Class<N> type) {
134         @SuppressWarnings("unchecked")
135         Map<K, V> ret = (Map<K,V>) namespaces.get(type);
136         if (ret == null) {
137             checkLocalNamespaceAllowed(type);
138             ret = new HashMap<>(1);
139
140             if (namespaces.isEmpty()) {
141                 namespaces = new HashMap<>(1);
142             }
143             namespaces.put(type, ret);
144         }
145
146         return ret;
147     }
148
149     @Override
150     public <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorage(final Class<N> type, final K key,
151             final V value) {
152         final V ret = ensureLocalNamespace(type).put(key, value);
153         onNamespaceElementAdded(type, key, value);
154         return ret;
155     }
156
157     @Override
158     public <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorageIfAbsent(final Class<N> type, final K key,
159             final V value) {
160         final V ret = ensureLocalNamespace(type).putIfAbsent(key, value);
161         if (ret == null) {
162             onNamespaceElementAdded(type, key, value);
163         }
164         return ret;
165     }
166 }