Define ExecutionOrder
[yangtools.git] / yang / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / StatementSupportBundle.java
index 3d9c9375f92b03c265049ede136da8ecf30e2e3c..a78dd7279513bc3d3f968404b1da7ac2cd7421ca 100644 (file)
@@ -7,6 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.parser.spi.meta;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.ImmutableMap;
@@ -19,7 +23,8 @@ 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;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public final class StatementSupportBundle implements Immutable, NamespaceBehaviour.Registry {
 
@@ -30,10 +35,10 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     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 final ImmutableSet<YangVersion> supportedVersions;
 
     private StatementSupportBundle(final StatementSupportBundle parent,
-            final Set<YangVersion> supportedVersions,
+            final ImmutableSet<YangVersion> supportedVersions,
             final ImmutableMap<QName, StatementSupport<?, ?, ?>> commonStatements,
             final ImmutableMap<Class<?>, NamespaceBehaviour<?, ?, ?>> namespaces,
             final ImmutableTable<YangVersion, QName, StatementSupport<?, ?, ?>> versionSpecificStatements) {
@@ -45,7 +50,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     }
 
     /**
-     * Returns statement definitions common for all versions
+     * Returns statement definitions common for all versions.
      *
      * @return map of common statement definitions
      */
@@ -54,8 +59,8 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     }
 
     /**
-     * Returns statement definitions specific for requested version. Result of
-     * this method doesn't include common statement definitions.
+     * Returns statement definitions specific for requested version. Result of this method does nit include common
+     * statement definitions.
      *
      * @param version
      *            requested version
@@ -67,8 +72,8 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     }
 
     /**
-     * Returns all version specific statement definitions. Result of this method
-     * doesn't include common statement definitions.
+     * Returns all version specific statement definitions. Result of this method does not include common statement
+     * definitions.
      *
      * @return table of all version specific statement definitions, it doesn't
      *         include common statement definitions.
@@ -86,7 +91,6 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     }
 
     public static Builder derivedFrom(final StatementSupportBundle parent) {
-        Preconditions.checkNotNull(parent);
         return new Builder(parent.getSupportedVersions(), parent);
     }
 
@@ -95,16 +99,14 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     }
 
     @Override
-    public <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(
-            final Class<N> namespace) throws NamespaceNotAvailableException {
+    @SuppressWarnings("unchecked")
+    public <K, V, N extends ParserNamespace<K, V>> NamespaceBehaviour<K, V, N> getNamespaceBehaviour(
+            final Class<N> namespace) {
         final NamespaceBehaviour<?, ?, ?> potential = namespaceDefinitions.get(namespace);
         if (potential != null) {
-            Preconditions.checkState(namespace.equals(potential.getIdentifier()));
+            checkState(namespace.equals(potential.getIdentifier()));
 
-            /*
-             * Safe cast, previous checkState checks equivalence of key from
-             * which type argument are derived
-             */
+            // Safe cast, previous checkState checks equivalence of key from which type argument are derived
             return (NamespaceBehaviour<K, V, N>) potential;
         }
         if (parent != null) {
@@ -113,7 +115,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
         return null;
     }
 
-    public <K, V, N extends IdentifierNamespace<K, V>> boolean hasNamespaceBehaviour(final Class<N> namespace) {
+    public <K, V, N extends ParserNamespace<K, V>> boolean hasNamespaceBehaviour(final Class<N> namespace) {
         if (namespaceDefinitions.containsKey(namespace)) {
             return true;
         }
@@ -157,57 +159,56 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
     }
 
     public static class Builder implements org.opendaylight.yangtools.concepts.Builder<StatementSupportBundle> {
+        private static final Logger LOG = LoggerFactory.getLogger(Builder.class);
+
         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<>();
 
-        private final Set<YangVersion> supportedVersions;
+        private final ImmutableSet<YangVersion> supportedVersions;
         private StatementSupportBundle parent;
 
         Builder(final Set<YangVersion> supportedVersions, final StatementSupportBundle parent) {
-            this.parent = Preconditions.checkNotNull(parent);
+            this.parent = requireNonNull(parent);
             this.supportedVersions = ImmutableSet.copyOf(supportedVersions);
         }
 
-        public Builder addSupport(final StatementSupport<?, ?, ?> definition) {
-            final QName identifier = definition.getStatementName();
-            Preconditions.checkState(!commonStatements.containsKey(identifier),
+        public Builder addSupport(final StatementSupport<?, ?, ?> support) {
+            final QName identifier = support.getStatementName();
+            checkNoParentDefinition(identifier);
+
+            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);
+            commonStatements.put(identifier, support);
+            return this;
+        }
+
+        public <K, V, N extends ParserNamespace<K, V>> Builder addSupport(
+                final NamespaceBehaviour<K, V, N> namespaceSupport) {
+            final Class<N> identifier = namespaceSupport.getIdentifier();
+            checkState(!namespaces.containsKey(identifier));
+            checkState(!parent.hasNamespaceBehaviour(identifier));
+            namespaces.put(identifier, namespaceSupport);
             return this;
         }
 
         public Builder addVersionSpecificSupport(final YangVersion version,
                 final StatementSupport<?, ?, ?> definition) {
-            Preconditions.checkNotNull(version);
-            Preconditions.checkNotNull(definition);
-            Preconditions.checkArgument(supportedVersions.contains(version));
+            checkArgument(supportedVersions.contains(requireNonNull(version)));
 
             final QName identifier = definition.getStatementName();
-            Preconditions.checkState(!commonStatements.containsKey(identifier),
+            checkState(!commonStatements.containsKey(identifier),
                     "Statement %s already defined in common statement bundle.", identifier);
-            Preconditions.checkState(!versionSpecificStatements.contains(version, identifier),
+            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,
+            checkNoParentDefinition(identifier);
+            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(
-                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;
-        }
-
         public Set<YangVersion> getSupportedVersions() {
             return supportedVersions;
         }
@@ -217,11 +218,26 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio
             return this;
         }
 
+        public Builder overrideSupport(final StatementSupport<?, ?, ?> support) {
+            final QName identifier = support.getStatementName();
+            checkNoParentDefinition(identifier);
+
+            final StatementSupport<?, ?, ?> previousSupport = commonStatements.replace(identifier, support);
+            checkState(previousSupport != null, "Statement %s was not previously defined", identifier);
+            LOG.debug("Changed statement {} support from {} to {}", identifier, previousSupport, support);
+            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));
         }
+
+        private void checkNoParentDefinition(final QName identifier) {
+            checkState(parent.getCommonStatementDefinition(identifier) == null,
+                    "Statement %s is defined in parent's common statement bundle", identifier);
+        }
     }
 }