2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.util;
11 import java.util.ArrayList;
12 import java.util.Date;
13 import java.util.HashSet;
14 import java.util.List;
17 import java.util.TreeMap;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
21 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
22 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
23 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
24 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
25 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
27 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
28 import org.opendaylight.yangtools.yang.model.api.Module;
29 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
30 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
31 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
32 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
33 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
34 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
35 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
36 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
37 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
38 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
39 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingMember;
40 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
41 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
42 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
43 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder;
44 import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceCaseBuilder;
45 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleBuilder;
46 import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder;
47 import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder;
49 public final class GroupingUtils {
51 private GroupingUtils() {
55 * Search given modules for grouping by name defined in uses node.
58 * builder of uses statement
63 * @return grouping with given name if found, null otherwise
65 public static GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder,
66 final Map<String, TreeMap<Date, ModuleBuilder>> modules, final ModuleBuilder module) {
67 final int line = usesBuilder.getLine();
68 final String groupingString = usesBuilder.getGroupingPathAsString();
69 String groupingPrefix;
72 if (groupingString.contains(":")) {
73 String[] splitted = groupingString.split(":");
74 if (splitted.length != 2 || groupingString.contains("/")) {
75 throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
77 groupingPrefix = splitted[0];
78 groupingName = splitted[1];
80 groupingPrefix = module.getPrefix();
81 groupingName = groupingString;
84 ModuleBuilder dependentModule = null;
85 if (groupingPrefix.equals(module.getPrefix())) {
86 dependentModule = module;
88 dependentModule = ParserUtils.findDependentModuleBuilder(modules, module, groupingPrefix, line);
91 if (dependentModule == null) {
95 GroupingBuilder result = null;
96 Set<GroupingBuilder> groupings = dependentModule.getGroupingBuilders();
97 result = findGroupingBuilder(groupings, groupingName);
102 Builder parent = usesBuilder.getParent();
104 while (parent != null) {
105 if (parent instanceof DataNodeContainerBuilder) {
106 groupings = ((DataNodeContainerBuilder) parent).getGroupingBuilders();
107 } else if (parent instanceof RpcDefinitionBuilder) {
108 groupings = ((RpcDefinitionBuilder) parent).getGroupings();
110 result = findGroupingBuilder(groupings, groupingName);
111 if (result == null) {
112 parent = parent.getParent();
118 if (result == null) {
119 throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName
126 * Search context for grouping by name defined in uses node.
129 * builder of uses statement
133 * SchemaContext containing already resolved modules
134 * @return grouping with given name if found, null otherwise
136 public static GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder,
137 final ModuleBuilder module, final SchemaContext context) {
138 final int line = usesBuilder.getLine();
139 String groupingString = usesBuilder.getGroupingPathAsString();
140 String groupingPrefix;
143 if (groupingString.contains(":")) {
144 String[] splitted = groupingString.split(":");
145 if (splitted.length != 2 || groupingString.contains("/")) {
146 throw new YangParseException(module.getName(), line, "Invalid name of target grouping");
148 groupingPrefix = splitted[0];
149 groupingName = splitted[1];
151 groupingPrefix = module.getPrefix();
152 groupingName = groupingString;
155 Module dependentModule = ParserUtils.findModuleFromContext(context, module, groupingPrefix, line);
156 return findGroupingDefinition(dependentModule.getGroupings(), groupingName);
160 * Find grouping by name.
163 * collection of grouping builders to search
166 * @return grouping with given name if present in collection, null otherwise
168 public static GroupingBuilder findGroupingBuilder(Set<GroupingBuilder> groupings, String name) {
169 for (GroupingBuilder grouping : groupings) {
170 if (grouping.getQName().getLocalName().equals(name)) {
178 * Find grouping by name.
181 * collection of grouping definitions to search
184 * @return grouping with given name if present in collection, null otherwise
186 public static GroupingDefinition findGroupingDefinition(Set<GroupingDefinition> groupings, String name) {
187 for (GroupingDefinition grouping : groupings) {
188 if (grouping.getQName().getLocalName().equals(name)) {
196 * Add nodes defined in uses target grouping to uses parent.
200 public static void updateUsesParent(UsesNodeBuilder usesNode) {
201 DataNodeContainerBuilder parent = usesNode.getParent();
204 for (DataSchemaNodeBuilder child : usesNode.getTargetChildren()) {
205 if (child instanceof GroupingMember) {
206 ((GroupingMember) child).setAddedByUses(true);
208 parent.addChildNode(child);
212 for (GroupingBuilder gb : usesNode.getTargetGroupings()) {
213 gb.setAddedByUses(true);
214 parent.addGrouping(gb);
218 for (TypeDefinitionBuilder tdb : usesNode.getTargetTypedefs()) {
219 tdb.setAddedByUses(true);
220 parent.addTypedef(tdb);
224 for (UnknownSchemaNodeBuilder un : usesNode.getTargetUnknownNodes()) {
225 un.setAddedByUses(true);
226 parent.addUnknownNodeBuilder(un);
231 * Read data defined in target grouping builder, make a copy and add them to
237 public static void collectUsesData(UsesNodeBuilder usesNode) {
238 collectTargetChildNodes(usesNode);
239 collectTargetTypedefs(usesNode);
240 collectTargetGroupings(usesNode);
241 collectTargetUnknownNodes(usesNode);
242 usesNode.setDataCollected(true);
246 * Read child nodes defined in target grouping and make a copy of them.
249 * @return copy of child nodes defined in uses target grouping
251 private static void collectTargetChildNodes(UsesNodeBuilder usesNode) {
252 final GroupingBuilder target = usesNode.getGroupingBuilder();
253 final Set<DataSchemaNodeBuilder> collection = new HashSet<>();
254 addChildNodeToCollection(usesNode, collection, target.getChildNodeBuilders());
256 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
257 Set<DataSchemaNodeBuilder> targetUsesChildNodes = collectTargetUsesChildNodes(targetUses,
258 usesNode.getParent());
259 addChildNodeToCollection(usesNode, collection, targetUsesChildNodes);
261 usesNode.getTargetChildren().addAll(collection);
264 private static Set<DataSchemaNodeBuilder> collectTargetUsesChildNodes(UsesNodeBuilder usesNode,
265 DataNodeContainerBuilder parent) {
266 final GroupingBuilder target = usesNode.getGroupingBuilder();
267 final Set<DataSchemaNodeBuilder> collection = new HashSet<>(usesNode.getTargetChildren());
268 addChildNodeToCollection(usesNode, collection, target.getChildNodeBuilders());
270 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
271 Set<DataSchemaNodeBuilder> targetUsesChildNodes = collectTargetUsesChildNodes(targetUses, parent);
272 addChildNodeToCollection(usesNode, collection, targetUsesChildNodes);
277 private static void addChildNodeToCollection(UsesNodeBuilder usesNode, Set<DataSchemaNodeBuilder> collection,
278 Set<DataSchemaNodeBuilder> allNodes) {
279 for (DataSchemaNodeBuilder childNode : allNodes) {
280 boolean exists = false;
281 for (DataSchemaNodeBuilder usesChildNode : usesNode.getTargetChildren()) {
282 if (usesChildNode.getQName().getLocalName().equals(childNode.getQName().getLocalName())) {
288 DataSchemaNodeBuilder copy = CopyUtils.copy(childNode, usesNode.getParent(), true);
289 collection.add(copy);
295 * Read typedefs defined in target grouping and make a copy of them.
298 * @return copy of typedefs defined in uses target grouping
300 private static void collectTargetTypedefs(UsesNodeBuilder usesNode) {
301 final GroupingBuilder target = usesNode.getGroupingBuilder();
302 Set<TypeDefinitionBuilder> collection = new HashSet<>();
303 addTypedefToCollection(usesNode, collection, target.getTypeDefinitionBuilders());
305 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
306 Set<TypeDefinitionBuilder> targetUsesTypedefs = collectTargetUsesTypedefs(targetUses, usesNode.getParent());
307 addTypedefToCollection(usesNode, collection, targetUsesTypedefs);
309 usesNode.getTargetTypedefs().addAll(collection);
312 private static Set<TypeDefinitionBuilder> collectTargetUsesTypedefs(UsesNodeBuilder usesNode,
313 DataNodeContainerBuilder parent) {
314 final GroupingBuilder target = usesNode.getGroupingBuilder();
315 Set<TypeDefinitionBuilder> collection = new HashSet<>(usesNode.getTargetTypedefs());
316 addTypedefToCollection(usesNode, collection, target.getTypeDefinitionBuilders());
318 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
319 Set<TypeDefinitionBuilder> targetUsesTypedefs = collectTargetUsesTypedefs(targetUses, parent);
320 addTypedefToCollection(usesNode, collection, targetUsesTypedefs);
325 private static void addTypedefToCollection(UsesNodeBuilder usesNode, Set<TypeDefinitionBuilder> collection,
326 Set<TypeDefinitionBuilder> allTypedefs) {
327 for (TypeDefinitionBuilder childNode : allTypedefs) {
328 boolean exists = false;
329 for (TypeDefinitionBuilder usesTypedef : usesNode.getTargetTypedefs()) {
330 if (usesTypedef.getQName().getLocalName().equals(childNode.getQName().getLocalName())) {
336 TypeDefinitionBuilder copy = CopyUtils.copy(childNode, usesNode.getParent(), true);
337 collection.add(copy);
343 * Read groupings defined in target grouping and make a copy of them.
346 * @return copy of groupings defined in uses target grouping
348 private static void collectTargetGroupings(UsesNodeBuilder usesNode) {
349 final GroupingBuilder target = usesNode.getGroupingBuilder();
350 Set<GroupingBuilder> collection = new HashSet<>();
351 addGroupingToCollection(usesNode, collection, target.getGroupingBuilders());
353 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
354 Set<GroupingBuilder> targetUsesGrouping = collectTargetGroupings(targetUses, usesNode.getParent());
355 addGroupingToCollection(usesNode, collection, targetUsesGrouping);
357 usesNode.getTargetGroupings().addAll(collection);
360 private static Set<GroupingBuilder> collectTargetGroupings(UsesNodeBuilder usesNode, DataNodeContainerBuilder parent) {
361 final GroupingBuilder target = usesNode.getGroupingBuilder();
362 Set<GroupingBuilder> collection = new HashSet<>(usesNode.getTargetGroupings());
363 addGroupingToCollection(usesNode, collection, target.getGroupingBuilders());
365 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
366 Set<GroupingBuilder> targetUsesGroupings = collectTargetGroupings(targetUses, parent);
367 addGroupingToCollection(usesNode, collection, targetUsesGroupings);
372 private static void addGroupingToCollection(UsesNodeBuilder usesNode, Set<GroupingBuilder> collection,
373 Set<GroupingBuilder> allGroupings) {
374 for (GroupingBuilder childNode : allGroupings) {
375 boolean exists = false;
376 for (GroupingBuilder usesGrouping : usesNode.getTargetGroupings()) {
377 if (usesGrouping.getQName().getLocalName().equals(childNode.getQName().getLocalName())) {
383 GroupingBuilder copy = CopyUtils.copy(childNode, usesNode.getParent(), true);
384 collection.add(copy);
390 * Read unknown nodes defined in target grouping and make a copy of them.
393 * @return copy of unknown nodes defined in uses target grouping
395 private static void collectTargetUnknownNodes(UsesNodeBuilder usesNode) {
396 final GroupingBuilder target = usesNode.getGroupingBuilder();
397 final List<UnknownSchemaNodeBuilder> collection = new ArrayList<>();
398 addUnknownNodeToCollection(usesNode, collection, target.getUnknownNodeBuilders());
400 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
401 List<UnknownSchemaNodeBuilder> targetUsesUnknownNodes = collectTargetUnknownNodes(targetUses,
402 usesNode.getParent());
403 addUnknownNodeToCollection(usesNode, collection, targetUsesUnknownNodes);
405 usesNode.getTargetUnknownNodes().addAll(collection);
408 private static List<UnknownSchemaNodeBuilder> collectTargetUnknownNodes(UsesNodeBuilder usesNode,
409 DataNodeContainerBuilder parent) {
410 final GroupingBuilder target = usesNode.getGroupingBuilder();
411 List<UnknownSchemaNodeBuilder> collection = new ArrayList<>(usesNode.getTargetUnknownNodes());
412 addUnknownNodeToCollection(usesNode, collection, target.getUnknownNodeBuilders());
414 for (UsesNodeBuilder targetUses : target.getUsesNodes()) {
415 List<UnknownSchemaNodeBuilder> targetUsesUnknownNodes = collectTargetUnknownNodes(targetUses, parent);
416 addUnknownNodeToCollection(usesNode, collection, targetUsesUnknownNodes);
421 private static void addUnknownNodeToCollection(UsesNodeBuilder usesNode, List<UnknownSchemaNodeBuilder> collection,
422 List<UnknownSchemaNodeBuilder> allUnknownNodes) {
423 for (UnknownSchemaNodeBuilder childNode : allUnknownNodes) {
424 boolean exists = false;
425 for (UnknownSchemaNodeBuilder usesUnknownNode : usesNode.getTargetUnknownNodes()) {
426 if (usesUnknownNode.getQName().getLocalName().equals(childNode.getQName().getLocalName())) {
432 UnknownSchemaNodeBuilder copy = CopyUtils.copy(childNode, usesNode.getParent(), true);
433 collection.add(copy);
439 * Read data defined in target grouping definition, make a copy and add them
440 * to uses node builder.
445 public static void collectUsesDataFromContext(UsesNodeBuilder usesNode) {
446 DataNodeContainerBuilder parent = usesNode.getParent();
447 URI namespace = parent.getQName().getNamespace();
448 Date revision = parent.getQName().getRevision();
449 String prefix = parent.getQName().getPrefix();
450 String moduleName = parent.getModuleName();
451 int line = parent.getLine();
454 copyGroupingNodesToUsesNode(usesNode, namespace, revision, prefix, moduleName, line);
457 final Set<GroupingBuilder> newGroupings = new HashSet<>();
458 for (GroupingDefinition g : usesNode.getGroupingDefinition().getGroupings()) {
459 QName newQName = new QName(namespace, revision, prefix, g.getQName().getLocalName());
460 GroupingBuilder newGrouping = CopyUtils.createGrouping(g, newQName, moduleName, line);
461 newGrouping.setAddedByUses(true);
462 newGroupings.add(newGrouping);
464 usesNode.getTargetGroupings().addAll(newGroupings);
467 final Set<TypeDefinitionBuilder> newTypedefs = new HashSet<>();
468 for (TypeDefinition<?> td : usesNode.getGroupingDefinition().getTypeDefinitions()) {
469 QName newQName = new QName(namespace, revision, prefix, td.getQName().getLocalName());
470 TypeDefinitionBuilder newType = CopyUtils.createTypedef((ExtendedType) td, newQName, moduleName, line);
471 newType.setAddedByUses(true);
472 newTypedefs.add(newType);
474 usesNode.getTargetTypedefs().addAll(newTypedefs);
477 final List<UnknownSchemaNodeBuilder> newUnknownNodes = new ArrayList<>();
478 for (UnknownSchemaNode un : usesNode.getGroupingDefinition().getUnknownSchemaNodes()) {
479 QName newQName = new QName(namespace, revision, prefix, un.getQName().getLocalName());
480 UnknownSchemaNodeBuilder newNode = CopyUtils.createUnknownSchemaNode(un, newQName, moduleName, line);
481 newNode.setAddedByUses(true);
482 newUnknownNodes.add(newNode);
484 usesNode.getTargetUnknownNodes().addAll(newUnknownNodes);
486 usesNode.setDataCollected(true);
490 * Read data defined in target grouping definition, make a copy and add them
491 * to uses node builder.
494 * used node builder to which are copied nodes from its
495 * <code>GroupingDefinition</code>
497 * URI with parent namespace
499 * date with parent revision date
501 * string with parent prefix
503 * string with parent module name
505 * number with YANG file row where is the parent defined
507 private static void copyGroupingNodesToUsesNode(final UsesNodeBuilder usesNode, final URI namespace,
508 final Date revision, final String prefix, final String moduleName, final int lineNumber) {
509 final Set<DataSchemaNodeBuilder> newChildren = new HashSet<>();
510 for (DataSchemaNode child : usesNode.getGroupingDefinition().getChildNodes()) {
512 DataSchemaNodeBuilder newChild = null;
513 QName newQName = new QName(namespace, revision, prefix, child.getQName().getLocalName());
514 if (child instanceof AnyXmlSchemaNode) {
515 newChild = CopyUtils.createAnyXml((AnyXmlSchemaNode) child, newQName, moduleName, lineNumber);
516 } else if (child instanceof ChoiceNode) {
517 newChild = CopyUtils.createChoice((ChoiceNode) child, newQName, moduleName, lineNumber);
518 } else if (child instanceof ContainerSchemaNode) {
519 newChild = CopyUtils.createContainer((ContainerSchemaNode) child, newQName, moduleName, lineNumber);
520 } else if (child instanceof LeafListSchemaNode) {
521 newChild = CopyUtils.createLeafList((LeafListSchemaNode) child, newQName, moduleName, lineNumber);
522 } else if (child instanceof LeafSchemaNode) {
523 newChild = CopyUtils.createLeafBuilder((LeafSchemaNode) child, newQName, moduleName, lineNumber);
524 } else if (child instanceof ListSchemaNode) {
525 newChild = CopyUtils.createList((ListSchemaNode) child, newQName, moduleName, lineNumber);
528 if (newChild == null) {
529 throw new YangParseException(moduleName, lineNumber,
530 "Unknown member of target grouping while resolving uses node.");
532 if (newChild instanceof GroupingMember) {
533 ((GroupingMember) newChild).setAddedByUses(true);
536 newChildren.add(newChild);
539 usesNode.getTargetChildren().addAll(newChildren);
544 * Fix schema path of all nodes which were defined by this usesNode.
548 public static void fixUsesNodesPath(UsesNodeBuilder usesNode) {
549 DataNodeContainerBuilder parent = usesNode.getParent();
550 ModuleBuilder module = ParserUtils.getParentModule(parent);
551 URI ns = module.getNamespace();
552 Date rev = module.getRevision();
553 String prefix = module.getPrefix();
555 SchemaPath parentPath = parent.getPath();
556 if(parent instanceof AugmentationSchemaBuilder) {
557 parentPath = ((AugmentationSchemaBuilder)parent).getTargetPath();
561 Set<DataSchemaNodeBuilder> currentChildNodes = parent.getChildNodeBuilders();
562 for (DataSchemaNodeBuilder child : currentChildNodes) {
563 if (child instanceof GroupingMember) {
564 GroupingMember gm = (GroupingMember) child;
565 if (gm.isAddedByUses()) {
566 if(usesNode.isAugmenting()) {
567 AugmentationSchemaBuilder parentAugment = usesNode.getParentAugment();
568 ModuleBuilder m = ParserUtils.getParentModule(parentAugment);
569 correctNodePathForUsesNodes(child, parentPath, m);
571 child.setQName(new QName(ns, rev, prefix, child.getQName().getLocalName()));
572 correctNodePathForUsesNodes(child, parentPath, module);
579 Set<GroupingBuilder> currentGroupings = parent.getGroupingBuilders();
580 for (GroupingBuilder grouping : currentGroupings) {
581 if (grouping.isAddedByUses()) {
582 grouping.setQName(new QName(ns, rev, prefix, grouping.getQName().getLocalName()));
583 correctNodePathForUsesNodes(grouping, parentPath, module);
589 Set<TypeDefinitionBuilder> currentTypedefs = parent.getTypeDefinitionBuilders();
590 for (TypeDefinitionBuilder typedef : currentTypedefs) {
591 if (typedef.isAddedByUses()) {
592 typedef.setQName(new QName(ns, rev, prefix, typedef.getQName().getLocalName()));
593 correctNodePathForUsesNodes(typedef, parentPath, module);
599 List<UnknownSchemaNodeBuilder> currentUN = parent.getUnknownNodeBuilders();
600 for (UnknownSchemaNodeBuilder un : currentUN) {
601 if (un.isAddedByUses()) {
602 un.setQName(new QName(ns, rev, prefix, un.getQName().getLocalName()));
603 correctNodePathForUsesNodes(un, parentPath, module);
609 * Correct schema path of nodes added by uses statement.
612 * node added by uses statement
613 * @param parentSchemaPath
614 * schema path of parent node
615 * @param parentModule
616 * current parent node module
618 private static void correctNodePathForUsesNodes(final SchemaNodeBuilder node, final SchemaPath parentSchemaPath,
619 final ModuleBuilder parentModule) {
621 List<QName> targetNodePath = new ArrayList<QName>(parentSchemaPath.getPath());
622 targetNodePath.add(new QName(parentModule.getNamespace(), parentModule.getRevision(), parentModule.getPrefix(),
623 node.getQName().getLocalName()));
624 node.setPath(new SchemaPath(targetNodePath, true));
626 // set correct path for all child nodes
627 if (node instanceof DataNodeContainerBuilder) {
628 DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) node;
629 for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) {
630 correctNodePathForUsesNodes(child, node.getPath(), parentModule);
634 // set correct path for all cases
635 if (node instanceof ChoiceBuilder) {
636 ChoiceBuilder choiceBuilder = (ChoiceBuilder) node;
637 for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) {
638 correctNodePathForUsesNodes(choiceCaseBuilder, node.getPath(), parentModule);
644 * Perform refinement of uses target grouping nodes. Uses process has to be
649 public static void performRefine(UsesNodeBuilder usesNode) {
650 for (RefineHolder refine : usesNode.getRefines()) {
651 DataSchemaNodeBuilder nodeToRefine = null;
652 for (DataSchemaNodeBuilder dataNode : usesNode.getParent().getChildNodeBuilders()) {
653 if (refine.getName().equals(dataNode.getQName().getLocalName())) {
654 nodeToRefine = dataNode;
658 if (nodeToRefine == null) {
659 throw new YangParseException(refine.getModuleName(), refine.getLine(), "Refine target node '"
660 + refine.getName() + "' not found");
662 RefineUtils.performRefine(nodeToRefine, refine);
663 usesNode.addRefineNode(nodeToRefine);