Fix leafref require-instance implementation 16/70216/2
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 29 Mar 2018 21:59:34 +0000 (23:59 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 1 Apr 2018 00:26:55 +0000 (02:26 +0200)
Both identityref and leafref types default to require-instace=true,
hence we should be starting with that and also properly inherit
the property from the parent type.

Add RequireInstanceRestrictedTypeDefinition to capture the common
method and adjust RequireInstanceRestrictedTypeBuilder to check
for it and initialize the require-instance value appropriately.

JIRA: YANGTOOLS-872
Change-Id: I125d5687950af21694c4510ce64adb00f92ae4e6
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit 38ca7ba1b5222af644f0e782f2876db9e9a58f05)

yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/InstanceIdentifierTypeDefinition.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/LeafrefTypeDefinition.java
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/RequireInstanceRestrictedTypeDefinition.java [new file with mode: 0644]
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/type/RequireInstanceRestrictedTypeBuilder.java
yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/LeafrefTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/LeafrefStatementTest.java

index 0bca31119b2b20e1d34ce72429cf160f26a1d007..69504e8d35292940f339f18388fa77d67707008e 100644 (file)
@@ -7,18 +7,10 @@
  */
 package org.opendaylight.yangtools.yang.model.api.type;
 
  */
 package org.opendaylight.yangtools.yang.model.api.type;
 
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-
 /**
 /**
- * Contains methods for getting data from the <code>instance-identifier</code>
- * YANG built-in type.
+ * Contains methods for getting data from the <code>instance-identifier</code> YANG built-in type.
  */
  */
-public interface InstanceIdentifierTypeDefinition extends TypeDefinition<InstanceIdentifierTypeDefinition> {
-    /**
-     * Returns true|false which represents argument of <code>require-instance</code> statement. This statement is the
-     * substatement of the <code>type</code> statement.
-     *
-     * @return boolean value which is true if the <code>require-instance</code> statement is true and vice versa
-     */
-    boolean requireInstance();
+public interface InstanceIdentifierTypeDefinition
+        extends RequireInstanceRestrictedTypeDefinition<InstanceIdentifierTypeDefinition> {
+
 }
 }
index 587ade58eb7efdbc6d13efa755db7f0b5d0c49ca..b807468fdcd19abeff7d442aa725acf5e51d5724 100644 (file)
@@ -8,9 +8,8 @@
 package org.opendaylight.yangtools.yang.model.api.type;
 
 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 package org.opendaylight.yangtools.yang.model.api.type;
 
 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
-import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 
 
-public interface LeafrefTypeDefinition extends TypeDefinition<LeafrefTypeDefinition> {
+public interface LeafrefTypeDefinition extends RequireInstanceRestrictedTypeDefinition<LeafrefTypeDefinition> {
 
     RevisionAwareXPath getPathStatement();
 
 
     RevisionAwareXPath getPathStatement();
 
@@ -22,7 +21,8 @@ public interface LeafrefTypeDefinition extends TypeDefinition<LeafrefTypeDefinit
      *
      * @return boolean value which is true if the <code>require-instance</code> statement is true and vice versa
      */
      *
      * @return boolean value which is true if the <code>require-instance</code> statement is true and vice versa
      */
-     // FIXME: version 2.0.0: make this method non-default
+    // FIXME: version 2.0.0: make this method non-default
+    @Override
     default boolean requireInstance() {
         return true;
     }
     default boolean requireInstance() {
         return true;
     }
diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/RequireInstanceRestrictedTypeDefinition.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/type/RequireInstanceRestrictedTypeDefinition.java
new file mode 100644 (file)
index 0000000..b04fd8e
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.api.type;
+
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+/**
+ * Interface for {@link TypeDefinition}s which can be restricted through a require-instance statement.
+ *
+ * @param <T> Concrete {@link TypeDefinition} subinterface
+ */
+public interface RequireInstanceRestrictedTypeDefinition<T extends TypeDefinition<T>> extends TypeDefinition<T> {
+    /**
+     * Returns true or false which represents argument of <code>require-instance</code> statement. This statement is
+     * the substatement of the <code>type</code> statement.
+     *
+     * @return boolean value which is true if the <code>require-instance</code> statement is true and vice versa
+     */
+    boolean requireInstance();
+}
index 6d4b988b12365e3cc8d16a7d114aab5ab75f16b9..c3c238e3cf6ef4004a7d0a9d50f741c2501dac47 100644 (file)
@@ -5,15 +5,15 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
  * 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.util.type;
 
 import com.google.common.annotations.Beta;
 package org.opendaylight.yangtools.yang.model.util.type;
 
 import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.RequireInstanceRestrictedTypeDefinition;
 
 @Beta
 
 @Beta
+//FIXME: 3.0.0: this should require T to be a RequireInstanceRestrictedTypeDefinition
 public abstract class RequireInstanceRestrictedTypeBuilder<T extends TypeDefinition<T>>
         extends AbstractRestrictedTypeBuilder<T> {
 
 public abstract class RequireInstanceRestrictedTypeBuilder<T extends TypeDefinition<T>>
         extends AbstractRestrictedTypeBuilder<T> {
 
@@ -21,13 +21,11 @@ public abstract class RequireInstanceRestrictedTypeBuilder<T extends TypeDefinit
 
     RequireInstanceRestrictedTypeBuilder(final T baseType, final SchemaPath path) {
         super(baseType, path);
 
     RequireInstanceRestrictedTypeBuilder(final T baseType, final SchemaPath path) {
         super(baseType, path);
+        requireInstance = baseType instanceof RequireInstanceRestrictedTypeDefinition
+                ? ((RequireInstanceRestrictedTypeDefinition<?>)baseType).requireInstance() : true;
     }
 
     public final void setRequireInstance(final boolean requireInstance) {
     }
 
     public final void setRequireInstance(final boolean requireInstance) {
-        if (this.requireInstance) {
-            Preconditions.checkArgument(requireInstance, "Cannot switch off require-instance in type %s", getPath());
-        }
-
         this.requireInstance = requireInstance;
         touch();
     }
         this.requireInstance = requireInstance;
         touch();
     }
index 2cd69698524137252bccedfe5af7c38e68abf6b4..fd4b33d2373fcb2e62d39df807865b6439c723f0 100644 (file)
@@ -13,7 +13,6 @@ import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
 
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -22,6 +21,8 @@ import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
 import org.opendaylight.yangtools.yang.model.util.type.LeafrefTypeBuilder;
 import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
 import org.opendaylight.yangtools.yang.model.util.type.LeafrefTypeBuilder;
+import org.opendaylight.yangtools.yang.model.util.type.RequireInstanceRestrictedTypeBuilder;
+import org.opendaylight.yangtools.yang.model.util.type.RestrictedTypes;
 
 public class LeafrefTest {
 
 
 public class LeafrefTest {
 
@@ -60,28 +61,24 @@ public class LeafrefTest {
     public void testRequireInstanceSubstatement() {
         final SchemaPath schemaPath = SchemaPath.create(true, QName.create("my-cont"), QName.create("my-leafref"));
         final RevisionAwareXPathImpl path = new RevisionAwareXPathImpl("../my-leaf", false);
     public void testRequireInstanceSubstatement() {
         final SchemaPath schemaPath = SchemaPath.create(true, QName.create("my-cont"), QName.create("my-leafref"));
         final RevisionAwareXPathImpl path = new RevisionAwareXPathImpl("../my-leaf", false);
+        final LeafrefTypeBuilder leafrefTypeBuilder = BaseTypes.leafrefTypeBuilder(schemaPath).setPathStatement(path);
 
 
-        LeafrefTypeBuilder leafrefTypeBuilder = BaseTypes.leafrefTypeBuilder(schemaPath).setPathStatement(path);
+        assertTrue(leafrefTypeBuilder.build().requireInstance());
 
         leafrefTypeBuilder.setRequireInstance(false);
 
         leafrefTypeBuilder.setRequireInstance(false);
-        LeafrefTypeDefinition leafref = leafrefTypeBuilder.build();
-        assertFalse(leafref.requireInstance());
+        final LeafrefTypeDefinition falseLeafref = leafrefTypeBuilder.build();
+        assertFalse(falseLeafref.requireInstance());
 
         leafrefTypeBuilder.setRequireInstance(true);
 
         leafrefTypeBuilder.setRequireInstance(true);
-        leafref = leafrefTypeBuilder.build();
-        assertTrue(leafref.requireInstance());
+        final LeafrefTypeDefinition trueLeafref = leafrefTypeBuilder.build();
+        assertTrue(trueLeafref.requireInstance());
 
 
-        leafrefTypeBuilder.setRequireInstance(true);
-        leafref = leafrefTypeBuilder.build();
-        assertTrue(leafref.requireInstance());
-
-        try {
-            leafrefTypeBuilder.setRequireInstance(false);
-            fail("An IllegalArgumentException should have been thrown.");
-        } catch (IllegalArgumentException ex) {
-            assertEquals("Cannot switch off require-instance in type AbsoluteSchemaPath{path=[my-cont, my-leafref]}",
-                    ex.getMessage());
-        }
+        final RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition> falseBuilder =
+                RestrictedTypes.newLeafrefBuilder(falseLeafref, schemaPath);
+        assertFalse(falseBuilder.build().requireInstance());
 
 
+        final RequireInstanceRestrictedTypeBuilder<LeafrefTypeDefinition> trueBuilder =
+                RestrictedTypes.newLeafrefBuilder(trueLeafref, schemaPath);
+        assertTrue(trueBuilder.build().requireInstance());
     }
 }
     }
 }
index 3857385a4ecfd5a662be3c69b0c7e807351d36ba..57dcd56272e8c88615f7b2196aa3e6924188d2ec 100644 (file)
@@ -58,7 +58,7 @@ public class LeafrefStatementTest {
         final LeafSchemaNode leafrefC = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(),
                 "leafref-c"));
         assertNotNull(leafrefC);
         final LeafSchemaNode leafrefC = (LeafSchemaNode) foo.getDataChildByName(QName.create(foo.getQNameModule(),
                 "leafref-c"));
         assertNotNull(leafrefC);
-        assertRequireInstanceInLeafref(leafrefC, false);
+        assertRequireInstanceInLeafref(leafrefC, true);
     }
 
     private static void assertRequireInstanceInLeafref(final LeafSchemaNode leaf, final boolean requireInstance) {
     }
 
     private static void assertRequireInstanceInLeafref(final LeafSchemaNode leaf, final boolean requireInstance) {