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;
11 import com.google.common.collect.HashBasedTable;
12 import com.google.common.collect.ImmutableMap;
13 import com.google.common.collect.ImmutableSet;
14 import com.google.common.collect.ImmutableTable;
15 import com.google.common.collect.Table;
16 import java.util.HashMap;
19 import org.opendaylight.yangtools.concepts.Immutable;
20 import org.opendaylight.yangtools.yang.common.QName;
21 import org.opendaylight.yangtools.yang.common.YangVersion;
22 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
24 public final class StatementSupportBundle implements Immutable, NamespaceBehaviour.Registry {
26 private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, null, ImmutableMap.of(),
27 ImmutableMap.of(), ImmutableTable.of());
29 private final StatementSupportBundle parent;
30 private final ImmutableMap<QName, StatementSupport<?, ?, ?>> commonDefinitions;
31 private final ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificDefinitions;
32 private final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaceDefinitions;
33 private final Set<YangVersion> supportedVersions;
35 private StatementSupportBundle(final StatementSupportBundle parent,
36 final Set<YangVersion> supportedVersions,
37 final ImmutableMap<QName, StatementSupport<?, ?, ?>> commonStatements,
38 final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces,
39 final ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificStatements) {
41 this.supportedVersions = supportedVersions;
42 this.commonDefinitions = commonStatements;
43 this.namespaceDefinitions = namespaces;
44 this.versionSpecificDefinitions = versionSpecificStatements;
48 * Returns statement definitions common for all versions
50 * @return map of common statement definitions
52 public ImmutableMap<QName, StatementSupport<?, ?, ?>> getCommonDefinitions() {
53 return commonDefinitions;
57 * Returns statement definitions specific for requested version. Result of
58 * this method doesn't include common statement definitions.
62 * @return map of statement definitions specific for requested version, it
63 * doesn't include common statement definitions.
65 public ImmutableMap<QName, StatementSupport<?, ?, ?>> getDefinitionsSpecificForVersion(final YangVersion version) {
66 return versionSpecificDefinitions.row(version);
70 * Returns all version specific statement definitions. Result of this method
71 * doesn't include common statement definitions.
73 * @return table of all version specific statement definitions, it doesn't
74 * include common statement definitions.
76 public ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> getAllVersionSpecificDefinitions() {
77 return versionSpecificDefinitions;
80 public ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> getNamespaceDefinitions() {
81 return namespaceDefinitions;
84 public static Builder builder(final Set<YangVersion> supportedVersions) {
85 return new Builder(supportedVersions, EMPTY);
88 public static Builder derivedFrom(final StatementSupportBundle parent) {
89 Preconditions.checkNotNull(parent);
90 return new Builder(parent.getSupportedVersions(), parent);
93 public Set<YangVersion> getSupportedVersions() {
94 return supportedVersions;
98 public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(
99 final Class<N> namespace) throws NamespaceNotAvailableException {
100 final NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
101 if (potential != null) {
102 Preconditions.checkState(namespace.equals(potential.getIdentifier()));
105 * Safe cast, previous checkState checks equivalence of key from
106 * which type argument are derived
108 return (NamespaceBehaviour<K, V, N>) potential;
110 if (parent != null) {
111 return parent.getNamespaceBehaviour(namespace);
116 public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(final Class<N> namespace) {
117 if (namespaceDefinitions.containsKey(namespace)) {
120 if (parent != null) {
121 return parent.hasNamespaceBehaviour(namespace);
126 public StatementSupport<?, ?, ?> getStatementDefinition(final YangVersion version, final QName stmtName) {
127 StatementSupport<?, ?, ?> result = getVersionSpecificStatementDefinition(version, stmtName);
128 if (result == null) {
129 result = getCommonStatementDefinition(stmtName);
135 private StatementSupport<?, ?, ?> getCommonStatementDefinition(final QName stmtName) {
136 final StatementSupport<?, ?, ?> potential = commonDefinitions.get(stmtName);
137 if (potential != null) {
140 if (parent != null) {
141 return parent.getCommonStatementDefinition(stmtName);
146 private StatementSupport<?, ?, ?> getVersionSpecificStatementDefinition(final YangVersion version,
147 final QName stmtName) {
148 final StatementSupport<?, ?, ?> potential = versionSpecificDefinitions.get(version, stmtName);
149 if (potential != null) {
153 if (parent != null) {
154 return parent.getVersionSpecificStatementDefinition(version, stmtName);
159 public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
160 private final Map<QName, StatementSupport<?, ?, ?>> commonStatements = new HashMap<>();
161 private final Table<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificStatements = HashBasedTable
163 private final Map<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces = new HashMap<>();
165 private final Set<YangVersion> supportedVersions;
166 private StatementSupportBundle parent;
168 Builder(final Set<YangVersion> supportedVersions, final StatementSupportBundle parent) {
169 this.parent = Preconditions.checkNotNull(parent);
170 this.supportedVersions = ImmutableSet.copyOf(supportedVersions);
173 public Builder addSupport(final StatementSupport<?, ?, ?> definition) {
174 final QName identifier = definition.getStatementName();
175 Preconditions.checkState(!commonStatements.containsKey(identifier),
176 "Statement %s already defined in common statement bundle.", identifier);
177 Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null,
178 "Statement %s already defined.", identifier);
179 commonStatements.put(identifier, definition);
183 public Builder addVersionSpecificSupport(final YangVersion version,
184 final StatementSupport<?, ?, ?> definition) {
185 Preconditions.checkNotNull(version);
186 Preconditions.checkNotNull(definition);
187 Preconditions.checkArgument(supportedVersions.contains(version));
189 final QName identifier = definition.getStatementName();
190 Preconditions.checkState(!commonStatements.containsKey(identifier),
191 "Statement %s already defined in common statement bundle.", identifier);
192 Preconditions.checkState(!versionSpecificStatements.contains(version, identifier),
193 "Statement %s already defined for version %s.", identifier, version);
194 Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null,
195 "Statement %s already defined in parent's common statement bundle.", identifier);
196 Preconditions.checkState(parent.getVersionSpecificStatementDefinition(version, identifier) == null,
197 "Statement %s already defined for version %s in parent's statement bundle.", identifier, version);
198 versionSpecificStatements.put(version, identifier, definition);
202 public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(
203 final NamespaceBehaviour<K, V, N> namespaceSupport) {
204 final Class<N> identifier = namespaceSupport.getIdentifier();
205 Preconditions.checkState(!namespaces.containsKey(identifier));
206 Preconditions.checkState(!parent.hasNamespaceBehaviour(identifier));
207 namespaces.put(identifier, namespaceSupport);
211 public Set<YangVersion> getSupportedVersions() {
212 return supportedVersions;
215 public Builder setParent(final StatementSupportBundle parent) {
216 this.parent = parent;
221 public StatementSupportBundle build() {
222 Preconditions.checkState(parent != null, "Parent must not be null");
223 return new StatementSupportBundle(parent, supportedVersions, ImmutableMap.copyOf(commonStatements),
224 ImmutableMap.copyOf(namespaces), ImmutableTable.copyOf(versionSpecificStatements));