01435600334c555d263c69ded77d1dff597b2452
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / StatementSupportBundle.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.spi.meta;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableMap;
12 import java.util.HashMap;
13 import java.util.Map;
14 import org.opendaylight.yangtools.concepts.Immutable;
15 import org.opendaylight.yangtools.yang.common.QName;
16 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
17
18 public final class StatementSupportBundle implements Immutable,NamespaceBehaviour.Registry {
19
20     private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, ImmutableMap.<QName, StatementSupport<?, ?, ?>>of(), ImmutableMap.<Class<?>, NamespaceBehaviour<?, ?, ?>>of());
21
22     private final StatementSupportBundle parent;
23     private final ImmutableMap<QName, StatementSupport<?,?,?>> definitions;
24     private final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaceDefinitions;
25
26     public ImmutableMap<QName, StatementSupport<?, ?, ?>> getDefinitions() {
27         return definitions;
28     }
29
30     private StatementSupportBundle(StatementSupportBundle parent,
31             ImmutableMap<QName, StatementSupport<?, ?, ?>> statements,
32             ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces) {
33         this.parent = parent;
34         this.definitions = statements;
35         this.namespaceDefinitions = namespaces;
36     }
37
38     public static Builder builder() {
39         return new Builder(EMPTY);
40     }
41
42     public static Builder derivedFrom(StatementSupportBundle parent) {
43         return new Builder(parent);
44     }
45
46     @Override
47     public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> namespace)
48             throws NamespaceNotAvailableException {
49         NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
50         if (potential != null) {
51             Preconditions.checkState(namespace.equals(potential.getIdentifier()));
52
53             /*
54              * Safe cast, previous checkState checks equivalence of key from
55              * which type argument are derived
56              */
57             @SuppressWarnings("unchecked")
58             NamespaceBehaviour<K, V, N> casted = (NamespaceBehaviour<K, V, N>) potential;
59             return casted;
60         }
61         if (parent != null) {
62             return parent.getNamespaceBehaviour(namespace);
63         }
64         return null;
65     }
66
67     public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(Class<N> namespace) {
68         if (namespaceDefinitions.containsKey(namespace)) {
69             return true;
70         }
71         if (parent != null) {
72             return parent.hasNamespaceBehaviour(namespace);
73         }
74         return false;
75     }
76
77     public StatementSupport<?, ?,?> getStatementDefinition(QName stmtName) {
78         StatementSupport<?,?, ?> potential = definitions.get(stmtName);
79         if (potential != null) {
80             return potential;
81         }
82         if (parent != null) {
83             return parent.getStatementDefinition(stmtName);
84         }
85         return null;
86     }
87
88     public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
89
90         private final StatementSupportBundle parent;
91         private final Map<QName, StatementSupport<?,?,?>> statements = new HashMap<>();
92         private final Map<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces = new HashMap<>();
93
94         Builder(StatementSupportBundle parent) {
95             this.parent = parent;
96         }
97
98         public Builder addSupport(StatementSupport<?, ?,?> definition) {
99             QName identifier = definition.getStatementName();
100             Preconditions.checkState(!statements.containsKey(identifier), "Statement %s already defined.",identifier);
101             Preconditions.checkState(parent.getStatementDefinition(identifier) == null, "Statement %s already defined.",identifier);
102             statements.put(identifier, definition);
103             return this;
104         }
105
106        public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(NamespaceBehaviour<K, V, N> namespaceSupport) {
107             Class<N> identifier = namespaceSupport.getIdentifier();
108             Preconditions.checkState(!namespaces.containsKey(identifier));
109             Preconditions.checkState(!parent.hasNamespaceBehaviour(identifier));
110             namespaces.put(identifier, namespaceSupport);
111             return this;
112         }
113
114        @Override
115         public StatementSupportBundle build() {
116             return new StatementSupportBundle(parent, ImmutableMap.copyOf(statements), ImmutableMap.copyOf(namespaces));
117         }
118
119     }
120
121 }