Enforce namespace listener compatibility 81/58381/6
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 6 Jun 2017 23:43:46 +0000 (01:43 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 7 Jun 2017 18:45:15 +0000 (20:45 +0200)
If we happened to register a listener to a namespace which does not
support listening, we would silently ignore the listener. Instead
of doing that, complain loudly when such a thing occurs.

Change-Id: If77bbec91571178fe7a1ada169a824d5d8a6807c
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java

index 7a4c4eea2e9ccd99522173eb3b80438f1b442aa9..52bd1aa1c965af39a60cb069cbbea0c9203b9725 100644 (file)
@@ -101,8 +101,14 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
     @Nonnull
     Collection<StatementContextBase<?, ?, ?>> effectiveSubstatements();
 
+    /**
+     * Builds {@link DeclaredStatement} for statement context.
+     */
     D buildDeclared();
 
+    /**
+     * Builds {@link EffectiveStatement} for statement context
+     */
     E buildEffective();
 
     boolean isSupportedToBuildEffective();
@@ -178,6 +184,16 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
          */
         @Nonnull ModelActionBuilder newInferenceAction(@Nonnull ModelProcessingPhase phase);
 
+        /**
+         * adds statement to namespace map with the key
+         *
+         * @param namespace
+         *            {@link StatementNamespace} child that determines namespace to be added to
+         * @param key
+         *            of type according to namespace class specification
+         * @param stmt
+         *            to be added to namespace map
+         */
         <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(
                 Class<N> namespace, KT key, StmtContext<?, ?, ?> stmt);
 
index 5f77fd4aaf4c3ec9c60ce4a010728621e24499e7..83225d064989013da61c4143330ddf75cfd38da4 100644 (file)
@@ -19,9 +19,9 @@ abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespa
 
     abstract static class ValueAddedListener<K> {
         private final NamespaceStorageNode ctxNode;
-        private K key;
+        private final K key;
 
-        public ValueAddedListener(final NamespaceStorageNode contextNode, K key) {
+        public ValueAddedListener(final NamespaceStorageNode contextNode, final K key) {
             this.ctxNode = contextNode;
             this.key = key;
         }
@@ -34,7 +34,7 @@ abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespa
             return key;
         }
 
-        void trigger(Object value) {
+        void trigger(final Object value) {
             onValueAdded(key, value);
         }
 
@@ -57,7 +57,7 @@ abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespa
     @Override
     public abstract void addTo(final NamespaceStorageNode storage, final K key, final V value);
 
-    protected void notifyListeners(final NamespaceStorageNode storage, Iterator<ValueAddedListener<K>> keyListeners,
+    protected void notifyListeners(final NamespaceStorageNode storage, final Iterator<ValueAddedListener<K>> keyListeners,
             final V value) {
         List<ValueAddedListener<K>> toNotify = new ArrayList<>();
         while (keyListeners.hasNext()) {
@@ -82,7 +82,7 @@ abstract class NamespaceBehaviourWithListeners<K, V, N extends IdentifierNamespa
         addListener(listener.key, listener);
     }
 
-    final void addDerivedNamespace(VirtualNamespaceContext<?, V, ?, K> namespace) {
+    final void addDerivedNamespace(final VirtualNamespaceContext<?, V, ?, K> namespace) {
         derivedNamespaces.add(namespace);
     }
 
index 82dd703048ae43cb4825ea82682acd6ca5c9f569..ba55707b374bb0fce7785c8916c1d5db3c29a2ea 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Namesp
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceNotAvailableException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 
 abstract class NamespaceStorageSupport implements NamespaceStorageNode {
 
@@ -39,6 +40,11 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode {
         // NOOP
     }
 
+    /**
+     * Occurs when an item is added to model namespace.
+     *
+     * @throws SourceException instance of SourceException
+     */
     protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(final Class<N> type, final K key,
             final V value) {
         // NOOP
index 5711829dd67d20fbf5eab37eb8049f05c285b535..6edf9203435a26dde04918fecf6b735cd91911e3 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMultimap;
@@ -40,12 +39,14 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.NamespaceBehaviourWithListeners.ValueAddedListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
         extends NamespaceStorageSupport implements StmtContext.Mutable<A, D, E> {
 
     /**
-     * event listener when an item is added to model namespace
+     * event listener when an item is added to model namespace.
      */
     interface OnNamespaceItemAdded extends EventListener {
         /**
@@ -55,7 +56,7 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     /**
-     * event listener when a parsing {@link ModelProcessingPhase} is completed
+     * event listener when a parsing {@link ModelProcessingPhase} is completed.
      */
     interface OnPhaseFinished extends EventListener {
         /**
@@ -65,13 +66,15 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     /**
-     * interface for all mutations within an {@link ModelActionBuilder.InferenceAction}
+     * interface for all mutations within an {@link ModelActionBuilder.InferenceAction}.
      */
     interface ContextMutation {
 
         boolean isFinished();
     }
 
+    private static final Logger LOG = LoggerFactory.getLogger(StatementContextBase.class);
+
     private final StatementDefinitionContext<A, D, E> definition;
     private final StatementSourceReference statementDeclSource;
     private final String rawArgument;
@@ -364,7 +367,8 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         Preconditions.checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL,
                 "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference());
 
-        final Optional<StatementContextBase<?, ?, ?>> implicitStatement = definition.beforeSubStatementCreated(this, offset, def, ref, argument);
+        final Optional<StatementContextBase<?, ?, ?>> implicitStatement = definition.beforeSubStatementCreated(this,
+            offset, def, ref, argument);
         if(implicitStatement.isPresent()) {
             final StatementContextBase<?, ?, ?> presentImplicitStmt = implicitStatement.get();
             return presentImplicitStmt.createSubstatement(offset, def, ref, argument);
@@ -386,9 +390,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         return substatements.get(offset);
     }
 
-    /**
-     * builds {@link DeclaredStatement} for statement context
-     */
     @Override
     public D buildDeclared() {
         Preconditions.checkArgument(completedPhase == ModelProcessingPhase.FULL_DECLARATION
@@ -399,9 +400,6 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         return declaredInstance;
     }
 
-    /**
-     * builds {@link EffectiveStatement} for statement context
-     */
     @Override
     public E buildEffective() {
         if (effectiveInstance == null) {
@@ -411,7 +409,7 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     /**
-     * tries to execute current {@link ModelProcessingPhase} of source parsing
+     * tries to execute current {@link ModelProcessingPhase} of source parsing.
      *
      * @param phase
      *            to be executed (completed)
@@ -457,7 +455,7 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     }
 
     /**
-     * Occurs on end of {@link ModelProcessingPhase} of source parsing
+     * Occurs on end of {@link ModelProcessingPhase} of source parsing.
      *
      * @param phase
      *            that was to be completed (finished)
@@ -510,13 +508,9 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         definition().checkNamespaceAllowed(type);
     }
 
-    /**
-     * occurs when an item is added to model namespace
-     *
-     * @throws SourceException instance of SourceException
-     */
     @Override
-    protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(final Class<N> type, final K key, final V value) {
+    protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(final Class<N> type, final K key,
+            final V value) {
         // definition().onNamespaceElementAdded(this, type, key, value);
     }
 
@@ -524,27 +518,26 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
             final OnNamespaceItemAdded listener) throws SourceException {
         final Object potential = getFromNamespace(type, key);
         if (potential != null) {
+            LOG.trace("Listener on {} key {} satisfied immediately", type, key);
             listener.namespaceItemAdded(this, type, key, potential);
             return;
         }
+
         final NamespaceBehaviour<K, V, N> behaviour = getBehaviourRegistry().getNamespaceBehaviour(type);
-        if (behaviour instanceof NamespaceBehaviourWithListeners) {
-            final NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K, V, N>) behaviour;
-            casted.addValueListener(new ValueAddedListener<K>(this, key) {
-                @Override
-                void onValueAdded(final Object key, final Object value) {
-                    try {
-                        listener.namespaceItemAdded(StatementContextBase.this, type, key, value);
-                    } catch (final SourceException e) {
-                        throw Throwables.propagate(e);
-                    }
-                }
-            });
-        }
+        Preconditions.checkArgument(behaviour instanceof NamespaceBehaviourWithListeners,
+            "Namespace {} does not support listeners", type);
+
+        final NamespaceBehaviourWithListeners<K, V, N> casted = (NamespaceBehaviourWithListeners<K, V, N>) behaviour;
+        casted.addValueListener(new ValueAddedListener<K>(this, key) {
+            @Override
+            void onValueAdded(final Object key, final Object value) {
+                listener.namespaceItemAdded(StatementContextBase.this, type, key, value);
+            }
+        });
     }
 
     /**
-     * @see StatementSupport#getPublicView()
+     * See {@link StatementSupport#getPublicView()}.
      */
     @Nonnull
     @Override
@@ -610,19 +603,9 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         phaseMutation.put(phase, mutation);
     }
 
-    /**
-     * adds statement to namespace map with the key
-     *
-     * @param namespace
-     *            {@link StatementNamespace} child that determines namespace to be added to
-     * @param key
-     *            of type according to namespace class specification
-     * @param stmt
-     *            to be added to namespace map
-     */
     @Override
-    public <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(final Class<N> namespace, final KT key,
-            final StmtContext<?, ?, ?> stmt) {
+    public <K, KT extends K, N extends StatementNamespace<K, ?, ?>> void addContext(final Class<N> namespace,
+            final KT key,final StmtContext<?, ?, ?> stmt) {
         addContextToNamespace(namespace, key, stmt);
     }