From f0f4e353a3942eba8eb4c02f6d59d5266436e32a Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 4 May 2022 23:10:35 +0200 Subject: [PATCH] StatementSupport is not a StatementDefinition Differentiate between StatementSupport and StatementDefinition, so as to separate their lifecycle. Change-Id: Id96ece0e6890b1aa1463e5f4e9a378fa3f5949fe Signed-off-by: Robert Varga --- .../OperationsCreateLeafStatements.java | 2 +- .../stmt/reactor/SourceSpecificContext.java | 12 ++++-- .../reactor/StatementDefinitionContext.java | 2 +- .../UnrecognizedStatementSupport.java | 8 ++-- .../meta/AbstractBooleanStatementSupport.java | 2 +- .../parser/spi/meta/StatementSupport.java | 39 ++++++++----------- .../spi/meta/StatementSupportBundle.java | 10 ++--- .../source/QNameToStatementDefinition.java | 2 +- .../source/QNameToStatementDefinitionMap.java | 23 +++++++++-- .../QNameToStatementDefinitionMapTest.java | 14 ++++++- 10 files changed, 69 insertions(+), 45 deletions(-) diff --git a/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/OperationsCreateLeafStatements.java b/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/OperationsCreateLeafStatements.java index 8703cbddf8..1f78430f04 100644 --- a/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/OperationsCreateLeafStatements.java +++ b/parser/rfc8040-parser-support/src/main/java/org/opendaylight/yangtools/rfc8040/parser/OperationsCreateLeafStatements.java @@ -101,7 +101,7 @@ final class OperationsCreateLeafStatements implements InferenceAction { StatementSupport getSupport(final StatementDefinition def, final Class effectiveClass) { final var tmp = verifyNotNull(operations.getFromNamespace(StatementSupportNamespace.class, def.getStatementName())); - final var repr = tmp.getEffectiveRepresentationClass(); + final var repr = tmp.definition().getEffectiveRepresentationClass(); verify(effectiveClass.equals(repr), "Unexpected support %s representation %s", tmp, repr); @SuppressWarnings("unchecked") diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index d34b4e19af..4626f24fc1 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -76,17 +76,21 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha @Override public StatementSupport getFrom(final NamespaceStorageNode storage, final QName key) { - return statementDefinitions.get(key); + return statementDefinitions.getSupport(key); } @Override public Map> getAllFrom(final NamespaceStorageNode storage) { - throw new UnsupportedOperationException("StatementSupportNamespace is immutable"); + throw uoe(); } @Override public void addTo(final NamespaceStorageNode storage, final QName key, final StatementSupport value) { - throw new UnsupportedOperationException("StatementSupportNamespace is immutable"); + throw uoe(); + } + + private static UnsupportedOperationException uoe() { + return new UnsupportedOperationException("StatementSupportNamespace is immutable"); } } @@ -135,7 +139,7 @@ final class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeha if (def == null) { def = globalContext.getModelDefinedStatementDefinition(name); if (def == null) { - final StatementSupport extension = qnameToStmtDefMap.get(name); + final StatementSupport extension = qnameToStmtDefMap.getSupport(name); if (extension != null) { def = new StatementDefinitionContext<>(extension); globalContext.putModelDefinedStatementDefinition(name, def); diff --git a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java index 5eaa0ac809..64d30e8fe3 100644 --- a/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java +++ b/parser/yang-parser-reactor/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java @@ -91,7 +91,7 @@ final class StatementDefinitionContext, E exte } @NonNull QName getStatementName() { - return support.getStatementName(); + return support.statementName(); } @Override diff --git a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java index c5e09340c2..b741dd9287 100644 --- a/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java +++ b/parser/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/UnrecognizedStatementSupport.java @@ -52,13 +52,13 @@ final class UnrecognizedStatementSupport * This code wraps statements encountered inside an extension so they do not get confused with regular * statements. */ - final QName baseQName = getStatementName(); - final QName statementName = QName.create(baseQName, childDef.getStatementName().getLocalName()); + // FIXME: remove this bit? + final QName statementName = QName.create(statementName(), childDef.getStatementName().getLocalName()); - final ModelDefinedStatementDefinition def; + final StatementDefinition def; final Optional optArgDef = childDef.getArgumentDefinition(); if (optArgDef.isPresent()) { - final ArgumentDefinition argDef = optArgDef.get(); + final ArgumentDefinition argDef = optArgDef.orElseThrow(); def = new ModelDefinedStatementDefinition(statementName, argDef.getArgumentName(), argDef.isYinElement()); } else { def = new ModelDefinedStatementDefinition(statementName); diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java index 7d1fc01c68..acce56a415 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java @@ -54,7 +54,7 @@ public abstract class AbstractBooleanStatementSupport Effective Statement representation */ public abstract class StatementSupport, E extends EffectiveStatement> - implements StatementDefinition, StatementFactory { + implements StatementFactory { /** * A baseline class for implementing the {@link StatementFactory#canReuseCurrent(Current, Current, Collection)} * contract in a manner which is consistent with a statement's {@link CopyPolicy}. @@ -196,21 +196,20 @@ public abstract class StatementSupport, E exte } private final @NonNull StatementPolicy policy; - private final @NonNull StatementDefinition def; + private final @NonNull StatementDefinition publicDefinition; private final @NonNull CopyPolicy copyPolicy; @Beta protected StatementSupport(final StatementSupport delegate) { checkArgument(delegate != this); - this.def = delegate.def; + this.publicDefinition = delegate.publicDefinition; this.policy = delegate.policy; this.copyPolicy = delegate.copyPolicy; } @Beta protected StatementSupport(final StatementDefinition publicDefinition, final StatementPolicy policy) { - checkArgument(publicDefinition != this); - this.def = requireNonNull(publicDefinition); + this.publicDefinition = requireNonNull(publicDefinition); this.policy = requireNonNull(policy); this.copyPolicy = policy.copyPolicy; } @@ -225,7 +224,13 @@ public abstract class StatementSupport, E exte * @return public statement definition, which will be present in built statements. */ public final @NonNull StatementDefinition getPublicView() { - return def; + return publicDefinition; + } + + // Appropriate to most definitions + // Non-final for compatible extensions + public @NonNull StatementDefinition definition() { + return publicDefinition; } /** @@ -438,26 +443,16 @@ public abstract class StatementSupport, E exte return false; } - @Override - public final QName getStatementName() { - return def.getStatementName(); + public final @NonNull QName statementName() { + return publicDefinition.getStatementName(); } - @Override - public final Optional getArgumentDefinition() { - return def.getArgumentDefinition(); + public final @Nullable QName argumentName() { + return publicDefinition.getArgumentDefinition().map(ArgumentDefinition::getArgumentName).orElse(null); } - @Override - // Non-final for compatible extensions - public Class> getDeclaredRepresentationClass() { - return def.getDeclaredRepresentationClass(); - } - - @Override - // Non-final for compatible extensions - public Class> getEffectiveRepresentationClass() { - return def.getEffectiveRepresentationClass(); + public final @NonNull Optional getArgumentDefinition() { + return publicDefinition.getArgumentDefinition(); } /** diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java index 8e74f508e5..33bb8b6454 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java @@ -176,7 +176,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio } public @NonNull Builder addSupport(final StatementSupport support) { - final QName identifier = support.getStatementName(); + final QName identifier = support.statementName(); checkNoParentDefinition(identifier); checkState(!commonStatements.containsKey(identifier), @@ -195,10 +195,10 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio } public @NonNull Builder addVersionSpecificSupport(final YangVersion version, - final StatementSupport definition) { + final StatementSupport support) { checkArgument(supportedVersions.contains(requireNonNull(version))); - final QName identifier = definition.getStatementName(); + final QName identifier = support.statementName(); checkState(!commonStatements.containsKey(identifier), "Statement %s already defined in common statement bundle.", identifier); checkState(!versionSpecificStatements.contains(version, identifier), @@ -206,7 +206,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio 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); + versionSpecificStatements.put(version, identifier, support); return this; } @@ -220,7 +220,7 @@ public final class StatementSupportBundle implements Immutable, NamespaceBehavio } public @NonNull Builder overrideSupport(final StatementSupport support) { - final QName identifier = support.getStatementName(); + final QName identifier = support.statementName(); checkNoParentDefinition(identifier); final StatementSupport previousSupport = commonStatements.replace(identifier, support); diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java index 7113ecc7b4..b52edf93f2 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinition.java @@ -23,7 +23,7 @@ public interface QNameToStatementDefinition { * @param identifier QName of requested statement * @return StatementDefinition */ - StatementDefinition get(QName identifier); + @Nullable StatementDefinition get(QName identifier); /** * Returns StatementDefinition with specified namespace and localName. diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMap.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMap.java index 9d7ac23c74..88535b6cb4 100644 --- a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMap.java +++ b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMap.java @@ -11,12 +11,13 @@ import static java.util.Objects.requireNonNull; import java.util.HashMap; import java.util.Map; +import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.XMLNamespace; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; -public class QNameToStatementDefinitionMap implements QNameToStatementDefinition { +public final class QNameToStatementDefinitionMap implements QNameToStatementDefinition { private final Map> noRevQNameToSupport; private final Map> qnameToSupport; @@ -60,12 +61,26 @@ public class QNameToStatementDefinitionMap implements QNameToStatementDefinition } @Override - public StatementSupport get(final QName identifier) { - return qnameToSupport.get(identifier); + public StatementDefinition get(final QName identifier) { + return definitionOf(getSupport(identifier)); } @Override public StatementDefinition getByNamespaceAndLocalName(final XMLNamespace namespace, final String localName) { - return noRevQNameToSupport.get(QName.create(namespace, localName)); + return definitionOf(noRevQNameToSupport.get(QName.create(namespace, localName))); + } + + /** + * Returns StatementSupport with specified QName. + * + * @param identifier QName of requested statement + * @return StatementSupport + */ + public @Nullable StatementSupport getSupport(final QName identifier) { + return qnameToSupport.get(requireNonNull(identifier)); + } + + private static @Nullable StatementDefinition definitionOf(final @Nullable StatementSupport support) { + return support != null ? support.definition() : null; } } diff --git a/parser/yang-parser-spi/src/test/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMapTest.java b/parser/yang-parser-spi/src/test/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMapTest.java index 783bc837e5..91e6e087c4 100644 --- a/parser/yang-parser-spi/src/test/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMapTest.java +++ b/parser/yang-parser-spi/src/test/java/org/opendaylight/yangtools/yang/parser/spi/source/QNameToStatementDefinitionMapTest.java @@ -9,10 +9,13 @@ package org.opendaylight.yangtools.yang.parser.spi.source; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import org.junit.Before; import org.junit.Test; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; public class QNameToStatementDefinitionMapTest { @@ -20,6 +23,12 @@ public class QNameToStatementDefinitionMapTest { private final QNameToStatementDefinitionMap map = new QNameToStatementDefinitionMap(); private final StatementSupport support = mock(StatementSupport.class); + private final StatementDefinition definition = mock(StatementDefinition.class); + + @Before + public void before() { + doReturn(definition).when(support).definition(); + } @Test public void testPutNullNull() { @@ -28,7 +37,7 @@ public class QNameToStatementDefinitionMapTest { @Test public void testPutNullSome() { - assertThrows(NullPointerException.class, () -> map.put(null, mock(StatementSupport.class))); + assertThrows(NullPointerException.class, () -> map.put(null, support)); } @Test @@ -39,6 +48,7 @@ public class QNameToStatementDefinitionMapTest { @Test public void testPut() { map.put(QNAME, support); - assertSame(support, map.get(QNAME)); + assertSame(definition, map.get(QNAME)); + assertSame(support, map.getSupport(QNAME)); } } -- 2.36.6