Bug 6880: [Yang 1.1] Allow leaf-lists to have default values 73/49473/3
authorPeter Kajsa <pkajsa@cisco.com>
Wed, 14 Dec 2016 09:59:10 +0000 (10:59 +0100)
committerRobert Varga <nite@hq.sk>
Tue, 20 Dec 2016 14:17:53 +0000 (14:17 +0000)
Allow leaf-lists to have default values in Yang 1.1 models.

Change-Id: I84df558e886eb695e83686e972f5cb9e1086b061
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/LeafListStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/LeafListEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/LeafListStatementRfc7950Support.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6880Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/rfc7950/bug6880/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/rfc7950/bug6880/invalid10.yang [new file with mode: 0644]

index f050ead6582e3707158ef6c73eba5cce2d28c7c5..0453fe04028de7c1b9d4b2d1067831ed46b74b44 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.DefaultStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
@@ -130,6 +131,11 @@ public class LeafListStatementImpl extends AbstractDeclaredStatement<QName>
         return firstDeclared(StatusStatement.class);
     }
 
+    @Override
+    public final Collection<? extends DefaultStatement> getDefaults() {
+        return allDeclared(DefaultStatement.class);
+    }
+
     @Nullable
     @Override
     public DescriptionStatement getDescription() {
index 2e8585bf116d2635a5d0b2468dbd029ae2bdb20e..ece59443472fb69778fdf4e31c2b2e11ebba5814 100644 (file)
@@ -73,6 +73,7 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.IdentityStatementRfc7
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.ImportStatementRfc7950Support;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.IncludeStatementRfc7950Support;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.InputStatementRfc7950Support;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.LeafListStatementRfc7950Support;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.ListStatementRfc7950Support;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.ModifierStatementImpl;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.ModuleStatementRfc7950Support;
@@ -211,7 +212,8 @@ public final class YangInferencePipeline {
             .addSupport(treeScoped(GroupingNamespace.class)) //treeScoped
             .addSupport(new ErrorMessageStatementImpl.Definition())
             .addSupport(new ErrorAppTagStatementImpl.Definition())
-            .addSupport(new LeafListStatementImpl.Definition())
+            .addVersionSpecificSupport(VERSION_1, new LeafListStatementImpl.Definition())
+            .addVersionSpecificSupport(VERSION_1_1, new LeafListStatementRfc7950Support())
             .addSupport(new PresenceStatementImpl.Definition())
             .addSupport(new KeyStatementImpl.Definition())
             .addSupport(new MaxElementsStatementImpl.Definition())
index de1322110d1db580e560bc9133714a1447976713..176c9c5bbca59df3ee2789c7dd91c5c658de9942 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode;
@@ -28,6 +31,7 @@ public final class LeafListEffectiveStatementImpl extends AbstractEffectiveDataS
     private final TypeDefinition<?> type;
     private final LeafListSchemaNode original;
     private final boolean userOrdered;
+    private final List<String> defaultValues;
 
     public LeafListEffectiveStatementImpl(
             final StmtContext<QName, LeafListStatement, EffectiveStatement<QName, LeafListStatement>> ctx) {
@@ -41,14 +45,15 @@ public final class LeafListEffectiveStatementImpl extends AbstractEffectiveDataS
 
         final ConcreteTypeBuilder<?> builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(),
             ctx.getSchemaPath().get());
+        final ImmutableList.Builder<String> defaultValuesBuilder = ImmutableList.builder();
         boolean isUserOrdered = false;
-        for (EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
+        for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
             if (stmt instanceof OrderedByEffectiveStatementImpl) {
                 isUserOrdered = ORDER_BY_USER_KEYWORD.equals(stmt.argument());
             }
 
             if (stmt instanceof DefaultEffectiveStatementImpl) {
-                builder.setDefaultValue(stmt.argument());
+                defaultValuesBuilder.add(((DefaultEffectiveStatementImpl) stmt).argument());
             } else if (stmt instanceof DescriptionEffectiveStatementImpl) {
                 builder.setDescription(((DescriptionEffectiveStatementImpl)stmt).argument());
             } else if (stmt instanceof ReferenceEffectiveStatementImpl) {
@@ -60,10 +65,16 @@ public final class LeafListEffectiveStatementImpl extends AbstractEffectiveDataS
             }
         }
 
+        defaultValues = defaultValuesBuilder.build();
         type = builder.build();
         userOrdered = isUserOrdered;
     }
 
+    @Override
+    public Collection<String> getDefaults() {
+        return defaultValues;
+    }
+
     @Override
     public Optional<LeafListSchemaNode> getOriginal() {
         return Optional.fromNullable(original);
@@ -99,7 +110,7 @@ public final class LeafListEffectiveStatementImpl extends AbstractEffectiveDataS
         if (getClass() != obj.getClass()) {
             return false;
         }
-        LeafListEffectiveStatementImpl other = (LeafListEffectiveStatementImpl) obj;
+        final LeafListEffectiveStatementImpl other = (LeafListEffectiveStatementImpl) obj;
         return Objects.equals(getQName(), other.getQName()) && Objects.equals(getPath(), other.getPath());
     }
 
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/LeafListStatementRfc7950Support.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/LeafListStatementRfc7950Support.java
new file mode 100644 (file)
index 0000000..1fdc4da
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.stmt.rfc7950;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.LeafListStatementImpl;
+
+/**
+ * Class providing necessary support for processing YANG 1.1 leaf-list statement.
+ */
+@Beta
+public class LeafListStatementRfc7950Support extends LeafListStatementImpl.Definition {
+    private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(YangStmtMapping
+            .LEAF_LIST)
+            .addOptional(YangStmtMapping.CONFIG)
+            .addAny(YangStmtMapping.DEFAULT)
+            .addOptional(YangStmtMapping.DESCRIPTION)
+            .addAny(YangStmtMapping.IF_FEATURE)
+            .addOptional(YangStmtMapping.MIN_ELEMENTS)
+            .addOptional(YangStmtMapping.MAX_ELEMENTS)
+            .addAny(YangStmtMapping.MUST)
+            .addOptional(YangStmtMapping.ORDERED_BY)
+            .addOptional(YangStmtMapping.REFERENCE)
+            .addOptional(YangStmtMapping.STATUS)
+            .addMandatory(YangStmtMapping.TYPE)
+            .addOptional(YangStmtMapping.UNITS)
+            .addOptional(YangStmtMapping.WHEN)
+            .build();
+
+    @Override
+    protected SubstatementValidator getSubstatementValidator() {
+        return SUBSTATEMENT_VALIDATOR;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6880Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6880Test.java
new file mode 100644 (file)
index 0000000..b08c141
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yangtools.yang.parser.stmt.rfc7950;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.FileNotFoundException;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.stmt.StmtTestUtils;
+
+public class Bug6880Test {
+    private static final String FOO_NS = "foo";
+    private static final String FOO_REV = "1970-01-01";
+
+    @Test
+    public void valid10Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException {
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/bug6880/foo.yang");
+        assertNotNull(schemaContext);
+
+        final SchemaNode findDataSchemaNode = SchemaContextUtil.findDataSchemaNode(schemaContext,
+                SchemaPath.create(true, QName.create(FOO_NS, FOO_REV, "my-leaf-list")));
+        assertTrue(findDataSchemaNode instanceof LeafListSchemaNode);
+        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) findDataSchemaNode;
+
+        final Collection<String> defaults = myLeafList.getDefaults();
+        assertEquals(2, defaults.size());
+        assertTrue(defaults.contains("my-default-value-1") && defaults.contains("my-default-value-2"));
+    }
+
+    @Test
+    public void invalid10Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException {
+        try {
+            StmtTestUtils.parseYangSource("/rfc7950/bug6880/invalid10.yang");
+            fail("Test should fail due to invalid Yang 1.0");
+        } catch (final SomeModifiersUnresolvedException e) {
+            assertTrue(e.getCause().getMessage().startsWith("DEFAULT is not valid for LEAF_LIST"));
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/bug6880/foo.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/bug6880/foo.yang
new file mode 100644 (file)
index 0000000..cbfae88
--- /dev/null
@@ -0,0 +1,11 @@
+module foo {
+    namespace "foo";
+    prefix foo;
+    yang-version 1.1;
+
+    leaf-list my-leaf-list {
+        type string;
+        default "my-default-value-1";
+        default "my-default-value-2";
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/bug6880/invalid10.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/bug6880/invalid10.yang
new file mode 100644 (file)
index 0000000..e52780d
--- /dev/null
@@ -0,0 +1,10 @@
+module foo {
+    namespace "foo";
+    prefix foo;
+
+    leaf-list my-leaf-list {
+        type string;
+        default "my-default-value-1";
+        default "my-default-value-2";
+    }
+}