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 this method does nit include common
58 * 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 does not include common statement
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()));
104 // Safe cast, previous checkState checks equivalence of key from which type argument are derived
105 return (NamespaceBehaviour<K, V, N>) potential;
107 if (parent != null) {
108 return parent.getNamespaceBehaviour(namespace);
113 public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(final Class<N> namespace) {
114 if (namespaceDefinitions.containsKey(namespace)) {
117 if (parent != null) {
118 return parent.hasNamespaceBehaviour(namespace);
123 public StatementSupport<?, ?, ?> getStatementDefinition(final YangVersion version, final QName stmtName) {
124 StatementSupport<?, ?, ?> result = getVersionSpecificStatementDefinition(version, stmtName);
125 if (result == null) {
126 result = getCommonStatementDefinition(stmtName);
132 private StatementSupport<?, ?, ?> getCommonStatementDefinition(final QName stmtName) {
133 final StatementSupport<?, ?, ?> potential = commonDefinitions.get(stmtName);
134 if (potential != null) {
137 if (parent != null) {
138 return parent.getCommonStatementDefinition(stmtName);
143 private StatementSupport<?, ?, ?> getVersionSpecificStatementDefinition(final YangVersion version,
144 final QName stmtName) {
145 final StatementSupport<?, ?, ?> potential = versionSpecificDefinitions.get(version, stmtName);
146 if (potential != null) {
150 if (parent != null) {
151 return parent.getVersionSpecificStatementDefinition(version, stmtName);
156 public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
157 private final Map<QName, StatementSupport<?, ?, ?>> commonStatements = new HashMap<>();
158 private final Table<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificStatements = HashBasedTable
160 private final Map<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces = new HashMap<>();
162 private final Set<YangVersion> supportedVersions;
163 private StatementSupportBundle parent;
165 Builder(final Set<YangVersion> supportedVersions, final StatementSupportBundle parent) {
166 this.parent = Preconditions.checkNotNull(parent);
167 this.supportedVersions = ImmutableSet.copyOf(supportedVersions);
170 public Builder addSupport(final StatementSupport<?, ?, ?> definition) {
171 final QName identifier = definition.getStatementName();
172 Preconditions.checkState(!commonStatements.containsKey(identifier),
173 "Statement %s already defined in common statement bundle.", identifier);
174 Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null,
175 "Statement %s already defined.", identifier);
176 commonStatements.put(identifier, definition);
180 public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(
181 final NamespaceBehaviour<K, V, N> namespaceSupport) {
182 final Class<N> identifier = namespaceSupport.getIdentifier();
183 Preconditions.checkState(!namespaces.containsKey(identifier));
184 Preconditions.checkState(!parent.hasNamespaceBehaviour(identifier));
185 namespaces.put(identifier, namespaceSupport);
189 public Builder addVersionSpecificSupport(final YangVersion version,
190 final StatementSupport<?, ?, ?> definition) {
191 Preconditions.checkNotNull(version);
192 Preconditions.checkNotNull(definition);
193 Preconditions.checkArgument(supportedVersions.contains(version));
195 final QName identifier = definition.getStatementName();
196 Preconditions.checkState(!commonStatements.containsKey(identifier),
197 "Statement %s already defined in common statement bundle.", identifier);
198 Preconditions.checkState(!versionSpecificStatements.contains(version, identifier),
199 "Statement %s already defined for version %s.", identifier, version);
200 Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null,
201 "Statement %s already defined in parent's common statement bundle.", identifier);
202 Preconditions.checkState(parent.getVersionSpecificStatementDefinition(version, identifier) == null,
203 "Statement %s already defined for version %s in parent's statement bundle.", identifier, version);
204 versionSpecificStatements.put(version, identifier, definition);
208 public Set<YangVersion> getSupportedVersions() {
209 return supportedVersions;
212 public Builder setParent(final StatementSupportBundle parent) {
213 this.parent = parent;
218 public StatementSupportBundle build() {
219 Preconditions.checkState(parent != null, "Parent must not be null");
220 return new StatementSupportBundle(parent, supportedVersions, ImmutableMap.copyOf(commonStatements),
221 ImmutableMap.copyOf(namespaces), ImmutableTable.copyOf(versionSpecificStatements));