package org.opendaylight.yangtools.yang.parser.spi.meta;
import com.google.common.base.Preconditions;
+import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
-public final class StatementSupportBundle implements Immutable,NamespaceBehaviour.Registry {
+public final class StatementSupportBundle implements Immutable, NamespaceBehaviour.Registry {
- private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, ImmutableMap.<QName, StatementSupport<?, ?, ?>>of(), ImmutableMap.<Class<?>, NamespaceBehaviour<?, ?, ?>>of());
+ private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, null, ImmutableMap.of(),
+ ImmutableMap.of(), ImmutableTable.of());
private final StatementSupportBundle parent;
- private final ImmutableMap<QName, StatementSupport<?,?,?>> definitions;
+ private final ImmutableMap<QName, StatementSupport<?, ?, ?>> commonDefinitions;
+ private final ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificDefinitions;
private final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaceDefinitions;
+ private final Set<YangVersion> supportedVersions;
- private StatementSupportBundle(StatementSupportBundle parent,
- ImmutableMap<QName, StatementSupport<?, ?, ?>> statements,
- ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces) {
+ private StatementSupportBundle(final StatementSupportBundle parent,
+ final Set<YangVersion> supportedVersions,
+ final ImmutableMap<QName, StatementSupport<?, ?, ?>> commonStatements,
+ final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces,
+ final ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificStatements) {
this.parent = parent;
- this.definitions = statements;
+ this.supportedVersions = supportedVersions;
+ this.commonDefinitions = commonStatements;
this.namespaceDefinitions = namespaces;
+ this.versionSpecificDefinitions = versionSpecificStatements;
}
- public static final Builder builder() {
- return new Builder(EMPTY);
+ /**
+ * Returns statement definitions common for all versions
+ *
+ * @return map of common statement definitions
+ */
+ public ImmutableMap<QName, StatementSupport<?, ?, ?>> getCommonDefinitions() {
+ return commonDefinitions;
}
- public static final Builder derivedFrom(StatementSupportBundle parent) {
- return new Builder(parent);
+ /**
+ * Returns statement definitions specific for requested version. Result of
+ * this method doesn't include common statement definitions.
+ *
+ * @param version
+ * requested version
+ * @return map of statement definitions specific for requested version, it
+ * doesn't include common statement definitions.
+ */
+ public ImmutableMap<QName, StatementSupport<?, ?, ?>> getDefinitionsSpecificForVersion(final YangVersion version) {
+ return versionSpecificDefinitions.row(version);
+ }
+
+ /**
+ * Returns all version specific statement definitions. Result of this method
+ * doesn't include common statement definitions.
+ *
+ * @return table of all version specific statement definitions, it doesn't
+ * include common statement definitions.
+ */
+ public ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> getAllVersionSpecificDefinitions() {
+ return versionSpecificDefinitions;
+ }
+
+ public ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> getNamespaceDefinitions() {
+ return namespaceDefinitions;
+ }
+
+ public static Builder builder(final Set<YangVersion> supportedVersions) {
+ return new Builder(supportedVersions, EMPTY);
+ }
+
+ public static Builder derivedFrom(final StatementSupportBundle parent) {
+ Preconditions.checkNotNull(parent);
+ return new Builder(parent.getSupportedVersions(), parent);
+ }
+
+ public Set<YangVersion> getSupportedVersions() {
+ return supportedVersions;
}
@Override
- public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(Class<N> namespace)
- throws NamespaceNotAvailableException {
- NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
+ public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(
+ final Class<N> namespace) throws NamespaceNotAvailableException {
+ final NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
if (potential != null) {
Preconditions.checkState(namespace.equals(potential.getIdentifier()));
* Safe cast, previous checkState checks equivalence of key from
* which type argument are derived
*/
- @SuppressWarnings("unchecked")
- NamespaceBehaviour<K, V, N> casted = (NamespaceBehaviour<K, V, N>) potential;
- return casted;
+ return (NamespaceBehaviour<K, V, N>) potential;
}
if (parent != null) {
return parent.getNamespaceBehaviour(namespace);
return null;
}
- public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(Class<N> namespace) {
+ public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(final Class<N> namespace) {
if (namespaceDefinitions.containsKey(namespace)) {
return true;
}
return false;
}
- public StatementSupport<?, ?,?> getStatementDefinition(QName stmtName) {
- StatementSupport<?,?, ?> potential = definitions.get(stmtName);
+ public StatementSupport<?, ?, ?> getStatementDefinition(final YangVersion version, final QName stmtName) {
+ StatementSupport<?, ?, ?> result = getVersionSpecificStatementDefinition(version, stmtName);
+ if (result == null) {
+ result = getCommonStatementDefinition(stmtName);
+ }
+
+ return result;
+ }
+
+ private StatementSupport<?, ?, ?> getCommonStatementDefinition(final QName stmtName) {
+ final StatementSupport<?, ?, ?> potential = commonDefinitions.get(stmtName);
if (potential != null) {
return potential;
}
if (parent != null) {
- return parent.getStatementDefinition(stmtName);
+ return parent.getCommonStatementDefinition(stmtName);
}
return null;
}
- public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
+ private StatementSupport<?, ?, ?> getVersionSpecificStatementDefinition(final YangVersion version,
+ final QName stmtName) {
+ final StatementSupport<?, ?, ?> potential = versionSpecificDefinitions.get(version, stmtName);
+ if (potential != null) {
+ return potential;
+ }
- private final StatementSupportBundle parent;
- private final Map<QName, StatementSupport<?,?,?>> statements = new HashMap<>();
+ if (parent != null) {
+ return parent.getVersionSpecificStatementDefinition(version, stmtName);
+ }
+ return null;
+ }
+
+ public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
+ private final Map<QName, StatementSupport<?, ?, ?>> commonStatements = new HashMap<>();
+ private final Table<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificStatements = HashBasedTable
+ .create();
private final Map<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces = new HashMap<>();
- Builder(StatementSupportBundle parent) {
- this.parent = parent;
+ private final Set<YangVersion> supportedVersions;
+ private StatementSupportBundle parent;
+
+ Builder(final Set<YangVersion> supportedVersions, final StatementSupportBundle parent) {
+ this.parent = Preconditions.checkNotNull(parent);
+ this.supportedVersions = ImmutableSet.copyOf(supportedVersions);
+ }
+
+ public Builder addSupport(final StatementSupport<?, ?, ?> definition) {
+ final QName identifier = definition.getStatementName();
+ Preconditions.checkState(!commonStatements.containsKey(identifier),
+ "Statement %s already defined in common statement bundle.", identifier);
+ Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null,
+ "Statement %s already defined.", identifier);
+ commonStatements.put(identifier, definition);
+ return this;
}
- public Builder addSupport(StatementSupport<?, ?,?> definition) {
- QName identifier = definition.getStatementName();
- Preconditions.checkState(!statements.containsKey(identifier), "Statement %s already defined.",identifier);
- Preconditions.checkState(parent.getStatementDefinition(identifier) == null, "Statement %s already defined.",identifier);
- statements.put(identifier, definition);
+ public Builder addVersionSpecificSupport(final YangVersion version,
+ final StatementSupport<?, ?, ?> definition) {
+ Preconditions.checkNotNull(version);
+ Preconditions.checkNotNull(definition);
+ Preconditions.checkArgument(supportedVersions.contains(version));
+
+ final QName identifier = definition.getStatementName();
+ Preconditions.checkState(!commonStatements.containsKey(identifier),
+ "Statement %s already defined in common statement bundle.", identifier);
+ Preconditions.checkState(!versionSpecificStatements.contains(version, identifier),
+ "Statement %s already defined for version %s.", identifier, version);
+ Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null,
+ "Statement %s already defined in parent's common statement bundle.", identifier);
+ Preconditions.checkState(parent.getVersionSpecificStatementDefinition(version, identifier) == null,
+ "Statement %s already defined for version %s in parent's statement bundle.", identifier, version);
+ versionSpecificStatements.put(version, identifier, definition);
return this;
}
- public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(NamespaceBehaviour<K, V, N> namespaceSupport) {
- Class<N> identifier = namespaceSupport.getIdentifier();
+ public <K, V, N extends IdentifierNamespace<K, V>> Builder addSupport(
+ final NamespaceBehaviour<K, V, N> namespaceSupport) {
+ final Class<N> identifier = namespaceSupport.getIdentifier();
Preconditions.checkState(!namespaces.containsKey(identifier));
Preconditions.checkState(!parent.hasNamespaceBehaviour(identifier));
namespaces.put(identifier, namespaceSupport);
return this;
}
- @Override
- public StatementSupportBundle build() {
- return new StatementSupportBundle(parent, ImmutableMap.copyOf(statements), ImmutableMap.copyOf(namespaces));
+ public Set<YangVersion> getSupportedVersions() {
+ return supportedVersions;
}
- }
+ public Builder setParent(final StatementSupportBundle parent) {
+ this.parent = parent;
+ return this;
+ }
+ @Override
+ public StatementSupportBundle build() {
+ Preconditions.checkState(parent != null, "Parent must not be null");
+ return new StatementSupportBundle(parent, supportedVersions, ImmutableMap.copyOf(commonStatements),
+ ImmutableMap.copyOf(namespaces), ImmutableTable.copyOf(versionSpecificStatements));
+ }
+ }
}