2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
10 import com.google.common.collect.ImmutableMap;
11 import java.util.Date;
12 import java.util.HashMap;
14 import java.util.Map.Entry;
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;
27 abstract class NamespaceStorageSupport implements NamespaceStorageNode {
29 private Map<Class<?>, Map<?,?>> namespaces = ImmutableMap.of();
32 public abstract NamespaceStorageNode getParentNamespaceStorage();
35 * Return the registry of a source context.
37 * @return registry of source context
39 public abstract Registry getBehaviourRegistry();
41 protected void checkLocalNamespaceAllowed(final Class<? extends IdentifierNamespace<?, ?>> type) {
46 * Occurs when an item is added to model namespace.
48 * @throws SourceException instance of SourceException
50 protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(final Class<N> type, final K key,
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);
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);
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);
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);
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);
82 @SuppressWarnings("unchecked")
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);
88 if (localNamespace != null) {
89 potential = localNamespace.get(key);
92 if (potential == null && isModuleIdentifierWithoutSpecifiedRevision(key)) {
93 potential = getRegardlessOfRevision((ModuleIdentifier)key,(Map<ModuleIdentifier,V>)localNamespace);
99 private static boolean isModuleIdentifierWithoutSpecifiedRevision(final Object obj) {
100 if (!(obj instanceof ModuleIdentifier)) {
104 final Date rev = ((ModuleIdentifier) obj).getRevision();
105 return rev == SimpleDateFormatUtil.DEFAULT_DATE_IMP || rev == SimpleDateFormatUtil.DEFAULT_BELONGS_TO_DATE;
108 private static <K, V, N extends IdentifierNamespace<K, V>> V getRegardlessOfRevision(final ModuleIdentifier key,
109 final Map<ModuleIdentifier, V> localNamespace) {
111 if (localNamespace == null) {
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();
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;
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);
137 checkLocalNamespaceAllowed(type);
138 ret = new HashMap<>(1);
140 if (namespaces.isEmpty()) {
141 namespaces = new HashMap<>(1);
143 namespaces.put(type, ret);
150 public <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorage(final Class<N> type, final K key,
152 final V ret = ensureLocalNamespace(type).put(key, value);
153 onNamespaceElementAdded(type, key, value);
158 public <K, V, N extends IdentifierNamespace<K, V>> V putToLocalStorageIfAbsent(final Class<N> type, final K key,
160 final V ret = ensureLocalNamespace(type).putIfAbsent(key, value);
162 onNamespaceElementAdded(type, key, value);