Eliminate ConstraintDefition.isMandatory() 95/65095/14
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 3 Nov 2017 12:37:33 +0000 (13:37 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 8 Nov 2017 10:24:41 +0000 (11:24 +0100)
This flag is not accurate for containers due to the fact that
augment can make it dependent on the document being processed.

Redefine meaning of isMandatory() to reflect just the effect
of 'mandatory' statement.

Change-Id: I0135f2ffd7df454880d8cf259cd21af9585ec857
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
31 files changed:
yang/yang-data-codec-xml/src/test/java/org/opendaylight/yangtools/yang/data/codec/xml/YangModeledAnyXMLDeserializationTest.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MandatoryLeafEnforcer.java
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ConstraintDefinitions.java
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/ContainerSchemaNodes.java
yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/EmptyConstraintDefinition.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/AnyDataSchemaNode.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/AnyXmlSchemaNode.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ChoiceSchemaNode.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/ConstraintDefinition.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/LeafSchemaNode.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/MandatoryAware.java [new file with mode: 0644]
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/package-info.java
yang/yang-model-export/src/main/java/org/opendaylight/yangtools/yang/model/export/SchemaContextEmitter.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AnyXmlEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ChoiceEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/effective/AnyDataEffectiveStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ConstraintDefinitionsTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6869Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9244Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/DeviationResolutionTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveUsesRefineAndConstraintsTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/GroupingTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/ListTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/YangParserSimpleTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/YangParserTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/YangParserWithContextTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/yin/YinFileChoiceStmtTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/yin/YinFileGroupingStmtTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/yin/YinFileListStmtTest.java

index a3a817e507384163a9b43caafec68abd94719e17..6d4477add6d0ca0666ccee8dbaf76d33f17c6c44 100644 (file)
@@ -189,6 +189,11 @@ public class YangModeledAnyXMLDeserializationTest {
             return false;
         }
 
+        @Override
+        public boolean isMandatory() {
+            return false;
+        }
+
         @Override
         public ConstraintDefinition getConstraints() {
             return null;
@@ -233,5 +238,6 @@ public class YangModeledAnyXMLDeserializationTest {
         public ContainerSchemaNode getSchemaOfAnyXmlData() {
             return contentSchema;
         }
+
     }
 }
index 34857a2f3ce2e88329f879ab2d0bee9ad3d8f1bf..7822038448ed635b37b1487b62e75bbfc19f697f 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.MandatoryAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,9 +71,10 @@ abstract class MandatoryLeafEnforcer implements Immutable {
                         findMandatoryNodes(builder, id.node(NodeIdentifier.create(child.getQName())), container, type);
                     }
                 } else {
+                    final boolean mandatory = child instanceof MandatoryAware && ((MandatoryAware) child).isMandatory();
                     final ConstraintDefinition constraints = child.getConstraints();
                     final Integer minElements = constraints.getMinElements();
-                    if (constraints.isMandatory() || minElements != null && minElements.intValue() > 0) {
+                    if (mandatory || minElements != null && minElements.intValue() > 0) {
                         final YangInstanceIdentifier childId = id.node(NodeIdentifier.create(child.getQName()));
                         LOG.debug("Adding mandatory child {}", childId);
                         builder.add(childId.toOptimized());
index a5edb1c890d2661e3e54c74e46dd80b7accf6795..1a94ac839274a22b0e2d88bc7c617215c772ab58 100644 (file)
@@ -26,7 +26,6 @@ public final class ConstraintDefinitions {
         result = prime * result + Objects.hashCode(def.getMustConstraints());
         result = prime * result + Objects.hashCode(def.getMinElements());
         result = prime * result + Objects.hashCode(def.getMaxElements());
-        result = prime * result + Boolean.hashCode(def.isMandatory());
         return result;
     }
 
@@ -38,9 +37,6 @@ public final class ConstraintDefinitions {
             return false;
         }
         final ConstraintDefinition other = (ConstraintDefinition) obj;
-        if (def.isMandatory() != other.isMandatory()) {
-            return false;
-        }
         if (!Objects.equals(def.getWhenCondition(), other.getWhenCondition())) {
             return false;
         }
@@ -60,7 +56,6 @@ public final class ConstraintDefinitions {
         return MoreObjects.toStringHelper(def).omitNullValues()
                 .add("whenCondition", def.getWhenCondition().orElse(null))
                 .add("mustConstraints", def.getMustConstraints())
-                .add("mandatory", def.isMandatory())
                 .add("minElements", def.getMinElements())
                 .add("maxElements", def.getMaxElements()).toString();
     }
index b62998eb43cbd30b4048f692bb80b3eec775a1d8..dfc003d47f0fa00ce9ce87f60400a277b8ffd5f4 100644 (file)
@@ -86,7 +86,7 @@ public final class ContainerSchemaNodes {
 
         @Override
         public ConstraintDefinition getConstraints() {
-            return EmptyConstraintDefinition.create(false);
+            return EmptyConstraintDefinition.getInstance();
         }
 
         @Nonnull
index ab348855a245b35217b7e48e8550045e5ab5cef3..d5d5e9a3038cc32607627d05657899caade26b68 100644 (file)
@@ -17,60 +17,49 @@ import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 /**
  * Utility holder for constraint definitions which do not really constrain anything.
  */
-public abstract class EmptyConstraintDefinition implements ConstraintDefinition {
-    private static final EmptyConstraintDefinition MANDATORY = new EmptyConstraintDefinition() {
-        @Override
-        public boolean isMandatory() {
-            return true;
-        }
-    };
-    private static final EmptyConstraintDefinition OPTIONAL = new EmptyConstraintDefinition() {
-        @Override
-        public boolean isMandatory() {
-            return false;
-        }
-    };
+public final class EmptyConstraintDefinition implements ConstraintDefinition {
+    private static final EmptyConstraintDefinition INSTANCE = new EmptyConstraintDefinition();
 
     private EmptyConstraintDefinition() {
         // Hidden on purpose
     }
 
-    public static EmptyConstraintDefinition create(final boolean mandatory) {
-        return mandatory ? MANDATORY : OPTIONAL;
+    public static EmptyConstraintDefinition getInstance() {
+        return INSTANCE;
     }
 
     @Override
-    public final Optional<RevisionAwareXPath> getWhenCondition() {
+    public Optional<RevisionAwareXPath> getWhenCondition() {
         return Optional.empty();
     }
 
     @Override
-    public final Set<MustDefinition> getMustConstraints() {
+    public Set<MustDefinition> getMustConstraints() {
         return ImmutableSet.of();
     }
 
     @Override
-    public final Integer getMinElements() {
+    public Integer getMinElements() {
         return null;
     }
 
     @Override
-    public final Integer getMaxElements() {
+    public Integer getMaxElements() {
         return null;
     }
 
     @Override
-    public final int hashCode() {
+    public int hashCode() {
         return ConstraintDefinitions.hashCode(this);
     }
 
     @Override
-    public final boolean equals(final Object obj) {
+    public boolean equals(final Object obj) {
         return ConstraintDefinitions.equals(this, obj);
     }
 
     @Override
-    public final String toString() {
+    public String toString() {
         return ConstraintDefinitions.toString(this);
     }
 }
index 62efe137c3b3723f5815f862d05c9652db28d680..6859ed7f5f3536a11841c5a4b004a46ffbdca293 100644 (file)
@@ -12,20 +12,17 @@ import com.google.common.annotations.Beta;
 import java.util.Optional;
 
 /**
- * The "anydata" statement defines an interior node in the schema tree.
- * It takes one argument, which is an identifier, followed by a block of
- * substatements that holds detailed anydata information.
+ * The "anydata" statement defines an interior node in the schema tree. It takes one argument, which is an identifier,
+ * followed by a block of substatements that holds detailed anydata information.
  *
  * <p>
- * The "anydata" statement is used to represent an unknown set of nodes
- * that can be modeled with YANG, except anyxml, but for which the data
- * model is not known at module design time.  It is possible, though not
- * required, for the data model for anydata content to become known
- * through protocol signaling or other means that are outside the scope
+ * The "anydata" statement is used to represent an unknown set of nodes that can be modeled with YANG, except anyxml,
+ * but for which the data model is not known at module design time.  It is possible, though not required, for the data
+ * model for anydata content to become known through protocol signaling or other means that are outside the scope
  * of this document.
  */
 @Beta
-public interface AnyDataSchemaNode extends DataSchemaNode {
+public interface AnyDataSchemaNode extends DataSchemaNode, MandatoryAware {
     /**
      * Schema of data.
      *
index 2ed8a4d566ed9119ec2f1e5a80d542d0ff15ef11..d4768a8c089de50220eaa4e7db5ee46396a36e2c 100644 (file)
@@ -8,15 +8,14 @@
 package org.opendaylight.yangtools.yang.model.api;
 
 /**
- * The "anyxml" interface defines an interior node in the schema tree. It takes
- * one argument, which is an identifier represented by QName inherited from
- * {@link SchemaNode}, followed by a block of substatements that holds detailed
- * anyxml information. The substatements are defined in {@link DataSchemaNode} <br>
- * <br>
- * This interface was modeled according to definition in <a
- * href="https://tools.ietf.org/html/rfc6020#section-7.10">[RFC-6020] The anyxml
- * Statement</a>
+ * The "anyxml" interface defines an interior node in the schema tree. It takes one argument, which is an identifier
+ * represented by QName inherited from {@link SchemaNode}, followed by a block of substatements that holds detailed
+ * anyxml information. The substatements are defined in {@link DataSchemaNode}.
+ *
+ * <p>
+ * This interface was modeled according to definition in
+ * <a href="https://tools.ietf.org/html/rfc6020#section-7.10">[RFC-6020] The anyxml Statement</a>
  */
-public interface AnyXmlSchemaNode extends DataSchemaNode {
+public interface AnyXmlSchemaNode extends DataSchemaNode, MandatoryAware {
 
 }
index 073b25c6c7d515efd5efcf2b29ea249cf56ff7e7..72a20d4fe61f3da82cb079b0f1e1b64511477ef9 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.yangtools.yang.common.QName;
  * A ChoiceSchemaNode defines a set of alternatives. It consists of a number of branches defined as
  * ChoiceCaseSchemaNode objects.
  */
-public interface ChoiceSchemaNode extends DataSchemaNode, AugmentationTarget {
+public interface ChoiceSchemaNode extends DataSchemaNode, AugmentationTarget, MandatoryAware {
     /**
      * Returns cases of choice, keyed by their {@link SchemaNode#getQName()}. Returned map does not contain null keys
      * nor values.
index 47f8cf0d83a2cd4d007b53ee9b3827be853c4527..35be486e24dda8469b63ae0adcb2879272102d95 100644 (file)
@@ -16,24 +16,6 @@ import javax.annotation.Nullable;
  * then the method returns <code>null</code> value.
  */
 public interface ConstraintDefinition extends MustConstraintAware, WhenConditionAware {
-    /**
-     * Expreses if the presence of the data element for which this constraint is
-     * specified is|isn't required.
-     *
-     * <p>
-     * Contains the value of the <b>mandatory</b> YANG substatement.
-     * It is used with YANG statements leaf, choice, anyxml, deviate.
-     *
-     * @return boolean value:
-     *         <ul>
-     *         <li>true - if <code>mandatory</code> YANG keyword argument =
-     *         <i>true</i></li>
-     *         <li>false - if <code>mandatory</code> YANG keyword argument =
-     *         <i>false</i></li>
-     *         </ul>
-     */
-    boolean isMandatory();
-
     /**
      * Returns the minimum required number of data elements for node where this
      * constraint is specified.
index e1ea75d642a73e2316d57a69b5f844ec12d546f6..00513411e3dd75d38f56689104585b68fa11ad8f 100644 (file)
@@ -17,6 +17,6 @@ package org.opendaylight.yangtools.yang.model.api;
  * Since we are presenting the effective model of the world, the information dictated by 'default' and 'units'
  * substatements is captured in the type returned via {@link #getType()}.
  */
-public interface LeafSchemaNode extends TypedSchemaNode {
+public interface LeafSchemaNode extends TypedSchemaNode, MandatoryAware {
 
 }
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/MandatoryAware.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/MandatoryAware.java
new file mode 100644 (file)
index 0000000..14ad2b3
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies, 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.model.api;
+
+/**
+ * Mix-in interface for {@link SchemaNode}s which can have a {@code mandatory} statement.
+ *
+ * @author Robert Varga
+ */
+public interface MandatoryAware {
+
+    /**
+     * Return whether this node is mandatory or not. Note this reflects the declared model, as defined by 'mandatory'
+     * statement, not the effective model. This notably means this attribute does not mirror the definition of
+     * {@code mandatory node} as per <a href="https://tools.ietf.org/html/rfc7950#page-14">RFC7950 Terminology</a>.
+     *
+     * @return True if this node is marked as mandatory.
+     */
+    boolean isMandatory();
+}
index fc6f6665824053f344d8b2a3e32a39a19bc1aa56..6643876d92fbdf1522faa41ea563a3e3b6e1fc84 100644 (file)
  *   <dd>{@link org.opendaylight.yangtools.yang.model.api.ListSchemaNode}
  *
  * <dt>mandatory
- *   <dd>{@link org.opendaylight.yangtools.yang.model.api.ConstraintDefinition#isMandatory()}
+ *   <dd>{@link org.opendaylight.yangtools.yang.model.api.MandatoryAware#isMandatory()}
  *
  * <dt>max-elements
  *   <dd>{@link org.opendaylight.yangtools.yang.model.api.ConstraintDefinition#getMinElements()}
index 653b91880c2fb60c4c1dd69b4468f6997f6cd449..0c8f0fda1ade06745b3e37ffbd323192aa0043cc 100644 (file)
@@ -1775,7 +1775,7 @@ abstract class SchemaContextEmitter {
             emitMustNodes(child.getConstraints().getMustConstraints());
             child.getType().getDefaultValue().ifPresent(this::emitDefaultNode);
             emitConfigNode(child.isConfiguration());
-            emitMandatoryNode(child.getConstraints().isMandatory());
+            emitMandatoryNode(child.isMandatory());
             emitDocumentedNode(child);
             emitUnknownStatementNodes(child.getUnknownSchemaNodes());
             super.writer.endNode();
@@ -1853,7 +1853,7 @@ abstract class SchemaContextEmitter {
             // FIXME: BUG-2444: *(ifFeatureNode )
             // FIXME: BUG-2444: defaultNode //Optional
             emitConfigNode(choice.isConfiguration());
-            emitMandatoryNode(choice.getConstraints().isMandatory());
+            emitMandatoryNode(choice.isMandatory());
             emitDocumentedNode(choice);
             for (final ChoiceCaseNode caze : choice.getCases().values()) {
                 // TODO: emit short case?
@@ -1894,7 +1894,6 @@ abstract class SchemaContextEmitter {
             // FIXME: BUG-2444: *(ifFeatureNode )
             emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
             emitConfigNode(dataSchemaNode.isConfiguration());
-            emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
             emitDocumentedNode(dataSchemaNode);
             emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
         }
@@ -1983,8 +1982,8 @@ abstract class SchemaContextEmitter {
                 emitConfigNode(value.isConfiguration());
             }
             emitDocumentedNodeRefine(original, value);
-            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-                emitMandatoryNode(value.getConstraints().isMandatory());
+            if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
+                emitMandatoryNode(value.isMandatory());
             }
 
         }
@@ -2034,8 +2033,8 @@ abstract class SchemaContextEmitter {
             if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
                 emitConfigNode(value.isConfiguration());
             }
-            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-                emitMandatoryNode(value.getConstraints().isMandatory());
+            if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
+                emitMandatoryNode(value.isMandatory());
             }
             emitDocumentedNodeRefine(original, value);
 
@@ -2055,8 +2054,8 @@ abstract class SchemaContextEmitter {
             if (Objects.deepEquals(original.isConfiguration(), value.isConfiguration())) {
                 emitConfigNode(value.isConfiguration());
             }
-            if (Objects.deepEquals(original.getConstraints().isMandatory(), value.getConstraints().isMandatory())) {
-                emitMandatoryNode(value.getConstraints().isMandatory());
+            if (Objects.deepEquals(original.isMandatory(), value.isMandatory())) {
+                emitMandatoryNode(value.isMandatory());
             }
             emitDocumentedNodeRefine(original, value);
 
index 1a08bf391c0ba8e11fc0ebb299e9470581cb074f..2582edf32bbdf9cd8a549c9136f1634c40e6489a 100644 (file)
@@ -20,11 +20,19 @@ public class AnyXmlEffectiveStatementImpl extends AbstractEffectiveDataSchemaNod
         implements AnyXmlSchemaNode, DerivableSchemaNode {
 
     private final AnyXmlSchemaNode original;
+    private final boolean mandatory;
 
     public AnyXmlEffectiveStatementImpl(
             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();
+    }
+
+    @Override
+    public boolean isMandatory() {
+        return mandatory;
     }
 
     @Override
index f76df175a8753cdd8c463783e02fd55dc8754e31..9eb0fa78773b1885088af8b9fbaaff7fedf4effb 100644 (file)
@@ -35,6 +35,7 @@ public final class ChoiceEffectiveStatementImpl extends AbstractEffectiveDataSch
     private final SortedMap<QName, ChoiceCaseNode> cases;
     private final ChoiceCaseNode defaultCase;
     private final ChoiceSchemaNode original;
+    private final boolean mandatory;
 
     public ChoiceEffectiveStatementImpl(
             final StmtContext<QName, ChoiceStatement, EffectiveStatement<QName, ChoiceStatement>> ctx) {
@@ -85,6 +86,9 @@ public final class ChoiceEffectiveStatementImpl extends AbstractEffectiveDataSch
         } else {
             defaultCase = null;
         }
+
+        final MandatoryEffectiveStatement mandatoryStmt = firstEffective(MandatoryEffectiveStatement.class);
+        mandatory = mandatoryStmt == null ? false : mandatoryStmt.argument().booleanValue();
     }
 
     private static void resetAugmenting(final DataSchemaNode dataSchemaNode) {
@@ -126,6 +130,11 @@ public final class ChoiceEffectiveStatementImpl extends AbstractEffectiveDataSch
         return Optional.ofNullable(defaultCase);
     }
 
+    @Override
+    public boolean isMandatory() {
+        return mandatory;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
index dfcf434a5f56fab137b32ac71828ce574a5f2851..6d6bfbcac15f29600a7992799793cc3ddd8036f8 100644 (file)
@@ -25,12 +25,9 @@ final class EffectiveConstraintDefinitionImpl implements ConstraintDefinition {
     private final Set<MustDefinition> mustConstraints;
     private final Integer minElements;
     private final Integer maxElements;
-    private final boolean mandatory;
 
-    private EffectiveConstraintDefinitionImpl(final boolean mandatory, final Integer minElements,
-            final Integer maxElements, final RevisionAwareXPath whenCondition,
-            final Set<MustDefinition> mustConstraints) {
-        this.mandatory = mandatory;
+    private EffectiveConstraintDefinitionImpl(final Integer minElements, final Integer maxElements,
+            final RevisionAwareXPath whenCondition, final Set<MustDefinition> mustConstraints) {
         this.minElements = minElements;
         this.maxElements = maxElements;
         this.whenCondition = whenCondition;
@@ -59,19 +56,16 @@ final class EffectiveConstraintDefinitionImpl implements ConstraintDefinition {
             maxElements = null;
         }
 
-        final MandatoryEffectiveStatement firstMandatoryStmt = parent.firstEffective(MandatoryEffectiveStatement.class);
-        final boolean mandatory = firstMandatoryStmt == null ? minElements != null : firstMandatoryStmt.argument();
-
         final Set<MustDefinition> mustSubstatements = ImmutableSet.copyOf(parent.allSubstatementsOfType(
             MustDefinition.class));
         final WhenEffectiveStatementImpl firstWhenStmt = parent.firstEffective(WhenEffectiveStatementImpl.class);
 
         // Check for singleton instances
         if (minElements == null && maxElements == null && mustSubstatements.isEmpty() && firstWhenStmt == null) {
-            return EmptyConstraintDefinition.create(mandatory);
+            return EmptyConstraintDefinition.getInstance();
         }
 
-        return new EffectiveConstraintDefinitionImpl(mandatory, minElements, maxElements,
+        return new EffectiveConstraintDefinitionImpl(minElements, maxElements,
             firstWhenStmt == null ? null : firstWhenStmt.argument(), mustSubstatements);
     }
 
@@ -85,11 +79,6 @@ final class EffectiveConstraintDefinitionImpl implements ConstraintDefinition {
         return mustConstraints;
     }
 
-    @Override
-    public boolean isMandatory() {
-        return mandatory;
-    }
-
     @Override
     public Integer getMinElements() {
         return minElements;
index 6b2076c6d6287f84bd29836366447ab9d43ccf5e..b963c7268bca4ad13d5079139b307688e58b94eb 100644 (file)
@@ -28,6 +28,7 @@ public final class LeafEffectiveStatementImpl extends AbstractEffectiveDataSchem
     private final TypeDefinition<?> type;
     private final String defaultStr;
     private final String unitsStr;
+    private final boolean mandatory;
 
     public LeafEffectiveStatementImpl(
             final StmtContext<QName, LeafStatement, EffectiveStatement<QName, LeafStatement>> ctx) {
@@ -66,6 +67,13 @@ 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();
+    }
+
+    @Override
+    public boolean isMandatory() {
+        return mandatory;
     }
 
     @Override
index 99216d61997c9247ad27e1f52b0ce4d577820c0c..f2e50cee48f260bae415b04c196a2275df49c2a6 100644 (file)
@@ -19,6 +19,7 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.AbstractEffectiveDataSchemaNode;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.MandatoryEffectiveStatement;
 
 /**
  * YANG 1.1 AnyData effective statement implementation.
@@ -29,11 +30,15 @@ public final class AnyDataEffectiveStatementImpl extends AbstractEffectiveDataSc
 
     private final AnyDataSchemaNode original;
     private final ContainerSchemaNode schema;
+    private final boolean mandatory;
 
     public AnyDataEffectiveStatementImpl(
             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();
+
         /*
          * :TODO we need to determine a way how to set schema of AnyData
          */
@@ -50,6 +55,11 @@ public final class AnyDataEffectiveStatementImpl extends AbstractEffectiveDataSc
         return Optional.ofNullable(schema);
     }
 
+    @Override
+    public boolean isMandatory() {
+        return mandatory;
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(getQName(),getPath());
index 5b8770cd9ad102cd236f698036c560c8553938da..0d435ee6e9073de17587d96bca72d59c1762c7a6 100644 (file)
@@ -67,8 +67,8 @@ public class ConstraintDefinitionsTest {
         assertNotNull(mandatoryLeaf3);
         ConstraintDefinition constraints3 = mandatoryLeaf3.getConstraints();
 
-        assertNotEquals(ConstraintDefinitions.hashCode(constraints2), ConstraintDefinitions.hashCode(constraints3));
-        assertFalse(ConstraintDefinitions.equals(constraints2, constraints3));
+        assertEquals(ConstraintDefinitions.hashCode(constraints2), ConstraintDefinitions.hashCode(constraints3));
+        assertTrue(ConstraintDefinitions.equals(constraints2, constraints3));
 
         final LeafSchemaNode mandatoryLeaf4 = (LeafSchemaNode) testModule.getDataChildByName(
                 QName.create(testModule.getQNameModule(), "mandatory-leaf-4"));
@@ -117,6 +117,6 @@ public class ConstraintDefinitionsTest {
 
         final String constraintsString = ConstraintDefinitions.toString(constraints4);
         assertEquals("EffectiveConstraintDefinitionImpl{whenCondition=foo = 'bar', mustConstraints=[bar != 'foo'], "
-                + "mandatory=true, minElements=50, maxElements=100}", constraintsString);
+                + "minElements=50, maxElements=100}", constraintsString);
     }
 }
\ No newline at end of file
index edf4b86aac11b034ea134ff1e4d4e501d458c981..e8c22ab27a08de9e4512a88c52b24b24a64e1e90 100644 (file)
@@ -46,7 +46,7 @@ public class Bug6869Test {
         final SchemaNode findNode = findNode(schemaContext, ImmutableList.of("root", "grp-leaf"));
         assertTrue(findNode instanceof LeafSchemaNode);
         final LeafSchemaNode grpLeaf = (LeafSchemaNode) findNode;
-        assertFalse(grpLeaf.getConstraints().isMandatory());
+        assertFalse(grpLeaf.isMandatory());
     }
 
     @Test
@@ -61,7 +61,7 @@ public class Bug6869Test {
         final SchemaNode findNode = findNode(schemaContext, ImmutableList.of("root", "grp-leaf"));
         assertTrue(findNode instanceof LeafSchemaNode);
         final LeafSchemaNode grpLeaf = (LeafSchemaNode) findNode;
-        assertTrue(grpLeaf.getConstraints().isMandatory());
+        assertTrue(grpLeaf.isMandatory());
     }
 
     private static Set<IdentitySchemaNode> getIdentities(final SchemaContext schemaContext) {
index de2e4141b297d4dc647dc1c6545b4349763237a1..ea44917ccab847bae98663cee16eaee485b0cd75 100644 (file)
@@ -44,6 +44,6 @@ public class Bug9244Test {
         final LeafSchemaNode barLeaf = (LeafSchemaNode) barModule.getDataChildByName(
                 QName.create(barModule.getQNameModule(), "bar-leaf"));
         assertNotNull(barLeaf);
-        assertTrue(barLeaf.getConstraints().isMandatory());
+        assertTrue(barLeaf.isMandatory());
     }
 }
index 84fe74a936b67084634acfc60d9eb1cecdc7f8f9..397bb51a2e586d520906621d01ca4a068568315d 100644 (file)
@@ -106,7 +106,7 @@ public class DeviationResolutionTest {
         final AnyXmlSchemaNode myAnyxml = (AnyXmlSchemaNode) barModule.getDataChildByName(
                 QName.create(barModule.getQNameModule(), "my-anyxml"));
         assertNotNull(myAnyxml);
-        assertTrue(myAnyxml.getConstraints().isMandatory());
+        assertTrue(myAnyxml.isMandatory());
         assertEquals(2, myAnyxml.getUnknownSchemaNodes().size());
     }
 
@@ -140,7 +140,7 @@ public class DeviationResolutionTest {
                 QName.create(barModule.getQNameModule(), "my-choice"));
         assertNotNull(myChoice);
 
-        assertFalse(myChoice.getConstraints().isMandatory());
+        assertFalse(myChoice.isMandatory());
         assertEquals(1, myChoice.getUnknownSchemaNodes().size());
         assertEquals("new arg", myChoice.getUnknownSchemaNodes().iterator().next().getNodeParameter());
 
index ce2a075568b1d0156c570cfc869fee33843b2c97..1d564cc6360a3528adbe0361daf17997dea73c02 100644 (file)
@@ -102,9 +102,9 @@ public class EffectiveUsesRefineAndConstraintsTest {
         assertNotNull(choiceInContainerNode);
 
         ChoiceSchemaNode choiceSchemaNode = (ChoiceSchemaNode) choiceInContainerNode;
+        assertFalse(choiceSchemaNode.isMandatory());
 
         ConstraintDefinition choiceConstraints = choiceSchemaNode.getConstraints();
-        assertFalse(choiceConstraints.isMandatory());
         assertTrue(choiceConstraints.getMustConstraints().isEmpty());
     }
 
@@ -142,9 +142,9 @@ public class EffectiveUsesRefineAndConstraintsTest {
         assertNotNull(choiceInContainerNode);
 
         ChoiceSchemaNode choiceSchemaNode = (ChoiceSchemaNode) choiceInContainerNode;
+        assertTrue(choiceSchemaNode.isMandatory());
 
         ConstraintDefinition choiceConstraints = choiceSchemaNode.getConstraints();
-        assertTrue(choiceConstraints.isMandatory());
         assertTrue(choiceConstraints.getMustConstraints().isEmpty());
     }
 
index 8e1ec849de5f1f0060b9cda43709f0fb18b9b6fb..5ce28716878d721dfb864075791acadc5abdabb5 100644 (file)
@@ -103,7 +103,7 @@ public class GroupingTest {
         assertEquals(Optional.of("IP address of target node"), refineLeaf.getDescription());
         assertEquals(Optional.of("address reference added by refine"), refineLeaf.getReference());
         assertFalse(refineLeaf.isConfiguration());
-        assertFalse(refineLeaf.getConstraints().isMandatory());
+        assertFalse(refineLeaf.isMandatory());
         final Collection<MustDefinition> leafMustConstraints = refineLeaf.getConstraints().getMustConstraints();
         assertEquals(1, leafMustConstraints.size());
         final MustDefinition leafMust = leafMustConstraints.iterator().next();
@@ -197,7 +197,7 @@ public class GroupingTest {
         assertEquals(Optional.of("address reference added by refine"), address_u.getReference());
         assertFalse(address_u.isConfiguration());
         assertTrue(address_u.isAddedByUses());
-        assertFalse(address_u.getConstraints().isMandatory());
+        assertFalse(address_u.isMandatory());
 
         final LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName(QName.create(
                 baz.getQNameModule(), "address"));
@@ -208,7 +208,7 @@ public class GroupingTest {
         assertFalse(address_g.getReference().isPresent());
         assertTrue(address_g.isConfiguration());
         assertFalse(address_u.equals(address_g));
-        assertTrue(address_g.getConstraints().isMandatory());
+        assertTrue(address_g.isMandatory());
         assertEquals(address_g, SchemaNodeUtils.getRootOriginalIfPossible(address_u));
 
         final ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName(QName.create(
index ff7e6bc04414facec4ba984891559a40409acc86..ca6e0a4d0c2b78e8f343e509a13eed9f2f1d9cae 100644 (file)
@@ -63,29 +63,28 @@ public class ListTest {
         LeafSchemaNode leaf = (LeafSchemaNode) list.getDataChildByName(QName.create(testModule.getQNameModule(),
             "key1"));
         assertNotNull(leaf);
-        assertTrue(leaf.getConstraints().isMandatory());
+        assertTrue(leaf.isMandatory());
         assertEquals("int32", leaf.getType().getQName().getLocalName());
 
         leaf = (LeafSchemaNode) list.getDataChildByName(QName.create(testModule.getQNameModule(), "key2"));
         assertNotNull(leaf);
-        assertTrue(leaf.getConstraints().isMandatory());
+        assertTrue(leaf.isMandatory());
         assertEquals("int16", leaf.getType().getQName().getLocalName());
 
         leaf = (LeafSchemaNode) list.getDataChildByName(QName.create(testModule.getQNameModule(), "old-leaf"));
         assertNotNull(leaf);
-        assertFalse(leaf.getConstraints().isMandatory());
+        assertFalse(leaf.isMandatory());
         assertEquals("string", leaf.getType().getQName().getLocalName());
 
         leaf = (LeafSchemaNode) list.getDataChildByName(QName.create(testModule.getQNameModule(), "young-leaf"));
         assertNotNull(leaf);
-        assertFalse(leaf.getConstraints().isMandatory());
+        assertFalse(leaf.isMandatory());
         assertEquals("young-leaf", leaf.getType().getQName().getLocalName());
         assertEquals(Optional.of("default-value"), leaf.getType().getDefaultValue());
 
         final LeafListSchemaNode leafList = (LeafListSchemaNode) list.getDataChildByName(
             QName.create(testModule.getQNameModule(), "list-of-leaves"));
         assertNotNull(leafList);
-        assertTrue(leafList.getConstraints().isMandatory());
         assertTrue(leafList.isUserOrdered());
         assertEquals(2, leafList.getConstraints().getMinElements().intValue());
         assertEquals(20, leafList.getConstraints().getMaxElements().intValue());
index 7fd9b2078fc9bbcb27770ec2e1dd183dfa0b5634..4b8d0fc1bfb8bffdc908f64d365749ef1c6955c7 100644 (file)
@@ -72,6 +72,8 @@ public class YangParserSimpleTest {
         // test DataSchemaNode args
         assertFalse(data.isAugmenting());
         assertFalse(data.isConfiguration());
+
+        assertTrue(data.isMandatory());
         final ConstraintDefinition constraints = data.getConstraints();
         assertEquals("class != 'wheel'", constraints.getWhenCondition().get().toString());
         final Collection<MustDefinition> mustConstraints = constraints.getMustConstraints();
@@ -97,7 +99,6 @@ public class YangParserSimpleTest {
         assertTrue(found1);
         assertTrue(found2);
 
-        assertTrue(constraints.isMandatory());
         assertNull(constraints.getMinElements());
         assertNull(constraints.getMaxElements());
     }
@@ -144,7 +145,6 @@ public class YangParserSimpleTest {
         assertTrue(found1);
         assertTrue(found2);
 
-        assertFalse(constraints.isMandatory());
         assertNull(constraints.getMinElements());
         assertNull(constraints.getMaxElements());
         assertTrue(nodes.isPresenceContainer());
index 865672de8c6a6394a5ed480faa387e689af60380..b49ae82969622672d17e39ec21f5f24618d8a6c9 100644 (file)
@@ -140,7 +140,6 @@ public class YangParserTest {
         // ifEntry should be a context node ?
         // assertNull(constraints.getWhenCondition());
         assertEquals(0, constraints.getMustConstraints().size());
-        assertTrue(constraints.isMandatory());
         assertEquals(1, (int) constraints.getMinElements());
         assertEquals(11, (int) constraints.getMaxElements());
         // test AugmentationTarget args
index a1a9d41afcf9309ae4bc572b10fa3082d2ee6cf3..74f43e19abe88bf128bb256c8a5d2dce3fb5b649 100644 (file)
@@ -262,7 +262,7 @@ public class YangParserWithContextTest {
         assertEquals(Optional.of("description of address defined by refine"), refineLeaf.getDescription());
         assertEquals(Optional.of("address reference added by refine"), refineLeaf.getReference());
         assertFalse(refineLeaf.isConfiguration());
-        assertTrue(refineLeaf.getConstraints().isMandatory());
+        assertTrue(refineLeaf.isMandatory());
         final Collection<MustDefinition> leafMustConstraints = refineLeaf.getConstraints().getMustConstraints();
         assertEquals(1, leafMustConstraints.size());
         final MustDefinition leafMust = leafMustConstraints.iterator().next();
index 5be7b4dca9c9fbc4f64086780b4a7a0d85449f6b..e0d125dae7588b0f1c2c1aa4bc394a24b42bc4e9 100644 (file)
@@ -56,7 +56,7 @@ public class YinFileChoiceStmtTest {
         assertNotNull(choice);
 
         assertEquals("configuration", choice.getQName().getLocalName());
-        assertTrue(choice.getConstraints().isMandatory());
+        assertTrue(choice.isMandatory());
         assertTrue(choice.isConfiguration());
         assertEquals(1, choice.getCases().size());
 
@@ -72,7 +72,7 @@ public class YinFileChoiceStmtTest {
         assertNotNull(choice);
 
         assertEquals("state", choice.getQName().getLocalName());
-        assertFalse(choice.getConstraints().isMandatory());
+        assertFalse(choice.isMandatory());
         assertFalse(choice.isConfiguration());
         assertTrue(choice.getCases().isEmpty());
     }
index fe6ed76155c6fac7c0cb68d853ccc66aa2669e5d..ab592aca2821d40f72f0f8e8aac115131348ec4e 100644 (file)
@@ -63,11 +63,11 @@ public class YinFileGroupingStmtTest {
         final LeafSchemaNode leaf1 = (LeafSchemaNode) grouping.getDataChildByName(QName.create(
                 testModule.getQNameModule(), "type"));
         assertNotNull(leaf1);
-        assertTrue(leaf1.getConstraints().isMandatory());
+        assertTrue(leaf1.isMandatory());
 
         final LeafSchemaNode leaf2 = (LeafSchemaNode) grouping.getDataChildByName(QName.create(
                 testModule.getQNameModule(), "name"));
         assertNotNull(leaf2);
-        assertTrue(leaf2.getConstraints().isMandatory());
+        assertTrue(leaf2.isMandatory());
     }
 }
index 55ff819fb6382add9efd3014ea18a4239ce55e6c..773854f36940e379d8794f76aa39a6459736e06f 100644 (file)
@@ -67,7 +67,7 @@ public class YinFileListStmtTest {
         assertEquals("name", leaf.getQName().getLocalName());
         assertEquals(Optional.of("Unique module instance name"), leaf.getDescription());
         assertEquals(BaseTypes.stringType(), leaf.getType());
-        assertTrue(leaf.getConstraints().isMandatory());
+        assertTrue(leaf.isMandatory());
 
         leaf = (LeafSchemaNode) childrenIterator.next();
         assertEquals("type", leaf.getQName().getLocalName());
@@ -76,7 +76,7 @@ public class YinFileListStmtTest {
         assertTrue(leafType instanceof IdentityrefTypeDefinition);
         assertEquals("module-type", ((IdentityrefTypeDefinition)leafType).getIdentities().iterator().next().getQName()
             .getLocalName());
-        assertTrue(leaf.getConstraints().isMandatory());
+        assertTrue(leaf.isMandatory());
     }
 
 }