Refactor notification statement implementation 83/87483/1
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 4 Feb 2020 23:03:34 +0000 (00:03 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 6 Feb 2020 11:25:56 +0000 (12:25 +0100)
Notification statements are quite common and our implementation
classes are needlessly bit. Refactor them to be smaller.

JIRA: YANGTOOLS-1065
Change-Id: Ibcccec1a532bde9458d31b82ce90465080289299
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationEffectiveStatement.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/NotificationStatement.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/AbstractNotificationStatementSupport.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/EmptyNotificationStatement.java [moved from yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/NotificationStatementImpl.java with 57% similarity]
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/NotificationEffectiveStatementImpl.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/NotificationStatementRFC6020Support.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/NotificationStatementRFC7950Support.java
yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/RegularNotificationStatement.java [new file with mode: 0644]

index 0d5add2ecf25d88bf7a07756ba14a42e66f59397..4b967f67db327a80e6d39b0768ee070fe2a0dd52 100644 (file)
@@ -9,9 +9,14 @@ package org.opendaylight.yangtools.yang.model.api.stmt;
 
 import com.google.common.annotations.Beta;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 @Beta
 public interface NotificationEffectiveStatement extends SchemaTreeEffectiveStatement<NotificationStatement>,
     DataTreeAwareEffectiveStatement<QName, NotificationStatement> {
-
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.NOTIFICATION;
+    }
 }
index aed5b0e013b74b9649be26de4d0c5c418a2ed6b3..4e9d061ef9a565d022a9c94d5c4f3d4712178c87 100644 (file)
@@ -11,10 +11,17 @@ import static com.google.common.base.Verify.verifyNotNull;
 
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 
 public interface NotificationStatement extends DocumentedDeclaredStatement.WithStatus<QName>,
         DataDefinitionAwareDeclaredStatement.WithReusableDefinitions<QName>, IfFeatureAwareDeclaredStatement<QName>,
         MustStatementAwareDeclaredStatement<QName> {
+    @Override
+    default StatementDefinition statementDefinition() {
+        return YangStmtMapping.NOTIFICATION;
+    }
+
     default @NonNull QName getName() {
         // FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
         return verifyNotNull(argument());
index 0c563e34949955022088dd756b38c20f16b34076..e90d20cdec6fe5899952568a37cedc8a1fe39ae4 100644 (file)
@@ -7,18 +7,24 @@
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification;
 
+import com.google.common.collect.ImmutableList;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+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.stmt.NotificationEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.namespace.ChildSchemaNodeNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseQNameStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 
 abstract class AbstractNotificationStatementSupport
-        extends AbstractQNameStatementSupport<NotificationStatement, NotificationEffectiveStatement> {
+        extends BaseQNameStatementSupport<NotificationStatement, NotificationEffectiveStatement> {
     AbstractNotificationStatementSupport() {
         super(YangStmtMapping.NOTIFICATION);
     }
@@ -35,7 +41,37 @@ abstract class AbstractNotificationStatementSupport
     }
 
     @Override
-    public final NotificationStatement createDeclared(final StmtContext<QName, NotificationStatement, ?> ctx) {
-        return new NotificationStatementImpl(ctx);
+    protected final NotificationStatement createDeclared(final StmtContext<QName, NotificationStatement, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        return new RegularNotificationStatement(ctx.coerceStatementArgument(), substatements);
     }
+
+    @Override
+    protected final NotificationStatement createEmptyDeclared(final StmtContext<QName, NotificationStatement, ?> ctx) {
+        return new EmptyNotificationStatement(ctx.coerceStatementArgument());
+    }
+
+    @Override
+    protected final NotificationEffectiveStatement createEffective(
+            final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx,
+            final NotificationStatement declared,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        checkEffective(ctx);
+
+        final int flags = new FlagsBuilder()
+                .setHistory(ctx.getCopyHistory())
+                .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))
+                .toFlags();
+
+        return new NotificationEffectiveStatementImpl(declared, flags, ctx, substatements);
+    }
+
+    @Override
+    protected final NotificationEffectiveStatement createEmptyEffective(
+            final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx,
+            final NotificationStatement declared) {
+        return createEffective(ctx, declared, ImmutableList.of());
+    }
+
+    abstract void checkEffective(StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx);
 }
\ No newline at end of file
@@ -9,11 +9,10 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument;
 
-final class NotificationStatementImpl extends AbstractDeclaredStatement<QName> implements NotificationStatement {
-    NotificationStatementImpl(final StmtContext<QName, NotificationStatement, ?> context) {
-        super(context);
+final class EmptyNotificationStatement extends WithQNameArgument implements NotificationStatement {
+    EmptyNotificationStatement(final QName argument) {
+        super(argument);
     }
 }
index f112eeefa9b1fbf246b2020aaf5ed52c8b6e4e17..6f06e8ef76689fca389781c999f7846ee3390825 100644 (file)
  */
 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.notification;
 
-import com.google.common.collect.ImmutableSet;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.VarHandle;
-import java.util.LinkedHashSet;
+import com.google.common.collect.ImmutableList;
 import java.util.Objects;
-import java.util.Set;
+import java.util.Optional;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.MustDefinition;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveDocumentedDataNodeContainer;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory;
-import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredEffectiveStatement.DefaultWithDataTree.WithSubstatements;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.AugmentationTargetMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.CopyableMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.DataNodeContainerMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.MustConstraintMixin;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.SchemaNodeMixin;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
 final class NotificationEffectiveStatementImpl
-        extends AbstractEffectiveDocumentedDataNodeContainer<QName, NotificationStatement>
-        implements NotificationDefinition, NotificationEffectiveStatement {
-    private static final VarHandle MUST_CONSTRAINTS;
+        extends WithSubstatements<QName, NotificationStatement, NotificationEffectiveStatement>
+        implements NotificationDefinition, NotificationEffectiveStatement,
+                   SchemaNodeMixin<QName, NotificationStatement>, DataNodeContainerMixin<QName, NotificationStatement>,
+                   AugmentationTargetMixin<QName, NotificationStatement>, CopyableMixin<QName, NotificationStatement>,
+                   MustConstraintMixin<QName, NotificationStatement> {
 
-    static {
-        try {
-            MUST_CONSTRAINTS = MethodHandles.lookup().findVarHandle(
-                NotificationEffectiveStatementImpl.class, "mustConstraints", ImmutableSet.class);
-        } catch (NoSuchFieldException | IllegalAccessException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-    }
-
-    private final @NonNull QName qname;
     private final @NonNull SchemaPath path;
-    private final ImmutableSet<AugmentationSchemaNode> augmentations;
-    private final boolean augmenting;
-    private final boolean addedByUses;
+    private final int flags;
 
-    @SuppressWarnings("unused")
-    private volatile ImmutableSet<MustDefinition> mustConstraints;
-
-    NotificationEffectiveStatementImpl(
-            final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx) {
-        super(ctx);
-        this.qname = ctx.coerceStatementArgument();
+    NotificationEffectiveStatementImpl(final NotificationStatement declared, final int flags,
+            final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        super(declared, ctx, substatements);
         this.path = ctx.getSchemaPath().get();
-
-        // initSubstatementCollections
-        final Set<AugmentationSchemaNode> augmentationsInit = new LinkedHashSet<>();
-        for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
-            if (effectiveStatement instanceof AugmentationSchemaNode) {
-                final AugmentationSchemaNode augmentationSchema = (AugmentationSchemaNode) effectiveStatement;
-                augmentationsInit.add(augmentationSchema);
-            }
-        }
-        this.augmentations = ImmutableSet.copyOf(augmentationsInit);
-
-        // initCopyType
-        final CopyHistory copyTypesFromOriginal = ctx.getCopyHistory();
-        if (copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES_AUGMENTATION)) {
-            this.augmenting = true;
-            this.addedByUses = true;
-        } else {
-            this.augmenting = copyTypesFromOriginal.contains(CopyType.ADDED_BY_AUGMENTATION);
-            this.addedByUses = copyTypesFromOriginal.contains(CopyType.ADDED_BY_USES);
-        }
-    }
-
-    @Override
-    public QName getQName() {
-        return qname;
-    }
-
-    @Override
-    public SchemaPath getPath() {
-        return path;
+        this.flags = flags;
     }
 
     @Override
-    public ImmutableSet<MustDefinition> getMustConstraints() {
-        return derivedSet(MUST_CONSTRAINTS, MustDefinition.class);
+    public @NonNull QName argument() {
+        return getQName();
     }
 
     @Override
-    public Set<AugmentationSchemaNode> getAvailableAugmentations() {
-        return augmentations;
+    public Optional<DataSchemaNode> findDataChildByName(final QName name) {
+        return findDataSchemaNode(name);
     }
 
-    @Deprecated
     @Override
-    public boolean isAugmenting() {
-        return augmenting;
+    public int flags() {
+        return flags;
     }
 
-    @Deprecated
     @Override
-    public boolean isAddedByUses() {
-        return addedByUses;
+    public SchemaPath getPath() {
+        return path;
     }
 
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + Objects.hashCode(qname);
+        result = prime * result + Objects.hashCode(getQName());
         result = prime * result + Objects.hashCode(path);
         return result;
     }
@@ -123,18 +78,16 @@ final class NotificationEffectiveStatementImpl
         if (this == obj) {
             return true;
         }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
+        if (obj == null || getClass() != obj.getClass()) {
             return false;
         }
         final NotificationEffectiveStatementImpl other = (NotificationEffectiveStatementImpl) obj;
-        return Objects.equals(qname, other.qname) && Objects.equals(path, other.path);
+        return Objects.equals(getQName(), other.getQName()) && Objects.equals(path, other.path);
     }
 
     @Override
     public String toString() {
-        return NotificationEffectiveStatementImpl.class.getSimpleName() + "[qname=" + qname + ", path=" + path + "]";
+        return NotificationEffectiveStatementImpl.class.getSimpleName() + "[qname=" + getQName() + ", path=" + path
+                + "]";
     }
 }
index 4f6d39096273b5473295166b058f9554e0dd16f4..02ab63174d7c12b59d706a5c255020d83c907c9b 100644 (file)
@@ -42,13 +42,12 @@ public final class NotificationStatementRFC6020Support extends AbstractNotificat
     }
 
     @Override
-    public NotificationEffectiveStatement createEffective(
-            final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx) {
-        return new NotificationEffectiveStatementImpl(ctx);
+    protected SubstatementValidator getSubstatementValidator() {
+        return SUBSTATEMENT_VALIDATOR;
     }
 
     @Override
-    protected SubstatementValidator getSubstatementValidator() {
-        return SUBSTATEMENT_VALIDATOR;
+    void checkEffective(final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx) {
+        // No-op
     }
 }
\ No newline at end of file
index e038113d21906e53e946ce658bc0439232559a40..6d95e0d961af7818b332cbbe5321ffe39e1a717f 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 
 /**
  * Class providing necessary support for processing YANG 1.1 Notification
@@ -57,23 +58,21 @@ public final class NotificationStatementRFC7950Support extends AbstractNotificat
     }
 
     @Override
-    public NotificationEffectiveStatement createEffective(
-            final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx) {
-        SourceException.throwIf(StmtContextUtils.hasAncestorOfType(ctx, ILLEGAL_PARENTS),
-            ctx.getStatementSourceReference(),
-            "Notification %s is defined within an rpc, action, or another notification",
-            ctx.getStatementArgument());
-        SourceException.throwIf(!StmtContextUtils.hasAncestorOfTypeWithChildOfType(ctx, YangStmtMapping.LIST,
-            YangStmtMapping.KEY), ctx.getStatementSourceReference(),
-            "Notification %s is defined within a list that has no key statement", ctx.getStatementArgument());
-        SourceException.throwIf(StmtContextUtils.hasParentOfType(ctx, YangStmtMapping.CASE),
-            ctx.getStatementSourceReference(), "Notification %s is defined within a case statement",
-            ctx.getStatementArgument());
-        return new NotificationEffectiveStatementImpl(ctx);
+    protected SubstatementValidator getSubstatementValidator() {
+        return SUBSTATEMENT_VALIDATOR;
     }
 
+
     @Override
-    protected SubstatementValidator getSubstatementValidator() {
-        return SUBSTATEMENT_VALIDATOR;
+    void checkEffective(final StmtContext<QName, NotificationStatement, NotificationEffectiveStatement> ctx) {
+        final StatementSourceReference ref = ctx.getStatementSourceReference();
+        final QName argument = ctx.getStatementArgument();
+        SourceException.throwIf(StmtContextUtils.hasAncestorOfType(ctx, ILLEGAL_PARENTS), ref,
+            "Notification %s is defined within an rpc, action, or another notification", argument);
+        SourceException.throwIf(
+            !StmtContextUtils.hasAncestorOfTypeWithChildOfType(ctx, YangStmtMapping.LIST, YangStmtMapping.KEY), ref,
+            "Notification %s is defined within a list that has no key statement", argument);
+        SourceException.throwIf(StmtContextUtils.hasParentOfType(ctx, YangStmtMapping.CASE), ref,
+            "Notification %s is defined within a case statement", argument);
     }
 }
diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/RegularNotificationStatement.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/notification/RegularNotificationStatement.java
new file mode 100644 (file)
index 0000000..13ea58a
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.notification;
+
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.NotificationStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
+
+final class RegularNotificationStatement extends WithSubstatements implements NotificationStatement {
+    RegularNotificationStatement(final QName argument,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        super(argument, substatements);
+    }
+}