Bug 527: fixed augment deserialization from xml.
[yangtools.git] / yang / yang-parser-impl / src / main / java / org / opendaylight / yangtools / yang / parser / util / GroupingUtils.java
index a09b1a2cb12158411a1550d46374a4437fa22584..2b37a2ce70f88e732465a071b72adfec89bc28e2 100644 (file)
@@ -7,11 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.parser.util;
 
-import java.net.URI;
-import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -19,19 +16,19 @@ import java.util.TreeMap;
 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.api.GroupingMember;
-import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
-import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
 
-public class GroupingUtils {
+public final class GroupingUtils {
+
+    private GroupingUtils() {
+    }
 
     /**
      * Search given modules for grouping by name defined in uses node.
@@ -47,7 +44,8 @@ public class GroupingUtils {
     public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
         final int line = usesBuilder.getLine();
-        final String groupingString = usesBuilder.getGroupingName();
+
+        final String groupingString = usesBuilder.getGroupingPathAsString();
         String groupingPrefix;
         String groupingName;
 
@@ -63,18 +61,21 @@ public class GroupingUtils {
             groupingName = groupingString;
         }
 
-        ModuleBuilder dependentModule = null;
+        ModuleBuilder dependentModule;
+        if(groupingPrefix == null) {
+            dependentModule = module;
+        }
         if (groupingPrefix.equals(module.getPrefix())) {
             dependentModule = module;
         } else {
-            dependentModule = ParserUtils.findDependentModuleBuilder(modules, module, groupingPrefix, line);
+            dependentModule = ParserUtils.findModuleFromBuilders(modules, module, groupingPrefix, line);
         }
 
         if (dependentModule == null) {
             return null;
         }
 
-        GroupingBuilder result = null;
+        GroupingBuilder result;
         Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
         result = findGroupingBuilder(groupings, groupingName);
         if (result != null) {
@@ -118,7 +119,7 @@ public class GroupingUtils {
     public static GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
             final ModuleBuilder module, final SchemaContext context) {
         final int line = usesBuilder.getLine();
-        String groupingString = usesBuilder.getGroupingName();
+        String groupingString = usesBuilder.getGroupingPathAsString();
         String groupingPrefix;
         String groupingName;
 
@@ -175,183 +176,51 @@ public class GroupingUtils {
     }
 
     /**
-     * Copy target grouping data to given uses node.
-     * <p>
-     * Copy all data-schema-nodes, groupings, typedefs and unknown nodes from
-     * target grouping to uses node.
-     * </p>
-     *
-     * @param usesNode
-     * @param targetGrouping
-     */
-    public static void loadTargetGroupingData(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
-        // child nodes
-        Set<DataSchemaNodeBuilder> targetChildren = new HashSet<>();
-        for (DataSchemaNodeBuilder targetChild : targetGrouping.getChildNodeBuilders()) {
-            targetChildren.add(CopyUtils.copy(targetChild, usesNode.getParent(), true));
-        }
-        usesNode.setTargetChildren(targetChildren);
-
-        // groupings
-        Set<GroupingBuilder> targetGroupingGroupings = new HashSet<>();
-        for (GroupingBuilder targetGroupingGrouping : targetGrouping.getGroupingBuilders()) {
-            targetGroupingGroupings.add(CopyUtils.copy(targetGroupingGrouping, usesNode.getParent(), true));
-        }
-        usesNode.setTargetGroupings(targetGroupingGroupings);
-
-        // typedefs
-        Set<TypeDefinitionBuilder> targetGroupingTypedefs = new HashSet<>();
-        for(TypeDefinitionBuilder targetGroupingTypedef : targetGrouping.getTypeDefinitionBuilders()) {
-            targetGroupingTypedefs.add(CopyUtils.copy(targetGroupingTypedef, usesNode.getParent(), true));
-        }
-        usesNode.setTargetTypedefs(targetGroupingTypedefs);
-
-        // unknown nodes
-        List<UnknownSchemaNodeBuilder> targetGroupingUNs = new ArrayList<>();
-        for(UnknownSchemaNodeBuilder targetGroupingUN : targetGrouping.getUnknownNodeBuilders()) {
-            targetGroupingUNs.add(CopyUtils.copy(targetGroupingUN, usesNode.getParent(), true));
-        }
-        usesNode.setTargetUnknownNodes(targetGroupingUNs);
-
-        usesNode.setLoadDone(true);
-    }
-
-    /**
-     * Copy all data from target grouping which were added by uses.
-     * <p>
-     * Traverse uses statements in target grouping and copy all
-     * data-schema-nodes, groupings, typedefs and unknown nodes to current uses
-     * node.
-     * </p>
+     * Perform refinement of uses target grouping nodes. Uses process has to be
+     * already performed.
      *
      * @param usesNode
-     * @param targetGrouping
-     */
-    public static void loadTargetGroupingUses(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) {
-        usesNode.getTargetGroupingUses().addAll(targetGrouping.getUsesNodes());
-    }
-
-    /**
-     * Create copy of collection of given nodes with new schema path.
-     *
-     * @param nodes
-     *            nodes to copy
-     * @param parentPath
-     *            schema path of parent node
-     * @param namespace
-     *            new namespace of node qname
-     * @param revision
-     *            new revision of node qname
-     * @param prefix
-     *            new prefix of node qname
-     * @param moduleName
-     *            current yang module name
-     * @param line
-     *            current line in yang module
-     * @return collection of new nodes with corrected path
+     *            uses node containing refine statements
      */
-    public static Set<DataSchemaNodeBuilder> copyUsesTargetNodesWithNewPath(UsesNodeBuilder usesNode, Builder parent) {
-        Set<DataSchemaNodeBuilder> newNodes = new HashSet<>();
-
-        for (DataSchemaNodeBuilder node : usesNode.getTargetChildren()) {
-            if (node != null) {
-                if (node instanceof GroupingMember) {
-                    ((GroupingMember) node).setAddedByUses(true);
+    public static void performRefine(UsesNodeBuilder usesNode) {
+        for (RefineHolder refine : usesNode.getRefines()) {
+            String refineTargetPath = refine.getName();
+
+            String[] splitted = refineTargetPath.split("/");
+            Builder currentNode = usesNode.getParent();
+            for (String pathElement : splitted) {
+                if (currentNode instanceof DataNodeContainerBuilder) {
+                    currentNode = ((DataNodeContainerBuilder) currentNode).getDataChildByName(pathElement);
+                } else if (currentNode instanceof ChoiceBuilder) {
+                    currentNode = ((ChoiceBuilder) currentNode).getCaseNodeByName(pathElement);
                 }
-                newNodes.add(node);
             }
-        }
-
-        return newNodes;
-    }
 
-    /**
-     * Create copy of collection of given groupings with new schema path.
-     *
-     * @param groupings
-     *            groupings to copy
-     * @param parentPath
-     *            schema path of parent node
-     * @param namespace
-     *            new namespace of node qname
-     * @param revision
-     *            new revision of node qname
-     * @param prefix
-     *            new prefix of node qname
-     * @return collection of new groupings with corrected path
-     */
-    public static Set<GroupingBuilder> copyUsesTargetGroupingsWithNewPath(UsesNodeBuilder usesNode,
-            SchemaPath parentPath, URI namespace, Date revision, String prefix) {
-        Set<GroupingBuilder> newGroupings = new HashSet<>();
-        for (GroupingBuilder node : usesNode.getTargetGroupings()) {
-            if (node != null) {
-                if (node instanceof GroupingMember) {
-                    ((GroupingMember) node).setAddedByUses(true);
-                }
-                newGroupings.add(node);
+            DataSchemaNodeBuilder nodeToRefine = (DataSchemaNodeBuilder) currentNode;
+            if (nodeToRefine == null) {
+                throw new YangParseException(refine.getModuleName(), refine.getLine(), "Refine target node '"
+                        + refine.getName() + "' not found");
             }
+            RefineUtils.performRefine(nodeToRefine, refine);
+            usesNode.addRefineNode(nodeToRefine);
         }
-
-        return newGroupings;
     }
 
-    /**
-     * Create copy of collection of given typedefs with new schema path.
-     *
-     * @param typedefs
-     *            typedefs to copy
-     * @param parentPath
-     *            schema path of parent node
-     * @param namespace
-     *            new namespace of node qname
-     * @param revision
-     *            new revision of node qname
-     * @param prefix
-     *            new prefix of node qname
-     * @return collection of new typedefs with corrected path
-     */
-    public static Set<TypeDefinitionBuilder> copyUsesTargetTypedefsWithNewPath(UsesNodeBuilder usesNode,
-            SchemaPath parentPath, URI namespace, Date revision, String prefix) {
-        Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
-
-        for (TypeDefinitionBuilder node : usesNode.getTargetTypedefs()) {
-            if (node != null) {
-                if (node instanceof GroupingMember) {
-                    ((GroupingMember) node).setAddedByUses(true);
-                }
-                newTypedefs.add(node);
-            }
+    public static class UsesComparator implements Comparator<UsesNodeBuilder> {
+        @Override
+        public int compare(UsesNodeBuilder o1, UsesNodeBuilder o2) {
+            return getElementPosition(o2) - getElementPosition(o1);
         }
-
-        return newTypedefs;
     }
 
-    /**
-     * Create copy of collection of given unknown nodes with new schema path.
-     *
-     * @param usesNode
-     * @param parentPath
-     *            schema path of parent node
-     * @param namespace
-     *            new namespace of node qname
-     * @param revision
-     *            new revision of node qname
-     * @param prefix
-     *            new prefix of node qname
-     * @return collection of new unknownNodes with corrected path
-     */
-    public static List<UnknownSchemaNodeBuilder> copyUsesTargetUnknownNodesWithNewPath(UsesNodeBuilder usesNode,
-            SchemaPath parentPath, URI namespace, Date revision, String prefix) {
-        List<UnknownSchemaNodeBuilder> newUnknownNodes = new ArrayList<>();
-
-        for (UnknownSchemaNodeBuilder node : usesNode.getTargetUnknownNodes()) {
-            if (node != null) {
-                node.setAddedByUses(true);
-                newUnknownNodes.add(node);
-            }
+    private static int getElementPosition(UsesNodeBuilder usesNode) {
+        int i = 0;
+        Builder parent = usesNode.getParent();
+        while (!(parent instanceof ModuleBuilder)) {
+            parent = parent.getParent();
+            i++;
         }
-
-        return newUnknownNodes;
+        return i;
     }
 
 }