Fixed yang grouping resolution. 95/395/2
authorMartin Vitez <mvitez@cisco.com>
Mon, 27 May 2013 15:10:16 +0000 (17:10 +0200)
committerMartin Vitez <mvitez@cisco.com>
Tue, 28 May 2013 10:29:02 +0000 (12:29 +0200)
Fixed refine parsing. Updated tests.

Change-Id: I1d0b27458fde7b7b78cbaff6af210b5885493506
Signed-off-by: Martin Vitez <mvitez@cisco.com>
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/antlr/YangParser.g4
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/GroupingBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/testfile2.yang

index 36aff55..c814831 100644 (file)
@@ -79,7 +79,7 @@ require_instance_stmt : REQUIRE_INSTANCE_KEYWORD require_instance_arg stmtend;
 path_stmt : PATH_KEYWORD string stmtend;
 leafref_specification : path_stmt;
 enum_stmt : ENUM_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt |value_stmt | status_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
-enum_specification : enum_stmt (identifier_stmt | enum_stmt )+;
+enum_specification : enum_stmt (identifier_stmt | enum_stmt )*;
 default_stmt : DEFAULT_KEYWORD string stmtend;
 pattern_stmt : PATTERN_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt |error_message_stmt | error_app_tag_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
 length_stmt : LENGTH_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt |error_message_stmt | error_app_tag_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
index 7d94cd9..2c1f94d 100644 (file)
@@ -7,7 +7,12 @@
  */
 package org.opendaylight.controller.yang.parser.builder.api;
 
+import java.util.List;
+import java.util.Set;
+
 import org.opendaylight.controller.yang.model.api.GroupingDefinition;
+import org.opendaylight.controller.yang.model.api.Status;
+import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 
 /**
  * Interface for builders of 'grouping' statement.
@@ -15,8 +20,22 @@ import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 public interface GroupingBuilder extends ChildNodeBuilder, SchemaNodeBuilder,
         TypeDefinitionAwareBuilder {
 
-    DataSchemaNodeBuilder getChildNode(String name);
+    String getDescription();
+
+    String getReference();
+
+    Status getStatus();
 
     GroupingDefinition build();
 
+    DataSchemaNodeBuilder getChildNode(String name);
+
+    List<UnknownSchemaNodeBuilder> getUnknownNodes();
+
+    Set<GroupingBuilder> getGroupings();
+
+    Set<TypeDefinitionBuilder> getTypedefs();
+
+    Set<UsesNodeBuilder> getUses();
+
 }
index 7ac4ec0..1c4a4ac 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.yang.parser.builder.api;
 
 import java.util.List;
+import java.util.Set;
 
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.UsesNode;
@@ -18,14 +19,22 @@ import org.opendaylight.controller.yang.parser.util.RefineHolder;
  */
 public interface UsesNodeBuilder extends Builder {
 
+    String getGroupingPathString();
+
     SchemaPath getGroupingPath();
 
+    Set<AugmentationSchemaBuilder> getAugmentations();
+
     void addAugment(AugmentationSchemaBuilder builder);
 
+    boolean isAugmenting();
+
     void setAugmenting(boolean augmenting);
 
     List<RefineHolder> getRefines();
 
+    List<SchemaNodeBuilder> getRefineNodes();
+
     void addRefine(RefineHolder refine);
 
     void addRefineNode(SchemaNodeBuilder refineNode);
index 19c94a3..759f54e 100644 (file)
@@ -29,58 +29,71 @@ import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 
 public class GroupingBuilderImpl implements GroupingBuilder {
+    private boolean built;
     private final GroupingDefinitionImpl instance;
     private final int line;
+    private final QName qname;
     private SchemaPath schemaPath;
+    private String description;
+    private String reference;
+    private Status status;
     private final Set<DataSchemaNodeBuilder> childNodes = new HashSet<DataSchemaNodeBuilder>();
     private final Set<GroupingBuilder> groupings = new HashSet<GroupingBuilder>();
     private final Set<TypeDefinitionBuilder> addedTypedefs = new HashSet<TypeDefinitionBuilder>();
     private final Set<UsesNodeBuilder> usesNodes = new HashSet<UsesNodeBuilder>();
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
 
-    GroupingBuilderImpl(final QName qname, final int line) {
+    public GroupingBuilderImpl(final QName qname, final int line) {
+        this.qname = qname;
         this.instance = new GroupingDefinitionImpl(qname);
         this.line = line;
     }
 
     @Override
     public GroupingDefinition build() {
-        instance.setPath(schemaPath);
+        if (!built) {
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+
+            // CHILD NODES
+            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            for (DataSchemaNodeBuilder node : childNodes) {
+                childs.put(node.getQName(), node.build());
+            }
+            instance.setChildNodes(childs);
 
-        // CHILD NODES
-        final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-        for (DataSchemaNodeBuilder node : childNodes) {
-            childs.put(node.getQName(), node.build());
-        }
-        instance.setChildNodes(childs);
+            // GROUPINGS
+            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
+            for (GroupingBuilder builder : groupings) {
+                groupingDefs.add(builder.build());
+            }
+            instance.setGroupings(groupingDefs);
 
-        // GROUPINGS
-        final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-        for (GroupingBuilder builder : groupings) {
-            groupingDefs.add(builder.build());
-        }
-        instance.setGroupings(groupingDefs);
+            // TYPEDEFS
+            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            for (TypeDefinitionBuilder entry : addedTypedefs) {
+                typedefs.add(entry.build());
+            }
+            instance.setTypeDefinitions(typedefs);
 
-        // TYPEDEFS
-        final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (TypeDefinitionBuilder entry : addedTypedefs) {
-            typedefs.add(entry.build());
-        }
-        instance.setTypeDefinitions(typedefs);
+            // USES
+            final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
+            for (UsesNodeBuilder builder : usesNodes) {
+                usesNodeDefs.add(builder.build());
+            }
+            instance.setUses(usesNodeDefs);
 
-        // USES
-        final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
-        for (UsesNodeBuilder builder : usesNodes) {
-            usesNodeDefs.add(builder.build());
-        }
-        instance.setUses(usesNodeDefs);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for(UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
+            built = true;
         }
-        instance.setUnknownSchemaNodes(unknownNodes);
 
         return instance;
     }
@@ -90,12 +103,14 @@ public class GroupingBuilderImpl implements GroupingBuilder {
         return line;
     }
 
-    /**
-     * Always returns null.
-     */
     @Override
     public QName getQName() {
-        return null;
+        return qname;
+    }
+
+    @Override
+    public Set<TypeDefinitionBuilder> getTypedefs() {
+        return addedTypedefs;
     }
 
     @Override
@@ -113,26 +128,41 @@ public class GroupingBuilderImpl implements GroupingBuilder {
         this.schemaPath = schemaPath;
     }
 
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
     @Override
     public void setDescription(final String description) {
-        instance.setDescription(description);
+        this.description = description;
+    }
+
+    @Override
+    public String getReference() {
+        return reference;
     }
 
     @Override
     public void setReference(final String reference) {
-        instance.setReference(reference);
+        this.reference = reference;
+    }
+
+    @Override
+    public Status getStatus() {
+        return status;
     }
 
     @Override
     public void setStatus(final Status status) {
-        instance.setStatus(status);
+        this.status = status;
     }
 
     @Override
     public DataSchemaNodeBuilder getChildNode(String name) {
         DataSchemaNodeBuilder result = null;
-        for(DataSchemaNodeBuilder node : childNodes) {
-            if(node.getQName().getLocalName().equals(name)) {
+        for (DataSchemaNodeBuilder node : childNodes) {
+            if (node.getQName().getLocalName().equals(name)) {
                 result = node;
                 break;
             }
@@ -150,16 +180,31 @@ public class GroupingBuilderImpl implements GroupingBuilder {
         return childNodes;
     }
 
+    @Override
+    public Set<GroupingBuilder> getGroupings() {
+        return groupings;
+    }
+
     @Override
     public void addGrouping(final GroupingBuilder grouping) {
         groupings.add(grouping);
     }
 
+    @Override
+    public Set<UsesNodeBuilder> getUses() {
+        return usesNodes;
+    }
+
     @Override
     public void addUsesNode(final UsesNodeBuilder usesBuilder) {
         usesNodes.add(usesBuilder);
     }
 
+    @Override
+    public List<UnknownSchemaNodeBuilder> getUnknownNodes() {
+        return addedUnknownNodes;
+    }
+
     @Override
     public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) {
         addedUnknownNodes.add(unknownNode);
@@ -264,7 +309,7 @@ public class GroupingBuilderImpl implements GroupingBuilder {
         }
 
         private void setUnknownSchemaNodes(List<UnknownSchemaNode> unknownNodes) {
-            if(unknownNodes != null) {
+            if (unknownNodes != null) {
                 this.unknownNodes = unknownNodes;
             }
         }
index 740f399..4865178 100644 (file)
@@ -1119,7 +1119,7 @@ public class ModuleBuilder implements Builder {
         final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
         for (Map.Entry<List<String>, GroupingBuilder> entry : addedGroupings
                 .entrySet()) {
-            if (entry.getKey().size() == 2) {
+            if (entry.getKey().size() == 3) {
                 groupings.add(entry.getValue().build());
             }
         }
index 0534f9d..6943b66 100644 (file)
@@ -25,16 +25,19 @@ import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;\r
 import org.opendaylight.controller.yang.parser.util.RefineHolder;\r
 \r
-final class UsesNodeBuilderImpl implements UsesNodeBuilder {\r
+public final class UsesNodeBuilderImpl implements UsesNodeBuilder {\r
     private boolean built;\r
     private final UsesNodeImpl instance;\r
     private final int line;\r
+    private final String groupingPathStr;\r
     private final SchemaPath groupingPath;\r
+    private boolean augmenting;\r
     private final Set<AugmentationSchemaBuilder> addedAugments = new HashSet<AugmentationSchemaBuilder>();\r
     private List<SchemaNodeBuilder> refineBuilders = new ArrayList<SchemaNodeBuilder>();\r
     private List<RefineHolder> refines = new ArrayList<RefineHolder>();\r
 \r
-    UsesNodeBuilderImpl(final String groupingPathStr, final int line) {\r
+    public UsesNodeBuilderImpl(final String groupingPathStr, final int line) {\r
+        this.groupingPathStr = groupingPathStr;\r
         this.groupingPath = parseUsesPath(groupingPathStr);\r
         this.line = line;\r
         instance = new UsesNodeImpl(groupingPath);\r
@@ -42,7 +45,9 @@ final class UsesNodeBuilderImpl implements UsesNodeBuilder {
 \r
     @Override\r
     public UsesNode build() {\r
-        if(!built) {\r
+        if (!built) {\r
+            instance.setAugmenting(augmenting);\r
+\r
             // AUGMENTATIONS\r
             final Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();\r
             for (AugmentationSchemaBuilder builder : addedAugments) {\r
@@ -68,19 +73,39 @@ final class UsesNodeBuilderImpl implements UsesNodeBuilder {
         return line;\r
     }\r
 \r
+    @Override\r
+    public String getGroupingPathString() {\r
+        return groupingPathStr;\r
+    }\r
+\r
     @Override\r
     public SchemaPath getGroupingPath() {\r
         return groupingPath;\r
     }\r
 \r
+    @Override\r
+    public Set<AugmentationSchemaBuilder> getAugmentations() {\r
+        return addedAugments;\r
+    }\r
+\r
     @Override\r
     public void addAugment(final AugmentationSchemaBuilder augmentBuilder) {\r
         addedAugments.add(augmentBuilder);\r
     }\r
 \r
+    @Override\r
+    public boolean isAugmenting() {\r
+        return augmenting;\r
+    }\r
+\r
     @Override\r
     public void setAugmenting(final boolean augmenting) {\r
-        instance.setAugmenting(augmenting);\r
+        this.augmenting = augmenting;\r
+    }\r
+\r
+    @Override\r
+    public List<SchemaNodeBuilder> getRefineNodes() {\r
+        return refineBuilders;\r
     }\r
 \r
     @Override\r
index 85ca367..ec46831 100644 (file)
@@ -800,8 +800,7 @@ public class YangParserImpl implements YangModelParser {
                     ParserUtils.refineList(list, refine, line);
                     usesNode.addRefineNode(list);
                 } else if (refineTarget instanceof LeafListSchemaNodeBuilder) {
-                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) getRefineNodeBuilderCopy(
-                            groupingName, refine, modules, module);
+                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) refineTarget;
                     ParserUtils.refineLeafList(leafList, refine, line);
                     usesNode.addRefineNode(leafList);
                 } else if (refineTarget instanceof ChoiceBuilder) {
@@ -812,6 +811,10 @@ public class YangParserImpl implements YangModelParser {
                     final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget;
                     ParserUtils.refineAnyxml(anyXml, refine, line);
                     usesNode.addRefineNode(anyXml);
+                } else if(refineTarget instanceof GroupingBuilder) {
+                    usesNode.addRefineNode((GroupingBuilder)refineTarget);
+                } else if(refineTarget instanceof TypedefBuilder) {
+                    usesNode.addRefineNode((TypedefBuilder)refineTarget);
                 }
             }
         }
@@ -861,6 +864,12 @@ public class YangParserImpl implements YangModelParser {
         } else if (lookedUpBuilder instanceof AnyXmlBuilder) {
             result = ParserUtils
                     .copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof GroupingBuilder) {
+            result = ParserUtils
+                    .copyGroupingBuilder((GroupingBuilder) lookedUpBuilder);
+        } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) {
+            result = ParserUtils
+                    .copyTypedefBuilder((TypedefBuilder) lookedUpBuilder);
         } else {
             throw new YangParseException(module.getName(), refine.getLine(),
                     "Target '" + refine.getName() + "' can not be refined");
@@ -873,8 +882,8 @@ public class YangParserImpl implements YangModelParser {
      *
      * @param groupingPath
      *            path to grouping which contains node to refine
-     * @param refineNodeName
-     *            name of node to be refined
+     * @param refine
+     *            object containing refine information
      * @param modules
      *            all loaded modules
      * @param module
@@ -886,6 +895,7 @@ public class YangParserImpl implements YangModelParser {
             final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
+        final String refineNodeName = refine.getName();
         final SchemaPath path = ParserUtils.parseUsesPath(groupingPath);
         final List<String> builderPath = new ArrayList<String>();
         String prefix = null;
@@ -904,7 +914,26 @@ public class YangParserImpl implements YangModelParser {
         final GroupingBuilder builder = (GroupingBuilder) dependentModule
                 .getNode(builderPath);
 
-        return builder.getChildNode(refine.getName());
+        Builder result = builder.getChildNode(refineNodeName);
+        if(result == null) {
+            Set<GroupingBuilder> grps = builder.getGroupings();
+            for(GroupingBuilder gr : grps) {
+                if(gr.getQName().getLocalName().equals(refineNodeName)) {
+                    result = gr;
+                    break;
+                }
+            }
+        }
+        if(result == null) {
+            Set<TypeDefinitionBuilder> typedefs = builder.getTypedefs();
+            for(TypeDefinitionBuilder typedef : typedefs) {
+                if(typedef.getQName().getLocalName().equals(refineNodeName)) {
+                    result = typedef;
+                    break;
+                }
+            }
+        }
+        return result;
     }
 
     private QName findFullQName(
index 84e0b04..05f9c65 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.controller.yang.parser.builder.api.Builder;
 import org.opendaylight.controller.yang.parser.builder.api.ChildNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder;
@@ -28,11 +29,14 @@ import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl;
 import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.TypedefBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl;
 
 public final class ParserUtils {
 
@@ -264,8 +268,7 @@ public final class ParserUtils {
      * @param line
      *            current line in yang model
      */
-    public static void refineDefault(Builder node, RefineHolder refine,
-            int line) {
+    public static void refineDefault(Builder node, RefineHolder refine, int line) {
         Class<? extends Builder> cls = node.getClass();
 
         String description = refine.getDescription();
@@ -355,9 +358,6 @@ public final class ParserUtils {
         for (UsesNodeBuilder use : old.getUsesNodes()) {
             copy.addUsesNode(use);
         }
-        for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
-            copy.addUnknownSchemaNode(unknown);
-        }
         copy.setDescription(old.getDescription());
         copy.setReference(old.getReference());
         copy.setStatus(old.getStatus());
@@ -391,9 +391,6 @@ public final class ParserUtils {
         for (UsesNodeBuilder use : old.getUsesNodes()) {
             copy.addUsesNode(use);
         }
-        for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
-            copy.addUnknownSchemaNode(unknown);
-        }
         copy.setDescription(old.getDescription());
         copy.setReference(old.getReference());
         copy.setStatus(old.getStatus());
@@ -418,9 +415,6 @@ public final class ParserUtils {
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
             copy.addUnknownSchemaNode(unknown);
         }
-        for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
-            copy.addUnknownSchemaNode(unknown);
-        }
         copy.setDescription(old.getDescription());
         copy.setReference(old.getReference());
         copy.setStatus(old.getStatus());
@@ -447,9 +441,6 @@ public final class ParserUtils {
         for (UsesNodeBuilder use : old.getUsesNodes()) {
             copy.addUsesNode(use);
         }
-        for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
-            copy.addUnknownSchemaNode(unknown);
-        }
         copy.setDefaultCase(old.getDefaultCase());
         copy.setDescription(old.getDescription());
         copy.setReference(old.getReference());
@@ -474,6 +465,72 @@ public final class ParserUtils {
         return copy;
     }
 
+    public static GroupingBuilder copyGroupingBuilder(final GroupingBuilder old) {
+        final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(),
+                old.getLine());
+        copy.setPath(old.getPath());
+        for (DataSchemaNodeBuilder child : old.getChildNodes()) {
+            copy.addChildNode(child);
+        }
+        for (GroupingBuilder grouping : old.getGroupings()) {
+            copy.addGrouping(grouping);
+        }
+        for (TypeDefinitionBuilder typedef : old.getTypedefs()) {
+            copy.addTypedef(typedef);
+        }
+        for (UsesNodeBuilder use : old.getUses()) {
+            copy.addUsesNode(use);
+        }
+        for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
+            copy.addUnknownSchemaNode(unknown);
+        }
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+        return copy;
+    }
+
+    public static TypedefBuilder copyTypedefBuilder(TypedefBuilder old) {
+        final TypedefBuilder copy = new TypedefBuilder(old.getQName(),
+                old.getLine());
+        copy.setPath(old.getPath());
+        copy.setDefaultValue(old.getDefaultValue());
+        copy.setUnits(old.getUnits());
+        copy.setDescription(old.getDescription());
+        copy.setReference(old.getReference());
+        copy.setStatus(old.getStatus());
+
+        copy.setRanges(old.getRanges());
+        copy.setLengths(old.getLengths());
+        copy.setPatterns(old.getPatterns());
+        copy.setFractionDigits(old.getFractionDigits());
+
+        TypeDefinition<?> type = old.getType();
+        if(type == null) {
+            copy.setType(old.getTypedef());
+        } else {
+            copy.setType(old.getType());
+        }
+        copy.setUnits(old.getUnits());
+        for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
+            copy.addUnknownSchemaNode(unknown);
+        }
+        return copy;
+    }
+
+    public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) {
+        final UsesNodeBuilder copy = new UsesNodeBuilderImpl(
+                old.getGroupingPathString(), old.getLine());
+        for (AugmentationSchemaBuilder augment : old.getAugmentations()) {
+            copy.addAugment(augment);
+        }
+        copy.setAugmenting(old.isAugmenting());
+        for (SchemaNodeBuilder refineNode : old.getRefineNodes()) {
+            copy.addRefineNode(refineNode);
+        }
+        return copy;
+    }
+
     private static void copyConstraints(final DataSchemaNodeBuilder oldBuilder,
             final DataSchemaNodeBuilder newBuilder) {
         final ConstraintsBuilder oldConstraints = oldBuilder.getConstraints();
index fe35899..910a360 100644 (file)
@@ -26,10 +26,12 @@ import org.opendaylight.controller.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.controller.yang.model.api.ChoiceNode;
 import org.opendaylight.controller.yang.model.api.ConstraintDefinition;
 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
 import org.opendaylight.controller.yang.model.api.Deviation;
 import org.opendaylight.controller.yang.model.api.Deviation.Deviate;
 import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
 import org.opendaylight.controller.yang.model.api.FeatureDefinition;
+import org.opendaylight.controller.yang.model.api.GroupingDefinition;
 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
 import org.opendaylight.controller.yang.model.api.Module;
@@ -551,11 +553,13 @@ public class YangParserTest {
         assertEquals(1, usesNodes.size());
         UsesNode usesNode = usesNodes.iterator().next();
         Map<SchemaPath, SchemaNode> refines = usesNode.getRefines();
-        assertEquals(3, refines.size());
+        assertEquals(5, refines.size());
 
         LeafSchemaNode refineLeaf = null;
         ContainerSchemaNode refineContainer = null;
         ListSchemaNode refineList = null;
+        GroupingDefinition refineGrouping = null;
+        TypeDefinition<?> typedef = null;
         for (Map.Entry<SchemaPath, SchemaNode> entry : refines.entrySet()) {
             SchemaNode value = entry.getValue();
             if (value instanceof LeafSchemaNode) {
@@ -564,6 +568,10 @@ public class YangParserTest {
                 refineContainer = (ContainerSchemaNode) value;
             } else if(value instanceof ListSchemaNode) {
                 refineList = (ListSchemaNode)value;
+            } else if(value instanceof GroupingDefinition) {
+                refineGrouping = (GroupingDefinition)value;
+            } else if(value instanceof TypeDefinition<?>) {
+                typedef = (TypeDefinition<?>)value;
             }
         }
 
@@ -607,6 +615,20 @@ public class YangParserTest {
         assertFalse(refineList.isConfiguration());
         assertEquals(2, (int)refineList.getConstraints().getMinElements());
         assertEquals(12, (int)refineList.getConstraints().getMaxElements());
+
+        // grouping target-inner
+        assertNotNull(refineGrouping);
+        Set<DataSchemaNode> refineGroupingChildren = refineGrouping.getChildNodes();
+        assertEquals(1, refineGroupingChildren.size());
+        LeafSchemaNode refineGroupingLeaf = (LeafSchemaNode)refineGroupingChildren.iterator().next();
+        assertEquals("inner-grouping-id", refineGroupingLeaf.getQName().getLocalName());
+        assertEquals("new target-inner grouping description", refineGrouping.getDescription());
+
+        // typedef group-type
+        assertNotNull(typedef);
+        assertEquals("new group-type description", typedef.getDescription());
+        assertEquals("new group-type reference", typedef.getReference());
+        assertTrue(typedef.getBaseType() instanceof ExtendedType);
     }
 
     @Test
@@ -729,4 +751,14 @@ public class YangParserTest {
         assertNotNull(output.getDataChildByName("data"));
     }
 
+    @Test
+    public void testGrouping() {
+        Module testModule = TestUtils.findModule(modules, "types2");
+        Set<GroupingDefinition> groupings = testModule.getGroupings();
+        assertEquals(1, groupings.size());
+        GroupingDefinition grouping = groupings.iterator().next();
+        Set<DataSchemaNode> children = grouping.getChildNodes();
+        assertEquals(5, children.size());
+    }
+
 }
index a4e5868..d75fc63 100644 (file)
@@ -136,6 +136,36 @@ module types2 {
     }
     
     grouping target {
+        anyxml data {
+            config true;
+            description "Copy of the source datastore subset.";
+            mandatory false;
+            must "test-condition-text";
+            reference "test-no-reference";
+            status "obsolete";
+            when "test-when-text";
+        }
+        choice how {
+            description "test choice description";
+            default interval;
+            case interval {
+                leaf interval {
+                    type uint16;
+                    default 30;
+                    units minutes;
+                }
+            }
+            case daily {
+                leaf daily {
+                    type empty;
+                }
+                leaf time-of-day {
+                    type string;
+                    units 24-hour-clock;
+                    default 1am;
+                }
+            }
+        }
         leaf address {
             type string;
             description "Target IP address";
@@ -143,13 +173,21 @@ module types2 {
         container port {
             description "Target port container";
         }
-        
         list addresses {
             key "id";
             leaf id {
                 type int8;
             }
         }
+        grouping target-inner {
+            description "target-inner default description";
+            leaf inner-grouping-id {
+                type int8;
+            }
+        }
+        typedef group-type {
+            type my-decimal-type;
+        }
     }
 
     container peer {
@@ -183,6 +221,13 @@ module types2 {
                     min-elements 2;
                     max-elements 12;
                 }
+                refine target-inner {
+                    description "new target-inner grouping description";
+                }
+                refine group-type {
+                    description "new group-type description";
+                    reference "new group-type reference";
+                }
             }
         }
     }