Bug 4610 - Do not create duplicate declared statements 88/31188/3
authorPeter Kajsa <pkajsa@cisco.com>
Fri, 11 Dec 2015 09:41:35 +0000 (10:41 +0100)
committerPeter Kajsa <pkajsa@cisco.com>
Mon, 14 Dec 2015 13:26:31 +0000 (13:26 +0000)
Fix of instantiation logic such that we do not produce duplicate instances
of declared statements in the same schema context.

Change-Id: If264811825760ebb39a7c911e4c68ae58cc673b5
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/DeclaredEffectiveStatementBase.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug4610Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug4610/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug4610/foo.yang [new file with mode: 0644]

index 88ed942844aac749b65e860f176510569b6cc44a..2c96fba980b1a8e1a3b4d0bc6a08cbe2ad4fd28e 100644 (file)
@@ -12,10 +12,13 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 
-public abstract class DeclaredEffectiveStatementBase<A, D extends DeclaredStatement<A>>
-        extends EffectiveStatementBase<A, D> {
+public abstract class DeclaredEffectiveStatementBase<A, D extends DeclaredStatement<A>> extends
+        EffectiveStatementBase<A, D> {
 
+    private final StatementSource statementSource;
+    private final A argument;
     private final D declaredInstance;
 
     public DeclaredEffectiveStatementBase(final StmtContext<A, D, ?> ctx) {
@@ -34,8 +37,21 @@ public abstract class DeclaredEffectiveStatementBase<A, D extends DeclaredStatem
      *            method of EffectiveStatementBase class. The main purpose of
      *            this is to allow the build of recursive extension definitions.
      */
-    protected DeclaredEffectiveStatementBase(final StmtContext<A, D, ?> ctx, boolean buildUnknownSubstatements) {
+    protected DeclaredEffectiveStatementBase(StmtContext<A, D, ?> ctx, final boolean buildUnknownSubstatements) {
         super(ctx, buildUnknownSubstatements);
+
+        this.argument = ctx.getStatementArgument();
+        this.statementSource = ctx.getStatementSource();
+
+        /*
+         * Share original instance of declared statement between all effective
+         * statements which have been copied or derived from this original
+         * declared statement.
+         */
+        StatementContextBase<A, D, ?> originalCtx = (StatementContextBase<A, D, ?>) ctx.getOriginalCtx();
+        if (originalCtx != null) {
+            ctx = originalCtx;
+        }
         declaredInstance = Verify.verifyNotNull(ctx.buildDeclared(), "Statement %s failed to build declared statement",
                 ctx);
     }
@@ -47,16 +63,16 @@ public abstract class DeclaredEffectiveStatementBase<A, D extends DeclaredStatem
 
     @Override
     public final A argument() {
-        return declaredInstance.argument();
+        return argument;
     }
 
     @Override
     public final StatementSource getStatementSource() {
-        return declaredInstance.getStatementSource();
+        return statementSource;
     }
 
     @Override
     public final D getDeclared() {
         return declaredInstance;
     }
-}
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug4610Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug4610Test.java
new file mode 100644 (file)
index 0000000..e3e9fb7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015 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.stmt.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Date;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+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.api.stmt.ContainerStatement;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ContainerEffectiveStatementImpl;
+
+public class Bug4610Test {
+
+    @Test
+    public void test() throws Exception {
+        SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug4610");
+
+        Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2015-12-12");
+        QNameModule foo = QNameModule.create(new URI("foo"), revision);
+        QNameModule bar = QNameModule.create(new URI("bar"), revision);
+
+        QName g1 = QName.create(bar, "g1");
+        QName g2 = QName.create(bar, "g2");
+        QName c1Bar = QName.create(bar, "c1");
+
+        QName c1Foo = QName.create(foo, "c1");
+        QName g3 = QName.create(foo, "g3");
+        QName root = QName.create(foo, "root");
+
+        ContainerEffectiveStatementImpl effectiveContainerStatementG1 = findContainer(context, g1, c1Bar);
+        ContainerEffectiveStatementImpl effectiveContainerStatementG2 = findContainer(context, g2, c1Bar);
+        ContainerEffectiveStatementImpl effectiveContainerStatementG3 = findContainer(context, g3, c1Foo);
+        ContainerEffectiveStatementImpl effectiveContainerStatementRoot = findContainer(context, root, c1Foo);
+
+        // check arguments
+        QName originalStatementArgument = effectiveContainerStatementG1.argument();
+        assertTrue(originalStatementArgument.equals(effectiveContainerStatementG2.argument()));
+        assertFalse(originalStatementArgument.equals(effectiveContainerStatementG3.argument()));
+        assertFalse(originalStatementArgument.equals(effectiveContainerStatementRoot.argument()));
+
+        ContainerStatement originalContainerStatement = effectiveContainerStatementG1.getDeclared();
+        ContainerStatement inGrouping2ContainerStatement = effectiveContainerStatementG2.getDeclared();
+        ContainerStatement inGrouping3ContainerStatement = effectiveContainerStatementG3.getDeclared();
+        ContainerStatement inRootContainerStatement = effectiveContainerStatementRoot.getDeclared();
+
+        // check declared instances
+        assertTrue(originalContainerStatement == inGrouping2ContainerStatement);
+        assertTrue(originalContainerStatement == inGrouping3ContainerStatement);
+        assertTrue(originalContainerStatement == inRootContainerStatement);
+
+    }
+
+    private ContainerEffectiveStatementImpl findContainer(SchemaContext context, QName... path) {
+        SchemaNode node = SchemaContextUtil.findDataSchemaNode(context, SchemaPath.create(true, path));
+        assertTrue(node instanceof ContainerEffectiveStatementImpl);
+        ContainerEffectiveStatementImpl container = (ContainerEffectiveStatementImpl) node;
+        return container;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug4610/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug4610/bar.yang
new file mode 100644 (file)
index 0000000..6eb5139
--- /dev/null
@@ -0,0 +1,18 @@
+module bar {
+    yang-version 1;
+    namespace "bar";
+    prefix bar;
+
+    revision 2015-12-12 {
+        description "Bug 4610 test model.";
+    }
+
+    grouping g1 {
+        container c1 {
+        }
+    }
+
+    grouping g2 {
+        uses g1;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug4610/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug4610/foo.yang
new file mode 100644 (file)
index 0000000..63828c3
--- /dev/null
@@ -0,0 +1,19 @@
+module foo {
+    yang-version 1;
+    namespace "foo";
+    prefix foo;
+
+    import bar { prefix bar; revision-date 2015-12-12; }
+
+    revision 2015-12-12 {
+        description "Bug 4610 test model";
+    }
+
+    grouping g3 {
+        uses bar:g2;
+    }
+
+    container root {
+        uses g3;
+    }
+}