YANGTOOLS-706: add utility method for finding substatements 16/65416/8
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 10 Nov 2017 17:51:24 +0000 (18:51 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 11 Nov 2017 13:43:52 +0000 (14:43 +0100)
This patch adds the ability to filter substatements on a type,
allowing more convenient use by users. Also convert users to
use this API, which allows us to reduce the footprint of exposed
implementation classes.

Change-Id: I87631810f6fd1df32a26908bbf085cbd25849765
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
24 files changed:
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/meta/EffectiveStatement.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDataSchemaNode.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveDocumentedNode.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveModule.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/AbstractEffectiveSimpleDataNodeContainer.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStatementBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/EffectiveStmtUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/anydata/AnydataEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/anyxml/AnyxmlEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/argument/ArgumentEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/augment/AugmentEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/belongs_to/BelongsToEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/choice/ChoiceEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/container/ContainerEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/deviate/DeviateEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/deviation/DeviationEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/extension/ExtensionEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/import_/ImportEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/leaf/LeafEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/list/ListEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/must/MustEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/revision/RevisionEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/submodule/SubmoduleEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/uses/UsesEffectiveStatementImpl.java

index 1900d6bcc6de7e17101b7c5d303c85a0937cf7d5..4815715f7b93f8e05371a4996f23f20c1e7e1812 100644 (file)
@@ -7,8 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.model.api.meta;
 
+import com.google.common.annotations.Beta;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
@@ -74,4 +77,37 @@ public interface EffectiveStatement<A, S extends DeclaredStatement<A>> extends M
      * @return collection of all effective substatements.
      */
     @Nonnull Collection<? extends EffectiveStatement<?, ?>> effectiveSubstatements();
+
+    /**
+     * Find the first effective substatement of specified type.
+     *
+     * @return First effective substatement, or empty if no match is found.
+     */
+    @Beta
+    default <T extends EffectiveStatement<?, ?>> Optional<T> findFirstEffectiveSubstatement(
+            @Nonnull final Class<T> type) {
+        return effectiveSubstatements().stream().filter(type::isInstance).findFirst().map(type::cast);
+    }
+
+    /**
+     * Find the first effective substatement of specified type and return its value.
+     *
+     * @return First effective substatement's argument, or empty if no match is found.
+     */
+    @Beta
+    default <V, T extends EffectiveStatement<V, ?>> Optional<V> findFirstEffectiveSubstatementArgument(
+            @Nonnull final Class<T> type) {
+        return effectiveSubstatements().stream().filter(type::isInstance).findFirst().map(type::cast)
+                .map(EffectiveStatement::argument);
+    }
+
+    /**
+     * Find all effective substatements of specified type and return them as a stream.
+     *
+     * @return A stream of all effective substatements of specified type.
+     */
+    @Beta
+    default <T extends EffectiveStatement<?, ?>> Stream<T> streamEffectiveSubstatements(@Nonnull final Class<T> type) {
+        return effectiveSubstatements().stream().filter(type::isInstance).map(type::cast);
+    }
 }
index 2494843c10ebd61e0d8b9c7811a3abf4dae11a51..254ee289a5fd7caf8b684be4379f8c03494f3e21 100644 (file)
@@ -30,9 +30,7 @@ public abstract class AbstractEffectiveDataSchemaNode<D extends DeclaredStatemen
     protected AbstractEffectiveDataSchemaNode(final StmtContext<QName, D, ?> ctx) {
         super(ctx);
         this.configuration = ctx.isConfiguration();
-
-        final WhenEffectiveStatement whenStmt = firstEffective(WhenEffectiveStatement.class);
-        whenCondition = whenStmt != null ? whenStmt.argument() : null;
+        whenCondition = findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class).orElse(null);
 
         // initCopyType
         final CopyHistory originalHistory = ctx.getCopyHistory();
index e5892a03bf6aa5e1d6a815adbd78b82a0b22d9e1..5750165967ed97693bba62673098850a1ec584f3 100644 (file)
@@ -32,27 +32,9 @@ public abstract class AbstractEffectiveDocumentedNode<A, D extends DeclaredState
      */
     protected AbstractEffectiveDocumentedNode(final StmtContext<A, D, ?> ctx) {
         super(ctx);
-
-        final DescriptionEffectiveStatement descStmt = firstEffective(DescriptionEffectiveStatement.class);
-        if (descStmt != null) {
-            description = descStmt.argument();
-        } else {
-            description = null;
-        }
-
-        final ReferenceEffectiveStatement refStmt = firstEffective(ReferenceEffectiveStatement.class);
-        if (refStmt != null) {
-            reference = refStmt.argument();
-        } else {
-            reference = null;
-        }
-
-        final StatusEffectiveStatement statusStmt = firstEffective(StatusEffectiveStatement.class);
-        if (statusStmt != null) {
-            status = statusStmt.argument();
-        } else {
-            status = Status.CURRENT;
-        }
+        description = findFirstEffectiveSubstatementArgument(DescriptionEffectiveStatement.class).orElse(null);
+        reference = findFirstEffectiveSubstatementArgument(ReferenceEffectiveStatement.class).orElse(null);
+        status = findFirstEffectiveSubstatementArgument(StatusEffectiveStatement.class).orElse(Status.CURRENT);
     }
 
     @Override
index e372ccec896054bdfc3080f4321b79bf06732176..6607bf821269d9069866a181988cd620b6dc1b90 100644 (file)
@@ -28,6 +28,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.concepts.SemVer;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Revision;
@@ -51,13 +52,13 @@ import org.opendaylight.yangtools.yang.model.api.UsesNode;
 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.BelongsToEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ContactEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.OrganizationEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionEffectiveStatement;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.belongs_to.BelongsToEffectiveStatementImpl;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.extension.ExtensionEffectiveStatementImpl;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.submodule.SubmoduleEffectiveStatementImpl;
 import org.opendaylight.yangtools.yang.parser.spi.meta.MutableStatement;
@@ -101,30 +102,30 @@ public abstract class AbstractEffectiveModule<D extends DeclaredStatement<String
 
         this.name = argument();
 
-        EffectiveStatementBase<?, ?> parentOfPrefix = this;
+        final EffectiveStatement<?, ?> parentOfPrefix;
         if (ctx.getPublicDefinition() == YangStmtMapping.SUBMODULE) {
-            parentOfPrefix = firstEffective(BelongsToEffectiveStatementImpl.class);
-            SourceException.throwIfNull(parentOfPrefix, ctx.getStatementSourceReference(),
+            final Optional<BelongsToEffectiveStatement> optParent =
+                    findFirstEffectiveSubstatement(BelongsToEffectiveStatement.class);
+            SourceException.throwIf(!optParent.isPresent(), ctx.getStatementSourceReference(),
                     "Unable to find belongs-to statement in submodule %s.", ctx.getStatementArgument());
+            parentOfPrefix = optParent.get();
+        } else {
+            parentOfPrefix = this;
         }
 
-        final PrefixEffectiveStatement prefixStmt = parentOfPrefix.firstEffective(PrefixEffectiveStatement.class);
-        SourceException.throwIfNull(prefixStmt, ctx.getStatementSourceReference(),
+        final Optional<@NonNull PrefixEffectiveStatement> prefixStmt = parentOfPrefix.findFirstEffectiveSubstatement(
+            PrefixEffectiveStatement.class);
+        SourceException.throwIf(!prefixStmt.isPresent(), ctx.getStatementSourceReference(),
                 "Unable to resolve prefix for module or submodule %s.", ctx.getStatementArgument());
-        this.prefix = prefixStmt.argument();
-
-        final YangVersionEffectiveStatement yangVersionStmt = firstEffective(YangVersionEffectiveStatement.class);
-        this.yangVersion = yangVersionStmt == null ? YangVersion.VERSION_1 : yangVersionStmt.argument();
-
-        final OpenconfigVersionEffectiveStatement semanticVersionStmt =
-                firstEffective(OpenconfigVersionEffectiveStatement.class);
-        this.semanticVersion = semanticVersionStmt == null ? null : semanticVersionStmt.argument();
-
-        final OrganizationEffectiveStatement organizationStmt = firstEffective(OrganizationEffectiveStatement.class);
-        this.organization = organizationStmt == null ? null : organizationStmt.argument();
-
-        final ContactEffectiveStatement contactStmt = firstEffective(ContactEffectiveStatement.class);
-        this.contact = contactStmt == null ? null : contactStmt.argument();
+        this.prefix = prefixStmt.get().argument();
+        this.yangVersion = findFirstEffectiveSubstatementArgument(YangVersionEffectiveStatement.class)
+                .orElse(YangVersion.VERSION_1);
+        this.semanticVersion = findFirstEffectiveSubstatementArgument(OpenconfigVersionEffectiveStatement.class)
+                .orElse(null);
+        this.organization = findFirstEffectiveSubstatementArgument(OrganizationEffectiveStatement.class)
+                .orElse(null);
+        this.contact = findFirstEffectiveSubstatementArgument(ContactEffectiveStatement.class)
+                .orElse(null);
 
         // init submodules and substatements of submodules
         final List<EffectiveStatement<?, ?>> substatementsOfSubmodules;
index 3da2b590cedec1f688f6592d0b979a4bec4a4d9a..de6d24aae8010630da39e7d7dc28802979638d5b 100644 (file)
@@ -50,8 +50,7 @@ public abstract class AbstractEffectiveSimpleDataNodeContainer<D extends Declare
         this.path = ctx.getSchemaPath().get();
         this.configuration = ctx.isConfiguration();
 
-        final WhenEffectiveStatement whenStmt = firstEffective(WhenEffectiveStatement.class);
-        whenCondition = whenStmt != null ? whenStmt.argument() : null;
+        whenCondition = findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class).orElse(null);
 
         // initSubstatementCollectionsAndFields
 
index 36cbabfb4bf42d8a2d59065f3a4a052d0029f9d0..efaf464d70acd5f6989f75bc581802a93cb22010 100644 (file)
@@ -15,6 +15,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Predicate;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
@@ -84,8 +85,17 @@ public abstract class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
         return substatements;
     }
 
+    /**
+     * Find first substatement of specified type.
+     *
+     * @param type Requested type
+     * @return First matching substatement, or null if no match is found.
+     *
+     * @deprecated Use {@link #findFirstEffectiveSubstatement(Class)} instead.
+     */
+    @Deprecated
     public final <S extends EffectiveStatement<?, ?>> S firstEffective(final Class<S> type) {
-        return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null);
+        return findFirstEffectiveSubstatement(type).orElse(null);
     }
 
     protected final <S extends SchemaNode> S firstSchemaNode(final Class<S> type) {
@@ -97,7 +107,7 @@ public abstract class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
         return Collection.class.cast(Collections2.filter(substatements, type::isInstance));
     }
 
-    protected final <T> T firstSubstatementOfType(final Class<T> type) {
+    @Nullable protected final <T> T firstSubstatementOfType(final Class<T> type) {
         return substatements.stream().filter(type::isInstance).findFirst().map(type::cast).orElse(null);
     }
 
index 61d674168969855b49ec5000d659bf0e83fd0646..ad5d8f7dd33cefee948cf51fc4639c98588a6a58 100644 (file)
@@ -33,24 +33,21 @@ public final class EffectiveStmtUtils {
             effectiveStatement.argument());
     }
 
-    public static Optional<ElementCountConstraint> createElementCountConstraint(
-            final EffectiveStatementBase<?, ?> stmt) {
-        final MinElementsEffectiveStatement firstMinElementsStmt = stmt.firstEffective(
-            MinElementsEffectiveStatement.class);
+    public static Optional<ElementCountConstraint> createElementCountConstraint(final EffectiveStatement<?, ?> stmt) {
         final Integer minElements;
-        if (firstMinElementsStmt != null) {
-            final Integer m = firstMinElementsStmt.argument();
+        final Optional<Integer> min = stmt.findFirstEffectiveSubstatementArgument(MinElementsEffectiveStatement.class);
+        if (min.isPresent()) {
+            final Integer m = min.get();
             minElements = m > 0 ? m : null;
         } else {
             minElements = null;
         }
 
-        final MaxElementsEffectiveStatement firstMaxElementsStmt = stmt.firstEffective(
-            MaxElementsEffectiveStatement.class);
-        final String maxElementsArg = firstMaxElementsStmt == null ? UNBOUNDED_STR : firstMaxElementsStmt.argument();
         final Integer maxElements;
-        if (!UNBOUNDED_STR.equals(maxElementsArg)) {
-            final Integer m = Integer.valueOf(maxElementsArg);
+        final String max = stmt.findFirstEffectiveSubstatementArgument(MaxElementsEffectiveStatement.class)
+                .orElse(UNBOUNDED_STR);
+        if (!UNBOUNDED_STR.equals(max)) {
+            final Integer m = Integer.valueOf(max);
             maxElements = m < Integer.MAX_VALUE ? m : null;
         } else {
             maxElements = null;
index 23d55bc222d8940aded7dfa55990e5941ecf6494..8c884bcca0cfa7fa5d7a0f899d279e0934fd3b48 100644 (file)
@@ -41,8 +41,8 @@ final class AnydataEffectiveStatementImpl extends AbstractEffectiveDataSchemaNod
             final StmtContext<QName, AnydataStatement, EffectiveStatement<QName, AnydataStatement>> ctx) {
         super(ctx);
         this.original = (AnyDataSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective).orElse(null);
-        final MandatoryEffectiveStatement mandatoryStmt = firstEffective(MandatoryEffectiveStatement.class);
-        mandatory = mandatoryStmt == null ? false : mandatoryStmt.argument().booleanValue();
+        mandatory = findFirstEffectiveSubstatementArgument(MandatoryEffectiveStatement.class).orElse(Boolean.FALSE)
+                .booleanValue();
         mustConstraints = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
 
         /*
index 363d18c400378975d5977384687c0b30a73fd125..480eb2d8845456890444c89de6933cf661d515d8 100644 (file)
@@ -34,8 +34,8 @@ public class AnyxmlEffectiveStatementImpl extends AbstractEffectiveDataSchemaNod
             final StmtContext<QName, AnyxmlStatement, EffectiveStatement<QName, AnyxmlStatement>> ctx) {
         super(ctx);
         this.original = (AnyXmlSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective).orElse(null);
-        final MandatoryEffectiveStatement mandatoryStmt = firstEffective(MandatoryEffectiveStatement.class);
-        mandatory = mandatoryStmt == null ? false : mandatoryStmt.argument().booleanValue();
+        mandatory = findFirstEffectiveSubstatementArgument(MandatoryEffectiveStatement.class).orElse(Boolean.FALSE)
+                .booleanValue();
         mustConstraints = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
     }
 
index f8cf50212dd682b28435ecb2339f8f49b562ccf5..9392c9548cbbf4db7fe48c861e298ba337d02fec 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
@@ -13,8 +13,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.DeclaredEffectiveStatementBase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-// FIXME: hide this class
-public final class ArgumentEffectiveStatementImpl extends DeclaredEffectiveStatementBase<QName, ArgumentStatement>
+final class ArgumentEffectiveStatementImpl extends DeclaredEffectiveStatementBase<QName, ArgumentStatement>
         implements ArgumentEffectiveStatement {
     ArgumentEffectiveStatementImpl(final StmtContext<QName, ArgumentStatement, ?> ctx) {
         super(ctx);
index 508013393791a7fea9076f81af7daab2b89531b7..661c46143b07a080825d4e778ad92d5cdadd24f3 100644 (file)
@@ -56,9 +56,7 @@ final class AugmentEffectiveStatementImpl
         this.revision = rootModuleQName.getRevision().orElse(null);
 
         this.copyOf = (AugmentationSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective).orElse(null);
-
-        final WhenEffectiveStatement whenStmt = firstEffective(WhenEffectiveStatement.class);
-        this.whenCondition = whenStmt == null ? null : whenStmt.argument();
+        whenCondition = findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class).orElse(null);
 
         // initSubstatementCollections
         final ImmutableSet.Builder<ActionDefinition> actionsBuilder = ImmutableSet.builder();
index 54e1d7f95f9a8f46719fb43665358300631582e9..06690e0d42e8e78cfc2503d65be2fc90def0fcab 100644 (file)
@@ -12,8 +12,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.DeclaredEffectiveStatementBase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
-// FIXME: hide this class
-public final class BelongsToEffectiveStatementImpl extends DeclaredEffectiveStatementBase<String, BelongsToStatement>
+final class BelongsToEffectiveStatementImpl extends DeclaredEffectiveStatementBase<String, BelongsToStatement>
         implements BelongsToEffectiveStatement {
     BelongsToEffectiveStatementImpl(final StmtContext<String, BelongsToStatement, ?> ctx) {
         super(ctx);
index b433df30110b4c9b769b042cb8dc37e56b13e923..974783526e8c682aa3a18c296c8b5346cb71ea29 100644 (file)
@@ -79,14 +79,15 @@ final class ChoiceEffectiveStatementImpl extends AbstractEffectiveDataSchemaNode
         this.augmentations = ImmutableSet.copyOf(augmentationsInit);
         this.cases = ImmutableSortedMap.copyOfSorted(casesInit);
 
-        final DefaultEffectiveStatement defaultStmt = firstEffective(DefaultEffectiveStatement.class);
-        if (defaultStmt != null) {
+        final Optional<String> defaultArg = findFirstEffectiveSubstatementArgument(DefaultEffectiveStatement.class);
+        if (defaultArg.isPresent()) {
+            final String arg = defaultArg.get();
             final QName qname;
             try {
-                qname = QName.create(getQName(), defaultStmt.argument());
+                qname = QName.create(getQName(), arg);
             } catch (IllegalArgumentException e) {
                 throw new SourceException(ctx.getStatementSourceReference(), "Default statement has invalid name '%s'",
-                    defaultStmt.argument(), e);
+                    arg, e);
             }
 
             // FIXME: this does not work with submodules, as they are
@@ -96,8 +97,8 @@ final class ChoiceEffectiveStatementImpl extends AbstractEffectiveDataSchemaNode
             defaultCase = null;
         }
 
-        final MandatoryEffectiveStatement mandatoryStmt = firstEffective(MandatoryEffectiveStatement.class);
-        mandatory = mandatoryStmt == null ? false : mandatoryStmt.argument().booleanValue();
+        mandatory = findFirstEffectiveSubstatementArgument(MandatoryEffectiveStatement.class).orElse(Boolean.FALSE)
+                .booleanValue();
     }
 
     private static void resetAugmenting(final DataSchemaNode dataSchemaNode) {
index c2ae9b4adedf3391aa59c9d13fae1a3f54a7d725..f615c8c3ad36812cf084fac34ca46017de6e8248 100644 (file)
@@ -50,7 +50,7 @@ public final class ContainerEffectiveStatementImpl extends AbstractEffectiveCont
 
         this.actions = actionsBuilder.build();
         this.notifications = notificationsBuilder.build();
-        presence = firstEffective(PresenceEffectiveStatement.class) != null;
+        presence = findFirstEffectiveSubstatement(PresenceEffectiveStatement.class).isPresent();
     }
 
     @Override
index c23d1963e3114d001e0ab917b380f3d74b2b5a92..ba9185a14f7c1fb800cfe26b9aba46602463706d 100644 (file)
@@ -26,7 +26,6 @@ import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryEffectiveStatemen
 import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UnitsEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.DeclaredEffectiveStatementBase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
@@ -49,25 +48,22 @@ final class DeviateEffectiveStatementImpl extends DeclaredEffectiveStatementBase
     DeviateEffectiveStatementImpl(final StmtContext<DeviateKind, DeviateStatement, ?> ctx) {
         super(ctx);
 
-        this.deviateType = argument();
-
-        final ConfigEffectiveStatement configStmt = firstEffective(ConfigEffectiveStatement.class);
-        this.deviatedConfig = OptionalBoolean.ofNullable(configStmt == null ? null : configStmt.argument());
-        final DefaultEffectiveStatement defaultStmt = firstEffective(DefaultEffectiveStatement.class);
-        this.deviatedDefault = defaultStmt == null ? null : defaultStmt.argument();
-        final MandatoryEffectiveStatement mandatoryStmt = firstEffective(MandatoryEffectiveStatement.class);
-        this.deviatedMandatory = OptionalBoolean.ofNullable(mandatoryStmt == null ? null : mandatoryStmt.argument());
-        final MaxElementsEffectiveStatement maxElementsStmt = firstEffective(MaxElementsEffectiveStatement.class);
-        this.deviatedMaxElements = maxElementsStmt == null ? null : Integer.valueOf(maxElementsStmt.argument());
-        final MinElementsEffectiveStatement minElementsStmt = firstEffective(MinElementsEffectiveStatement.class);
-        this.deviatedMinElements = minElementsStmt == null ? null : minElementsStmt.argument();
-        final TypeEffectiveStatement<TypeStatement> typeStmt = firstEffective(TypeEffectiveStatement.class);
-        this.deviatedType = typeStmt == null ? null : typeStmt.getTypeDefinition();
-        final UnitsEffectiveStatement unitsStmt = firstEffective(UnitsEffectiveStatement.class);
-        this.deviatedUnits = unitsStmt == null ? null : unitsStmt.argument();
-
-        this.deviatedMustDefinitions = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
-        this.deviatedUniqueConstraints = ImmutableList.copyOf(allSubstatementsOfType(UniqueConstraint.class));
+        deviateType = argument();
+        deviatedConfig = OptionalBoolean.ofNullable(findFirstEffectiveSubstatementArgument(
+            ConfigEffectiveStatement.class).orElse(null));
+        deviatedMandatory = OptionalBoolean.ofNullable(findFirstEffectiveSubstatementArgument(
+            MandatoryEffectiveStatement.class).orElse(null));
+        deviatedDefault = findFirstEffectiveSubstatementArgument(DefaultEffectiveStatement.class).orElse(null);
+        deviatedMaxElements = findFirstEffectiveSubstatementArgument(MaxElementsEffectiveStatement.class)
+                // FIXME: this does not handle 'unbounded'
+                .map(Integer::valueOf).orElse(null);
+        deviatedMinElements = findFirstEffectiveSubstatementArgument(MinElementsEffectiveStatement.class).orElse(null);
+        deviatedType = findFirstEffectiveSubstatement(TypeEffectiveStatement.class)
+                .map(TypeEffectiveStatement::getTypeDefinition).orElse(null);
+        deviatedUnits = findFirstEffectiveSubstatementArgument(UnitsEffectiveStatement.class).orElse(null);
+
+        deviatedMustDefinitions = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
+        deviatedUniqueConstraints = ImmutableList.copyOf(allSubstatementsOfType(UniqueConstraint.class));
     }
 
     @Override
index 3d80dfd2971716c782aab73873e2c7dbfe80e1ab..c9a4c6422e44f7b7cc5e5b49335aa7df4a91575d 100644 (file)
@@ -41,11 +41,8 @@ final class DeviationEffectiveStatementImpl
 
         this.deviateDefinitions = ImmutableList.copyOf(allSubstatementsOfType(DeviateDefinition.class));
 
-        DescriptionEffectiveStatement descriptionStmt = firstEffective(DescriptionEffectiveStatement.class);
-        this.description = descriptionStmt == null ? null : descriptionStmt.argument();
-
-        ReferenceEffectiveStatement referenceStmt = firstEffective(ReferenceEffectiveStatement.class);
-        this.reference = referenceStmt == null ? null : referenceStmt.argument();
+        description = findFirstEffectiveSubstatementArgument(DescriptionEffectiveStatement.class).orElse(null);
+        reference = findFirstEffectiveSubstatementArgument(ReferenceEffectiveStatement.class).orElse(null);
 
         List<UnknownSchemaNode> unknownSchemaNodesInit = new ArrayList<>();
         for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
index 0bceae20fc80ebedadb643b601f01b341940e11e..20fcaae201d20ef95213823c0becb9b117f8f196 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Collection;
 import java.util.Deque;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.util.RecursiveObjectLeaker;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -21,11 +22,11 @@ import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionEffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.YinElementEffectiveStatement;
 import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveDocumentedNode;
-import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.argument.ArgumentEffectiveStatementImpl;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 
 // FIXME: hide this class
@@ -87,17 +88,13 @@ public final class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocu
         this.unknownNodes = ImmutableList.copyOf(unknownNodesInit);
 
         // initFields
-        ArgumentEffectiveStatementImpl argumentSubstatement = firstEffective(ArgumentEffectiveStatementImpl.class);
-        if (argumentSubstatement != null) {
-            this.argument = argumentSubstatement.argument().getLocalName();
-
-            YinElementEffectiveStatement yinElement = argumentSubstatement
-                    .firstEffective(YinElementEffectiveStatement.class);
-            if (yinElement != null) {
-                this.yin = yinElement.argument();
-            } else {
-                this.yin = false;
-            }
+        final Optional<ArgumentEffectiveStatement> optArgumentSubstatement = findFirstEffectiveSubstatement(
+            ArgumentEffectiveStatement.class);
+        if (optArgumentSubstatement.isPresent()) {
+            final ArgumentEffectiveStatement argumentStatement = optArgumentSubstatement.get();
+            this.argument = argumentStatement.argument().getLocalName();
+            this.yin = argumentStatement.findFirstEffectiveSubstatement(YinElementEffectiveStatement.class)
+                    .map(YinElementEffectiveStatement::argument).orElse(Boolean.FALSE).booleanValue();
         } else {
             this.argument = null;
             this.yin = false;
index 434d9ff2d25974cb8677e81d764f2c28ea75cc72..99d55db978ad8b704b42e3d8ab9e745ce772e1f2 100644 (file)
@@ -42,18 +42,15 @@ final class ImportEffectiveStatementImpl extends DeclaredEffectiveStatementBase<
         super(ctx);
 
         moduleName = ctx.getStatementArgument();
-        final PrefixEffectiveStatement prefixStmt = firstEffective(PrefixEffectiveStatement.class);
-        if (prefixStmt != null) {
-            this.prefix = prefixStmt.argument();
-        } else {
-            throw new MissingSubstatementException("Prefix is mandatory substatement of import statement",
-                    ctx.getStatementSourceReference());
-        }
+        final Optional<String> prefixStmt = findFirstEffectiveSubstatementArgument(PrefixEffectiveStatement.class);
+        MissingSubstatementException.throwIf(!prefixStmt.isPresent(), ctx.getStatementSourceReference(),
+            "Prefix is mandatory substatement of import statement");
+        this.prefix = prefixStmt.get();
 
         if (!ctx.isEnabledSemanticVersioning()) {
-            final RevisionDateEffectiveStatement revisionDateStmt = firstEffective(
+            final Optional<Revision> optRev = findFirstEffectiveSubstatementArgument(
                 RevisionDateEffectiveStatement.class);
-            this.revision = revisionDateStmt == null ? getImportedRevision(ctx) : revisionDateStmt.argument();
+            this.revision = optRev.isPresent() ? optRev.get() : getImportedRevision(ctx);
             this.semVer = null;
         } else {
             final SemVerSourceIdentifier importedModuleIdentifier = ctx.getFromNamespace(
@@ -62,11 +59,8 @@ final class ImportEffectiveStatementImpl extends DeclaredEffectiveStatementBase<
             semVer = importedModuleIdentifier.getSemanticVersion().orElse(null);
         }
 
-        final DescriptionEffectiveStatement descriptionStmt = firstEffective(DescriptionEffectiveStatement.class);
-        this.description = descriptionStmt != null ? descriptionStmt.argument() : null;
-
-        final ReferenceEffectiveStatement referenceStmt = firstEffective(ReferenceEffectiveStatement.class);
-        this.reference = referenceStmt != null ? referenceStmt.argument() : null;
+        description = findFirstEffectiveSubstatementArgument(DescriptionEffectiveStatement.class).orElse(null);
+        reference = findFirstEffectiveSubstatementArgument(ReferenceEffectiveStatement.class).orElse(null);
     }
 
     private Revision getImportedRevision(final StmtContext<String, ImportStatement, ?> ctx) {
index 348639e8937d8c38e364ab1875239bde862d2639..0c4261c66937dc3aa75028fee5acb077a9e96bf9 100644 (file)
@@ -79,8 +79,8 @@ public final class LeafEffectiveStatementImpl extends AbstractEffectiveDataSchem
         defaultStr = dflt;
         unitsStr = units;
         type = builder.build();
-        final MandatoryEffectiveStatement mandatoryStmt = firstEffective(MandatoryEffectiveStatement.class);
-        mandatory = mandatoryStmt == null ? false : mandatoryStmt.argument().booleanValue();
+        mandatory = findFirstEffectiveSubstatementArgument(MandatoryEffectiveStatement.class).orElse(Boolean.FALSE)
+                .booleanValue();
         mustConstraints = ImmutableSet.copyOf(allSubstatementsOfType(MustDefinition.class));
     }
 
index abaaae1feb0281ca1de1fe0d899080115a3a0507..f8721d892626a85eea427efba173754b98ff57fb 100644 (file)
@@ -10,9 +10,9 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.list;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
@@ -57,36 +57,36 @@ public final class ListEffectiveStatementImpl extends AbstractEffectiveSimpleDat
         super(ctx);
 
         this.original = (ListSchemaNode) ctx.getOriginalCtx().map(StmtContext::buildEffective).orElse(null);
-
-        final OrderedByEffectiveStatement orderedByStmt = firstEffective(OrderedByEffectiveStatement.class);
-        if (orderedByStmt != null && ORDER_BY_USER_KEYWORD.equals(orderedByStmt.argument())) {
-            this.userOrdered = true;
-        } else {
-            this.userOrdered = false;
-        }
+        this.userOrdered = findFirstEffectiveSubstatementArgument(OrderedByEffectiveStatement.class)
+                .map(ORDER_BY_USER_KEYWORD::equals).orElse(Boolean.FALSE).booleanValue();
 
         // initKeyDefinition
-        final List<QName> keyDefinitionInit = new LinkedList<>();
-        final KeyEffectiveStatement keyEffectiveSubstatement = firstEffective(KeyEffectiveStatement.class);
-        if (keyEffectiveSubstatement != null) {
+        final Optional<KeyEffectiveStatement> optKeyStmt = findFirstEffectiveSubstatement(KeyEffectiveStatement.class);
+        if (optKeyStmt.isPresent()) {
+            final KeyEffectiveStatement keyStmt = optKeyStmt.get();
+            final List<QName> keyDefinitionInit = new ArrayList<>(keyStmt.argument().size());
             final Set<QName> possibleLeafQNamesForKey = new HashSet<>();
             for (final EffectiveStatement<?, ?> effectiveStatement : effectiveSubstatements()) {
                 if (effectiveStatement instanceof LeafSchemaNode) {
                     possibleLeafQNamesForKey.add(((LeafSchemaNode) effectiveStatement).getQName());
                 }
             }
-            for (final SchemaNodeIdentifier key : keyEffectiveSubstatement.argument()) {
+            for (final SchemaNodeIdentifier key : keyStmt.argument()) {
                 final QName keyQName = key.getLastComponent();
 
                 if (!possibleLeafQNamesForKey.contains(keyQName)) {
                     throw new InferenceException(ctx.getStatementSourceReference(),
-                            "Key '%s' misses node '%s' in list '%s'", keyEffectiveSubstatement.getDeclared()
-                                    .rawArgument(), keyQName.getLocalName(), ctx.getStatementArgument());
+                            "Key '%s' misses node '%s' in list '%s'", keyStmt.getDeclared().rawArgument(),
+                            keyQName.getLocalName(), ctx.getStatementArgument());
                 }
                 keyDefinitionInit.add(keyQName);
             }
+
+            this.keyDefinition = ImmutableList.copyOf(keyDefinitionInit);
+        } else {
+            this.keyDefinition = ImmutableList.of();
         }
-        this.keyDefinition = ImmutableList.copyOf(keyDefinitionInit);
+
         this.uniqueConstraints = ImmutableList.copyOf(allSubstatementsOfType(UniqueConstraint.class));
 
         final ImmutableSet.Builder<ActionDefinition> actionsBuilder = ImmutableSet.builder();
index eb6d477140e5aeee27acea6f01b2fb0e3140ee5d..94ef045cfcef4ee3839dd759553d829438343452 100644 (file)
@@ -31,19 +31,11 @@ final class MustEffectiveStatementImpl extends DeclaredEffectiveStatementBase<Re
 
     MustEffectiveStatementImpl(final StmtContext<RevisionAwareXPath, MustStatement, ?> ctx) {
         super(ctx);
-        this.xpath = ctx.getStatementArgument();
-
-        DescriptionEffectiveStatement descriptionStmt = firstEffective(DescriptionEffectiveStatement.class);
-        this.description = descriptionStmt == null ? null : descriptionStmt.argument();
-
-        ErrorAppTagEffectiveStatement errorAppTagStmt = firstEffective(ErrorAppTagEffectiveStatement.class);
-        this.errorAppTag = errorAppTagStmt == null ? null : errorAppTagStmt.argument();
-
-        ErrorMessageEffectiveStatement errorMessageStmt = firstEffective(ErrorMessageEffectiveStatement.class);
-        this.errorMessage = errorMessageStmt == null ? null : errorMessageStmt.argument();
-
-        ReferenceEffectiveStatement referenceStmt = firstEffective(ReferenceEffectiveStatement.class);
-        this.reference = referenceStmt == null ? null : referenceStmt.argument();
+        xpath = ctx.getStatementArgument();
+        description = findFirstEffectiveSubstatementArgument(DescriptionEffectiveStatement.class).orElse(null);
+        errorAppTag = findFirstEffectiveSubstatementArgument(ErrorAppTagEffectiveStatement.class).orElse(null);
+        errorMessage = findFirstEffectiveSubstatementArgument(ErrorMessageEffectiveStatement.class).orElse(null);
+        reference = findFirstEffectiveSubstatementArgument(ReferenceEffectiveStatement.class).orElse(null);
     }
 
     @Override
index 115de7fb86595feb6805faeabe7c3042704093c3..df9ec74fd0dac1d8cfd2211e2344cfb59425e34f 100644 (file)
@@ -25,20 +25,8 @@ final class RevisionEffectiveStatementImpl extends DeclaredEffectiveStatementBas
 
     RevisionEffectiveStatementImpl(final StmtContext<Revision, RevisionStatement, ?> ctx) {
         super(ctx);
-
-        final DescriptionEffectiveStatement descStmt = firstEffective(DescriptionEffectiveStatement.class);
-        if (descStmt != null) {
-            this.description = descStmt.argument();
-        } else {
-            this.description = null;
-        }
-
-        final ReferenceEffectiveStatement refStmt = firstEffective(ReferenceEffectiveStatement.class);
-        if (refStmt != null) {
-            this.reference = refStmt.argument();
-        } else {
-            this.reference = null;
-        }
+        description = findFirstEffectiveSubstatementArgument(DescriptionEffectiveStatement.class).orElse(null);
+        reference = findFirstEffectiveSubstatementArgument(ReferenceEffectiveStatement.class).orElse(null);
     }
 
     @Override
index dfcdf23b0914fbfa476223cab5db1d509d0a49f2..786a64a0778621e458e3b1a152634574dba2f4a9 100644 (file)
@@ -10,7 +10,9 @@ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.submodule;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
 import java.util.Objects;
+import java.util.Optional;
 import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.Revision;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.BelongsToStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.RevisionEffectiveStatement;
@@ -33,9 +35,10 @@ public final class SubmoduleEffectiveStatementImpl extends AbstractEffectiveModu
         final String belongsToModuleName = firstAttributeOf(ctx.declaredSubstatements(), BelongsToStatement.class);
         final QNameModule belongsToModuleQName = ctx.getFromNamespace(ModuleNameToModuleQName.class,
                 belongsToModuleName);
-        final RevisionEffectiveStatement submoduleRevision = firstEffective(RevisionEffectiveStatement.class);
-        this.qnameModule = QNameModule.create(belongsToModuleQName.getNamespace(),
-            submoduleRevision == null ? null : submoduleRevision.argument()).intern();
+
+        final Optional<Revision> submoduleRevision = findFirstEffectiveSubstatementArgument(
+            RevisionEffectiveStatement.class);
+        this.qnameModule = QNameModule.create(belongsToModuleQName.getNamespace(), submoduleRevision).intern();
     }
 
     @Override
index 3ee623e5f7b5e48827eb8b50fe662ce173d5b9bd..71bdc4acb8726b626d82e0abdad946cec3e5ca8a 100644 (file)
@@ -81,8 +81,7 @@ final class UsesEffectiveStatementImpl extends AbstractEffectiveDocumentedNode<Q
         this.augmentations = ImmutableSet.copyOf(augmentationsInit);
         this.refines = ImmutableMap.copyOf(refinesInit);
 
-        final WhenEffectiveStatement whenStmt = firstEffective(WhenEffectiveStatement.class);
-        this.whenCondition = whenStmt == null ? null : whenStmt.argument();
+        whenCondition = findFirstEffectiveSubstatementArgument(WhenEffectiveStatement.class).orElse(null);
     }
 
     @Nonnull