Binding Generator Implementation & decomposition 26/56226/1
authorMartin Ciglan <mciglan@cisco.com>
Thu, 27 Apr 2017 08:34:22 +0000 (10:34 +0200)
committerMartin Ciglan <mciglan@cisco.com>
Fri, 28 Apr 2017 06:26:55 +0000 (06:26 +0000)
- support YANG groupings

Change-Id: If8b62b09fc61db523050ff94f53d2b7f03c422ad
Signed-off-by: Martin Ciglan <mciglan@cisco.com>
(cherry picked from commit 950d1931ec8830300bf5904dc0af082d9e9dc59e)

binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AugmentToGenType.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/GenHelperUtil.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/impl/ModuleToGenType.java
binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/yang/types/GroupingDefinitionDependencySort.java [new file with mode: 0644]
binding2/mdsal-binding2-generator-impl/src/test/java/org/opendaylight/mdsal/binding/javav2/generator/impl/AugmentToGenTypeTest.java

index 685197f9a3f218737dd95ff6951a38f047c1a8f8..91a5fa15cfc775a262627595ad740b8e931842f3 100644 (file)
@@ -201,7 +201,7 @@ final class AugmentToGenType {
             final Type targetType = new ReferencedTypeImpl(targetTypeBuilder.getPackageName(),
                     targetTypeBuilder.getName());
             generatedCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName, targetType,
-                    augSchema, genTypeBuilders, generatedCtx);
+                    augSchema, genTypeBuilders, generatedCtx, schemaContext, verboseClassComments, typeProvider);
             return generatedCtx;
 
         } else {
@@ -248,7 +248,8 @@ final class AugmentToGenType {
                         ((SchemaNode) usesNodeParent).getPath());
             }
             generatedCtx = GenHelperUtil.addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
-                    targetTypeBuilder.toInstance(), augSchema, genTypeBuilders, generatedCtx);
+                    targetTypeBuilder.toInstance(), augSchema, genTypeBuilders, generatedCtx, schemaContext,
+                    verboseClassComments, typeProvider);
             return generatedCtx;
         } else {
             generatedCtx = generateTypesFromAugmentedChoiceCases(schemaContext, module, augmentPackageName,
@@ -360,7 +361,7 @@ final class AugmentToGenType {
                 final String packageName = BindingGeneratorUtil.packageNameForGeneratedType(basePackageName,
                         caseNode.getPath(), null);
                 final GeneratedTypeBuilder caseTypeBuilder = GenHelperUtil.addDefaultInterfaceDefinition(packageName,
-                        caseNode, module, genCtx, schemaContext, verboseClassComments, genTypeBuilders);
+                        caseNode, module, genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
                 caseTypeBuilder.addImplementsType(targetType);
 
                 SchemaNode parent;
index 6ba5baccc349b03cfc9c6b736b102e222145cad4..1e45f2be39bdb20d6d7a61378572ee0f4744eebc 100644 (file)
@@ -29,6 +29,7 @@ import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findP
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Preconditions;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -40,6 +41,7 @@ import org.opendaylight.mdsal.binding.javav2.generator.util.JavaIdentifierNormal
 import org.opendaylight.mdsal.binding.javav2.generator.util.Types;
 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
 import org.opendaylight.mdsal.binding.javav2.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
+import org.opendaylight.mdsal.binding.javav2.generator.yang.types.GroupingDefinitionDependencySort;
 import org.opendaylight.mdsal.binding.javav2.generator.yang.types.TypeProviderImpl;
 import org.opendaylight.mdsal.binding.javav2.model.api.AccessModifier;
 import org.opendaylight.mdsal.binding.javav2.model.api.GeneratedTransferObject;
@@ -225,9 +227,10 @@ final class GenHelperUtil {
 
     static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode
             schemaNode, final Module module, final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext,
-                                                              final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+            final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders,
+            final TypeProvider typeProvider) {
         return addDefaultInterfaceDefinition(packageName, schemaNode, null, module, genCtx, schemaContext,
-                verboseClassComments, genTypeBuilders);
+                verboseClassComments, genTypeBuilders, typeProvider);
     }
 
     static Map<Module, ModuleContext> processUsesAugments(final SchemaContext schemaContext, final
@@ -289,13 +292,11 @@ final class GenHelperUtil {
      */
     static Map<Module, ModuleContext> addRawAugmentGenTypeDefinition(final Module module, final String augmentPackageName,
                 final String basePackageName, final Type targetTypeRef, final AugmentationSchema augSchema,
-                final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final Map<Module, ModuleContext> genCtx) {
+                final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final Map<Module,
+                ModuleContext> genCtx, final SchemaContext schemaContext, final boolean verboseClassComments, final
+                TypeProvider typeProvider) {
 
-        Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.get(augmentPackageName);
-        if (augmentBuilders == null) {
-            augmentBuilders = new HashMap<>();
-            genTypeBuilders.put(augmentPackageName, augmentBuilders);
-        }
+        Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders.computeIfAbsent(augmentPackageName, k -> new HashMap<>());
         String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes());
 
         if (augIdentifier == null) {
@@ -310,7 +311,7 @@ final class GenHelperUtil {
         augTypeBuilder = addImplementedInterfaceFromUses(augSchema, augTypeBuilder, genCtx);
 
         augTypeBuilder = augSchemaNodeToMethods(module, basePackageName, augTypeBuilder, augTypeBuilder, augSchema
-                .getChildNodes());
+                .getChildNodes(), genCtx, schemaContext, verboseClassComments, typeProvider, genTypeBuilders);
         augmentBuilders.put(augTypeBuilder.getName(), augTypeBuilder);
 
         if(!augSchema.getChildNodes().isEmpty()) {
@@ -344,13 +345,15 @@ final class GenHelperUtil {
      *         added to it.
      */
     private static GeneratedTypeBuilder augSchemaNodeToMethods(final Module module, final String basePackageName,
-            final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf,
-            final Iterable<DataSchemaNode> schemaNodes) {
+            final GeneratedTypeBuilder typeBuilder, final GeneratedTypeBuilder childOf, final Iterable<DataSchemaNode> schemaNodes,
+            final Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext, final boolean
+            verboseClassComments, final TypeProvider typeProvider, final Map<String, Map<String,
+            GeneratedTypeBuilder>> genTypeBuilders) {
         if (schemaNodes != null && typeBuilder != null) {
             for (final DataSchemaNode schemaNode : schemaNodes) {
                 if (!schemaNode.isAugmenting()) {
-                    //TODO: design decomposition and implement it
-                    //addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module);
+                    addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode, typeBuilder, childOf, module, genCtx,
+                            schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
                 }
             }
         }
@@ -383,7 +386,8 @@ final class GenHelperUtil {
      */
     static GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode
             schemaNode, final Type parent, final Module module, final Map<Module, ModuleContext> genCtx,
-            final SchemaContext schemaContext, final boolean verboseClassComments, final Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders) {
+            final SchemaContext schemaContext, final boolean verboseClassComments, final Map<String, Map<String,
+            GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
 
         GeneratedTypeBuilder it = addRawInterfaceDefinition(packageName, schemaNode, schemaContext, "",
                 verboseClassComments, genTypeBuilders);
@@ -405,8 +409,8 @@ final class GenHelperUtil {
         }
 
         if (schemaNode instanceof DataNodeContainer) {
-            //TODO: design decomposition and implement it
-            //groupingsToGenTypes(module, ((DataNodeContainer) schemaNode).getGroupings());
+            groupingsToGenTypes(module, ((DataNodeContainer) schemaNode).getGroupings(), genCtx, schemaContext,
+                    verboseClassComments, genTypeBuilders, typeProvider);
             it = addImplementedInterfaceFromUses((DataNodeContainer) schemaNode, it, genCtx);
         }
 
@@ -423,7 +427,7 @@ final class GenHelperUtil {
 
         final GeneratedTypeBuilder notificationInterface = addDefaultInterfaceDefinition
                 (basePackageName, notification, null, module, genCtx, schemaContext,
-                        verboseClassComments, genTypeBuilders);
+                        verboseClassComments, genTypeBuilders, typeProvider);
         annotateDeprecatedIfNecessary(notification.getStatus(), notificationInterface);
         notificationInterface.addImplementsType(NOTIFICATION);
         genCtx.get(module).addChildNodeType(notification, notificationInterface);
@@ -459,7 +463,7 @@ final class GenHelperUtil {
      *            builder belongs
      * @param schemaNode
      *            schema node which provide data about the schema node name
-     * @param schemaContext
+     * @param schemaContext schema context
      * @param prefix
      *            return type name prefix
      * @return generated type builder for <code>schemaNode</code>
@@ -767,7 +771,7 @@ final class GenHelperUtil {
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private static GeneratedTypeBuilder processDataSchemaNode(final Module module, final String basePackageName,
         final GeneratedTypeBuilder childOf, final DataSchemaNode node, final SchemaContext schemaContext,
-        final boolean verboseClassComments, final Map<Module, ModuleContext> genCtx, final Map<String, Map<String,
+        final boolean verboseClassComments, Map<Module, ModuleContext> genCtx, final Map<String, Map<String,
         GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
 
         if (node.isAugmenting() || node.isAddedByUses()) {
@@ -775,7 +779,7 @@ final class GenHelperUtil {
         }
         final String packageName = packageNameForGeneratedType(basePackageName, node.getPath(), BindingNamespaceType.Data);
         final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, node, childOf, module,
-                genCtx, schemaContext, verboseClassComments, genTypeBuilders);
+                genCtx, schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
         genType.addComment(node.getDescription());
         annotateDeprecatedIfNecessary(node.getStatus(), genType);
         genType.setDescription(createDescription(node, genType.getFullyQualifiedName(), schemaContext, verboseClassComments));
@@ -784,11 +788,89 @@ final class GenHelperUtil {
         genType.setSchemaPath((List) node.getPath().getPathFromRoot());
         if (node instanceof DataNodeContainer) {
             genCtx.get(module).addChildNodeType(node, genType);
-            //TODO: implement groupings to GTO building first
-            // groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings());
+            genCtx = groupingsToGenTypes(module, ((DataNodeContainer) node).getGroupings(), genCtx, schemaContext,
+                    verboseClassComments, genTypeBuilders, typeProvider);
             processUsesAugments(schemaContext, (DataNodeContainer) node, module, genCtx, genTypeBuilders,
                     verboseClassComments, typeProvider);
         }
         return genType;
     }
+
+    /**
+     * Converts all <b>groupings</b> of the module to the list of
+     * <code>Type</code> objects. Firstly are groupings sorted according mutual
+     * dependencies. At least dependent (independent) groupings are in the list
+     * saved at first positions. For every grouping the record is added to map
+     * {@link ModuleContext#groupings allGroupings}
+     *
+     * @param module
+     *            current module
+     * @param groupings
+     *            collection of groupings from which types will be generated
+     * @param typeProvider
+     *            provider that defines contract for generated types
+     * @param schemaContext
+     *            schema context
+     * @param genCtx
+     *            map of generated entities in context of YANG modules
+     * @param genTypeBuilders
+     *            map of generated type builders
+     * @param verboseClassComments
+     *            generate verbose comments
+     *
+     */
+    static Map<Module, ModuleContext> groupingsToGenTypes(final Module module, final Collection<GroupingDefinition>
+            groupings, Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext, final boolean
+            verboseClassComments, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
+        final String basePackageName = BindingMapping.getRootPackageName(module);
+        final List<GroupingDefinition> groupingsSortedByDependencies = new GroupingDefinitionDependencySort()
+                .sort(groupings);
+        for (final GroupingDefinition grouping : groupingsSortedByDependencies) {
+            genCtx = groupingToGenType(basePackageName, grouping, module, genCtx, schemaContext,
+                    verboseClassComments, genTypeBuilders, typeProvider);
+        }
+        return genCtx;
+    }
+
+    /**
+     * Converts individual grouping to GeneratedType. Firstly generated type
+     * builder is created and every child node of grouping is resolved to the
+     * method.
+     *
+     * @param basePackageName
+     *            string contains the module package name
+     * @param grouping
+     *            GroupingDefinition which contains data about grouping
+     * @param module
+     *            current module
+     * @param typeProvider
+     *            provider that defines contract for generated types
+     * @param schemaContext
+     *            schema context
+     * @param genCtx
+     *            map of generated entities in context of YANG modules
+     * @param genTypeBuilders
+     *            map of generated type builders
+     * @param verboseClassComments
+     *            generate verbose comments
+     *
+     * @return GeneratedType which is generated from grouping (object of type
+     *         <code>GroupingDefinition</code>)
+     */
+    private static Map<Module, ModuleContext> groupingToGenType(final String basePackageName, final GroupingDefinition grouping, final Module
+            module, Map<Module, ModuleContext> genCtx, final SchemaContext schemaContext, final boolean
+            verboseClassComments, Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders, final TypeProvider typeProvider) {
+        final String packageName = packageNameForGeneratedType(basePackageName, grouping.getPath(), BindingNamespaceType.Grouping);
+        final GeneratedTypeBuilder genType = addDefaultInterfaceDefinition(packageName, grouping, module, genCtx,
+                schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
+        annotateDeprecatedIfNecessary(grouping.getStatus(), genType);
+        genCtx.get(module).addGroupingType(grouping.getPath(), genType);
+        resolveDataSchemaNodes(module, basePackageName, genType, genType, grouping.getChildNodes(), genCtx,
+                schemaContext, verboseClassComments, genTypeBuilders, typeProvider);
+        genCtx = groupingsToGenTypes(module, grouping.getGroupings(), genCtx, schemaContext, verboseClassComments,
+                genTypeBuilders, typeProvider);
+        genCtx = processUsesAugments(schemaContext, grouping, module, genCtx, genTypeBuilders, verboseClassComments,
+                typeProvider);
+        return genCtx;
+    }
 }
index 10f3f44ff2db1c738f9d7e2542ec7ee5d6acf155..9af13aa2932ff9a6a37df4dabddd92d949650ff3 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.mdsal.binding.javav2.generator.impl;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.AuxiliaryGenUtils.createDescription;
+import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.groupingsToGenTypes;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.moduleTypeBuilder;
 import static org.opendaylight.mdsal.binding.javav2.generator.impl.GenHelperUtil.resolveNotification;
 import static org.opendaylight.mdsal.binding.javav2.generator.util.BindingTypes.NOTIFICATION_LISTENER;
@@ -46,11 +47,13 @@ final class ModuleToGenType {
 
         genCtx.put(module, new ModuleContext());
         genCtx = allTypeDefinitionsToGenTypes(module, genCtx, typeProvider);
+        genCtx = groupingsToGenTypes(module, module.getGroupings(), genCtx, schemaContext, verboseClassComments,
+                genTypeBuilders, typeProvider);
         genCtx = actionsAndRPCMethodsToGenType(module, genCtx, schemaContext, verboseClassComments,
                 genTypeBuilders, typeProvider);
         genCtx = notificationsToGenType(module, genCtx, schemaContext, genTypeBuilders, verboseClassComments, typeProvider);
 
-        //TODO: call generate for other entities (groupings, identities)
+        //TODO: call generate for other entities (identities)
 
         if (!module.getChildNodes().isEmpty()) {
             final GeneratedTypeBuilder moduleType = GenHelperUtil.moduleToDataType(module, genCtx, verboseClassComments);
diff --git a/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/yang/types/GroupingDefinitionDependencySort.java b/binding2/mdsal-binding2-generator-impl/src/main/java/org/opendaylight/mdsal/binding/javav2/generator/yang/types/GroupingDefinitionDependencySort.java
new file mode 100644 (file)
index 0000000..e0c470b
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * 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.yang.types;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import org.opendaylight.yangtools.yang.parser.util.NodeWrappedType;
+import org.opendaylight.yangtools.yang.parser.util.TopologicalSort;
+import org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node;
+
+public class GroupingDefinitionDependencySort {
+
+    /**
+     * Sorts set <code>groupingDefinitions</code> according to the mutual
+     * dependencies.<br>
+     *
+     * Elements of <code>groupingDefinitions</code> are firstly transformed to
+     * {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort.Node
+     * Node} interfaces and then are sorted by
+     * {@link org.opendaylight.yangtools.yang.parser.util.TopologicalSort#sort(Set)
+     * sort()} method of <code>TopologicalSort</code>.<br>
+     * <br>
+     *
+     *
+     * <i>Definition of dependency relation:<br>
+     * The first <code>GroupingDefinition</code> object (in this context)
+     * depends on second <code>GroupingDefinition</code> object if the first one
+     * contains in its set of <code>UsesNode</code> (obtained through
+     * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer#getUses()
+     * getUses} method) reference to the second one.</i>
+     *
+     * @param groupingDefinitions
+     *            set of grouping definition which should be sorted according to
+     *            mutual dependencies
+     * @return list of grouping definitiond which are sorted by mutual
+     *         dependencies
+     * @throws IllegalArgumentException
+     *             if <code>groupingDefinitions</code>
+     *
+     */
+    public List<GroupingDefinition> sort(final Collection<GroupingDefinition> groupingDefinitions) {
+        if (groupingDefinitions == null) {
+            throw new IllegalArgumentException("Set of Type Definitions " + "cannot be NULL!");
+        }
+
+        final List<GroupingDefinition> resultGroupingDefinitions = new ArrayList<GroupingDefinition>();
+        final Set<Node> unsorted = groupingDefinitionsToNodes(groupingDefinitions);
+        final List<Node> sortedNodes = TopologicalSort.sort(unsorted);
+        for (Node node : sortedNodes) {
+            NodeWrappedType nodeWrappedType = (NodeWrappedType) node;
+            resultGroupingDefinitions.add((GroupingDefinition) (nodeWrappedType.getWrappedType()));
+        }
+        return resultGroupingDefinitions;
+
+    }
+
+    /**
+     * Wraps every grouping definition to node type and adds to every node
+     * information about dependencies.
+     *
+     * The map with mapping from schema path (represents grouping definition) to
+     * node is created. For every created node (next <i>nodeFrom</i>) is for its
+     * wrapped grouping definition passed the set of its <i>uses nodes</i>
+     * through. For every uses node is found its wrapping node (next as
+     * <i>nodeTo</i>). This dependency relationship between nodeFrom and all
+     * found nodesTo is modeled with creating of one edge from nodeFrom to
+     * nodeTo.
+     *
+     *
+     * @param groupingDefinitions
+     *            set of goruping definition which will be wrapped to nodes
+     *
+     * @return set of nodes where every one contains wrapped grouping definition
+     */
+    private Set<Node> groupingDefinitionsToNodes(final Collection<GroupingDefinition> groupingDefinitions) {
+        final Map<SchemaPath, Node> nodeMap = Maps.newHashMap();
+        final Set<Node> resultNodes = Sets.newHashSet();
+
+        for (final GroupingDefinition groupingDefinition : groupingDefinitions) {
+            final Node node = new NodeWrappedType(groupingDefinition);
+            nodeMap.put(groupingDefinition.getPath(), node);
+            resultNodes.add(node);
+        }
+
+        for (final Node node : resultNodes) {
+            final NodeWrappedType nodeWrappedType = (NodeWrappedType) node;
+            final GroupingDefinition groupingDefinition = (GroupingDefinition) nodeWrappedType.getWrappedType();
+
+            Set<UsesNode> usesNodes = getAllUsesNodes(groupingDefinition);
+
+            for (UsesNode usesNode : usesNodes) {
+                SchemaPath schemaPath = usesNode.getGroupingPath();
+                Node nodeTo = nodeMap.get(schemaPath);
+                if (nodeTo != null) {
+                    nodeWrappedType.addEdge(nodeTo);
+                }
+            }
+        }
+
+        return resultNodes;
+    }
+
+    /**
+     * Returns the set of the uses nodes which are get from uses in
+     * <code>container</code>, from uses in groupings inside
+     * <code>container</code> and from uses inside child nodes of the
+     * <code>container</code>.
+     *
+     * @param container
+     *            data node container which can contain some uses of grouping
+     * @return set of uses nodes which were find in <code>container</code>.
+     */
+    private Set<UsesNode> getAllUsesNodes(final DataNodeContainer container) {
+        Set<UsesNode> ret = new HashSet<>();
+        Set<UsesNode> usesNodes = container.getUses();
+        ret.addAll(usesNodes);
+
+        for (UsesNode usesNode : usesNodes) {
+            for (AugmentationSchema augment : usesNode.getAugmentations()) {
+                ret.addAll(getAllUsesNodes(augment));
+            }
+        }
+        Set<GroupingDefinition> groupings = container.getGroupings();
+        for (GroupingDefinition groupingDefinition : groupings) {
+            ret.addAll(getAllUsesNodes(groupingDefinition));
+        }
+        for (DataSchemaNode childNode : container.getChildNodes()) {
+            if (childNode instanceof DataNodeContainer) {
+                ret.addAll(getAllUsesNodes((DataNodeContainer) childNode));
+            } else if (childNode instanceof ChoiceSchemaNode) {
+                Set<ChoiceCaseNode> cases = ((ChoiceSchemaNode) childNode).getCases();
+                for (ChoiceCaseNode choiceCaseNode : cases) {
+                    ret.addAll(getAllUsesNodes(choiceCaseNode));
+                }
+            }
+        }
+        return ret;
+    }
+}
index b2aff19aadfce03a65dcda0dcd3d08d4d4e202a5..741d9b7827de4a3ee4a3322c7b3a75b1834e1429 100644 (file)
@@ -1187,6 +1187,8 @@ public class AugmentToGenTypeTest {
         when(module.getName()).thenReturn("test-module-case");
         final DataSchemaNode schemaNode = mock(DataSchemaNode.class);
         when(module.getDataChildByName(qnamePath)).thenReturn(schemaNode);
+        when(module.getRevision()).thenReturn(qnamePath.getRevision());
+        when(module.getNamespace()).thenReturn(qnamePath.getNamespace());
         final String pckgName = "test.augment.choice.cases";
         final Type targetType = mock(Type.class);
         final Set<DataSchemaNode> augmentNodes = new HashSet<>();
@@ -1242,6 +1244,8 @@ public class AugmentToGenTypeTest {
         final ChoiceCaseNode schemaNode = mock(ChoiceCaseNode.class);
         when(schemaNode.getPath()).thenReturn(path);
         when(module.getDataChildByName(qnamePath)).thenReturn(schemaNode);
+        when(module.getRevision()).thenReturn(qnamePath.getRevision());
+        when(module.getNamespace()).thenReturn(qnamePath.getNamespace());
         final String pckgName = "test.augment.choice.cases";
         final Type targetType = mock(Type.class);
         final Set<DataSchemaNode> augmentNodes = new HashSet<>();