Binding generator v2 - Augmentation - Fix package name for recursively uses augment 58/59058/1
authorJie Han <han.jie@zte.com.cn>
Wed, 24 May 2017 08:15:08 +0000 (16:15 +0800)
committerMartin Ciglan <martin.ciglan@pantheon.tech>
Fri, 16 Jun 2017 06:37:00 +0000 (06:37 +0000)
- Fix package name for recursively uses augmentation, the yang file like:
         ...
         grouping D{
                uses "grp:A" {
                    augment "A1/A1-inner" {
                        leaf D-aug-A1 {
                            type string;
                        }
                        uses B {
                            augment "B1/B1-inner" {
                                 leaf D-aug-B1-inner {
                                      type string;
                                 }
                                 uses C {
                                         augment  "C1/C1-inner" {
                                              leaf D-aug-C1-inner {
                                                   type string;
                                              }
                                         }
                                     }
                            }

                        }

                    }
                }
            }
       ...
- add UT and yang file

Change-Id: If0b1131f15ab42be5c64a0fd087bd2a14a6597ce
Signed-off-by: Jie Han <han.jie@zte.com.cn>
(cherry picked from commit 0f8b8f57e35969bf0e37f918b8b18409963f55dc)

binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AugmentToGenType.java
binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/Bug8542Test.java [new file with mode: 0644]
binding2/mdsal-binding2-generator-impl/src/test/resources/bug-8542/recursive-uses-augment.yang [new file with mode: 0644]
binding2/mdsal-binding2-generator-util/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/util/BindingGeneratorUtil.java

index 0eab7e04c95a85eb94599633bd0c7d80e74bcc6d..bf2521fc9eebb219922b7b88a1792ab48b89d741 100644 (file)
@@ -217,14 +217,11 @@ final class AugmentToGenType {
                         Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
                         final boolean verboseClassComments, final TypeProvider typeProvider) {
 
-        Map<Module, ModuleContext> generatedCtx;
         Preconditions.checkArgument(augmentPackageName != null, "Package Name cannot be NULL.");
         Preconditions.checkArgument(augSchema != null, "Augmentation Schema cannot be NULL.");
         Preconditions.checkState(augSchema.getTargetPath() != null,
                 "Augmentation Schema does not contain Target Path (Target Path is NULL).");
 
-        generatedCtx = GenHelperUtil.processUsesAugments(schemaContext, augSchema, module, genCtx, genTypeBuilders,
-                verboseClassComments, typeProvider);
         final SchemaPath targetPath = augSchema.getTargetPath();
         final SchemaNode targetSchemaNode = findOriginalTargetFromGrouping(schemaContext, targetPath, usesNode);
         if (targetSchemaNode == null) {
@@ -232,9 +229,9 @@ final class AugmentToGenType {
         }
 
         GeneratedTypeBuilder targetTypeBuilder = GenHelperUtil.findChildNodeByPath(targetSchemaNode.getPath(),
-                generatedCtx);
+                genCtx);
         if (targetTypeBuilder == null) {
-            targetTypeBuilder = GenHelperUtil.findCaseByPath(targetSchemaNode.getPath(), generatedCtx);
+            targetTypeBuilder = GenHelperUtil.findCaseByPath(targetSchemaNode.getPath(), genCtx);
         }
         if (targetTypeBuilder == null) {
             throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
@@ -245,16 +242,20 @@ final class AugmentToGenType {
             if (usesNodeParent instanceof SchemaNode) {
                 packageName = BindingGeneratorUtil.packageNameForAugmentedGeneratedType(augmentPackageName,
                         ((SchemaNode) usesNodeParent).getPath());
+            } else if (usesNodeParent instanceof AugmentationSchema) {
+                Type parentTypeBuiler = genCtx.get(module).getTypeToAugmentation().inverse().get(usesNodeParent);
+                packageName = BindingGeneratorUtil.packageNameForAugmentedGeneratedType(
+                        parentTypeBuiler.getPackageName(), (AugmentationSchema)usesNodeParent);
             }
-            generatedCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
-                    targetTypeBuilder.toInstance(), augSchema, genTypeBuilders, generatedCtx, schemaContext,
+            genCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
+                    targetTypeBuilder.toInstance(), augSchema, genTypeBuilders, genCtx, schemaContext,
                     verboseClassComments, typeProvider);
-            return generatedCtx;
+            return genCtx;
         } else {
-            generatedCtx = generateTypesFromAugmentedChoiceCases(schemaContext, module, augmentPackageName,
+            genCtx = generateTypesFromAugmentedChoiceCases(schemaContext, module, augmentPackageName,
                     targetTypeBuilder.toInstance(), (ChoiceSchemaNode) targetSchemaNode, augSchema.getChildNodes(),
-                    usesNodeParent, generatedCtx, verboseClassComments, genTypeBuilders, typeProvider);
-            return generatedCtx;
+                    usesNodeParent, genCtx, verboseClassComments, genTypeBuilders, typeProvider);
+            return genCtx;
         }
     }
 
diff --git a/binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/Bug8542Test.java b/binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/Bug8542Test.java
new file mode 100644 (file)
index 0000000..1257661
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 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.mdsal.binding.javav2.generator.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.opendaylight.mdsal.binding.javav2.generator.api.BindingGenerator;
+import org.opendaylight.mdsal.binding.javav2.model.api.Type;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+import java.util.List;
+
+public class Bug8542Test {
+    @Test
+    public void Bug8542Test() throws Exception {
+        final BindingGenerator bg = new BindingGeneratorImpl(false);
+        final SchemaContext context = YangParserTestUtils.parseYangSource("/bug-8542/recursive-uses-augment.yang");
+        final List<Type> generateTypes = bg.generateTypes(context);
+        assertNotNull(generateTypes);
+        assertTrue(!generateTypes.isEmpty());
+        for (final Type type : generateTypes) {
+            if (type.getName().equals("A11")) {
+                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.d",
+                        type.getPackageName());
+            } else if (type.getName().equals("B11")) {
+                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.d.a1",
+                        type.getPackageName());
+            } else if (type.getName().equals("C11")) {
+                assertEquals("org.opendaylight.mdsal.gen.javav2.yang.test.uses.augment.recursive.rev170519.d.a1.b1",
+                        type.getPackageName());
+            }
+        }
+    }
+}
diff --git a/binding2/mdsal-binding2-generator-impl/src/test/resources/bug-8542/recursive-uses-augment.yang b/binding2/mdsal-binding2-generator-impl/src/test/resources/bug-8542/recursive-uses-augment.yang
new file mode 100644 (file)
index 0000000..e223a9a
--- /dev/null
@@ -0,0 +1,53 @@
+module recursive-uses-augment {
+
+    namespace "yang:test:uses-augment-recursive";
+    prefix ruses;
+
+    revision 2017-05-19;
+
+    container my-cont {
+        uses D;
+    }
+
+    grouping A {
+        container A1 {
+            leaf leaf-A1 {
+                type string;
+            }
+        }
+    }
+
+    grouping B {
+        container B1 {
+            leaf leaf-B1 {
+                type string;
+            }
+        }
+    }
+
+    grouping C {
+        container C1 {
+            leaf leaf-C1 {
+                type string;
+            }
+        }
+    }
+
+    grouping D {
+        uses "A" {
+            augment "A1" {
+                uses B {
+                    augment "B1" {
+                        uses C {
+                            augment  "C1" {
+                                leaf D-aug-C1 {
+                                    type string;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
index 184a9089344e5c72022c07dae1bb78fc15950e50..0eb0124bbf144e7f712a16d0951a2d9968b37035 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.MethodSignat
 import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.TypeMemberBuilder;
 import org.opendaylight.mdsal.binding.javav2.spec.runtime.BindingNamespaceType;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
@@ -349,6 +350,31 @@ public final class BindingGeneratorUtil {
         return generateNormalizedPackageName(basePackageName, pathFromRoot, size, null);
     }
 
+    /**
+     * Creates package name from <code>parentAugmentPackageName</code> (package
+     * name for direct parent augmentation) and <code>augmentationSchema</code> .
+     *
+     * Resulting package name is concatenation of <code>parentAugmentPackageName</code>
+     * and the local name of <code>schemaPath</code>.
+     *
+     * Based on type of node, there is also possible suffix added in order
+     * to prevent package name conflicts.
+     *
+     * @param parentAugmentPackageName
+     *            string with package name of direct parent augmentation, MUST be normalized,
+     *            otherwise this method may return an invalid string.
+     * @param augmentationSchema
+     *            augmentation schema which is direct son of parent augmentation.
+     * @return string with valid JAVA package name
+     * @throws NullPointerException if any of the arguments are null
+     */
+    public static String packageNameForAugmentedGeneratedType(final String parentAugmentPackageName,
+                                                              final AugmentationSchema augmentationSchema) {
+        final QName last = augmentationSchema.getTargetPath().getLastComponent();
+
+        return generateNormalizedPackageName(parentAugmentPackageName, last);
+    }
+
     private static final ThreadLocal<MessageDigest> SHA1_MD = new ThreadLocal<MessageDigest>() {
         @Override
         protected MessageDigest initialValue() {
@@ -378,6 +404,17 @@ public final class BindingGeneratorUtil {
         return normalizedPackageName;
     }
 
+    private static String generateNormalizedPackageName(final String parent, final QName path) {
+        final StringBuilder sb = new StringBuilder(parent)
+                .append('.')
+                .append(path.getLocalName());
+
+        final String normalizedPackageName = JavaIdentifierNormalizer.normalizeFullPackageName(sb.toString());
+        // Prevent duplication of input
+        PACKAGE_INTERNER.intern(normalizedPackageName);
+        return normalizedPackageName;
+    }
+
     private static <T> Iterable<T> sortedCollection(final Comparator<? super T> comparator, final Collection<T> input) {
         if (input.size() > 1) {
             final List<T> ret = new ArrayList<>(input);