X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Futil%2FGroupingUtils.java;h=7faef14300e84d598ceed097fadd8aafb53f9c2a;hb=f75b7abb9dcc2ba02a14a316212da1c1b434a9b3;hp=a09b1a2cb12158411a1550d46374a4437fa22584;hpb=c87589087031a10996e0c11740d8a9f41b991c05;p=yangtools.git diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/GroupingUtils.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/GroupingUtils.java index a09b1a2cb1..7faef14300 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/GroupingUtils.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/GroupingUtils.java @@ -16,22 +16,40 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ChoiceNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; 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.model.api.TypeDefinition; +import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; +import org.opendaylight.yangtools.yang.model.util.ExtendedType; +import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder; 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.SchemaNodeBuilder; 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.ChoiceCaseBuilder; 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 +65,7 @@ public class GroupingUtils { public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder, final Map> 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 +81,18 @@ public class GroupingUtils { groupingName = groupingString; } - ModuleBuilder dependentModule = null; + ModuleBuilder dependentModule; 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 groupings = dependentModule.getGroupingBuilders(); result = findGroupingBuilder(groupings, groupingName); if (result != null) { @@ -118,7 +136,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; @@ -174,184 +192,473 @@ public class GroupingUtils { return null; } + private static void setNodeAugmenting(DataSchemaNodeBuilder node) { + node.setAugmenting(true); + if (node instanceof DataNodeContainerBuilder) { + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder)node).getChildNodeBuilders()) { + setNodeAugmenting(child); + } + } + if (node instanceof ChoiceBuilder) { + for (ChoiceCaseBuilder child : ((ChoiceBuilder)node).getCases()) { + setNodeAugmenting(child); + } + } + } + /** - * Copy target grouping data to given uses node. - *

- * Copy all data-schema-nodes, groupings, typedefs and unknown nodes from - * target grouping to uses node. - *

+ * Add nodes defined in uses target grouping to uses parent. * * @param usesNode - * @param targetGrouping + * yang uses node which will be instantiated in current location */ - public static void loadTargetGroupingData(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) { + public static void updateUsesParent(UsesNodeBuilder usesNode) { + DataNodeContainerBuilder parent = usesNode.getParent(); + ModuleBuilder module = ParserUtils.getParentModule(parent); + URI ns = module.getNamespace(); + Date rev = module.getRevision(); + String prefix = module.getPrefix(); + + SchemaPath parentPath = parent.getPath(); + if (parent instanceof AugmentationSchemaBuilder) { + parentPath = ((AugmentationSchemaBuilder) parent).getTargetNodeSchemaPath(); + } + // child nodes - Set targetChildren = new HashSet<>(); - for (DataSchemaNodeBuilder targetChild : targetGrouping.getChildNodeBuilders()) { - targetChildren.add(CopyUtils.copy(targetChild, usesNode.getParent(), true)); + for (DataSchemaNodeBuilder child : usesNode.getTargetChildren()) { + setAddedByUsesToNode(child); + + if (usesNode.isAugmenting()) { + //child.setAugmenting(true); + setNodeAugmenting(child); + } + if (usesNode.isAugmenting() && !(usesNode.getParentAugment().getParent() instanceof UsesNodeBuilder)) { + AugmentationSchemaBuilder parentAugment = usesNode.getParentAugment(); + ModuleBuilder m = ParserUtils.getParentModule(parentAugment); + correctNodePathForUsesNodes(child, parentPath, m); + } else { + child.setQName(new QName(ns, rev, prefix, child.getQName().getLocalName())); + correctNodePathForUsesNodes(child, parentPath, module); + } + + parent.addChildNode(child); } - usesNode.setTargetChildren(targetChildren); // groupings - Set targetGroupingGroupings = new HashSet<>(); - for (GroupingBuilder targetGroupingGrouping : targetGrouping.getGroupingBuilders()) { - targetGroupingGroupings.add(CopyUtils.copy(targetGroupingGrouping, usesNode.getParent(), true)); + for (GroupingBuilder gb : usesNode.getTargetGroupings()) { + setAddedByUsesToNode(gb); + gb.setQName(new QName(ns, rev, prefix, gb.getQName().getLocalName())); + correctNodePathForUsesNodes(gb, parentPath, module); + parent.addGrouping(gb); } - usesNode.setTargetGroupings(targetGroupingGroupings); // typedefs - Set targetGroupingTypedefs = new HashSet<>(); - for(TypeDefinitionBuilder targetGroupingTypedef : targetGrouping.getTypeDefinitionBuilders()) { - targetGroupingTypedefs.add(CopyUtils.copy(targetGroupingTypedef, usesNode.getParent(), true)); + for (TypeDefinitionBuilder tdb : usesNode.getTargetTypedefs()) { + setAddedByUsesToNode(tdb); + tdb.setQName(new QName(ns, rev, prefix, tdb.getQName().getLocalName())); + correctNodePathForUsesNodes(tdb, parentPath, module); + parent.addTypedef(tdb); } - usesNode.setTargetTypedefs(targetGroupingTypedefs); // unknown nodes - List targetGroupingUNs = new ArrayList<>(); - for(UnknownSchemaNodeBuilder targetGroupingUN : targetGrouping.getUnknownNodeBuilders()) { - targetGroupingUNs.add(CopyUtils.copy(targetGroupingUN, usesNode.getParent(), true)); + for (UnknownSchemaNodeBuilder un : usesNode.getTargetUnknownNodes()) { + un.setAddedByUses(true); + un.setQName(new QName(ns, rev, prefix, un.getQName().getLocalName())); + correctNodePathForUsesNodes(un, parentPath, module); + parent.addUnknownNodeBuilder(un); } - usesNode.setTargetUnknownNodes(targetGroupingUNs); + } + + private static void setAddedByUsesToNode(GroupingMember node) { + node.setAddedByUses(true); + if (node instanceof DataNodeContainerBuilder) { + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) node).getChildNodeBuilders()) { + setAddedByUsesToNode(child); - usesNode.setLoadDone(true); + } + } else if (node instanceof ChoiceBuilder) { + for (ChoiceCaseBuilder caseNode : ((ChoiceBuilder) node).getCases()) { + setAddedByUsesToNode((caseNode)); + } + } } /** - * Copy all data from target grouping which were added by uses. - *

- * Traverse uses statements in target grouping and copy all - * data-schema-nodes, groupings, typedefs and unknown nodes to current uses - * node. - *

+ * Read data defined in target grouping builder, make a copy and add them to + * uses node builder. * * @param usesNode - * @param targetGrouping + * uses node builder */ - public static void loadTargetGroupingUses(final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) { - usesNode.getTargetGroupingUses().addAll(targetGrouping.getUsesNodes()); + public static void collectUsesData(UsesNodeBuilder usesNode) { + collectTargetChildNodes(usesNode); + collectTargetTypedefs(usesNode); + collectTargetGroupings(usesNode); + collectTargetUnknownNodes(usesNode); + usesNode.setDataCollected(true); } /** - * Create copy of collection of given nodes with new schema path. + * Read child nodes defined in target grouping and make a copy of them. * - * @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 + * @param usesNode + * uses node for which data will be collected */ - public static Set copyUsesTargetNodesWithNewPath(UsesNodeBuilder usesNode, Builder parent) { - Set newNodes = new HashSet<>(); + private static void collectTargetChildNodes(UsesNodeBuilder usesNode) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + final Set collection = new HashSet<>(); + addChildNodeToCollection(usesNode, collection, target.getChildNodeBuilders(), usesNode.getParent()); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + Set targetUsesChildNodes = collectTargetUsesChildNodes(targetUses, + usesNode.getParent()); + addChildNodeToCollection(usesNode, collection, targetUsesChildNodes, usesNode.getParent()); + } + usesNode.getTargetChildren().addAll(collection); + } + + private static Set collectTargetUsesChildNodes(UsesNodeBuilder usesNode, + DataNodeContainerBuilder parent) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + final Set collection = new HashSet<>(usesNode.getTargetChildren()); + addChildNodeToCollection(usesNode, collection, target.getChildNodeBuilders(), parent); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + Set targetUsesChildNodes = collectTargetUsesChildNodes(targetUses, parent); + addChildNodeToCollection(usesNode, collection, targetUsesChildNodes, parent); + } + return collection; + } - for (DataSchemaNodeBuilder node : usesNode.getTargetChildren()) { - if (node != null) { - if (node instanceof GroupingMember) { - ((GroupingMember) node).setAddedByUses(true); + private static void addChildNodeToCollection(UsesNodeBuilder usesNode, Set collection, + Set allNodes, Builder parent) { + for (DataSchemaNodeBuilder childNode : allNodes) { + boolean exists = false; + for (DataSchemaNodeBuilder usesChildNode : usesNode.getTargetChildren()) { + if (usesChildNode.getQName().getLocalName().equals(childNode.getQName().getLocalName())) { + exists = true; + break; } - newNodes.add(node); + } + if (!exists) { + DataSchemaNodeBuilder copy = CopyUtils.copy(childNode, parent, true); + setAddedByUsesToNode(copy); + collection.add(copy); } } + } + + /** + * Read typedefs defined in target grouping and make a copy of them. + * + * @param usesNode + * uses node for which data will be collected + */ + private static void collectTargetTypedefs(UsesNodeBuilder usesNode) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + Set collection = new HashSet<>(); + addTypedefToCollection(usesNode, collection, target.getTypeDefinitionBuilders(), usesNode.getParent()); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + Set targetUsesTypedefs = collectTargetUsesTypedefs(targetUses, usesNode.getParent()); + addTypedefToCollection(usesNode, collection, targetUsesTypedefs, usesNode.getParent()); + } + usesNode.getTargetTypedefs().addAll(collection); + } + + private static Set collectTargetUsesTypedefs(UsesNodeBuilder usesNode, + DataNodeContainerBuilder parent) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + Set collection = new HashSet<>(usesNode.getTargetTypedefs()); + addTypedefToCollection(usesNode, collection, target.getTypeDefinitionBuilders(), parent); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + Set targetUsesTypedefs = collectTargetUsesTypedefs(targetUses, parent); + addTypedefToCollection(usesNode, collection, targetUsesTypedefs, parent); + } + return collection; + } - return newNodes; + private static void addTypedefToCollection(UsesNodeBuilder usesNode, Set collection, + Set allTypedefs, Builder parent) { + for (TypeDefinitionBuilder childNode : allTypedefs) { + boolean exists = false; + for (TypeDefinitionBuilder usesTypedef : usesNode.getTargetTypedefs()) { + if (usesTypedef.getQName().getLocalName().equals(childNode.getQName().getLocalName())) { + exists = true; + break; + } + } + if (!exists) { + TypeDefinitionBuilder copy = CopyUtils.copy(childNode, parent, true); + collection.add(copy); + } + } } /** - * Create copy of collection of given groupings with new schema path. + * Read groupings defined in target grouping and make a copy of them. * - * @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 + * @param usesNode + * uses node for which data will be collected + */ + private static void collectTargetGroupings(UsesNodeBuilder usesNode) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + Set collection = new HashSet<>(); + addGroupingToCollection(usesNode, collection, target.getGroupingBuilders(), usesNode.getParent()); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + Set targetUsesGrouping = collectTargetGroupings(targetUses, usesNode.getParent()); + addGroupingToCollection(usesNode, collection, targetUsesGrouping, usesNode.getParent()); + } + usesNode.getTargetGroupings().addAll(collection); + } + + private static Set collectTargetGroupings(UsesNodeBuilder usesNode, DataNodeContainerBuilder parent) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + Set collection = new HashSet<>(usesNode.getTargetGroupings()); + addGroupingToCollection(usesNode, collection, target.getGroupingBuilders(), parent); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + Set targetUsesGroupings = collectTargetGroupings(targetUses, parent); + addGroupingToCollection(usesNode, collection, targetUsesGroupings, parent); + } + return collection; + } + + private static void addGroupingToCollection(UsesNodeBuilder usesNode, Set collection, + Set allGroupings, Builder parent) { + for (GroupingBuilder childNode : allGroupings) { + boolean exists = false; + for (GroupingBuilder usesGrouping : usesNode.getTargetGroupings()) { + if (usesGrouping.getQName().getLocalName().equals(childNode.getQName().getLocalName())) { + exists = true; + break; + } + } + if (!exists) { + GroupingBuilder copy = CopyUtils.copy(childNode, parent, true); + collection.add(copy); + } + } + } + + /** + * Read unknown nodes defined in target grouping and make a copy of them. + * + * @param usesNode + * uses node for which data will be collected */ - public static Set copyUsesTargetGroupingsWithNewPath(UsesNodeBuilder usesNode, - SchemaPath parentPath, URI namespace, Date revision, String prefix) { - Set newGroupings = new HashSet<>(); - for (GroupingBuilder node : usesNode.getTargetGroupings()) { - if (node != null) { - if (node instanceof GroupingMember) { - ((GroupingMember) node).setAddedByUses(true); + private static void collectTargetUnknownNodes(UsesNodeBuilder usesNode) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + final List collection = new ArrayList<>(); + addUnknownNodeToCollection(usesNode, collection, target.getUnknownNodeBuilders(), usesNode.getParent()); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + List targetUsesUnknownNodes = collectTargetUnknownNodes(targetUses, + usesNode.getParent()); + addUnknownNodeToCollection(usesNode, collection, targetUsesUnknownNodes, usesNode.getParent()); + } + usesNode.getTargetUnknownNodes().addAll(collection); + } + + private static List collectTargetUnknownNodes(UsesNodeBuilder usesNode, + DataNodeContainerBuilder parent) { + final GroupingBuilder target = usesNode.getGroupingBuilder(); + List collection = new ArrayList<>(usesNode.getTargetUnknownNodes()); + addUnknownNodeToCollection(usesNode, collection, target.getUnknownNodeBuilders(), parent); + + for (UsesNodeBuilder targetUses : target.getUsesNodes()) { + List targetUsesUnknownNodes = collectTargetUnknownNodes(targetUses, parent); + addUnknownNodeToCollection(usesNode, collection, targetUsesUnknownNodes, parent); + } + return collection; + } + + private static void addUnknownNodeToCollection(UsesNodeBuilder usesNode, List collection, + List allUnknownNodes, Builder parent) { + for (UnknownSchemaNodeBuilder childNode : allUnknownNodes) { + boolean exists = false; + for (UnknownSchemaNodeBuilder usesUnknownNode : usesNode.getTargetUnknownNodes()) { + if (usesUnknownNode.getQName().getLocalName().equals(childNode.getQName().getLocalName())) { + exists = true; + break; } - newGroupings.add(node); } + if (!exists) { + UnknownSchemaNodeBuilder copy = CopyUtils.copy(childNode, parent, true); + collection.add(copy); + } + } + } + + /** + * Read data defined in target grouping definition, make a copy and add them + * to uses node builder. + * + * @param usesNode + * uses node builder + */ + public static void collectUsesDataFromContext(UsesNodeBuilder usesNode) { + DataNodeContainerBuilder parent = usesNode.getParent(); + URI namespace = parent.getQName().getNamespace(); + Date revision = parent.getQName().getRevision(); + String prefix = parent.getQName().getPrefix(); + String moduleName = parent.getModuleName(); + int line = parent.getLine(); + + // child nodes + copyGroupingNodesToUsesNode(usesNode, namespace, revision, prefix, moduleName, line); + + // groupings + final Set newGroupings = new HashSet<>(); + for (GroupingDefinition g : usesNode.getGroupingDefinition().getGroupings()) { + QName newQName = new QName(namespace, revision, prefix, g.getQName().getLocalName()); + GroupingBuilder newGrouping = CopyUtils.createGrouping(g, newQName, moduleName, line); + newGrouping.setAddedByUses(true); + newGroupings.add(newGrouping); + } + usesNode.getTargetGroupings().addAll(newGroupings); + + // typedefs + final Set newTypedefs = new HashSet<>(); + for (TypeDefinition td : usesNode.getGroupingDefinition().getTypeDefinitions()) { + QName newQName = new QName(namespace, revision, prefix, td.getQName().getLocalName()); + TypeDefinitionBuilder newType = CopyUtils.createTypedef((ExtendedType) td, newQName, moduleName, line); + newType.setAddedByUses(true); + newTypedefs.add(newType); } + usesNode.getTargetTypedefs().addAll(newTypedefs); - return newGroupings; + // unknown nodes + final List newUnknownNodes = new ArrayList<>(); + for (UnknownSchemaNode un : usesNode.getGroupingDefinition().getUnknownSchemaNodes()) { + QName newQName = new QName(namespace, revision, prefix, un.getQName().getLocalName()); + UnknownSchemaNodeBuilder newNode = CopyUtils.createUnknownSchemaNode(un, newQName, moduleName, line); + newNode.setAddedByUses(true); + newUnknownNodes.add(newNode); + } + usesNode.getTargetUnknownNodes().addAll(newUnknownNodes); + + usesNode.setDataCollected(true); } /** - * Create copy of collection of given typedefs with new schema path. + * Read data defined in target grouping definition, make a copy and add them + * to uses node builder. * - * @param typedefs - * typedefs to copy - * @param parentPath - * schema path of parent node + * @param usesNode + * used node builder to which are copied nodes from its + * GroupingDefinition * @param namespace - * new namespace of node qname + * URI with parent namespace * @param revision - * new revision of node qname + * date with parent revision date * @param prefix - * new prefix of node qname - * @return collection of new typedefs with corrected path + * string with parent prefix + * @param moduleName + * string with parent module name + * @param lineNumber + * number with YANG file row where is the parent defined */ - public static Set copyUsesTargetTypedefsWithNewPath(UsesNodeBuilder usesNode, - SchemaPath parentPath, URI namespace, Date revision, String prefix) { - Set newTypedefs = new HashSet<>(); - - for (TypeDefinitionBuilder node : usesNode.getTargetTypedefs()) { - if (node != null) { - if (node instanceof GroupingMember) { - ((GroupingMember) node).setAddedByUses(true); + private static void copyGroupingNodesToUsesNode(final UsesNodeBuilder usesNode, final URI namespace, + final Date revision, final String prefix, final String moduleName, final int lineNumber) { + final Set newChildren = new HashSet<>(); + for (DataSchemaNode child : usesNode.getGroupingDefinition().getChildNodes()) { + if (child != null) { + DataSchemaNodeBuilder newChild = null; + QName newQName = new QName(namespace, revision, prefix, child.getQName().getLocalName()); + if (child instanceof AnyXmlSchemaNode) { + newChild = CopyUtils.createAnyXml((AnyXmlSchemaNode) child, newQName, moduleName, lineNumber); + } else if (child instanceof ChoiceNode) { + newChild = CopyUtils.createChoice((ChoiceNode) child, newQName, moduleName, lineNumber); + } else if (child instanceof ContainerSchemaNode) { + newChild = CopyUtils.createContainer((ContainerSchemaNode) child, newQName, moduleName, lineNumber); + } else if (child instanceof LeafListSchemaNode) { + newChild = CopyUtils.createLeafList((LeafListSchemaNode) child, newQName, moduleName, lineNumber); + } else if (child instanceof LeafSchemaNode) { + newChild = CopyUtils.createLeafBuilder((LeafSchemaNode) child, newQName, moduleName, lineNumber); + } else if (child instanceof ListSchemaNode) { + newChild = CopyUtils.createList((ListSchemaNode) child, newQName, moduleName, lineNumber); + } + + if (newChild == null) { + throw new YangParseException(moduleName, lineNumber, + "Unknown member of target grouping while resolving uses node."); } - newTypedefs.add(node); + + ((GroupingMember) newChild).setAddedByUses(true); + newChildren.add(newChild); } } + usesNode.getTargetChildren().addAll(newChildren); - return newTypedefs; } /** - * Create copy of collection of given unknown nodes with new schema path. + * Correct schema path of nodes added by uses statement. * - * @param usesNode - * @param parentPath + * @param node + * node added by uses statement + * @param parentSchemaPath * 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 + * @param parentModule + * current parent node module */ - public static List copyUsesTargetUnknownNodesWithNewPath(UsesNodeBuilder usesNode, - SchemaPath parentPath, URI namespace, Date revision, String prefix) { - List newUnknownNodes = new ArrayList<>(); - - for (UnknownSchemaNodeBuilder node : usesNode.getTargetUnknownNodes()) { - if (node != null) { - node.setAddedByUses(true); - newUnknownNodes.add(node); + private static void correctNodePathForUsesNodes(final SchemaNodeBuilder node, final SchemaPath parentSchemaPath, + final ModuleBuilder parentModule) { + // set correct path + List targetNodePath = new ArrayList<>(parentSchemaPath.getPath()); + targetNodePath.add(new QName(parentModule.getNamespace(), parentModule.getRevision(), parentModule.getPrefix(), + node.getQName().getLocalName())); + node.setPath(new SchemaPath(targetNodePath, true)); + + // set correct path for all child nodes + if (node instanceof DataNodeContainerBuilder) { + DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) node; + for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) { + correctNodePathForUsesNodes(child, node.getPath(), parentModule); + } + } + + // set correct path for all cases + if (node instanceof ChoiceBuilder) { + ChoiceBuilder choiceBuilder = (ChoiceBuilder) node; + for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) { + correctNodePathForUsesNodes(choiceCaseBuilder, node.getPath(), parentModule); } } + } - return newUnknownNodes; + /** + * Perform refinement of uses target grouping nodes. Uses process has to be + * already performed. + * + * @param usesNode + * uses node containing refine statements + */ + 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); + } + } + + 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); + } } }