From e9bd7d686d3d32db05c322224fa331fc6449d6ad Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 7 Aug 2020 13:45:59 +0200 Subject: [PATCH] Remove EffectiveStatementBase This is a badly-designed class, integrate it into its only subclass. Change-Id: I4ddf2ec785e295c1f854eacb906060b3d76ab94c Signed-off-by: Robert Varga --- .../stmt/AbstractEffectiveDocumentedNode.java | 100 +++++++++++++++++- .../stmt/AbstractEffectiveStatement.java | 5 +- .../stmt/DeclaredEffectiveStatementBase.java | 61 ----------- .../rfc7950/stmt/EffectiveStatementBase.java | 94 ---------------- .../UndeclaredEffectiveStatementBase.java | 60 ----------- 5 files changed, 100 insertions(+), 220 deletions(-) delete mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/DeclaredEffectiveStatementBase.java delete mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementBase.java delete mode 100644 yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/UndeclaredEffectiveStatementBase.java diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDocumentedNode.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDocumentedNode.java index f85da9d118..450aff1baf 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDocumentedNode.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDocumentedNode.java @@ -8,28 +8,83 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; import com.google.common.annotations.Beta; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableList; +import java.util.Collection; import java.util.Optional; +import java.util.function.Predicate; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.yangtools.yang.model.api.DocumentedNode; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; +import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +/** + * A declared {@link AbstractEffectiveStatement}. + * + * @deprecated This class has a number of design problems. Use {@link AbstractDeclaredEffectiveStatement} and its + * subclasses instead. + */ +// TODO: This class is problematic in that it interacts with its subclasses via methods which are guaranteed to allows +// atrocities like RecursiveObjectLeaker tricks. That should be avoided and pushed to caller in a way where +// this class is a pure holder taking {@code ImmutableList>} in the +// constructor. +// +// From memory efficiency perspective, it is very common to have effective statements without any substatements, +// in which case 'substatements' field is redundant. @Beta @Deprecated(forRemoval = true) // FIXME: 6.0.0: fold this into AbstractEffectiveDocumentedNodeWithStatus public abstract class AbstractEffectiveDocumentedNode> - extends DeclaredEffectiveStatementBase implements DocumentedNode { + extends AbstractEffectiveStatement implements DocumentedNode { + private final @NonNull ImmutableList> substatements; + private final @NonNull StatementSource statementSource; + private final A argument; + private final @NonNull D declaredInstance; private final @Nullable String description; private final @Nullable String reference; protected AbstractEffectiveDocumentedNode(final StmtContext ctx) { - super(ctx); + argument = ctx.getStatementArgument(); + statementSource = ctx.getStatementSource(); + declaredInstance = ctx.buildDeclared(); + substatements = ImmutableList.copyOf(initSubstatements(BaseStatementSupport.declaredSubstatements(ctx))); + description = findFirstEffectiveSubstatementArgument(DescriptionEffectiveStatement.class).orElse(null); reference = findFirstEffectiveSubstatementArgument(ReferenceEffectiveStatement.class).orElse(null); } + @Override + public final StatementDefinition statementDefinition() { + return declaredInstance.statementDefinition(); + } + + @Override + public A argument() { + return argument; + } + + @Override + public final StatementSource getStatementSource() { + return statementSource; + } + + @Override + public final D getDeclared() { + return declaredInstance; + } + + @Override + public final Collection> effectiveSubstatements() { + return substatements; + } + @Override public final Optional getDescription() { return Optional.ofNullable(description); @@ -40,6 +95,12 @@ public abstract class AbstractEffectiveDocumentedNode Collection allSubstatementsOfType(final Class type) { + return Collection.class.cast(Collections2.filter(effectiveSubstatements(), type::isInstance)); + } + + protected final @Nullable String nullableDescription() { return description; } @@ -47,4 +108,39 @@ public abstract class AbstractEffectiveDocumentedNode> initSubstatements( + final Collection> substatementsInit) { + return Collections2.transform(Collections2.filter(substatementsInit, + StmtContext::isSupportedToBuildEffective), StmtContext::buildEffective); + } + + protected final @Nullable T firstSubstatementOfType(final Class type) { + return effectiveSubstatements().stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null); + } + + protected final R firstSubstatementOfType(final Class type, final Class returnType) { + return effectiveSubstatements().stream() + .filter(((Predicate)type::isInstance).and(returnType::isInstance)) + .findFirst().map(returnType::cast).orElse(null); + } + + protected final EffectiveStatement firstEffectiveSubstatementOfType(final Class type) { + return effectiveSubstatements().stream().filter(type::isInstance).findFirst().orElse(null); + } + + // FIXME: rename to 'getFirstEffectiveStatement()' + protected final S firstSchemaNode(final Class type) { + return findFirstEffectiveSubstatement(type).orElse(null); + } + + } diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveStatement.java index 980e7455ce..429b2d5c0f 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveStatement.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveStatement.java @@ -30,9 +30,8 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReferenc /** * Baseline stateless implementation of an EffectiveStatement. This class adds a few default implementations and - * namespace dispatch, but does not actually force any state on its subclasses. This approach is different from - * {@link EffectiveStatementBase} in that it adds requirements for an implementation, but it leaves it up to the final - * class to provide object layout. + * namespace dispatch, but does not actually force any state on its subclasses. This approach adds requirements for an + * implementation, but it leaves it up to the final class to provide object layout. * *

* This finds immense value in catering the common case, for example effective statements which can, but typically diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/DeclaredEffectiveStatementBase.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/DeclaredEffectiveStatementBase.java deleted file mode 100644 index 132bb32f2c..0000000000 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/DeclaredEffectiveStatementBase.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; - -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; -import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; - -/** - * A declared {@link EffectiveStatementBase}. - * - * @deprecated Use {@link AbstractDeclaredEffectiveStatement} and its subclasses instead. - */ -@Deprecated(forRemoval = true) -// FIXME: 6.0.0: fold this into AbstractEffectiveDocumentedNodeWithStatus -public abstract class DeclaredEffectiveStatementBase> extends - EffectiveStatementBase { - - private final @NonNull StatementSource statementSource; - private final A argument; - private final @NonNull D declaredInstance; - - /** - * Constructor. - * - * @param ctx context of statement. - */ - protected DeclaredEffectiveStatementBase(final StmtContext ctx) { - super(ctx); - argument = ctx.getStatementArgument(); - statementSource = ctx.getStatementSource(); - declaredInstance = ctx.buildDeclared(); - } - - @Override - public final StatementDefinition statementDefinition() { - return declaredInstance.statementDefinition(); - } - - @Override - public A argument() { - return argument; - } - - @Override - public final StatementSource getStatementSource() { - return statementSource; - } - - @Override - public final D getDeclared() { - return declaredInstance; - } -} \ No newline at end of file diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementBase.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementBase.java deleted file mode 100644 index 35a630d661..0000000000 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementBase.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; - -import com.google.common.collect.Collections2; -import com.google.common.collect.ImmutableList; -import java.util.Collection; -import java.util.function.Predicate; -import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.yangtools.yang.model.api.SchemaNode; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; - -/** - * Stateful version of {@link AbstractEffectiveStatement}, which holds substatements in an {@link ImmutableList}. - * - * @param Argument type ({@link Void} if statement does not have argument.) - * @param Class representing declared version of this statement. - * - * @deprecated This class has a number of design problems. Please use either {@link AbstractDeclaredEffectiveStatement} - * or {@link AbstractUndeclaredEffectiveStatement} instead. - */ -// TODO: This class is problematic in that it interacts with its subclasses via methods which are guaranteed to allows -// atrocities like RecursiveObjectLeaker tricks. That should be avoided and pushed to caller in a way where -// this class is a pure holder taking {@code ImmutableList>} in the -// constructor. -// -// From memory efficiency perspective, it is very common to have effective statements without any substatements, -// in which case 'substatements' field is redundant. -@Deprecated(forRemoval = true) -// FIXME: 6.0.0: fold this into AbstractEffectiveDocumentedNodeWithStatus -public abstract class EffectiveStatementBase> - extends AbstractEffectiveStatement { - private final @NonNull ImmutableList> substatements; - - /** - * Constructor. - * - * @param ctx context of statement. - */ - protected EffectiveStatementBase(final StmtContext ctx) { - this.substatements = ImmutableList.copyOf(initSubstatements(BaseStatementSupport.declaredSubstatements(ctx))); - } - - /** - * Create a set of substatements. This method is split out so it can be overridden in - * ExtensionEffectiveStatementImpl to leak a not-fully-initialized instance. - * - * @param substatementsInit proposed substatements - * @return Filtered substatements - */ - // FIXME: 6.0.0: this facility is only overridden by ExtensionEffectiveStatementImpl - protected Collection> initSubstatements( - final Collection> substatementsInit) { - return Collections2.transform(Collections2.filter(substatementsInit, - StmtContext::isSupportedToBuildEffective), StmtContext::buildEffective); - } - - @Override - public final Collection> effectiveSubstatements() { - return substatements; - } - - @SuppressWarnings("unchecked") - public final Collection allSubstatementsOfType(final Class type) { - return Collection.class.cast(Collections2.filter(effectiveSubstatements(), type::isInstance)); - } - - protected final @Nullable T firstSubstatementOfType(final Class type) { - return effectiveSubstatements().stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null); - } - - protected final R firstSubstatementOfType(final Class type, final Class returnType) { - return effectiveSubstatements().stream() - .filter(((Predicate)type::isInstance).and(returnType::isInstance)) - .findFirst().map(returnType::cast).orElse(null); - } - - protected final EffectiveStatement firstEffectiveSubstatementOfType(final Class type) { - return effectiveSubstatements().stream().filter(type::isInstance).findFirst().orElse(null); - } - - // FIXME: rename to 'getFirstEffectiveStatement()' - protected final S firstSchemaNode(final Class type) { - return findFirstEffectiveSubstatement(type).orElse(null); - } -} diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/UndeclaredEffectiveStatementBase.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/UndeclaredEffectiveStatementBase.java deleted file mode 100644 index 87dc615375..0000000000 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/UndeclaredEffectiveStatementBase.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yangtools.yang.parser.rfc7950.stmt; - -import com.google.common.base.Verify; -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; -import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; - -/** - * A base class for context-implied statements. - * - * @deprecated Use {@link AbstractUndeclaredEffectiveStatement} instead. - */ -@Deprecated(forRemoval = true) -// FIXME: 6.0.0: remove this class -public abstract class UndeclaredEffectiveStatementBase> - extends EffectiveStatementBase { - - private final @NonNull StatementSource statementSource; - private final @NonNull StatementDefinition statementDefinition; - private final A argument; - - protected UndeclaredEffectiveStatementBase(final StmtContext ctx) { - super(ctx); - this.statementDefinition = ctx.getPublicDefinition(); - this.argument = ctx.getStatementArgument(); - this.statementSource = ctx.getStatementSource(); - - final D declareInstance = ctx.buildDeclared(); - Verify.verify(declareInstance == null, "Statement %s resulted in declared statement %s", declareInstance); - } - - @Override - public final StatementDefinition statementDefinition() { - return statementDefinition; - } - - @Override - public final A argument() { - return argument; - } - - @Override - public final StatementSource getStatementSource() { - return statementSource; - } - - @Override - public final D getDeclared() { - return null; - } -} -- 2.36.6