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.spi.meta;
10 import com.google.common.base.Preconditions;
12 import javax.annotation.Nonnull;
13 import javax.annotation.Nullable;
14 import org.opendaylight.yangtools.concepts.Identifiable;
15 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
18 * Definition / implementation of specific Identifier Namespace behaviour.
20 * Namespace behaviour is build on top of tree of {@link NamespaceStorageNode} which represents local context of one of
21 * types defined in {@link StorageNodeType}.
23 * For common behaviour models please use static factories {@link #global(Class)}, {@link #sourceLocal(Class)} and
24 * {@link #treeScoped(Class)}.
33 public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K, V>> implements Identifiable<Class<N>> {
35 public enum StorageNodeType {
36 GLOBAL, SOURCE_LOCAL_SPECIAL, STATEMENT_LOCAL, ROOT_STATEMENT_LOCAL
39 public interface Registry {
40 <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> type);
43 public interface NamespaceStorageNode {
45 * @return local namespace behaviour type {@link NamespaceBehaviour}
47 StorageNodeType getStorageNodeType();
50 NamespaceStorageNode getParentNamespaceStorage();
53 <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(Class<N> type, K key);
56 <K, V, N extends IdentifierNamespace<K, V>> Map<K, V> getAllFromLocalStorage(Class<N> type);
58 <K, V, N extends IdentifierNamespace<K, V>> void addToLocalStorage(Class<N> type, K key, V value);
62 private final Class<N> identifier;
64 protected NamespaceBehaviour(final Class<N> identifier) {
65 this.identifier = Preconditions.checkNotNull(identifier);
70 * Creates global namespace behaviour for supplied namespace type.
72 * Global behaviour stores and loads all values from root {@link NamespaceStorageNode} with type of
73 * {@link StorageNodeType#GLOBAL}.
76 * Namespace identifier.
77 * @param <K> type parameter
78 * @param <V> type parameter
79 * @param <N> type parameter
81 * @return global namespace behaviour for supplied namespace type.
83 public static @Nonnull <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> global(
84 final Class<N> identifier) {
85 return new StorageSpecific<>(identifier, StorageNodeType.GLOBAL);
90 * Creates source-local namespace behaviour for supplied namespace type.
92 * Source-local namespace behaviour stores and loads all values from closest {@link NamespaceStorageNode} ancestor
93 * with type of {@link StorageNodeType#SOURCE_LOCAL_SPECIAL}.
96 * Namespace identifier.
97 * @param <K> type parameter
98 * @param <V> type parameter
99 * @param <N> type parameter
101 * @return source-local namespace behaviour for supplied namespace type.
103 public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> sourceLocal(
104 final Class<N> identifier) {
105 return new StorageSpecific<>(identifier, StorageNodeType.SOURCE_LOCAL_SPECIAL);
108 public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> statementLocal(
109 final Class<N> identifier) {
110 return new StorageSpecific<>(identifier, StorageNodeType.STATEMENT_LOCAL);
115 * Creates tree-scoped namespace behaviour for supplied namespace type.
117 * Tree-scoped namespace behaviour search for value in all storage nodes up to the root and stores values in
121 * Namespace identifier. *
122 * @param <K> type parameter
123 * @param <V> type parameter
124 * @param <N> type parameter
126 * @return tree-scoped namespace behaviour for supplied namespace type.
128 public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> treeScoped(final Class<N> identifier) {
129 return new TreeScoped<>(identifier);
133 * returns value from model namespace storage according to key param class
135 * @param storage namespace storage
136 * @param key type parameter
138 * @return value from model namespace storage according to key param class
140 public abstract V getFrom(NamespaceStorageNode storage, K key);
143 * returns all values of a keys of param class from model namespace storage
145 * @param storage namespace storage
147 * @return all values of keys of param class from model namespace storage
149 public abstract Map<K, V> getAllFrom(NamespaceStorageNode storage);
152 * adds key and value to corresponding namespace storage according to param class
154 * @param storage namespace storage
155 * @param key type parameter
156 * @param value type parameter
158 public abstract void addTo(NamespaceStorageNode storage, K key, V value);
161 public Class<N> getIdentifier() {
165 protected final V getFromLocalStorage(final NamespaceStorageNode storage, final K key) {
166 return storage.getFromLocalStorage(getIdentifier(), key);
169 protected final Map<K, V> getAllFromLocalStorage(final NamespaceStorageNode storage) {
170 return storage.getAllFromLocalStorage(getIdentifier());
173 protected final void addToStorage(final NamespaceStorageNode storage, final K key, final V value) {
174 storage.addToLocalStorage(getIdentifier(), key, value);
177 static class StorageSpecific<K, V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
179 StorageNodeType storageType;
181 public StorageSpecific(final Class<N> identifier, final StorageNodeType type) {
183 storageType = Preconditions.checkNotNull(type);
187 public V getFrom(final NamespaceStorageNode storage, final K key) {
188 NamespaceStorageNode current = findClosestTowardsRoot(storage, storageType);
189 return getFromLocalStorage(current, key);
193 public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
194 NamespaceStorageNode current = storage;
195 while (current.getStorageNodeType() != storageType) {
196 current = current.getParentNamespaceStorage();
199 return getAllFromLocalStorage(current);
203 public void addTo(final NamespaceBehaviour.NamespaceStorageNode storage, final K key, final V value) {
204 NamespaceStorageNode current = findClosestTowardsRoot(storage, storageType);
205 addToStorage(current, key, value);
210 static class TreeScoped<K, V, N extends IdentifierNamespace<K, V>> extends NamespaceBehaviour<K, V, N> {
212 public TreeScoped(final Class<N> identifier) {
217 public V getFrom(final NamespaceStorageNode storage, final K key) {
218 NamespaceStorageNode current = storage;
219 while (current != null) {
220 final V val = getFromLocalStorage(current, key);
224 current = current.getParentNamespaceStorage();
230 public Map<K, V> getAllFrom(final NamespaceStorageNode storage) {
231 NamespaceStorageNode current = storage;
232 while (current != null) {
233 final Map<K, V> val = getAllFromLocalStorage(current);
237 current = current.getParentNamespaceStorage();
243 public void addTo(final NamespaceStorageNode storage, final K key, final V value) {
244 addToStorage(storage, key, value);
249 protected static NamespaceStorageNode findClosestTowardsRoot(final NamespaceStorageNode storage, final StorageNodeType type) {
250 NamespaceStorageNode current = storage;
251 while (current != null && current.getStorageNodeType() != type) {
252 current = current.getParentNamespaceStorage();