From 47f59f9312e328c8182bbe588972de95cb43d68f Mon Sep 17 00:00:00 2001 From: Martin Vitez Date: Thu, 1 Aug 2013 17:11:39 +0200 Subject: [PATCH] Refactored parsing of yang uses statement. Added more tests. Signed-off-by: Martin Vitez --- .../parser/builder/api/UsesNodeBuilder.java | 11 +- .../parser/builder/impl/AnyXmlBuilder.java | 2 +- .../impl/AugmentationSchemaBuilderImpl.java | 6 + .../parser/builder/impl/ChoiceBuilder.java | 2 +- .../builder/impl/ChoiceCaseBuilder.java | 6 + .../builder/impl/ConstraintsBuilder.java | 10 ++ .../impl/ContainerSchemaNodeBuilder.java | 10 +- .../builder/impl/GroupingBuilderImpl.java | 8 + .../impl/LeafListSchemaNodeBuilder.java | 2 +- .../builder/impl/LeafSchemaNodeBuilder.java | 2 +- .../builder/impl/ListSchemaNodeBuilder.java | 10 +- .../parser/builder/impl/ModuleBuilder.java | 8 + .../builder/impl/NotificationBuilder.java | 8 + .../builder/impl/UsesNodeBuilderImpl.java | 41 ++++- .../yang/parser/impl/YangParserImpl.java | 168 +++++++++++------- .../yang/parser/util/ParserUtils.java | 76 +------- .../yang/parser/util/RefineUtils.java | 34 ++-- .../yang/parser/impl/GroupingTest.java | 69 ++++--- .../impl/YangParserWithContextTest.java | 23 +-- .../test/resources/context-test/test2.yang | 7 - .../src/test/resources/model/custom.yang | 1 + .../src/test/resources/model/nodes.yang | 9 +- .../resources/simple-test/cascade-uses.yang | 52 ++++++ 23 files changed, 337 insertions(+), 228 deletions(-) create mode 100644 yang-parser-impl/src/test/resources/simple-test/cascade-uses.yang diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/UsesNodeBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/UsesNodeBuilder.java index 33efa60627..e33e6f2a19 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/UsesNodeBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/UsesNodeBuilder.java @@ -12,6 +12,7 @@ import java.util.Set; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.UsesNode; +import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.util.RefineHolder; /** @@ -41,8 +42,16 @@ public interface UsesNodeBuilder extends GroupingMember, Builder { void addRefine(RefineHolder refine); - void addRefineNode(SchemaNodeBuilder refineNode); + void addRefineNode(DataSchemaNodeBuilder refineNode); UsesNode build(); + Set getTargetChildren(); + + Set getTargetGroupings(); + + Set getTargetTypedefs(); + + List getTargetUnknownNodes(); + } diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AnyXmlBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AnyXmlBuilder.java index 248e094926..fc6d6762bf 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AnyXmlBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AnyXmlBuilder.java @@ -42,7 +42,7 @@ public final class AnyXmlBuilder extends AbstractSchemaNodeBuilder implements Da super(builder.getModuleName(), builder.getLine(), builder.getQName()); parent = builder.getParent(); instance = new AnyXmlSchemaNodeImpl(qname); - constraints = builder.getConstraints(); + constraints = new ConstraintsBuilder(builder.getConstraints()); schemaPath = builder.getPath(); unknownNodes = builder.unknownNodes; addedUnknownNodes.addAll(builder.getUnknownNodes()); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java index a7a9d2b466..ef7b28b6fd 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java @@ -93,6 +93,12 @@ public final class AugmentationSchemaBuilderImpl extends AbstractDataNodeContain @Override public AugmentationSchema build() { if (!built) { + // process uses + for(UsesNodeBuilder use : usesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + instance.setDescription(description); instance.setReference(reference); instance.setStatus(status); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceBuilder.java index 0677d1f3c1..cba4a94e27 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceBuilder.java @@ -57,7 +57,7 @@ public final class ChoiceBuilder extends AbstractSchemaNodeBuilder implements Da super(b.getModuleName(), b.getLine(), b.getQName()); parent = b.getParent(); instance = new ChoiceNodeImpl(qname); - constraints = b.getConstraints(); + constraints = new ConstraintsBuilder(b.getConstraints()); schemaPath = b.getPath(); description = b.getDescription(); reference = b.getReference(); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceCaseBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceCaseBuilder.java index d702fa236e..272e2bbc57 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceCaseBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ChoiceCaseBuilder.java @@ -54,6 +54,12 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im @Override public ChoiceCaseNode build() { if (!isBuilt) { + // process uses + for(UsesNodeBuilder use : addedUsesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + instance.setConstraints(constraints.build()); instance.setPath(schemaPath); instance.setDescription(description); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ConstraintsBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ConstraintsBuilder.java index 2174c895d9..8976f07bc4 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ConstraintsBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ConstraintsBuilder.java @@ -33,6 +33,16 @@ public final class ConstraintsBuilder extends AbstractBuilder { mustDefinitions = new HashSet(); } + ConstraintsBuilder(final ConstraintsBuilder b) { + super(b.getModuleName(), b.getLine()); + instance = new ConstraintDefinitionImpl(); + mustDefinitions = new HashSet(b.getMustDefinitions()); + whenCondition = b.getWhenCondition(); + mandatory = b.isMandatory(); + min = b.getMinElements(); + max = b.getMaxElements(); + } + @Override public ConstraintDefinition build() { RevisionAwareXPath whenStmt; diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java index d074b374b4..a854003000 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java @@ -75,7 +75,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB public ContainerSchemaNodeBuilder(final ContainerSchemaNodeBuilder b) { super(b.getModuleName(), b.getLine(), b.getQName()); instance = new ContainerSchemaNodeImpl(b.getQName()); - constraints = b.getConstraints(); + constraints = new ConstraintsBuilder(b.getConstraints()); schemaPath = b.getPath(); description = b.getDescription(); reference = b.getReference(); @@ -101,6 +101,14 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB @Override public ContainerSchemaNode build() { if (!isBuilt) { + // process uses + for(UsesNodeBuilder use : addedUsesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedGroupings.addAll(use.getTargetGroupings()); + addedTypedefs.addAll(use.getTargetTypedefs()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + instance.setPath(schemaPath); instance.setDescription(description); instance.setReference(reference); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingBuilderImpl.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingBuilderImpl.java index b7d712ad9f..90d61c361a 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingBuilderImpl.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/GroupingBuilderImpl.java @@ -72,6 +72,14 @@ public final class GroupingBuilderImpl extends AbstractDataNodeContainerBuilder @Override public GroupingDefinition build() { if (!isBuilt) { + // process uses + for(UsesNodeBuilder use : addedUsesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedGroupings.addAll(use.getTargetGroupings()); + addedTypedefs.addAll(use.getTargetTypedefs()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + instance.setPath(schemaPath); instance.setDescription(description); instance.setReference(reference); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java index 0cc0e89d3d..0c9153404a 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java @@ -55,7 +55,7 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder im type = b.getType(); typedef = b.getTypedef(); - constraints = b.getConstraints(); + constraints = new ConstraintsBuilder(b.getConstraints()); schemaPath = b.getPath(); description = b.getDescription(); reference = b.getReference(); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafSchemaNodeBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafSchemaNodeBuilder.java index e832d72bbf..05327e0e6a 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafSchemaNodeBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/LeafSchemaNodeBuilder.java @@ -51,7 +51,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implem public LeafSchemaNodeBuilder(final LeafSchemaNodeBuilder b) { super(b.getModuleName(), b.getLine(), b.getQName()); instance = new LeafSchemaNodeImpl(qname); - constraints = b.getConstraints(); + constraints = new ConstraintsBuilder(b.getConstraints()); schemaPath = b.getPath(); type = b.getType(); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ListSchemaNodeBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ListSchemaNodeBuilder.java index f5c21219af..36016a3004 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ListSchemaNodeBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ListSchemaNodeBuilder.java @@ -74,7 +74,7 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde public ListSchemaNodeBuilder(final ListSchemaNodeBuilder b) { super(b.getModuleName(), b.getLine(), b.getQName()); instance = new ListSchemaNodeImpl(b.getQName()); - constraints = b.getConstraints(); + constraints = new ConstraintsBuilder(b.getConstraints()); schemaPath = b.getPath(); description = b.getDescription(); reference = b.getReference(); @@ -101,6 +101,14 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde @Override public ListSchemaNode build() { if (!isBuilt) { + // process uses + for(UsesNodeBuilder use : addedUsesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedGroupings.addAll(use.getTargetGroupings()); + addedTypedefs.addAll(use.getTargetTypedefs()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + instance.setKeyDefinition(keyDefinition); instance.setPath(schemaPath); instance.setDescription(description); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java index d934437a51..a820f65f03 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleBuilder.java @@ -98,6 +98,14 @@ public class ModuleBuilder extends AbstractDataNodeContainerBuilder { instance.setImports(imports); instance.setNamespace(namespace); + // process uses + for(UsesNodeBuilder use : addedUsesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedGroupings.addAll(use.getTargetGroupings()); + addedTypedefs.addAll(use.getTargetTypedefs()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + // TYPEDEFS final Set> typedefs = new TreeSet>(Comparators.SCHEMA_NODE_COMP); for (TypeDefinitionBuilder tdb : addedTypedefs) { diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/NotificationBuilder.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/NotificationBuilder.java index 41856413a6..16eeacab9b 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/NotificationBuilder.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/NotificationBuilder.java @@ -57,6 +57,14 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder @Override public NotificationDefinition build() { if (!isBuilt) { + // process uses + for(UsesNodeBuilder use : addedUsesNodes) { + addedChildNodes.addAll(use.getTargetChildren()); + addedGroupings.addAll(use.getTargetGroupings()); + addedTypedefs.addAll(use.getTargetTypedefs()); + addedUnknownNodes.addAll(use.getTargetUnknownNodes()); + } + instance.setPath(schemaPath); instance.setDescription(description); instance.setReference(reference); diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/UsesNodeBuilderImpl.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/UsesNodeBuilderImpl.java index 404c01910b..ce7ef8737a 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/UsesNodeBuilderImpl.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/UsesNodeBuilderImpl.java @@ -24,7 +24,10 @@ import org.opendaylight.yangtools.yang.parser.builder.api.AbstractBuilder; 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.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.util.RefineHolder; import org.opendaylight.yangtools.yang.parser.util.YangParseException; @@ -41,6 +44,11 @@ public final class UsesNodeBuilderImpl extends AbstractBuilder implements UsesNo private final List refineBuilders = new ArrayList(); private final List refines = new ArrayList(); + private final Set targetChildren = new HashSet<>(); + private final Set targetGroupings = new HashSet<>(); + private final Set targetTypedefs = new HashSet<>(); + private final List targetUnknownNodes = new ArrayList<>(); + public UsesNodeBuilderImpl(final String moduleName, final int line, final String groupingName) { super(moduleName, line); this.groupingName = groupingName; @@ -156,8 +164,19 @@ public final class UsesNodeBuilderImpl extends AbstractBuilder implements UsesNo } @Override - public void addRefineNode(SchemaNodeBuilder refineNode) { + public void addRefineNode(DataSchemaNodeBuilder refineNode) { + // add to refine nodes refineBuilders.add(refineNode); + // replace in target children + DataSchemaNodeBuilder toRemove = null; + for(DataSchemaNodeBuilder child : targetChildren) { + if(child.getQName().equals(refineNode.getQName())) { + toRemove = child; + break; + } + } + targetChildren.remove(toRemove); + targetChildren.add(refineNode); } @Override @@ -170,6 +189,26 @@ public final class UsesNodeBuilderImpl extends AbstractBuilder implements UsesNo refines.add(refine); } + @Override + public Set getTargetChildren() { + return targetChildren; + } + + @Override + public Set getTargetGroupings() { + return targetGroupings; + } + + @Override + public Set getTargetTypedefs() { + return targetTypedefs; + } + + @Override + public List getTargetUnknownNodes() { + return targetUnknownNodes; + } + @Override public int hashCode() { final int prime = 31; diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java index cb927bcf09..93dcadf167 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java @@ -53,7 +53,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode; 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.api.UsesNode; import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser; import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.model.util.IdentityrefType; @@ -83,8 +82,6 @@ import org.opendaylight.yangtools.yang.parser.builder.impl.RpcDefinitionBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl; import org.opendaylight.yangtools.yang.parser.builder.impl.UnionTypeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.UsesNodeBuilderImpl; -import org.opendaylight.yangtools.yang.parser.builder.impl.UsesNodeBuilderImpl.UsesNodeImpl; import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort; import org.opendaylight.yangtools.yang.parser.util.RefineHolder; import org.opendaylight.yangtools.yang.parser.util.RefineUtils; @@ -360,7 +357,7 @@ public final class YangParserImpl implements YangModelParser { private void fixUnresolvedNodes(final Map> modules, final ModuleBuilder builder) { resolveDirtyNodes(modules, builder); resolveIdentities(modules, builder); - resolveUsesRefine(modules, builder); + resolveUsesNodes(modules, builder); resolveUnknownNodes(modules, builder); } @@ -368,7 +365,7 @@ public final class YangParserImpl implements YangModelParser { final ModuleBuilder builder, final SchemaContext context) { resolveDirtyNodesWithContext(modules, builder, context); resolveIdentitiesWithContext(modules, builder, context); - resolveUsesRefineWithContext(modules, builder, context); + resolveUsesNodesWithContext(modules, builder, context); resolveUnknownNodesWithContext(modules, builder, context); } @@ -876,25 +873,37 @@ public final class YangParserImpl implements YangModelParser { * @param module * module being resolved */ - private void resolveUsesRefine(final Map> modules, final ModuleBuilder module) { + private void resolveUsesNodes(final Map> modules, final ModuleBuilder module) { final List allModuleUses = module.getAllUsesNodes(); for (UsesNodeBuilder usesNode : allModuleUses) { - // refine + // perform uses final int line = usesNode.getLine(); final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module); usesNode.setGroupingPath(targetGrouping.getPath()); + processUsesNode(module, usesNode, targetGrouping); + // refine for (RefineHolder refine : usesNode.getRefines()) { - final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(targetGrouping, - refine, module.getName()); + DataSchemaNodeBuilder nodeToRefine = null; + for (DataSchemaNodeBuilder dsnb : usesNode.getTargetChildren()) { + if (refine.getName().equals(dsnb.getQName().getLocalName())) { + nodeToRefine = dsnb; + break; + } + } + if (nodeToRefine == null) { + throw new YangParseException(refine.getModuleName(), refine.getLine(), "Refine target node '" + + refine.getName() + "' not found"); + } if (nodeToRefine instanceof GroupingMember) { ((GroupingMember) nodeToRefine).setAddedByUses(true); } RefineUtils.performRefine(nodeToRefine, refine, line); usesNode.addRefineNode(nodeToRefine); } - - // child nodes - processUsesNode(module, usesNode, targetGrouping); + } + for (UsesNodeBuilder usesNode : allModuleUses) { + final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module); + processUsesTarget(module, usesNode, targetGrouping); } } @@ -910,7 +919,7 @@ public final class YangParserImpl implements YangModelParser { * @param context * SchemaContext containing already resolved modules */ - private void resolveUsesRefineWithContext(final Map> modules, + private void resolveUsesNodesWithContext(final Map> modules, final ModuleBuilder module, final SchemaContext context) { final List moduleUses = module.getAllUsesNodes(); for (UsesNodeBuilder usesNode : moduleUses) { @@ -920,30 +929,46 @@ public final class YangParserImpl implements YangModelParser { if (targetGroupingBuilder == null) { final GroupingDefinition targetGrouping = getTargetGroupingFromContext(usesNode, module, context); usesNode.setGroupingPath(targetGrouping.getPath()); + processUsesNode(usesNode, targetGrouping); for (RefineHolder refine : usesNode.getRefines()) { - final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition( - targetGrouping, refine); + DataSchemaNodeBuilder nodeToRefine = null; + for (DataSchemaNodeBuilder dsnb : usesNode.getTargetChildren()) { + if (refine.getName().equals(dsnb.getQName().getLocalName())) { + nodeToRefine = dsnb; + break; + } + } + if (nodeToRefine == null) { + throw new YangParseException(refine.getModuleName(), refine.getLine(), "Refine target node '" + + refine.getName() + "' not found"); + } if (nodeToRefine instanceof GroupingMember) { ((GroupingMember) nodeToRefine).setAddedByUses(true); } RefineUtils.performRefine(nodeToRefine, refine, line); usesNode.addRefineNode(nodeToRefine); } - - processUsesNode(usesNode, targetGrouping); } else { usesNode.setGroupingPath(targetGroupingBuilder.getPath()); + processUsesNode(module, usesNode, targetGroupingBuilder); for (RefineHolder refine : usesNode.getRefines()) { - final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder( - targetGroupingBuilder, refine, module.getName()); + DataSchemaNodeBuilder nodeToRefine = null; + for (DataSchemaNodeBuilder dsnb : usesNode.getTargetChildren()) { + if (refine.getName().equals(dsnb.getQName().getLocalName())) { + nodeToRefine = dsnb; + break; + } + } + if (nodeToRefine == null) { + throw new YangParseException(refine.getModuleName(), refine.getLine(), "Refine target node '" + + refine.getName() + "' not found"); + } if (nodeToRefine instanceof GroupingMember) { ((GroupingMember) nodeToRefine).setAddedByUses(true); } RefineUtils.performRefine(nodeToRefine, refine, line); usesNode.addRefineNode(nodeToRefine); } - - processUsesNode(module, usesNode, targetGroupingBuilder); } } } @@ -1054,15 +1079,15 @@ public final class YangParserImpl implements YangModelParser { } /** - * Add nodes defined in target grouping to current context. Refinement has - * to be already performed. + * Add nodes defined in target grouping to current context. * - * @param module current module + * @param module + * current module * @param usesNode * @param targetGrouping */ - private void processUsesNode(final ModuleBuilder module, final UsesNodeBuilder usesNode, final GroupingBuilder targetGrouping) { - List refineNodes = usesNode.getRefineNodes(); + private void processUsesNode(final ModuleBuilder module, final UsesNodeBuilder usesNode, + final GroupingBuilder targetGrouping) { DataNodeContainerBuilder parent = usesNode.getParent(); URI namespace = null; Date revision = null; @@ -1078,17 +1103,10 @@ public final class YangParserImpl implements YangModelParser { prefix = parentQName.getPrefix(); } SchemaPath parentPath = parent.getPath(); + + Set newChildren = new HashSet<>(); for (DataSchemaNodeBuilder child : targetGrouping.getChildNodeBuilders()) { if (child != null) { - // if node is refined, take it from refined nodes and continue - SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes); - if (refined != null) { - refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName(), namespace, - revision, prefix)); - parent.addChildNode((DataSchemaNodeBuilder) refined); - continue; - } - DataSchemaNodeBuilder newChild = null; if (child instanceof AnyXmlBuilder) { newChild = new AnyXmlBuilder((AnyXmlBuilder) child); @@ -1115,40 +1133,61 @@ public final class YangParserImpl implements YangModelParser { newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision, prefix)); - parent.addChildNode(newChild); + newChildren.add(newChild); } } + usesNode.getTargetChildren().addAll(newChildren); + + Set newGroupings = new HashSet<>(); for (GroupingBuilder g : targetGrouping.getGroupingBuilders()) { GroupingBuilder newGrouping = new GroupingBuilderImpl(g); newGrouping.setAddedByUses(true); newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace, revision, prefix)); - parent.addGrouping(newGrouping); + newGroupings.add(newGrouping); } + usesNode.getTargetGroupings().addAll(newGroupings); + + Set newTypedefs = new HashSet<>(); for (TypeDefinitionBuilder td : targetGrouping.getTypeDefinitionBuilders()) { TypeDefinitionBuilder newType = new TypeDefinitionBuilderImpl(td); newType.setAddedByUses(true); newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix)); - parent.addTypedef(newType); - } - for (UsesNodeBuilder un : targetGrouping.getUses()) { - UsesNodeBuilder newUses = new UsesNodeBuilderImpl(un); - newUses.setAddedByUses(true); - // uses has not path - parent.addUsesNode(newUses); + newTypedefs.add(newType); } + usesNode.getTargetTypedefs().addAll(newTypedefs); + + List newUnknownNodes = new ArrayList<>(); for (UnknownSchemaNodeBuilder un : targetGrouping.getUnknownNodeBuilders()) { UnknownSchemaNodeBuilder newUn = new UnknownSchemaNodeBuilder(un); newUn.setAddedByUses(true); newUn.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix)); - parent.addUnknownNodeBuilder(newUn); + newUnknownNodes.add(newUn); + } + usesNode.getTargetUnknownNodes().addAll(newUnknownNodes); + } + + /** + * Check if target grouping contains uses nodes and if it does, merge + * current uses with them. + * + * @param module + * @param usesNode + * @param targetGrouping + */ + private void processUsesTarget(final ModuleBuilder module, final UsesNodeBuilder usesNode, + final GroupingBuilder targetGrouping) { + for (UsesNodeBuilder unb : targetGrouping.getUses()) { + usesNode.getTargetChildren().addAll(unb.getTargetChildren()); + usesNode.getTargetGroupings().addAll(unb.getTargetGroupings()); + usesNode.getTargetTypedefs().addAll(unb.getTargetTypedefs()); + usesNode.getTargetUnknownNodes().addAll(unb.getTargetUnknownNodes()); } } private void processUsesNode(final UsesNodeBuilder usesNode, final GroupingDefinition targetGrouping) { final String moduleName = usesNode.getModuleName(); final int line = usesNode.getLine(); - List refineNodes = usesNode.getRefineNodes(); DataNodeContainerBuilder parent = usesNode.getParent(); URI namespace = null; Date revision = null; @@ -1165,17 +1204,10 @@ public final class YangParserImpl implements YangModelParser { prefix = parentQName.getPrefix(); } SchemaPath parentPath = parent.getPath(); + + final Set newChildren = new HashSet<>(); for (DataSchemaNode child : targetGrouping.getChildNodes()) { if (child != null) { - // if node is refined, take it from refined nodes and continue - SchemaNodeBuilder refined = getRefined(child.getQName(), refineNodes); - if (refined != null) { - refined.setPath(createSchemaPath(parentPath, refined.getQName().getLocalName(), namespace, - revision, prefix)); - parent.addChildNode((DataSchemaNodeBuilder) refined); - continue; - } - DataSchemaNodeBuilder newChild = null; if (child instanceof AnyXmlSchemaNode) { newChild = createAnyXml((AnyXmlSchemaNode) child, moduleName, line); @@ -1201,36 +1233,38 @@ public final class YangParserImpl implements YangModelParser { } newChild.setPath(createSchemaPath(parentPath, newChild.getQName().getLocalName(), namespace, revision, prefix)); - parent.addChildNode(newChild); + newChildren.add(newChild); } } + usesNode.getTargetChildren().addAll(newChildren); + + final Set newGroupings = new HashSet<>(); for (GroupingDefinition g : targetGrouping.getGroupings()) { GroupingBuilder newGrouping = createGrouping(g, moduleName, line); newGrouping.setAddedByUses(true); newGrouping.setPath(createSchemaPath(parentPath, newGrouping.getQName().getLocalName(), namespace, revision, prefix)); - parent.addGrouping(newGrouping); + newGroupings.add(newGrouping); } + usesNode.getTargetGroupings().addAll(newGroupings); + + final Set newTypedefs = new HashSet<>(); for (TypeDefinition td : targetGrouping.getTypeDefinitions()) { TypeDefinitionBuilder newType = createTypedef((ExtendedType) td, moduleName, line); newType.setAddedByUses(true); newType.setPath(createSchemaPath(parentPath, newType.getQName().getLocalName(), namespace, revision, prefix)); - parent.addTypedef(newType); - } - for (UsesNode un : targetGrouping.getUses()) { - if (un instanceof UsesNodeImpl) { - UsesNodeBuilder newUses = new UsesNodeBuilderImpl(((UsesNodeImpl) un).toBuilder()); - newUses.setAddedByUses(true); - // uses has not path - parent.addUsesNode(newUses); - } + newTypedefs.add(newType); } + usesNode.getTargetTypedefs().addAll(newTypedefs); + + final List newUnknownNodes = new ArrayList<>(); for (UnknownSchemaNode un : targetGrouping.getUnknownSchemaNodes()) { UnknownSchemaNodeBuilder newNode = createUnknownSchemaNode(un, moduleName, line); newNode.setAddedByUses(true); newNode.setPath(createSchemaPath(parentPath, un.getQName().getLocalName(), namespace, revision, prefix)); - parent.addUnknownNodeBuilder(newNode); + newUnknownNodes.add(newNode); } + usesNode.getTargetUnknownNodes().addAll(newUnknownNodes); } private QName findFullQName(final Map> modules, final ModuleBuilder module, diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java index 5933e96673..59f729874c 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserUtils.java @@ -115,9 +115,7 @@ public final class ParserUtils { /** * Create new SchemaPath from given path and name. * - * Append new qname to schema path created from name argument. New QName - * gets namespace, revision and prefix same as last qname in current schema - * path. + * Append new qname to schema path created from name argument. * * @param schemaPath * @param name @@ -342,13 +340,13 @@ public final class ParserUtils { } /** - * Check if node is present in refine nodes. + * Get node from collection of refined nodes based on qname. * * @param nodeQName * qname of node * @param refineNodes * collections of refined nodes - * @return true, if node with given qname was found, false otherwise + * @return node with given qname if present, null otherwise */ public static SchemaNodeBuilder getRefined(QName nodeQName, List refineNodes) { for (SchemaNodeBuilder rn : refineNodes) { @@ -379,74 +377,6 @@ public final class ParserUtils { } } - /** - * Find node in grouping by name. - * - * @param grouping - * grouping to search - * @param refineNodeName - * name of node - * @return builder of node with given name if present in grouping, null - * otherwise - */ - public static Builder findRefineTargetBuilder(final GroupingBuilder grouping, final String refineNodeName) { - // search child nodes - Builder result = grouping.getDataChildByName(refineNodeName); - // search groupings - if (result == null) { - Set grps = grouping.getGroupingBuilders(); - for (GroupingBuilder gr : grps) { - if (gr.getQName().getLocalName().equals(refineNodeName)) { - result = gr; - break; - } - } - } - // search typedefs - if (result == null) { - Set typedefs = grouping.getTypeDefinitionBuilders(); - for (TypeDefinitionBuilder typedef : typedefs) { - if (typedef.getQName().getLocalName().equals(refineNodeName)) { - result = typedef; - break; - } - } - } - return result; - } - - /** - * Find node in grouping by name. - * - * @param builder - * grouping to search - * @param refineNodeName - * name of node - * @return node with given name if present in grouping, null otherwise - */ - public static Object findRefineTargetNode(final GroupingDefinition builder, final String refineNodeName) { - Object result = builder.getDataChildByName(refineNodeName); - if (result == null) { - Set grps = builder.getGroupings(); - for (GroupingDefinition gr : grps) { - if (gr.getQName().getLocalName().equals(refineNodeName)) { - result = gr; - break; - } - } - } - if (result == null) { - Set> typedefs = builder.getTypeDefinitions(); - for (TypeDefinition typedef : typedefs) { - if (typedef.getQName().getLocalName().equals(refineNodeName)) { - result = typedef; - break; - } - } - } - return result; - } - /** * Add all augment's child nodes to given target. * diff --git a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/RefineUtils.java b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/RefineUtils.java index 87aa68215a..639a7ccce5 100644 --- a/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/RefineUtils.java +++ b/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/RefineUtils.java @@ -20,9 +20,8 @@ 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.MustDefinition; -import org.opendaylight.yangtools.yang.model.api.TypeDefinition; -import org.opendaylight.yangtools.yang.model.util.ExtendedType; import org.opendaylight.yangtools.yang.parser.builder.api.Builder; +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.SchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder; @@ -30,11 +29,9 @@ import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.AnyXmlBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.ChoiceBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.ContainerSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.GroupingBuilderImpl; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafListSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.opendaylight.yangtools.yang.parser.builder.impl.ListSchemaNodeBuilder; -import org.opendaylight.yangtools.yang.parser.builder.impl.TypeDefinitionBuilderImpl; import org.opendaylight.yangtools.yang.parser.builder.impl.UnknownSchemaNodeBuilder; /** @@ -62,10 +59,14 @@ public class RefineUtils { * current module name * @return */ - public static SchemaNodeBuilder getRefineNodeFromGroupingBuilder(final GroupingBuilder targetGrouping, + public static DataSchemaNodeBuilder getRefineNodeFromGroupingBuilder(final GroupingBuilder targetGrouping, final RefineHolder refine, final String moduleName) { - Builder result = null; - final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine.getName()); + DataSchemaNodeBuilder result = null; + final Builder lookedUpBuilder = targetGrouping.getDataChildByName(refine.getName()); + if (lookedUpBuilder == null) { + throw new YangParseException(moduleName, refine.getLine(), "Target node '" + refine.getName() + + "' not found"); + } if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) { result = new LeafSchemaNodeBuilder((LeafSchemaNodeBuilder) lookedUpBuilder); } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) { @@ -78,15 +79,11 @@ public class RefineUtils { result = new ChoiceBuilder((ChoiceBuilder) lookedUpBuilder); } else if (lookedUpBuilder instanceof AnyXmlBuilder) { result = new AnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof GroupingBuilder) { - result = new GroupingBuilderImpl((GroupingBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) { - result = new TypeDefinitionBuilderImpl((TypeDefinitionBuilder) lookedUpBuilder); } else { throw new YangParseException(moduleName, refine.getLine(), "Target '" + refine.getName() + "' can not be refined"); } - return (SchemaNodeBuilder) result; + return result; } /** @@ -98,12 +95,15 @@ public class RefineUtils { * refine object containing informations about refine * @return */ - public static SchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping, + public static DataSchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping, final RefineHolder refine) { final String moduleName = refine.getModuleName(); final int line = refine.getLine(); - SchemaNodeBuilder result = null; - final Object lookedUpNode = findRefineTargetNode(grouping, refine.getName()); + DataSchemaNodeBuilder result = null; + final Object lookedUpNode = grouping.getDataChildByName(refine.getName()); + if (lookedUpNode == null) { + throw new YangParseException(moduleName, line, "Refine target node '" + refine.getName() + "' not found"); + } if (lookedUpNode instanceof LeafSchemaNode) { result = createLeafBuilder((LeafSchemaNode) lookedUpNode, moduleName, line); } else if (lookedUpNode instanceof ContainerSchemaNode) { @@ -116,10 +116,6 @@ public class RefineUtils { result = createChoice((ChoiceNode) lookedUpNode, moduleName, line); } else if (lookedUpNode instanceof AnyXmlSchemaNode) { result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, moduleName, line); - } else if (lookedUpNode instanceof GroupingDefinition) { - result = createGrouping((GroupingDefinition) lookedUpNode, moduleName, line); - } else if (lookedUpNode instanceof TypeDefinition) { - result = createTypedef((ExtendedType) lookedUpNode, moduleName, line); } else { throw new YangParseException(moduleName, line, "Target '" + refine.getName() + "' can not be refined"); } diff --git a/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java b/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java index effc312cfc..c1f4de493d 100644 --- a/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java +++ b/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/GroupingTest.java @@ -28,10 +28,8 @@ import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaNode; 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.api.UsesNode; -import org.opendaylight.yangtools.yang.model.util.ExtendedType; public class GroupingTest { private Set modules; @@ -52,13 +50,11 @@ public class GroupingTest { assertEquals(1, usesNodes.size()); UsesNode usesNode = usesNodes.iterator().next(); Map refines = usesNode.getRefines(); - assertEquals(5, refines.size()); + assertEquals(3, refines.size()); LeafSchemaNode refineLeaf = null; ContainerSchemaNode refineContainer = null; ListSchemaNode refineList = null; - GroupingDefinition refineGrouping = null; - TypeDefinition typedef = null; for (Map.Entry entry : refines.entrySet()) { SchemaNode value = entry.getValue(); if (value instanceof LeafSchemaNode) { @@ -67,10 +63,6 @@ public class GroupingTest { 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; } } @@ -80,7 +72,7 @@ public class GroupingTest { assertEquals("IP address of target node", refineLeaf.getDescription()); assertEquals("address reference added by refine", refineLeaf.getReference()); assertFalse(refineLeaf.isConfiguration()); - assertTrue(refineLeaf.getConstraints().isMandatory()); + assertFalse(refineLeaf.getConstraints().isMandatory()); Set leafMustConstraints = refineLeaf.getConstraints().getMustConstraints(); assertEquals(1, leafMustConstraints.size()); MustDefinition leafMust = leafMustConstraints.iterator().next(); @@ -102,20 +94,6 @@ public class GroupingTest { assertFalse(refineList.isConfiguration()); assertEquals(2, (int) refineList.getConstraints().getMinElements()); assertEquals(12, (int) refineList.getConstraints().getMaxElements()); - - // grouping target-inner - assertNotNull(refineGrouping); - Set 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 @@ -176,6 +154,7 @@ public class GroupingTest { assertEquals("address reference added by refine", address_u.getReference()); assertFalse(address_u.isConfiguration()); assertTrue(address_u.isAddedByUses()); + assertFalse(address_u.getConstraints().isMandatory()); LeafSchemaNode address_g = (LeafSchemaNode) grouping.getDataChildByName("address"); assertNotNull(address_g); @@ -185,6 +164,7 @@ public class GroupingTest { assertNull(address_g.getReference()); assertTrue(address_g.isConfiguration()); assertFalse(address_u.equals(address_g)); + assertTrue(address_g.getConstraints().isMandatory()); ContainerSchemaNode port_u = (ContainerSchemaNode) destination.getDataChildByName("port"); assertNotNull(port_u); @@ -338,4 +318,45 @@ public class GroupingTest { assertEquals("name", leaf.getQName().getLocalName()); } + @Test + public void testCascadeUses() throws FileNotFoundException { + modules = TestUtils.loadModules(getClass().getResource("/simple-test").getPath()); + Module testModule = TestUtils.findModule(modules, "cascade-uses"); + Set groupings = testModule.getGroupings(); + + GroupingDefinition gu = null; + GroupingDefinition gv = null; + GroupingDefinition gx = null; + GroupingDefinition gy = null; + GroupingDefinition gz = null; + GroupingDefinition gzz = null; + for (GroupingDefinition gd : groupings) { + if ("grouping-U".equals(gd.getQName().getLocalName())) + gu = gd; + if ("grouping-V".equals(gd.getQName().getLocalName())) + gv = gd; + if ("grouping-X".equals(gd.getQName().getLocalName())) + gx = gd; + if ("grouping-Y".equals(gd.getQName().getLocalName())) + gy = gd; + if ("grouping-Z".equals(gd.getQName().getLocalName())) + gz = gd; + if ("grouping-ZZ".equals(gd.getQName().getLocalName())) + gzz = gd; + } + assertNotNull(gu); + assertNotNull(gv); + assertNotNull(gx); + assertNotNull(gy); + assertNotNull(gz); + assertNotNull(gzz); + + assertEquals(6, gu.getChildNodes().size()); + assertEquals(3, gv.getChildNodes().size()); + assertEquals(2, gx.getChildNodes().size()); + assertEquals(1, gy.getChildNodes().size()); + assertEquals(1, gz.getChildNodes().size()); + assertEquals(1, gzz.getChildNodes().size()); + } + } diff --git a/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserWithContextTest.java b/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserWithContextTest.java index cb8f1a13e3..0941438f84 100644 --- a/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserWithContextTest.java +++ b/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/impl/YangParserWithContextTest.java @@ -37,7 +37,6 @@ import org.opendaylight.yangtools.yang.model.api.MustDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaNode; 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.api.UsesNode; import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint; @@ -221,13 +220,11 @@ public class YangParserWithContextTest { // test refine Map refines = usesNode.getRefines(); - assertEquals(5, refines.size()); + assertEquals(3, refines.size()); LeafSchemaNode refineLeaf = null; ContainerSchemaNode refineContainer = null; ListSchemaNode refineList = null; - GroupingDefinition refineGrouping = null; - TypeDefinition typedef = null; for (Map.Entry entry : refines.entrySet()) { SchemaNode value = entry.getValue(); if (value instanceof LeafSchemaNode) { @@ -236,10 +233,6 @@ public class YangParserWithContextTest { 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; } } @@ -271,20 +264,6 @@ public class YangParserWithContextTest { assertFalse(refineList.isConfiguration()); assertEquals(2, (int) refineList.getConstraints().getMinElements()); assertEquals(12, (int) refineList.getConstraints().getMaxElements()); - - // grouping target-inner - assertNotNull(refineGrouping); - Set 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 diff --git a/yang-parser-impl/src/test/resources/context-test/test2.yang b/yang-parser-impl/src/test/resources/context-test/test2.yang index 4cff19259e..588d066fad 100644 --- a/yang-parser-impl/src/test/resources/context-test/test2.yang +++ b/yang-parser-impl/src/test/resources/context-test/test2.yang @@ -40,13 +40,6 @@ module test2 { 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"; - } } } } diff --git a/yang-parser-impl/src/test/resources/model/custom.yang b/yang-parser-impl/src/test/resources/model/custom.yang index d8d6054b59..0444b5c848 100644 --- a/yang-parser-impl/src/test/resources/model/custom.yang +++ b/yang-parser-impl/src/test/resources/model/custom.yang @@ -179,6 +179,7 @@ module custom { leaf address { type string; description "Target IP address"; + mandatory true; } container port { description "Target port container"; diff --git a/yang-parser-impl/src/test/resources/model/nodes.yang b/yang-parser-impl/src/test/resources/model/nodes.yang index 2cde38598b..4d4dde4ea5 100644 --- a/yang-parser-impl/src/test/resources/model/nodes.yang +++ b/yang-parser-impl/src/test/resources/model/nodes.yang @@ -168,7 +168,7 @@ module nodes { description "IP address of target node"; reference "address reference added by refine"; config false; - mandatory true; + mandatory false; must "ifType != 'ethernet' or " + "(ifType = 'ethernet' and ifMTU = 1500)" { error-message "An ethernet MTU must be 1500"; @@ -187,13 +187,6 @@ module nodes { 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"; - } } } } diff --git a/yang-parser-impl/src/test/resources/simple-test/cascade-uses.yang b/yang-parser-impl/src/test/resources/simple-test/cascade-uses.yang new file mode 100644 index 0000000000..4dd8d1765b --- /dev/null +++ b/yang-parser-impl/src/test/resources/simple-test/cascade-uses.yang @@ -0,0 +1,52 @@ +module cascade-uses { + + namespace "urn:grouping:dependencies"; + prefix "sbd"; + + organization "OPEN DAYLIGHT"; + contact "http://www.opendaylight.org/"; + + revision 2013-07-18 { + } + + grouping grouping-U { + leaf leaf-grouping-U { + type string; + } + uses grouping-V; + uses grouping-X; + } + + grouping grouping-V { + leaf leaf-grouping-V { + type string; + } + uses grouping-Z; + uses grouping-ZZ; + } + + grouping grouping-X { + leaf leaf-grouping-X { + type string; + } + uses grouping-Y; + } + + grouping grouping-Y { + leaf leaf-grouping-Y { + type string; + } + } + + grouping grouping-Z { + leaf leaf-grouping-Z { + type string; + } + } + + grouping grouping-ZZ { + leaf leaf-grouping-ZZ { + type string; + } + } +} \ No newline at end of file -- 2.36.6