From 064d4eae6564dc3892d85caecf87ccdaf4e2ea20 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 7 Jun 2017 01:43:46 +0200 Subject: [PATCH] Enforce namespace listener compatibility 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 --- .../yang/parser/spi/meta/StmtContext.java | 16 ++++ .../NamespaceBehaviourWithListeners.java | 10 +-- .../stmt/reactor/NamespaceStorageSupport.java | 6 ++ .../stmt/reactor/StatementContextBase.java | 73 +++++++------------ 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java index 7a4c4eea2e..52bd1aa1c9 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java @@ -101,8 +101,14 @@ public interface StmtContext, E extends Effect @Nonnull Collection> 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, 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 + */ > void addContext( Class namespace, KT key, StmtContext stmt); diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java index 5f77fd4aaf..83225d0649 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java @@ -19,9 +19,9 @@ abstract class NamespaceBehaviourWithListeners { 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> keyListeners, + protected void notifyListeners(final NamespaceStorageNode storage, final Iterator> keyListeners, final V value) { List> toNotify = new ArrayList<>(); while (keyListeners.hasNext()) { @@ -82,7 +82,7 @@ abstract class NamespaceBehaviourWithListeners namespace) { + final void addDerivedNamespace(final VirtualNamespaceContext namespace) { derivedNamespaces.add(namespace); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java index 82dd703048..ba55707b37 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java @@ -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 > void onNamespaceElementAdded(final Class type, final K key, final V value) { // NOOP diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java index 5711829dd6..6edf920343 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java @@ -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, E extends EffectiveStatement> extends NamespaceStorageSupport implements StmtContext.Mutable { /** - * 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, 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, 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 definition; private final StatementSourceReference statementDeclSource; private final String rawArgument; @@ -364,7 +367,8 @@ public abstract class StatementContextBase, E Preconditions.checkState(inProgressPhase != ModelProcessingPhase.EFFECTIVE_MODEL, "Declared statement cannot be added in effective phase at: %s", getStatementSourceReference()); - final Optional> implicitStatement = definition.beforeSubStatementCreated(this, offset, def, ref, argument); + final Optional> 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, 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, E return declaredInstance; } - /** - * builds {@link EffectiveStatement} for statement context - */ @Override public E buildEffective() { if (effectiveInstance == null) { @@ -411,7 +409,7 @@ public abstract class StatementContextBase, 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, 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, E definition().checkNamespaceAllowed(type); } - /** - * occurs when an item is added to model namespace - * - * @throws SourceException instance of SourceException - */ @Override - protected > void onNamespaceElementAdded(final Class type, final K key, final V value) { + protected > void onNamespaceElementAdded(final Class type, final K key, + final V value) { // definition().onNamespaceElementAdded(this, type, key, value); } @@ -524,27 +518,26 @@ public abstract class StatementContextBase, 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 behaviour = getBehaviourRegistry().getNamespaceBehaviour(type); - if (behaviour instanceof NamespaceBehaviourWithListeners) { - final NamespaceBehaviourWithListeners casted = (NamespaceBehaviourWithListeners) behaviour; - casted.addValueListener(new ValueAddedListener(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 casted = (NamespaceBehaviourWithListeners) behaviour; + casted.addValueListener(new ValueAddedListener(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, 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 > void addContext(final Class namespace, final KT key, - final StmtContext stmt) { + public > void addContext(final Class namespace, + final KT key,final StmtContext stmt) { addContextToNamespace(namespace, key, stmt); } -- 2.36.6