From f0b551cfbf794966124da7475935c27c3e7311c0 Mon Sep 17 00:00:00 2001 From: Martin Vitez Date: Mon, 24 Jun 2013 11:48:14 +0200 Subject: [PATCH] Added support for parsing yang models with already resolved context. Added rebuild method to AugmentationTargetBuilder interface to support augmentation of resolved context. Refactored YangParserImpl to improve readability, internal utility methods moved to ParserUtils class. Added test to check parsing with context. Added YangErrorListener to redirect antlr4 error messages from standard error output to logger. Added more javadocs. Change-Id: I838646cc4b3593a03420c1b578ee39c043f89e3d Signed-off-by: Martin Vitez --- .../model/parser/api/YangModelParser.java | 56 +- .../api/AbstractDataNodeContainerBuilder.java | 26 +- .../api/AugmentationTargetBuilder.java | 11 + .../yang/parser/builder/api/Builder.java | 9 + .../builder/api/DataSchemaNodeBuilder.java | 4 + .../parser/builder/api/SchemaNodeBuilder.java | 6 + .../parser/builder/impl/AnyXmlBuilder.java | 19 +- .../parser/builder/impl/ChoiceBuilder.java | 62 +- .../builder/impl/ChoiceCaseBuilder.java | 87 +- .../impl/ContainerSchemaNodeBuilder.java | 92 +- .../parser/builder/impl/ExtensionBuilder.java | 33 +- .../parser/builder/impl/FeatureBuilder.java | 27 +- .../builder/impl/GroupingBuilderImpl.java | 99 +- .../impl/IdentitySchemaNodeBuilder.java | 70 +- .../impl/LeafListSchemaNodeBuilder.java | 28 +- .../builder/impl/LeafSchemaNodeBuilder.java | 20 +- .../builder/impl/ListSchemaNodeBuilder.java | 87 +- .../parser/builder/impl/ModuleBuilder.java | 345 ++-- .../builder/impl/NotificationBuilder.java | 90 +- .../builder/impl/RpcDefinitionBuilder.java | 45 +- .../impl/UnknownSchemaNodeBuilder.java | 38 +- .../yang/parser/impl/SchemaContextImpl.java | 3 +- .../yang/parser/impl/YangErrorListener.java | 25 + .../yang/parser/impl/YangParserImpl.java | 947 ++++++----- .../parser/util/ModuleDependencySort.java | 23 + .../yang/parser/util/ParserUtils.java | 1420 +++++++++++------ .../yang/parser/util/RefineUtils.java | 410 +++++ .../parser/util/YangModelBuilderUtil.java | 5 +- .../yang/parser/impl/TestUtils.java | 20 + .../impl/YangParserWithContextTest.java | 283 ++++ .../resources/context-augment-test/test1.yang | 34 + .../resources/context-augment-test/test2.yang | 41 + .../resources/context-augment-test/test3.yang | 24 + .../resources/context-augment-test/test4.yang | 27 + .../test/resources/context-test/test1.yang | 29 + .../test/resources/context-test/test2.yang | 54 + .../test/resources/context-test/test3.yang | 32 + .../controller/yang/model/api/ChoiceNode.java | 2 +- .../controller/yang/model/api/Module.java | 2 + .../model/api/NotificationDefinition.java | 6 +- .../model/util/AbstractUnsignedInteger.java | 6 +- 41 files changed, 3350 insertions(+), 1297 deletions(-) create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang create mode 100644 opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java index 842bb43d79..142f199af4 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-api/src/main/java/org/opendaylight/controller/yang/model/parser/api/YangModelParser.java @@ -26,7 +26,7 @@ public interface YangModelParser { /** * Parse one or more Yang model files and return the definitions of Yang - * modules defined in *.Yang files;
+ * modules defined in *.yang files;
* This method SHOULD be used if user need to parse multiple yang models * that are referenced either through import or include statements. * @@ -36,6 +36,21 @@ public interface YangModelParser { */ Set parseYangModels(final List yangFiles); + /** + * Parse one or more Yang model files and return the definitions of Yang + * modules defined in *.yang files.
+ * This method SHOULD be used if user has already parsed context and need to + * parse additinal yang models which can have dependencies on models in this + * context. + * + * @param yangFiles + * yang files to parse + * @param context + * SchemaContext containing already parsed yang models + * @return Set of Yang Modules + */ + Set parseYangModels(final List yangFiles, final SchemaContext context); + /** * Equivalent to {@link #parseYangModels(List)} that returns parsed modules * mapped to Files from which they were parsed. @@ -46,11 +61,42 @@ public interface YangModelParser { */ Map parseYangModelsMapped(final List yangFiles); - Set parseYangModelsFromStreams( - final List yangModelStreams); + /** + * Parse one or more Yang model streams and return the definitions of Yang + * modules defined in *.yang files;
+ * This method SHOULD be used if user need to parse multiple yang models + * that are referenced either through import or include statements. + * + * @param yangModelStreams + * yang streams to parse + * @return Set of Yang Modules + */ + Set parseYangModelsFromStreams(final List yangModelStreams); + + /** + * Parse one or more Yang model streams and return the definitions of Yang + * modules defined in *.yang files.
+ * This method SHOULD be used if user has already parsed context and need to + * parse additinal yang models which can have dependencies on models in this + * context. + * + * @param yangModelStreams + * yang streams to parse + * @param context + * SchemaContext containing already parsed yang models + * @return Set of Yang Modules + */ + Set parseYangModelsFromStreams(final List yangModelStreams, final SchemaContext context); - Map parseYangModelsFromStreamsMapped( - final List yangModelStreams); + /** + * Equivalent to {@link #parseYangModels(List)} that returns parsed modules + * mapped to IputStreams from which they were parsed. + * + * @param yangModelStreams + * yang streams to parse + * @return Map of Yang Modules + */ + Map parseYangModelsFromStreamsMapped(final List yangModelStreams); /** * Creates {@link SchemaContext} from specified Modules. The modules SHOULD diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java index c56b40488c..8ca88d8d61 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AbstractDataNodeContainerBuilder.java @@ -11,12 +11,18 @@ import java.util.HashSet; import java.util.Set; import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.model.api.DataSchemaNode; +import org.opendaylight.controller.yang.model.api.GroupingDefinition; public abstract class AbstractDataNodeContainerBuilder implements DataNodeContainerBuilder { private final QName qname; - protected final Set childNodes = new HashSet(); - protected final Set groupings = new HashSet(); + + protected Set childNodes; + protected final Set addedChildNodes = new HashSet(); + + protected Set groupings; + protected final Set addedGroupings = new HashSet(); protected AbstractDataNodeContainerBuilder(QName qname) { this.qname = qname; @@ -29,21 +35,29 @@ public abstract class AbstractDataNodeContainerBuilder implements DataNodeContai @Override public Set getChildNodes() { - return childNodes; + return addedChildNodes; } @Override public void addChildNode(DataSchemaNodeBuilder childNode) { - childNodes.add(childNode); + addedChildNodes.add(childNode); + } + + public void setChildNodes(Set childNodes) { + this.childNodes = childNodes; } public Set getGroupings() { - return groupings; + return addedGroupings; } @Override public void addGrouping(GroupingBuilder grouping) { - groupings.add(grouping); + addedGroupings.add(grouping); + } + + public void setGroupings(final Set groupings) { + this.groupings = groupings; } } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java index add9bac333..639e18c3ad 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/AugmentationTargetBuilder.java @@ -20,4 +20,15 @@ public interface AugmentationTargetBuilder { */ void addAugmentation(AugmentationSchemaBuilder augment); + /** + * Build again already built data node. + * + * In general, when Builder.build is called first time, it creates YANG data + * model node instance. With every other call it just return this instance + * without checking for properties change. This method causes that builder + * object process again all its properties and return an updated instance of + * YANG data node. + */ + void rebuild(); + } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java index 49be55737c..ee50d2ad02 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/Builder.java @@ -12,6 +12,15 @@ package org.opendaylight.controller.yang.parser.builder.api; */ public interface Builder { + /** + * Build YANG data model node. + * + * This method should create an instance of YANG data model node. After + * creating an instance, this instance should be returned for each call + * without repeating build process. + * + * @return YANG data model node + */ Object build(); int getLine(); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java index de0453105f..a831b3d92f 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/DataSchemaNodeBuilder.java @@ -18,8 +18,12 @@ public interface DataSchemaNodeBuilder extends SchemaNodeBuilder { DataSchemaNode build(); + boolean isAugmenting(); + void setAugmenting(boolean augmenting); + boolean isConfiguration(); + void setConfiguration(boolean configuration); ConstraintsBuilder getConstraints(); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java index eb3286e4f6..6e872b3d1f 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/SchemaNodeBuilder.java @@ -24,10 +24,16 @@ public interface SchemaNodeBuilder extends Builder { void setPath(SchemaPath schemaPath); + String getDescription(); + void setDescription(String description); + String getReference(); + void setReference(String reference); + Status getStatus(); + void setStatus(Status status); void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java index d82cbe215e..78284c142e 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java @@ -26,6 +26,8 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder { private SchemaPath path; private final AnyXmlSchemaNodeImpl instance; private final ConstraintsBuilder constraints; + + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); private String description; @@ -53,9 +55,11 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder { instance.setAugmenting(augmenting); // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if(unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); @@ -97,6 +101,10 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder { return addedUnknownNodes; } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + public String getDescription() { return description; } @@ -126,6 +134,11 @@ public final class AnyXmlBuilder implements DataSchemaNodeBuilder { } } + @Override + public boolean isAugmenting() { + return augmenting; + } + @Override public void setAugmenting(final boolean augmenting) { this.augmenting = augmenting; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java index f520bf917a..1ba1a2dfdc 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java @@ -26,7 +26,7 @@ import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBui import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationTargetBuilder { - private boolean built; + private boolean isBuilt; private final ChoiceNodeImpl instance; private final int line; // SchemaNode args @@ -35,6 +35,7 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT private String description; private String reference; private Status status = Status.CURRENT; + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); // DataSchemaNode args private boolean augmenting; @@ -43,7 +44,8 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT // AugmentationTarget args private final Set addedAugmentations = new HashSet(); // ChoiceNode args - private final Set cases = new HashSet(); + private Set cases; + private final Set addedCases = new HashSet(); private String defaultCase; public ChoiceBuilder(final QName qname, final int line) { @@ -55,7 +57,7 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT @Override public ChoiceNode build() { - if (!built) { + if (!isBuilt) { instance.setPath(schemaPath); instance.setDescription(description); instance.setReference(reference); @@ -66,11 +68,13 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT instance.setDefaultCase(defaultCase); // CASES - final Set choiceCases = new HashSet(); - for (ChoiceCaseBuilder caseBuilder : cases) { - choiceCases.add(caseBuilder.build()); + if(cases == null) { + cases = new HashSet(); + for (ChoiceCaseBuilder caseBuilder : addedCases) { + cases.add(caseBuilder.build()); + } } - instance.setCases(choiceCases); + instance.setCases(cases); // AUGMENTATIONS final Set augmentations = new HashSet(); @@ -80,36 +84,48 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT instance.setAvailableAugmentations(augmentations); // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if(unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); - built = true; + isBuilt = true; } return instance; } + @Override + public void rebuild() { + isBuilt = false; + build(); + } + @Override public int getLine() { return line; } public Set getCases() { - return cases; + return addedCases; } public void addChildNode(DataSchemaNodeBuilder childNode) { if (!(childNode instanceof ChoiceCaseBuilder)) { ChoiceCaseBuilder caseBuilder = new ChoiceCaseBuilder(childNode.getQName(), childNode.getLine()); caseBuilder.addChildNode(childNode); - cases.add(caseBuilder); + addedCases.add(caseBuilder); } else { - cases.add((ChoiceCaseBuilder) childNode); + addedCases.add((ChoiceCaseBuilder) childNode); } } + public void setCases(Set cases) { + this.cases = cases; + } + @Override public QName getQName() { return qname; @@ -176,10 +192,6 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT return constraints; } - public List getUnknownNodes() { - return addedUnknownNodes; - } - public Set getAugmentations() { return addedAugmentations; } @@ -189,11 +201,19 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT addedAugmentations.add(augment); } + public List getUnknownNodes() { + return addedUnknownNodes; + } + @Override public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) { addedUnknownNodes.add(unknownNode); } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + public String getDefaultCase() { return defaultCase; } @@ -202,7 +222,7 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT this.defaultCase = defaultCase; } - private final class ChoiceNodeImpl implements ChoiceNode { + public final class ChoiceNodeImpl implements ChoiceNode { private final QName qname; private SchemaPath path; private String description; @@ -332,6 +352,10 @@ public final class ChoiceBuilder implements DataSchemaNodeBuilder, AugmentationT this.defaultCase = defaultCase; } + public ChoiceBuilder toBuilder() { + return ChoiceBuilder.this; + } + @Override public int hashCode() { final int prime = 31; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java index 7117afe469..d54cd22ec8 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java @@ -20,13 +20,16 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.model.api.UsesNode; import org.opendaylight.controller.yang.parser.builder.api.AbstractDataNodeContainerBuilder; +import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder; +import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder; import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder; import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder; import org.opendaylight.controller.yang.parser.util.YangParseException; public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder implements - DataSchemaNodeBuilder { + DataSchemaNodeBuilder, AugmentationTargetBuilder { + private boolean isBuilt; private final ChoiceCaseNodeImpl instance; private final int line; private SchemaPath schemaPath; @@ -37,7 +40,7 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im private boolean augmenting; private final ConstraintsBuilder constraints; private final Set addedUsesNodes = new HashSet(); - private final Set augmentations = new HashSet(); + private final Set addedAugmentations = new HashSet(); ChoiceCaseBuilder(final QName qname, final int line) { super(qname); @@ -48,38 +51,54 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im @Override public ChoiceCaseNode build() { - instance.setConstraints(constraints.build()); - instance.setPath(schemaPath); - instance.setDescription(description); - instance.setReference(reference); - instance.setStatus(status); - instance.setAugmenting(augmenting); - instance.setAvailableAugmentations(augmentations); + if(!isBuilt) { + instance.setConstraints(constraints.build()); + instance.setPath(schemaPath); + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); + instance.setAugmenting(augmenting); + + // CHILD NODES + final Map childs = new HashMap(); + for (DataSchemaNodeBuilder node : addedChildNodes) { + childs.put(node.getQName(), node.build()); + } + instance.setChildNodes(childs); - // CHILD NODES - final Map childs = new HashMap(); - for (DataSchemaNodeBuilder node : childNodes) { - childs.put(node.getQName(), node.build()); - } - instance.setChildNodes(childs); + // USES + final Set uses = new HashSet(); + for (UsesNodeBuilder builder : addedUsesNodes) { + uses.add(builder.build()); + } + instance.setUses(uses); - // USES - final Set uses = new HashSet(); - for (UsesNodeBuilder builder : addedUsesNodes) { - uses.add(builder.build()); - } - instance.setUses(uses); + // UNKNOWN NODES + final List unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } + instance.setUnknownSchemaNodes(unknownNodes); + + // AUGMENTATIONS + final Set augmentations = new HashSet(); + for (AugmentationSchemaBuilder builder : addedAugmentations) { + augmentations.add(builder.build()); + } + instance.setAvailableAugmentations(augmentations); - // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + isBuilt = true; } - instance.setUnknownSchemaNodes(unknownNodes); return instance; } + @Override + public void rebuild() { + isBuilt = false; + build(); + } + @Override public int getLine() { return line; @@ -161,6 +180,11 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im "Can not add type definition to choice case."); } + @Override + public boolean isConfiguration() { + return false; + } + @Override public void setConfiguration(boolean configuration) { throw new YangParseException(line, @@ -172,11 +196,12 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im return constraints; } - public Set getAugmentations() { - return augmentations; + @Override + public void addAugmentation(AugmentationSchemaBuilder augment) { + addedAugmentations.add(augment); } - private final class ChoiceCaseNodeImpl implements ChoiceCaseNode { + public final class ChoiceCaseNodeImpl implements ChoiceCaseNode { private final QName qname; private SchemaPath path; private String description; @@ -335,6 +360,10 @@ public final class ChoiceCaseBuilder extends AbstractDataNodeContainerBuilder im } } + public ChoiceCaseBuilder toBuilder() { + return ChoiceCaseBuilder.this; + } + @Override public int hashCode() { final int prime = 31; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java index 4831a2218e..e677d3c7a5 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java @@ -49,10 +49,13 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB private boolean presence; private boolean augmenting; private boolean configuration; - + private Set> typedefs; private final Set addedTypedefs = new HashSet(); + private Set usesNodes; private final Set addedUsesNodes = new HashSet(); + private Set augmentations; private final Set addedAugmentations = new HashSet(); + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); public ContainerSchemaNodeBuilder(final QName qname, final int line) { @@ -75,43 +78,59 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB // CHILD NODES final Map childs = new HashMap(); - for (DataSchemaNodeBuilder node : childNodes) { - childs.put(node.getQName(), node.build()); + if(childNodes == null) { + for (DataSchemaNodeBuilder node : addedChildNodes) { + childs.put(node.getQName(), node.build()); + } + } else { + for(DataSchemaNode node : childNodes) { + childs.put(node.getQName(), node); + } } instance.setChildNodes(childs); // GROUPINGS - final Set groupingDefs = new HashSet(); - for (GroupingBuilder builder : groupings) { - groupingDefs.add(builder.build()); + if(groupings == null) { + groupings = new HashSet(); + for (GroupingBuilder builder : addedGroupings) { + groupings.add(builder.build()); + } } - instance.setGroupings(groupingDefs); + instance.setGroupings(groupings); // TYPEDEFS - final Set> typedefs = new HashSet>(); - for (TypeDefinitionBuilder entry : addedTypedefs) { - typedefs.add(entry.build()); + if(typedefs == null) { + typedefs = new HashSet>(); + for (TypeDefinitionBuilder entry : addedTypedefs) { + typedefs.add(entry.build()); + } } instance.setTypeDefinitions(typedefs); // USES - final Set uses = new HashSet(); - for (UsesNodeBuilder builder : addedUsesNodes) { - uses.add(builder.build()); + if(usesNodes == null) { + usesNodes = new HashSet(); + for (UsesNodeBuilder builder : addedUsesNodes) { + usesNodes.add(builder.build()); + } } - instance.setUses(uses); + instance.setUses(usesNodes); // AUGMENTATIONS - final Set augmentations = new HashSet(); - for (AugmentationSchemaBuilder builder : addedAugmentations) { - augmentations.add(builder.build()); + if(augmentations == null) { + augmentations = new HashSet(); + for (AugmentationSchemaBuilder builder : addedAugmentations) { + augmentations.add(builder.build()); + } } instance.setAvailableAugmentations(augmentations); // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if(unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); @@ -123,6 +142,12 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB return instance; } + @Override + public void rebuild() { + isBuilt = false; + build(); + } + @Override public int getLine() { return line; @@ -138,6 +163,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB addedTypedefs.add(type); } + public void setTypedefs(final Set> typedefs) { + this.typedefs = typedefs; + } + public Set getAugmentations() { return addedAugmentations; } @@ -147,6 +176,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB addedAugmentations.add(augment); } + public void setAugmentations(final Set augmentations) { + this.augmentations = augmentations; + } + public SchemaPath getPath() { return schemaPath; } @@ -156,6 +189,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB this.schemaPath = schemaPath; } + @Override public String getDescription() { return description; } @@ -165,6 +199,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB this.description = description; } + @Override public String getReference() { return reference; } @@ -174,6 +209,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB this.reference = reference; } + @Override public Status getStatus() { return status; } @@ -185,6 +221,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB } } + @Override public boolean isAugmenting() { return augmenting; } @@ -194,6 +231,7 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB this.augmenting = augmenting; } + @Override public boolean isConfiguration() { return configuration; } @@ -217,6 +255,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB addedUsesNodes.add(usesNodeBuilder); } + public void setUsesnodes(final Set usesNodes) { + this.usesNodes = usesNodes; + } + public boolean isPresence() { return presence; } @@ -234,12 +276,16 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB addedUnknownNodes.add(unknownNode); } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + @Override public String toString() { return "container " + getQName().getLocalName(); } - private final class ContainerSchemaNodeImpl implements ContainerSchemaNode { + public final class ContainerSchemaNodeImpl implements ContainerSchemaNode { private final QName qname; private SchemaPath path; private String description; @@ -424,6 +470,10 @@ public final class ContainerSchemaNodeBuilder extends AbstractDataNodeContainerB } } + public ContainerSchemaNodeBuilder toBuilder() { + return ContainerSchemaNodeBuilder.this; + } + @Override public int hashCode() { final int prime = 31; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java index a04fc3c1a6..0558b91cd0 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ExtensionBuilder.java @@ -24,6 +24,9 @@ public final class ExtensionBuilder implements SchemaNodeBuilder { private final int line; private final QName qname; private SchemaPath schemaPath; + private String description; + private String reference; + private Status status = Status.CURRENT; private final List addedExtensions = new ArrayList(); private final List addedUnknownNodes = new ArrayList(); @@ -37,6 +40,9 @@ public final class ExtensionBuilder implements SchemaNodeBuilder { public ExtensionDefinition build() { if(!isBuilt) { instance.setPath(schemaPath); + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); // UNKNOWN NODES final List extensions = new ArrayList(); @@ -84,22 +90,37 @@ public final class ExtensionBuilder implements SchemaNodeBuilder { } @Override - public void setDescription(String description) { - instance.setDescription(description); + public String getDescription() { + return description; } @Override - public void setReference(String reference) { - instance.setReference(reference); + public void setDescription(final String description) { + this.description = description; } @Override - public void setStatus(Status status) { + public String getReference() { + return reference; + } + + @Override + public void setReference(final String reference) { + this.reference = reference; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { instance.setStatus(status); } @Override - public void addUnknownSchemaNode(UnknownSchemaNodeBuilder unknownNode) { + public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) { addedUnknownNodes.add(unknownNode); } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java index 5418e09451..0681cf6b15 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/FeatureBuilder.java @@ -24,6 +24,9 @@ public final class FeatureBuilder implements SchemaNodeBuilder { private final int line; private final QName qname; private SchemaPath schemaPath; + private String description; + private String reference; + private Status status = Status.CURRENT; private final List addedUnknownNodes = new ArrayList(); FeatureBuilder(final QName qname, final int line) { @@ -36,6 +39,9 @@ public final class FeatureBuilder implements SchemaNodeBuilder { public FeatureDefinitionImpl build() { if(!isBuilt) { instance.setPath(schemaPath); + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); // UNKNOWN NODES final List unknownNodes = new ArrayList(); @@ -69,19 +75,34 @@ public final class FeatureBuilder implements SchemaNodeBuilder { this.schemaPath = schemaPath; } + @Override + public String getDescription() { + return description; + } + @Override public void setDescription(final String description) { - instance.setDescription(description); + this.description = description; + } + + @Override + public String getReference() { + return reference; } @Override public void setReference(final String reference) { - instance.setReference(reference); + this.reference = reference; + } + + @Override + public Status getStatus() { + return status; } @Override public void setStatus(final Status status) { - instance.setStatus(status); + this.status = status; } @Override diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java index 6fe43addd0..5428259324 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/GroupingBuilderImpl.java @@ -36,11 +36,21 @@ public final class GroupingBuilderImpl implements GroupingBuilder { private SchemaPath schemaPath; private String description; private String reference; - private Status status; - private final Set childNodes = new HashSet(); - private final Set groupings = new HashSet(); + private Status status = Status.CURRENT; + + private Set childNodes; + private final Set addedChildNodes = new HashSet(); + + private Set groupings; + private final Set addedGroupings = new HashSet(); + + private Set> typedefs; private final Set addedTypedefs = new HashSet(); - private final Set usesNodes = new HashSet(); + + private Set usesNodes; + private final Set addedUsesNodes = new HashSet(); + + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); public GroupingBuilderImpl(final QName qname, final int line) { @@ -59,36 +69,50 @@ public final class GroupingBuilderImpl implements GroupingBuilder { // CHILD NODES final Map childs = new HashMap(); - for (DataSchemaNodeBuilder node : childNodes) { - childs.put(node.getQName(), node.build()); + if(childNodes == null) { + for (DataSchemaNodeBuilder node : addedChildNodes) { + childs.put(node.getQName(), node.build()); + } + } else { + for(DataSchemaNode node : childNodes) { + childs.put(node.getQName(), node); + } } instance.setChildNodes(childs); // GROUPINGS - final Set groupingDefs = new HashSet(); - for (GroupingBuilder builder : groupings) { - groupingDefs.add(builder.build()); + if(groupings == null) { + groupings = new HashSet(); + for (GroupingBuilder builder : addedGroupings) { + groupings.add(builder.build()); + } } - instance.setGroupings(groupingDefs); + instance.setGroupings(groupings); // TYPEDEFS - final Set> typedefs = new HashSet>(); - for (TypeDefinitionBuilder entry : addedTypedefs) { - typedefs.add(entry.build()); + if(typedefs == null) { + typedefs = new HashSet>(); + for (TypeDefinitionBuilder entry : addedTypedefs) { + typedefs.add(entry.build()); + } } instance.setTypeDefinitions(typedefs); // USES - final Set usesNodeDefs = new HashSet(); - for (UsesNodeBuilder builder : usesNodes) { - usesNodeDefs.add(builder.build()); + if(usesNodes == null) { + usesNodes = new HashSet(); + for (UsesNodeBuilder builder : addedUsesNodes) { + usesNodes.add(builder.build()); + } } - instance.setUses(usesNodeDefs); + instance.setUses(usesNodes); // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if(unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); @@ -118,6 +142,10 @@ public final class GroupingBuilderImpl implements GroupingBuilder { addedTypedefs.add(type); } + public void setTypedefs(final Set> typedefs) { + this.typedefs = typedefs; + } + @Override public SchemaPath getPath() { return schemaPath; @@ -161,7 +189,7 @@ public final class GroupingBuilderImpl implements GroupingBuilder { @Override public DataSchemaNodeBuilder getChildNode(String name) { DataSchemaNodeBuilder result = null; - for (DataSchemaNodeBuilder node : childNodes) { + for (DataSchemaNodeBuilder node : addedChildNodes) { if (node.getQName().getLocalName().equals(name)) { result = node; break; @@ -172,32 +200,44 @@ public final class GroupingBuilderImpl implements GroupingBuilder { @Override public void addChildNode(final DataSchemaNodeBuilder childNode) { - childNodes.add(childNode); + addedChildNodes.add(childNode); } @Override public Set getChildNodes() { - return childNodes; + return addedChildNodes; + } + + public void setChildNodes(final Set childNodes) { + this.childNodes = childNodes; } @Override public Set getGroupings() { - return groupings; + return addedGroupings; } @Override public void addGrouping(final GroupingBuilder grouping) { - groupings.add(grouping); + addedGroupings.add(grouping); + } + + public void setGroupings(final Set groupings) { + this.groupings = groupings; } @Override public Set getUses() { - return usesNodes; + return addedUsesNodes; } @Override public void addUsesNode(final UsesNodeBuilder usesBuilder) { - usesNodes.add(usesBuilder); + addedUsesNodes.add(usesBuilder); + } + + public void setUsesnodes(final Set usesNodes) { + this.usesNodes = usesNodes; } @Override @@ -210,6 +250,11 @@ public final class GroupingBuilderImpl implements GroupingBuilder { addedUnknownNodes.add(unknownNode); } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + + private final class GroupingDefinitionImpl implements GroupingDefinition { private final QName qname; private SchemaPath path; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java index 96c4121653..6b76314e5c 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java @@ -19,11 +19,16 @@ import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder { + private boolean isBuilt; private final IdentitySchemaNodeImpl instance; private final int line; private final QName qname; private SchemaPath schemaPath; - private IdentitySchemaNodeBuilder baseIdentity; + private String description; + private String reference; + private Status status = Status.CURRENT; + private IdentitySchemaNodeBuilder baseIdentityBuilder; + private IdentitySchemaNode baseIdentity; private String baseIdentityName; private final List addedUnknownNodes = new ArrayList(); @@ -35,17 +40,29 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder { @Override public IdentitySchemaNode build() { - instance.setPath(schemaPath); - if (baseIdentity != null) { - instance.setBaseIdentity(baseIdentity.build()); - } + if(!isBuilt) { + instance.setPath(schemaPath); + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); + + if (baseIdentity == null) { + if (baseIdentityBuilder != null) { + instance.setBaseIdentity(baseIdentityBuilder.build()); + } + } else { + instance.setBaseIdentity(baseIdentity); + } - // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + // UNKNOWN NODES + final List unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } + instance.setUnknownSchemaNodes(unknownNodes); + + isBuilt = true; } - instance.setUnknownSchemaNodes(unknownNodes); return instance; } @@ -70,27 +87,40 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder { this.schemaPath = schemaPath; } + @Override + public String getDescription() { + return description; + } + @Override public void setDescription(final String description) { - instance.setDescription(description); + this.description = description; + } + + @Override + public String getReference() { + return reference; } @Override public void setReference(final String reference) { - instance.setReference(reference); + this.reference = reference; + } + + @Override + public Status getStatus() { + return status; } @Override public void setStatus(final Status status) { if (status != null) { - instance.setStatus(status); + this.status = status; } } @Override public void addUnknownSchemaNode(final UnknownSchemaNodeBuilder unknownNode) { - - addedUnknownNodes.add(unknownNode); } @@ -103,6 +133,10 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder { } public void setBaseIdentity(final IdentitySchemaNodeBuilder baseType) { + this.baseIdentityBuilder = baseType; + } + + public void setBaseIdentity(final IdentitySchemaNode baseType) { this.baseIdentity = baseType; } @@ -176,8 +210,7 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder { return unknownNodes; } - private void setUnknownSchemaNodes( - List unknownSchemaNodes) { + private void setUnknownSchemaNodes(List unknownSchemaNodes) { if (unknownSchemaNodes != null) { this.unknownNodes = unknownSchemaNodes; } @@ -223,8 +256,7 @@ public final class IdentitySchemaNodeBuilder implements SchemaNodeBuilder { @Override public String toString() { - StringBuilder sb = new StringBuilder( - IdentitySchemaNodeImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(IdentitySchemaNodeImpl.class.getSimpleName()); sb.append("["); sb.append("base=" + baseIdentity); sb.append(", qname=" + qname); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java index b35ff4e9f1..fdc8cd72dd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java @@ -20,10 +20,8 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuilder; import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; -import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; -public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder - implements SchemaNodeBuilder, DataSchemaNodeBuilder { +public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder implements DataSchemaNodeBuilder { private boolean isBuilt; private final LeafListSchemaNodeImpl instance; private final int line; @@ -33,6 +31,7 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder private String description; private String reference; private Status status = Status.CURRENT; + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); // DataSchemaNode args private boolean augmenting; @@ -67,9 +66,11 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder } // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if (unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); @@ -166,6 +167,10 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder addedUnknownNodes.add(unknownNode); } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + private final class LeafListSchemaNodeImpl implements LeafListSchemaNode { private final QName qname; private SchemaPath path; @@ -320,16 +325,9 @@ public final class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder @Override public String toString() { - StringBuilder sb = new StringBuilder( - LeafListSchemaNodeImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(LeafListSchemaNodeImpl.class.getSimpleName()); sb.append("["); - sb.append("qname=" + qname); - sb.append(", path=" + path); - sb.append(", augmenting=" + augmenting); - sb.append(", configuration=" + configuration); - sb.append(", constraints=" + constraintsDef); - sb.append(", type=" + type); - sb.append(", userOrdered=" + userOrdered); + sb.append(qname); sb.append("]"); return sb.toString(); } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java index ec9c35c1bd..786f08de49 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java @@ -20,10 +20,8 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.parser.builder.api.AbstractTypeAwareBuilder; import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; -import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; -public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder - implements DataSchemaNodeBuilder, SchemaNodeBuilder { +public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implements DataSchemaNodeBuilder { private boolean isBuilt; private final LeafSchemaNodeImpl instance; private final int line; @@ -33,6 +31,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder private String description; private String reference; private Status status = Status.CURRENT; + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); // DataSchemaNode args private boolean augmenting; @@ -70,9 +69,11 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder } // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if (unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); @@ -114,6 +115,10 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder return addedUnknownNodes; } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + public String getDescription() { return description; } @@ -348,8 +353,7 @@ public final class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder @Override public String toString() { - StringBuilder sb = new StringBuilder( - LeafSchemaNodeImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(LeafSchemaNodeImpl.class.getSimpleName()); sb.append("["); sb.append("qname=" + qname); sb.append(", path=" + path); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java index 65839d34b1..63a66e0892 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java @@ -46,15 +46,19 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde private String description; private String reference; private Status status = Status.CURRENT; + private List unknownNodes; private final List addedUnknownNodes = new ArrayList(); // DataSchemaNode args private boolean augmenting; private boolean configuration; private final ConstraintsBuilder constraints; // DataNodeContainer args + private Set> typedefs; private final Set addedTypedefs = new HashSet(); + private Set usesNodes; private final Set addedUsesNodes = new HashSet(); // AugmentationTarget args + private Set augmentations; private final Set addedAugmentations = new HashSet(); // ListSchemaNode args private List keyDefinition = Collections.emptyList(); @@ -81,43 +85,59 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde // CHILD NODES final Map childs = new HashMap(); - for (DataSchemaNodeBuilder node : childNodes) { - childs.put(node.getQName(), node.build()); + if(childNodes == null) { + for (DataSchemaNodeBuilder node : addedChildNodes) { + childs.put(node.getQName(), node.build()); + } + } else { + for(DataSchemaNode node : childNodes) { + childs.put(node.getQName(), node); + } } instance.setChildNodes(childs); // TYPEDEFS - final Set> typedefs = new HashSet>(); - for (TypeDefinitionBuilder entry : addedTypedefs) { - typedefs.add(entry.build()); + if(typedefs == null) { + typedefs = new HashSet>(); + for (TypeDefinitionBuilder entry : addedTypedefs) { + typedefs.add(entry.build()); + } } instance.setTypeDefinitions(typedefs); // USES - final Set usesNodeDefs = new HashSet(); - for (UsesNodeBuilder builder : addedUsesNodes) { - usesNodeDefs.add(builder.build()); + if(usesNodes == null) { + usesNodes = new HashSet(); + for (UsesNodeBuilder builder : addedUsesNodes) { + usesNodes.add(builder.build()); + } } - instance.setUses(usesNodeDefs); + instance.setUses(usesNodes); // GROUPINGS - final Set groupingDefs = new HashSet(); - for (GroupingBuilder builder : groupings) { - groupingDefs.add(builder.build()); + if(groupings == null) { + groupings = new HashSet(); + for (GroupingBuilder builder : addedGroupings) { + groupings.add(builder.build()); + } } - instance.setGroupings(groupingDefs); + instance.setGroupings(groupings); // AUGMENTATIONS - final Set augmentations = new HashSet(); - for (AugmentationSchemaBuilder builder : addedAugmentations) { - augmentations.add(builder.build()); + if(augmentations == null) { + augmentations = new HashSet(); + for (AugmentationSchemaBuilder builder : addedAugmentations) { + augmentations.add(builder.build()); + } } instance.setAvailableAugmentations(augmentations); // UNKNOWN NODES - final List unknownNodes = new ArrayList(); - for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { - unknownNodes.add(b.build()); + if(unknownNodes == null) { + unknownNodes = new ArrayList(); + for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { + unknownNodes.add(b.build()); + } } instance.setUnknownSchemaNodes(unknownNodes); @@ -129,6 +149,12 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde return instance; } + @Override + public void rebuild() { + isBuilt = false; + build(); + } + @Override public int getLine() { return line; @@ -144,6 +170,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde addedTypedefs.add(type); } + public void setTypedefs(final Set> typedefs) { + this.typedefs = typedefs; + } + public SchemaPath getPath() { return schemaPath; } @@ -191,6 +221,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde addedUsesNodes.add(usesBuilder); } + public void setUsesnodes(final Set usesNodes) { + this.usesNodes = usesNodes; + } + public Set getAugmentations() { return addedAugmentations; } @@ -200,6 +234,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde addedAugmentations.add(augment); } + public void setAugmentations(final Set augmentations) { + this.augmentations = augmentations; + } + public List getKeyDefinition() { return keyDefinition; } @@ -250,7 +288,12 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde addedUnknownNodes.add(unknownNode); } - private final class ListSchemaNodeImpl implements ListSchemaNode { + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + + + public final class ListSchemaNodeImpl implements ListSchemaNode { private final QName qname; private SchemaPath path; private String description; @@ -444,6 +487,10 @@ public final class ListSchemaNodeBuilder extends AbstractDataNodeContainerBuilde } } + public ListSchemaNodeBuilder toBuilder() { + return ListSchemaNodeBuilder.this; + } + @Override public int hashCode() { final int prime = 31; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java index fa307972d4..efa3849e90 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java @@ -32,6 +32,7 @@ import org.opendaylight.controller.yang.model.api.NotificationDefinition; import org.opendaylight.controller.yang.model.api.RpcDefinition; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.TypeDefinition; +import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.model.api.UsesNode; import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder; import org.opendaylight.controller.yang.parser.builder.api.Builder; @@ -79,7 +80,7 @@ public class ModuleBuilder implements Builder { private final Map, TypeDefinitionBuilder> addedTypedefs = new HashMap, TypeDefinitionBuilder>(); private final Map, UnionTypeBuilder> addedUnionTypes = new HashMap, UnionTypeBuilder>(); private final List addedExtensions = new ArrayList(); - private final Set addedUnknownNodes = new HashSet(); + private final Map, UnknownSchemaNodeBuilder> addedUnknownNodes = new HashMap, UnknownSchemaNodeBuilder>(); private final Map, TypeAwareBuilder> dirtyNodes = new HashMap, TypeAwareBuilder>(); @@ -123,7 +124,7 @@ public class ModuleBuilder implements Builder { // NOTIFICATIONS final Set notifications = new HashSet(); for (NotificationBuilder entry : addedNotifications) { - notifications.add((NotificationDefinition) entry.build()); + notifications.add(entry.build()); } instance.setNotifications(notifications); @@ -140,8 +141,7 @@ public class ModuleBuilder implements Builder { // DEVIATIONS final Set deviations = new HashSet(); - for (Map.Entry, DeviationBuilder> entry : addedDeviations - .entrySet()) { + for (Map.Entry, DeviationBuilder> entry : addedDeviations.entrySet()) { deviations.add(entry.getValue().build()); } instance.setDeviations(deviations); @@ -160,6 +160,10 @@ public class ModuleBuilder implements Builder { } instance.setIdentities(identities); + // UNKNOWN NODES + final List unknownNodes = buildModuleUnknownNodes(addedUnknownNodes); + instance.setUnknownSchemaNodes(unknownNodes); + return instance; } @@ -198,8 +202,7 @@ public class ModuleBuilder implements Builder { public Set getChildNodes() { final Set children = new HashSet(); - for (Map.Entry, DataSchemaNodeBuilder> entry : childNodes - .entrySet()) { + for (Map.Entry, DataSchemaNodeBuilder> entry : childNodes.entrySet()) { final List path = entry.getKey(); final DataSchemaNodeBuilder child = entry.getValue(); if (path.size() == 2) { @@ -226,13 +229,12 @@ public class ModuleBuilder implements Builder { } public Set getUnknownNodes() { - return addedUnknownNodes; + return new HashSet(addedUnknownNodes.values()); } public Set getModuleTypedefs() { final Set typedefs = new HashSet(); - for (Map.Entry, TypeDefinitionBuilder> entry : addedTypedefs - .entrySet()) { + for (Map.Entry, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) { if (entry.getKey().size() == 2) { typedefs.add(entry.getValue()); } @@ -242,8 +244,7 @@ public class ModuleBuilder implements Builder { public Set getModuleGroupings() { final Set groupings = new HashSet(); - for (Map.Entry, GroupingBuilder> entry : addedGroupings - .entrySet()) { + for (Map.Entry, GroupingBuilder> entry : addedGroupings.entrySet()) { if (entry.getKey().size() == 2) { groupings.add(entry.getValue()); } @@ -281,8 +282,7 @@ public class ModuleBuilder implements Builder { public void addDirtyNode(final List path) { final List dirtyNodePath = new ArrayList(path); - final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) actualPath - .getFirst(); + final TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) actualPath.getFirst(); dirtyNodes.put(dirtyNodePath, nodeBuilder); } @@ -314,10 +314,8 @@ public class ModuleBuilder implements Builder { instance.setContact(contact); } - public boolean addModuleImport(final String moduleName, - final Date revision, final String prefix) { - final ModuleImport moduleImport = createModuleImport(moduleName, - revision, prefix); + public boolean addModuleImport(final String moduleName, final Date revision, final String prefix) { + final ModuleImport moduleImport = createModuleImport(moduleName, revision, prefix); return imports.add(moduleImport); } @@ -331,12 +329,10 @@ public class ModuleBuilder implements Builder { return builder; } - public ContainerSchemaNodeBuilder addContainerNode( - final QName containerName, final List parentPath, + public ContainerSchemaNodeBuilder addContainerNode(final QName containerName, final List parentPath, final int line) { final List pathToNode = new ArrayList(parentPath); - final ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder( - containerName, line); + final ContainerSchemaNodeBuilder containerBuilder = new ContainerSchemaNodeBuilder(containerName, line); updateParent(containerBuilder, line, "container"); pathToNode.add(containerName.getLocalName()); @@ -345,11 +341,9 @@ public class ModuleBuilder implements Builder { return containerBuilder; } - public ListSchemaNodeBuilder addListNode(final QName listName, - final List parentPath, final int line) { + public ListSchemaNodeBuilder addListNode(final QName listName, final List parentPath, final int line) { final List pathToNode = new ArrayList(parentPath); - final ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder( - listName, line); + final ListSchemaNodeBuilder listBuilder = new ListSchemaNodeBuilder(listName, line); updateParent(listBuilder, line, "list"); pathToNode.add(listName.getLocalName()); @@ -358,11 +352,9 @@ public class ModuleBuilder implements Builder { return listBuilder; } - public LeafSchemaNodeBuilder addLeafNode(final QName leafName, - final List parentPath, final int line) { + public LeafSchemaNodeBuilder addLeafNode(final QName leafName, final List parentPath, final int line) { final List pathToNode = new ArrayList(parentPath); - final LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder( - leafName, line); + final LeafSchemaNodeBuilder leafBuilder = new LeafSchemaNodeBuilder(leafName, line); updateParent(leafBuilder, line, "leaf"); pathToNode.add(leafName.getLocalName()); @@ -371,11 +363,9 @@ public class ModuleBuilder implements Builder { return leafBuilder; } - public LeafListSchemaNodeBuilder addLeafListNode(final QName qname, - final List parentPath, final int line) { + public LeafListSchemaNodeBuilder addLeafListNode(final QName qname, final List parentPath, final int line) { final List pathToNode = new ArrayList(parentPath); - final LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder( - qname, line); + final LeafListSchemaNodeBuilder leafListBuilder = new LeafListSchemaNodeBuilder(qname, line); updateParent(leafListBuilder, line, "leaf-list"); pathToNode.add(qname.getLocalName()); @@ -384,8 +374,7 @@ public class ModuleBuilder implements Builder { return leafListBuilder; } - public GroupingBuilder addGrouping(final QName qname, - final List parentPath, final int line) { + public GroupingBuilder addGrouping(final QName qname, final List parentPath, final int line) { final List pathToGroup = new ArrayList(parentPath); final GroupingBuilder builder = new GroupingBuilderImpl(qname, line); @@ -394,8 +383,7 @@ public class ModuleBuilder implements Builder { if (parent instanceof DataNodeContainerBuilder) { ((DataNodeContainerBuilder) parent).addGrouping(builder); } else { - throw new YangParseException(name, line, - "Unresolved parent of grouping " + qname.getLocalName()); + throw new YangParseException(name, line, "Unresolved parent of grouping " + qname.getLocalName()); } } @@ -405,11 +393,9 @@ public class ModuleBuilder implements Builder { return builder; } - public AugmentationSchemaBuilder addAugment(final String name, - final List parentPath, final int line) { + public AugmentationSchemaBuilder addAugment(final String name, final List parentPath, final int line) { final List pathToAugment = new ArrayList(parentPath); - final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl( - name, line); + final AugmentationSchemaBuilder builder = new AugmentationSchemaBuilderImpl(name, line); // augment can only be in 'module' or 'uses' statement if (!(actualPath.isEmpty())) { @@ -417,8 +403,7 @@ public class ModuleBuilder implements Builder { if (parent instanceof UsesNodeBuilder) { ((UsesNodeBuilder) parent).addAugment(builder); } else { - throw new YangParseException(this.name, line, - "Unresolved parent of augment " + name); + throw new YangParseException(this.name, line, "Unresolved parent of augment " + name); } } @@ -428,11 +413,9 @@ public class ModuleBuilder implements Builder { return builder; } - public UsesNodeBuilder addUsesNode(final String groupingPathStr, - final List parentPath, final int line) { + public UsesNodeBuilder addUsesNode(final String groupingPathStr, final List parentPath, final int line) { final List pathToUses = new ArrayList(parentPath); - final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl( - groupingPathStr, line); + final UsesNodeBuilder usesBuilder = new UsesNodeBuilderImpl(groupingPathStr, line); if (!(actualPath.isEmpty())) { final Builder parent = actualPath.getFirst(); @@ -442,8 +425,7 @@ public class ModuleBuilder implements Builder { } ((DataNodeContainerBuilder) parent).addUsesNode(usesBuilder); } else { - throw new YangParseException(name, line, - "Unresolved parent of uses " + groupingPathStr); + throw new YangParseException(name, line, "Unresolved parent of uses " + groupingPathStr); } } @@ -452,37 +434,31 @@ public class ModuleBuilder implements Builder { return usesBuilder; } - public void addRefine(final RefineHolder refine, - final List parentPath) { + public void addRefine(final RefineHolder refine, final List parentPath) { final List path = new ArrayList(parentPath); if (actualPath.isEmpty()) { - throw new YangParseException(name, refine.getLine(), - "refine can be defined only in uses statement"); + throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement"); } else { final Builder parent = actualPath.getFirst(); if (parent instanceof UsesNodeBuilder) { ((UsesNodeBuilder) parent).addRefine(refine); } else { - throw new YangParseException(name, refine.getLine(), - "refine can be defined only in uses statement"); + throw new YangParseException(name, refine.getLine(), "refine can be defined only in uses statement"); } } path.add(refine.getName()); } - public RpcDefinitionBuilder addRpc(final QName qname, - final List parentPath, final int line) { + public RpcDefinitionBuilder addRpc(final QName qname, final List parentPath, final int line) { if (!(actualPath.isEmpty())) { - throw new YangParseException(name, line, - "rpc can be defined only in module or submodule"); + throw new YangParseException(name, line, "rpc can be defined only in module or submodule"); } final List pathToRpc = new ArrayList(parentPath); - final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname, - line); + final RpcDefinitionBuilder rpcBuilder = new RpcDefinitionBuilder(qname, line); pathToRpc.add(qname.getLocalName()); addedRpcs.put(pathToRpc, rpcBuilder); @@ -490,45 +466,36 @@ public class ModuleBuilder implements Builder { return rpcBuilder; } - public ContainerSchemaNodeBuilder addRpcInput(final QName inputQName, - final int line) { + public ContainerSchemaNodeBuilder addRpcInput(final QName inputQName, final int line) { final Builder parent = actualPath.getFirst(); if (!(parent instanceof RpcDefinitionBuilder)) { - throw new YangParseException(name, line, - "input can be defined only in rpc statement"); + throw new YangParseException(name, line, "input can be defined only in rpc statement"); } final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent; - final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder( - inputQName, line); + final ContainerSchemaNodeBuilder inputBuilder = new ContainerSchemaNodeBuilder(inputQName, line); rpc.setInput(inputBuilder); return inputBuilder; } - public ContainerSchemaNodeBuilder addRpcOutput(final QName outputQName, - final int line) { + public ContainerSchemaNodeBuilder addRpcOutput(final QName outputQName, final int line) { final Builder parent = actualPath.getFirst(); if (!(parent instanceof RpcDefinitionBuilder)) { - throw new YangParseException(name, line, - "output can be defined only in rpc statement"); + throw new YangParseException(name, line, "output can be defined only in rpc statement"); } final RpcDefinitionBuilder rpc = (RpcDefinitionBuilder) parent; - final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder( - outputQName, line); + final ContainerSchemaNodeBuilder outputBuilder = new ContainerSchemaNodeBuilder(outputQName, line); rpc.setOutput(outputBuilder); return outputBuilder; } - public NotificationBuilder addNotification(final QName notificationName, - final List parentPath, final int line) { + public NotificationBuilder addNotification(final QName notificationName, final List parentPath, + final int line) { if (!(actualPath.isEmpty())) { - throw new YangParseException(name, line, - "notification can be defined only in module or submodule"); + throw new YangParseException(name, line, "notification can be defined only in module or submodule"); } - - final NotificationBuilder builder = new NotificationBuilder( - notificationName, line); + final NotificationBuilder builder = new NotificationBuilder(notificationName, line); final List notificationPath = new ArrayList(parentPath); notificationPath.add(notificationName.getLocalName()); @@ -537,11 +504,9 @@ public class ModuleBuilder implements Builder { return builder; } - public FeatureBuilder addFeature(final QName featureName, - final List parentPath, final int line) { + public FeatureBuilder addFeature(final QName featureName, final List parentPath, final int line) { if (!(actualPath.isEmpty())) { - throw new YangParseException(name, line, - "feature can be defined only in module or submodule"); + throw new YangParseException(name, line, "feature can be defined only in module or submodule"); } final List pathToFeature = new ArrayList(parentPath); @@ -552,22 +517,19 @@ public class ModuleBuilder implements Builder { return builder; } - public ChoiceBuilder addChoice(final QName choiceName, - final List parentPath, final int line) { + public ChoiceBuilder addChoice(final QName choiceName, final List parentPath, final int line) { final List pathToChoice = new ArrayList(parentPath); final ChoiceBuilder builder = new ChoiceBuilder(choiceName, line); if (!(actualPath.isEmpty())) { - Builder parent = actualPath.getFirst(); + final Builder parent = actualPath.getFirst(); if (parent instanceof DataNodeContainerBuilder) { if (parent instanceof AugmentationSchemaBuilder) { builder.setAugmenting(true); } ((DataNodeContainerBuilder) parent).addChildNode(builder); } else { - throw new YangParseException(name, line, - "Unresolved parent of choice " - + choiceName.getLocalName()); + throw new YangParseException(name, line, "Unresolved parent of choice " + choiceName.getLocalName()); } } @@ -577,8 +539,7 @@ public class ModuleBuilder implements Builder { return builder; } - public ChoiceCaseBuilder addCase(final QName caseName, - final List parentPath, final int line) { + public ChoiceCaseBuilder addCase(final QName caseName, final List parentPath, final int line) { final List pathToCase = new ArrayList(parentPath); final ChoiceCaseBuilder builder = new ChoiceCaseBuilder(caseName, line); @@ -592,9 +553,7 @@ public class ModuleBuilder implements Builder { builder.setAugmenting(true); ((AugmentationSchemaBuilder) parent).addChildNode(builder); } else { - throw new YangParseException(name, line, - "Unresolved parent of 'case' " - + caseName.getLocalName()); + throw new YangParseException(name, line, "Unresolved parent of 'case' " + caseName.getLocalName()); } } @@ -604,8 +563,7 @@ public class ModuleBuilder implements Builder { return builder; } - public AnyXmlBuilder addAnyXml(final QName anyXmlName, - final List parentPath, final int line) { + public AnyXmlBuilder addAnyXml(final QName anyXmlName, final List parentPath, final int line) { final List pathToAnyXml = new ArrayList(parentPath); final AnyXmlBuilder builder = new AnyXmlBuilder(anyXmlName, line); updateParent(builder, line, "anyxml"); @@ -616,20 +574,16 @@ public class ModuleBuilder implements Builder { return builder; } - public TypeDefinitionBuilderImpl addTypedef(final QName typeDefName, - final List parentPath, final int line) { + public TypeDefinitionBuilderImpl addTypedef(final QName typeDefName, final List parentPath, final int line) { final List pathToType = new ArrayList(parentPath); - final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl( - typeDefName, line); + final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typeDefName, line); if (!(actualPath.isEmpty())) { final Builder parent = actualPath.getFirst(); if (parent instanceof TypeDefinitionAwareBuilder) { ((TypeDefinitionAwareBuilder) parent).addTypedef(builder); } else { - throw new YangParseException(name, line, - "Unresolved parent of typedef " - + typeDefName.getLocalName()); + throw new YangParseException(name, line, "Unresolved parent of typedef " + typeDefName.getLocalName()); } } @@ -638,23 +592,20 @@ public class ModuleBuilder implements Builder { return builder; } - public void setType(final TypeDefinition type, - final List parentPath) { - + public void setType(final TypeDefinition type, final List parentPath) { if (!(actualPath.isEmpty())) { final Builder parent = actualPath.getFirst(); if (parent instanceof TypeAwareBuilder) { ((TypeAwareBuilder) parent).setType(type); } else { - throw new YangParseException("Failed to set type '" - + type.getQName().getLocalName() + throw new YangParseException("Failed to set type '" + type.getQName().getLocalName() + "'. Unknown parent node: " + parent); } } } - public UnionTypeBuilder addUnionType(final List currentPath, - final URI namespace, final Date revision, final int line) { + public UnionTypeBuilder addUnionType(final List currentPath, final URI namespace, final Date revision, + final int line) { final List pathToUnion = new ArrayList(currentPath); final UnionTypeBuilder union = new UnionTypeBuilder(line); @@ -672,18 +623,15 @@ public class ModuleBuilder implements Builder { addedUnionTypes.put(path, union); return union; } else { - throw new YangParseException(name, line, - "Unresolved parent of union type."); + throw new YangParseException(name, line, "Unresolved parent of union type."); } } } - public void addIdentityrefType(final String baseString, - final List parentPath, final SchemaPath schemaPath, + public void addIdentityrefType(final String baseString, final List parentPath, final SchemaPath schemaPath, final int line) { final List pathToIdentityref = new ArrayList(parentPath); - final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder( - baseString, schemaPath, line); + final IdentityrefTypeBuilder identityref = new IdentityrefTypeBuilder(baseString, schemaPath, line); if (actualPath.isEmpty()) { throw new YangParseException(line, "identityref error"); @@ -694,17 +642,14 @@ public class ModuleBuilder implements Builder { typeParent.setTypedef(identityref); dirtyNodes.put(pathToIdentityref, typeParent); } else { - throw new YangParseException(name, line, - "Unresolved parent of identityref type."); + throw new YangParseException(name, line, "Unresolved parent of identityref type."); } } } - public DeviationBuilder addDeviation(final String targetPath, - final List parentPath, final int line) { + public DeviationBuilder addDeviation(final String targetPath, final List parentPath, final int line) { if (!(actualPath.isEmpty())) { - throw new YangParseException(name, line, - "deviation can be defined only in module or submodule"); + throw new YangParseException(name, line, "deviation can be defined only in module or submodule"); } final List pathToDeviation = new ArrayList(parentPath); @@ -714,31 +659,25 @@ public class ModuleBuilder implements Builder { return builder; } - public IdentitySchemaNodeBuilder addIdentity(final QName qname, - final List parentPath, final int line) { + public IdentitySchemaNodeBuilder addIdentity(final QName qname, final List parentPath, final int line) { if (!(actualPath.isEmpty())) { - throw new YangParseException(name, line, - "identity can be defined only in module or submodule"); + throw new YangParseException(name, line, "identity can be defined only in module or submodule"); } final List pathToIdentity = new ArrayList(parentPath); - final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder( - qname, line); + final IdentitySchemaNodeBuilder builder = new IdentitySchemaNodeBuilder(qname, line); pathToIdentity.add(qname.getLocalName()); addedIdentities.add(builder); return builder; } - public void addConfiguration(final boolean configuration, - final List parentPath, final int line) { + public void addConfiguration(final boolean configuration, final List parentPath, final int line) { if (actualPath.isEmpty()) { - throw new YangParseException(name, line, - "Parent node of config statement not found."); + throw new YangParseException(name, line, "Parent node of config statement not found."); } else { final Builder parent = actualPath.getFirst(); if (parent instanceof DataSchemaNodeBuilder) { - ((DataSchemaNodeBuilder) parent) - .setConfiguration(configuration); + ((DataSchemaNodeBuilder) parent).setConfiguration(configuration); } else if (parent instanceof RefineHolder) { ((RefineHolder) parent).setConfig(configuration); } else if (parent instanceof DeviationBuilder) { @@ -746,16 +685,14 @@ public class ModuleBuilder implements Builder { // current api return; } else { - throw new YangParseException(name, line, - "Unresolved parent of config statement."); + throw new YangParseException(name, line, "Unresolved parent of config statement."); } } } - public UnknownSchemaNodeBuilder addUnknownSchemaNode(final QName qname, - final List parentPath, final int line) { - final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder( - qname, line); + public UnknownSchemaNodeBuilder addUnknownSchemaNode(final QName qname, final List parentPath, + final int line) { + final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(qname, line); if (!(actualPath.isEmpty())) { final Builder parent = actualPath.getFirst(); @@ -764,13 +701,13 @@ public class ModuleBuilder implements Builder { } else if (parent instanceof RefineHolder) { ((RefineHolder) parent).addUnknownSchemaNode(builder); } else { - throw new YangParseException(name, line, - "Unresolved parent of unknown node '" - + qname.getLocalName() + "'"); + throw new YangParseException(name, line, "Unresolved parent of unknown node '" + qname.getLocalName() + + "'"); } } - - addedUnknownNodes.add(builder); + final List unPath = new ArrayList(parentPath); + unPath.add(qname.getLocalName()); + addedUnknownNodes.put(unPath, builder); return builder; } @@ -792,17 +729,16 @@ public class ModuleBuilder implements Builder { private Set imports = Collections.emptySet(); private Set features = Collections.emptySet(); private Set> typeDefinitions = Collections.emptySet(); - private Set notifications = Collections - .emptySet(); + private Set notifications = Collections.emptySet(); private Set augmentations = Collections.emptySet(); private Set rpcs = Collections.emptySet(); private Set deviations = Collections.emptySet(); private Map childNodes = Collections.emptyMap(); private Set groupings = Collections.emptySet(); private Set uses = Collections.emptySet(); - private List extensionNodes = Collections - .emptyList(); + private List extensionNodes = Collections.emptyList(); private Set identities = Collections.emptySet(); + private List unknownNodes = Collections.emptyList(); private ModuleImpl(String name) { this.name = name; @@ -1000,8 +936,7 @@ public class ModuleBuilder implements Builder { return extensionNodes; } - private void setExtensionSchemaNodes( - List extensionNodes) { + private void setExtensionSchemaNodes(final List extensionNodes) { if (extensionNodes != null) { this.extensionNodes = extensionNodes; } @@ -1012,12 +947,23 @@ public class ModuleBuilder implements Builder { return identities; } - private void setIdentities(Set identities) { + private void setIdentities(final Set identities) { if (identities != null) { this.identities = identities; } } + @Override + public List getUnknownSchemaNodes() { + return unknownNodes; + } + + private void setUnknownSchemaNodes(final List unknownNodes) { + if (unknownNodes != null) { + this.unknownNodes = unknownNodes; + } + } + @Override public DataSchemaNode getDataChildByName(QName name) { return childNodes.get(name); @@ -1039,15 +985,11 @@ public class ModuleBuilder implements Builder { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result - + ((namespace == null) ? 0 : namespace.hashCode()); + result = prime * result + ((namespace == null) ? 0 : namespace.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((revision == null) ? 0 : revision.hashCode()); - result = prime * result - + ((prefix == null) ? 0 : prefix.hashCode()); - result = prime * result - + ((yangVersion == null) ? 0 : yangVersion.hashCode()); + result = prime * result + ((revision == null) ? 0 : revision.hashCode()); + result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); + result = prime * result + ((yangVersion == null) ? 0 : yangVersion.hashCode()); return result; } @@ -1103,8 +1045,7 @@ public class ModuleBuilder implements Builder { @Override public String toString() { - StringBuilder sb = new StringBuilder( - ModuleImpl.class.getSimpleName()); + StringBuilder sb = new StringBuilder(ModuleImpl.class.getSimpleName()); sb.append("["); sb.append("name=" + name); sb.append(", namespace=" + namespace); @@ -1116,8 +1057,7 @@ public class ModuleBuilder implements Builder { } } - private void updateParent(DataSchemaNodeBuilder nodeBuilder, int line, - String nodeTypeName) { + private void updateParent(DataSchemaNodeBuilder nodeBuilder, int line, String nodeTypeName) { if (!(actualPath.isEmpty())) { final Builder parent = actualPath.getFirst(); if (parent instanceof DataNodeContainerBuilder) { @@ -1128,16 +1068,14 @@ public class ModuleBuilder implements Builder { } else if (parent instanceof ChoiceBuilder) { ((ChoiceBuilder) parent).addChildNode(nodeBuilder); } else { - throw new YangParseException(name, line, - "Unresolved parent of " + nodeTypeName + " " - + nodeBuilder.getQName().getLocalName()); + throw new YangParseException(name, line, "Unresolved parent of " + nodeTypeName + " " + + nodeBuilder.getQName().getLocalName()); } } } - private ModuleImport createModuleImport(final String moduleName, - final Date revision, final String prefix) { - ModuleImport moduleImport = new ModuleImport() { + private ModuleImport createModuleImport(final String moduleName, final Date revision, final String prefix) { + final ModuleImport moduleImport = new ModuleImport() { @Override public String getModuleName() { return moduleName; @@ -1157,12 +1095,9 @@ public class ModuleBuilder implements Builder { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result - + ((moduleName == null) ? 0 : moduleName.hashCode()); - result = prime * result - + ((revision == null) ? 0 : revision.hashCode()); - result = prime * result - + ((prefix == null) ? 0 : prefix.hashCode()); + result = prime * result + ((moduleName == null) ? 0 : moduleName.hashCode()); + result = prime * result + ((revision == null) ? 0 : revision.hashCode()); + result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); return result; } @@ -1204,8 +1139,7 @@ public class ModuleBuilder implements Builder { @Override public String toString() { - return "ModuleImport[moduleName=" + moduleName + ", revision=" - + revision + ", prefix=" + prefix + "]"; + return "ModuleImport[moduleName=" + moduleName + ", revision=" + revision + ", prefix=" + prefix + "]"; } }; return moduleImport; @@ -1219,11 +1153,9 @@ public class ModuleBuilder implements Builder { * @return map of children, where key is child QName and value is child * itself */ - private Map buildModuleChildNodes( - Map, DataSchemaNodeBuilder> addedChilds) { + private Map buildModuleChildNodes(Map, DataSchemaNodeBuilder> addedChilds) { final Map childNodes = new HashMap(); - for (Map.Entry, DataSchemaNodeBuilder> entry : addedChilds - .entrySet()) { + for (Map.Entry, DataSchemaNodeBuilder> entry : addedChilds.entrySet()) { List path = entry.getKey(); DataSchemaNodeBuilder child = entry.getValue(); if (path.size() == 2) { @@ -1243,11 +1175,9 @@ public class ModuleBuilder implements Builder { * @param addedGroupings * @return set of built GroupingDefinition objects */ - private Set buildModuleGroupings( - Map, GroupingBuilder> addedGroupings) { + private Set buildModuleGroupings(Map, GroupingBuilder> addedGroupings) { final Set groupings = new HashSet(); - for (Map.Entry, GroupingBuilder> entry : addedGroupings - .entrySet()) { + for (Map.Entry, GroupingBuilder> entry : addedGroupings.entrySet()) { if (entry.getKey().size() == 2) { groupings.add(entry.getValue().build()); } @@ -1261,12 +1191,10 @@ public class ModuleBuilder implements Builder { * @param addedRpcs * @return set of built RpcDefinition objects */ - private Set buildModuleRpcs( - Map, RpcDefinitionBuilder> addedRpcs) { + private Set buildModuleRpcs(Map, RpcDefinitionBuilder> addedRpcs) { final Set rpcs = new HashSet(); RpcDefinitionBuilder builder; - for (Map.Entry, RpcDefinitionBuilder> entry : addedRpcs - .entrySet()) { + for (Map.Entry, RpcDefinitionBuilder> entry : addedRpcs.entrySet()) { builder = entry.getValue(); RpcDefinition rpc = builder.build(); rpcs.add(rpc); @@ -1282,16 +1210,13 @@ public class ModuleBuilder implements Builder { * @param addedTypedefs * @return set of built module typedef statements */ - private Set> buildModuleTypedefs( - Map, TypeDefinitionBuilder> addedTypedefs) { + private Set> buildModuleTypedefs(Map, TypeDefinitionBuilder> addedTypedefs) { Set> typedefs = new HashSet>(); - for (Map.Entry, TypeDefinitionBuilder> entry : addedTypedefs - .entrySet()) { + for (Map.Entry, TypeDefinitionBuilder> entry : addedTypedefs.entrySet()) { List key = entry.getKey(); TypeDefinitionBuilder typedefBuilder = entry.getValue(); if (key.size() == 2) { - TypeDefinition> node = typedefBuilder - .build(); + TypeDefinition> node = typedefBuilder.build(); typedefs.add(node); } } @@ -1306,11 +1231,9 @@ public class ModuleBuilder implements Builder { * @param addedUsesNodes * @return set of built module uses nodes */ - private Set buildUsesNodes( - Map, UsesNodeBuilder> addedUsesNodes) { + private Set buildUsesNodes(Map, UsesNodeBuilder> addedUsesNodes) { final Set usesNodeDefs = new HashSet(); - for (Map.Entry, UsesNodeBuilder> entry : addedUsesNodes - .entrySet()) { + for (Map.Entry, UsesNodeBuilder> entry : addedUsesNodes.entrySet()) { if (entry.getKey().size() == 2) { usesNodeDefs.add(entry.getValue().build()); } @@ -1325,11 +1248,9 @@ public class ModuleBuilder implements Builder { * @param addedFeatures * @return set of built module features */ - private Set buildModuleFeatures( - Map, FeatureBuilder> addedFeatures) { + private Set buildModuleFeatures(Map, FeatureBuilder> addedFeatures) { Set features = new HashSet(); - for (Map.Entry, FeatureBuilder> entry : addedFeatures - .entrySet()) { + for (Map.Entry, FeatureBuilder> entry : addedFeatures.entrySet()) { if (entry.getKey().size() == 2) { features.add(entry.getValue().build()); } @@ -1337,4 +1258,18 @@ public class ModuleBuilder implements Builder { return features; } + private List buildModuleUnknownNodes( + final Map, UnknownSchemaNodeBuilder> addedUnknownNodes) { + final List unknownNodes = new ArrayList(); + for (Map.Entry, UnknownSchemaNodeBuilder> entry : addedUnknownNodes.entrySet()) { + final List path = entry.getKey(); + final UnknownSchemaNodeBuilder child = entry.getValue(); + if (path.size() == 2) { + final UnknownSchemaNode node = child.build(); + unknownNodes.add(node); + } + } + return unknownNodes; + } + } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java index f75b97d1d7..956d8fe449 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java @@ -16,16 +16,18 @@ import java.util.Map; import java.util.Set; import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.model.api.AugmentationSchema; import org.opendaylight.controller.yang.model.api.DataSchemaNode; import org.opendaylight.controller.yang.model.api.GroupingDefinition; import org.opendaylight.controller.yang.model.api.NotificationDefinition; -import org.opendaylight.controller.yang.model.api.SchemaNode; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.Status; import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; import org.opendaylight.controller.yang.model.api.UsesNode; import org.opendaylight.controller.yang.parser.builder.api.AbstractDataNodeContainerBuilder; +import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder; +import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder; import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder; import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; @@ -34,13 +36,18 @@ import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder; public final class NotificationBuilder extends AbstractDataNodeContainerBuilder - implements TypeDefinitionAwareBuilder, SchemaNodeBuilder { + implements TypeDefinitionAwareBuilder, SchemaNodeBuilder, AugmentationTargetBuilder { private boolean isBuilt; private final NotificationDefinitionImpl instance; private final int line; private SchemaPath schemaPath; + private String description; + private String reference; + private Status status = Status.CURRENT; private final Set addedTypedefs = new HashSet(); private final Set addedUsesNodes = new HashSet(); + private Set augmentations; + private final Set addedAugmentations = new HashSet(); private final List addedUnknownNodes = new ArrayList(); NotificationBuilder(final QName qname, final int line) { @@ -50,20 +57,23 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder } @Override - public SchemaNode build() { + public NotificationDefinition build() { if (!isBuilt) { instance.setPath(schemaPath); + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); // CHILD NODES final Map childs = new HashMap(); - for (DataSchemaNodeBuilder node : childNodes) { + for (DataSchemaNodeBuilder node : addedChildNodes) { childs.put(node.getQName(), node.build()); } instance.setChildNodes(childs); // GROUPINGS final Set groupingDefs = new HashSet(); - for (GroupingBuilder builder : groupings) { + for (GroupingBuilder builder : addedGroupings) { groupingDefs.add(builder.build()); } instance.setGroupings(groupingDefs); @@ -82,6 +92,15 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder } instance.setUses(uses); + // AUGMENTATIONS + if(augmentations == null) { + augmentations = new HashSet(); + for (AugmentationSchemaBuilder builder : addedAugmentations) { + augmentations.add(builder.build()); + } + } + instance.setAvailableAugmentations(augmentations); + // UNKNOWN NODES final List unknownNodes = new ArrayList(); for (UnknownSchemaNodeBuilder b : addedUnknownNodes) { @@ -95,6 +114,12 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder return instance; } + @Override + public void rebuild() { + isBuilt = false; + build(); + } + @Override public int getLine() { return line; @@ -125,19 +150,49 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder this.schemaPath = schemaPath; } + @Override + public String getDescription() { + return description; + } + @Override public void setDescription(final String description) { - instance.setDescription(description); + this.description = description; + } + + @Override + public String getReference() { + return reference; } @Override public void setReference(final String reference) { - instance.setReference(reference); + this.reference = reference; + } + + @Override + public Status getStatus() { + return status; } @Override public void setStatus(final Status status) { - instance.setStatus(status); + if(status != null) { + this.status = status; + } + } + + public Set getAugmentations() { + return addedAugmentations; + } + + @Override + public void addAugmentation(AugmentationSchemaBuilder augment) { + addedAugmentations.add(augment); + } + + public void setAugmentations(final Set augmentations) { + this.augmentations = augmentations; } @Override @@ -150,7 +205,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder return "notification " + getQName().getLocalName(); } - private final class NotificationDefinitionImpl implements NotificationDefinition { + public final class NotificationDefinitionImpl implements NotificationDefinition { private final QName qname; private SchemaPath path; private String description; @@ -160,6 +215,7 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder private Set groupings = Collections.emptySet(); private Set> typeDefinitions = Collections.emptySet(); private Set uses = Collections.emptySet(); + private Set augmentations = Collections.emptySet(); private List unknownNodes = Collections.emptyList(); private NotificationDefinitionImpl(final QName qname) { @@ -254,6 +310,18 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder } } + @Override + public Set getAvailableAugmentations() { + return augmentations; + } + + private void setAvailableAugmentations( + Set augmentations) { + if (augmentations != null) { + this.augmentations = augmentations; + } + } + @Override public List getUnknownSchemaNodes() { return unknownNodes; @@ -283,6 +351,10 @@ public final class NotificationBuilder extends AbstractDataNodeContainerBuilder return result; } + public NotificationBuilder toBuilder() { + return NotificationBuilder.this; + } + @Override public int hashCode() { final int prime = 31; diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java index 855d0264ae..e36adbdeb2 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java @@ -32,6 +32,9 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini private final int line; private final QName qname; private SchemaPath schemaPath; + private String description; + private String reference; + private Status status = Status.CURRENT; private ContainerSchemaNodeBuilder inputBuilder; private ContainerSchemaNodeBuilder outputBuilder; private final Set addedTypedefs = new HashSet(); @@ -47,6 +50,10 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini @Override public RpcDefinition build() { if (!isBuilt) { + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); + final ContainerSchemaNode input = inputBuilder == null ? null : inputBuilder.build(); final ContainerSchemaNode output = outputBuilder == null ? null : outputBuilder.build(); instance.setInput(input); @@ -120,19 +127,36 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini this.schemaPath = schemaPath; } + @Override + public String getDescription() { + return description; + } + @Override public void setDescription(final String description) { - instance.setDescription(description); + this.description = description; + } + + @Override + public String getReference() { + return reference; + } + + @Override + public void setReference(String reference) { + this.reference = reference; } @Override - public void setReference(final String reference) { - instance.setReference(reference); + public Status getStatus() { + return status; } @Override public void setStatus(final Status status) { - instance.setStatus(status); + if (status != null) { + this.status = status; + } } @Override @@ -147,7 +171,11 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini @Override public int hashCode() { - return qname.hashCode(); + final int prime = 31; + int result = 1; + result = prime * result + ((qname == null) ? 0 : qname.hashCode()); + result = prime * result + ((schemaPath == null) ? 0 : schemaPath.hashCode()); + return result; } @Override @@ -166,6 +194,13 @@ public final class RpcDefinitionBuilder implements SchemaNodeBuilder, TypeDefini } else if (!other.qname.equals(this.qname)) { return false; } + if (other.schemaPath == null) { + if (this.schemaPath != null) { + return false; + } + } else if (!other.schemaPath.equals(this.schemaPath)) { + return false; + } return true; } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java index 222290188e..3d3ad28891 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UnknownSchemaNodeBuilder.java @@ -23,6 +23,9 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder { private final int line; private final QName qname; private SchemaPath schemaPath; + private String description; + private String reference; + private Status status = Status.CURRENT; private final List addedUnknownNodes = new ArrayList(); private QName nodeType; private String nodeParameter; @@ -35,10 +38,13 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder { @Override public UnknownSchemaNode build() { - if(!isBuilt) { + if (!isBuilt) { instance.setPath(schemaPath); instance.setNodeType(nodeType); instance.setNodeParameter(nodeParameter); + instance.setDescription(description); + instance.setReference(reference); + instance.setStatus(status); // UNKNOWN NODES final List unknownNodes = new ArrayList(); @@ -73,19 +79,36 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder { this.schemaPath = schemaPath; } + @Override + public String getDescription() { + return description; + } + @Override public void setDescription(final String description) { - instance.setDescription(description); + this.description = description; + } + + @Override + public String getReference() { + return reference; } @Override - public void setReference(final String reference) { - instance.setReference(reference); + public void setReference(String reference) { + this.reference = reference; } @Override - public void setStatus(final Status status) { - instance.setStatus(status); + public Status getStatus() { + return status; + } + + @Override + public void setStatus(Status status) { + if (status != null) { + this.status = status; + } } @Override @@ -171,8 +194,7 @@ public final class UnknownSchemaNodeBuilder implements SchemaNodeBuilder { return unknownNodes; } - private void setUnknownSchemaNodes( - final List unknownNodes) { + private void setUnknownSchemaNodes(final List unknownNodes) { if (unknownNodes != null) { this.unknownNodes = unknownNodes; } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java index 1a71abf70c..611d2ce1bd 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java @@ -75,8 +75,7 @@ final class SchemaContextImpl implements SchemaContext { if (module.getName().equals(name)) { return module; } - } else if (module.getName().equals(name) - && module.getRevision().equals(revision)) { + } else if (module.getName().equals(name) && module.getRevision().equals(revision)) { return module; } } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java new file mode 100644 index 0000000000..2725162d0a --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangErrorListener.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.yang.parser.impl; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class YangErrorListener extends BaseErrorListener { + private final static Logger logger = LoggerFactory.getLogger(YangErrorListener.class); + + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, + String msg, RecognitionException e) { + logger.warn("line " + line + ":" + charPositionInLine + " " + msg); + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java index 6814322bde..e74029b424 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java @@ -7,6 +7,8 @@ */ package org.opendaylight.controller.yang.parser.impl; +import static org.opendaylight.controller.yang.parser.util.ParserUtils.*; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -19,6 +21,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -33,45 +36,33 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.opendaylight.controller.antlrv4.code.gen.YangLexer; import org.opendaylight.controller.antlrv4.code.gen.YangParser; import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.model.api.GroupingDefinition; +import org.opendaylight.controller.yang.model.api.IdentitySchemaNode; import org.opendaylight.controller.yang.model.api.Module; -import org.opendaylight.controller.yang.model.api.ModuleImport; import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.TypeDefinition; -import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition; -import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition; -import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition; -import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition; import org.opendaylight.controller.yang.model.parser.api.YangModelParser; import org.opendaylight.controller.yang.model.util.ExtendedType; import org.opendaylight.controller.yang.model.util.IdentityrefType; import org.opendaylight.controller.yang.model.util.UnknownType; import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder; -import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder; import org.opendaylight.controller.yang.parser.builder.api.Builder; import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder; -import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder; import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.api.TypeAwareBuilder; import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder; import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.IdentitySchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.IdentityrefTypeBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder; import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl; import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.util.ModuleDependencySort; -import org.opendaylight.controller.yang.parser.util.ParserUtils; import org.opendaylight.controller.yang.parser.util.RefineHolder; +import org.opendaylight.controller.yang.parser.util.RefineUtils; import org.opendaylight.controller.yang.parser.util.TypeConstraints; import org.opendaylight.controller.yang.parser.util.YangParseException; import org.opendaylight.controller.yang.validator.YangModelBasicValidator; @@ -87,7 +78,12 @@ public final class YangParserImpl implements YangModelParser { private static final Logger logger = LoggerFactory.getLogger(YangParserImpl.class); @Override - public Map parseYangModelsMapped(List yangFiles) { + public Set parseYangModels(final List yangFiles) { + return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); + } + + @Override + public Set parseYangModels(final List yangFiles, final SchemaContext context) { if (yangFiles != null) { final Map inputStreams = Maps.newHashMap(); @@ -103,7 +99,60 @@ public final class YangParserImpl implements YangModelParser { final Map> modules = resolveModuleBuilders( Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); - // return new LinkedHashSet(build(modules).values()); + + for (InputStream is : inputStreams.keySet()) { + try { + is.close(); + } catch (IOException e) { + logger.debug("Failed to close stream."); + } + } + + return new LinkedHashSet(buildWithContext(modules, context).values()); + } + return Collections.emptySet(); + } + + @Override + public Set parseYangModelsFromStreams(final List yangModelStreams) { + return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values()); + } + + @Override + public Set parseYangModelsFromStreams(final List yangModelStreams, SchemaContext context) { + if (yangModelStreams != null) { + Map builderToStreamMap = Maps.newHashMap(); + final Map> modules = resolveModuleBuildersWithContext( + yangModelStreams, builderToStreamMap, context); + return new LinkedHashSet(buildWithContext(modules, context).values()); + } + return Collections.emptySet(); + } + + @Override + public Map parseYangModelsMapped(List yangFiles) { + if (yangFiles != null) { + final Map inputStreams = Maps.newHashMap(); + + for (final File yangFile : yangFiles) { + try { + inputStreams.put(new FileInputStream(yangFile), yangFile); + } catch (FileNotFoundException e) { + logger.warn("Exception while reading yang file: " + yangFile.getName(), e); + } + } + + Map builderToStreamMap = Maps.newHashMap(); + final Map> modules = resolveModuleBuilders( + Lists.newArrayList(inputStreams.keySet()), builderToStreamMap); + + for (InputStream is : inputStreams.keySet()) { + try { + is.close(); + } catch (IOException e) { + logger.debug("Failed to close stream."); + } + } Map retVal = Maps.newLinkedHashMap(); Map builderToModuleMap = build(modules); @@ -118,16 +167,6 @@ public final class YangParserImpl implements YangModelParser { return Collections.emptyMap(); } - @Override - public Set parseYangModels(final List yangFiles) { - return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); - } - - @Override - public Set parseYangModelsFromStreams(final List yangModelStreams) { - return Sets.newHashSet(parseYangModelsFromStreamsMapped(yangModelStreams).values()); - } - @Override public Map parseYangModelsFromStreamsMapped(final List yangModelStreams) { Map builderToStreamMap = Maps.newHashMap(); @@ -173,7 +212,12 @@ public final class YangParserImpl implements YangModelParser { private Map> resolveModuleBuilders(final List yangFileStreams, Map streamToBuilderMap) { + return resolveModuleBuildersWithContext(yangFileStreams, streamToBuilderMap, null); + } + private Map> resolveModuleBuildersWithContext( + final List yangFileStreams, final Map streamToBuilderMap, + final SchemaContext context) { final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, streamToBuilderMap); // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER @@ -181,9 +225,17 @@ public final class YangParserImpl implements YangModelParser { final LinkedHashMap> modules = new LinkedHashMap>(); // module dependency graph sorted - List sorted = ModuleDependencySort.sort(builders); + List sorted = null; + if (context == null) { + sorted = ModuleDependencySort.sort(builders); + } else { + sorted = ModuleDependencySort.sortWithContext(context, builders); + } - for (ModuleBuilder builder : sorted) { + for (final ModuleBuilder builder : sorted) { + if (builder == null) { + continue; + } final String builderName = builder.getName(); Date builderRevision = builder.getRevision(); if (builderRevision == null) { @@ -214,6 +266,8 @@ public final class YangParserImpl implements YangModelParser { final YangLexer lexer = new YangLexer(input); final CommonTokenStream tokens = new CommonTokenStream(lexer); final YangParser parser = new YangParser(tokens); + parser.removeErrorListeners(); + parser.addErrorListener(new YangErrorListener()); result = parser.yang(); } catch (IOException e) { @@ -249,13 +303,49 @@ public final class YangParserImpl implements YangModelParser { return result; } + private Map buildWithContext(final Map> modules, + SchemaContext context) { + // fix unresolved nodes + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder moduleBuilder = childEntry.getValue(); + fixUnresolvedNodesWithContext(modules, moduleBuilder, context); + } + } + resolveAugmentsWithContext(modules, context); + + // build + // LinkedHashMap MUST be used otherwise the values will not maintain + // order! + // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html + final Map result = new LinkedHashMap(); + for (Map.Entry> entry : modules.entrySet()) { + final Map modulesByRevision = new HashMap(); + for (Map.Entry childEntry : entry.getValue().entrySet()) { + final ModuleBuilder moduleBuilder = childEntry.getValue(); + final Module module = moduleBuilder.build(); + modulesByRevision.put(childEntry.getKey(), module); + result.put(moduleBuilder, module); + } + } + return result; + } + private void fixUnresolvedNodes(final Map> modules, final ModuleBuilder builder) { resolveDirtyNodes(modules, builder); resolveIdentities(modules, builder); - resolveUsesRefines(modules, builder); + resolveUsesRefine(modules, builder); resolveUnknownNodes(modules, builder); } + private void fixUnresolvedNodesWithContext(final Map> modules, + final ModuleBuilder builder, final SchemaContext context) { + resolveDirtyNodesWithContext(modules, builder, context); + resolveIdentitiesWithContext(modules, builder, context); + resolveUsesRefineWithContext(modules, builder, context); + resolveUnknownNodesWithContext(modules, builder, context); + } + /** * Search for dirty nodes (node which contains UnknownType) and resolve * unknown types. @@ -285,34 +375,135 @@ public final class YangParserImpl implements YangModelParser { } } + private void resolveDirtyNodesWithContext(final Map> modules, + final ModuleBuilder module, SchemaContext context) { + final Map, TypeAwareBuilder> dirtyNodes = module.getDirtyNodes(); + if (!dirtyNodes.isEmpty()) { + for (Map.Entry, TypeAwareBuilder> entry : dirtyNodes.entrySet()) { + final TypeAwareBuilder nodeToResolve = entry.getValue(); + + if (nodeToResolve instanceof UnionTypeBuilder) { + // special handling for union types + resolveTypeUnionWithContext((UnionTypeBuilder) nodeToResolve, modules, module, context); + } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { + // special handling for identityref types + IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve.getTypedef(); + nodeToResolve.setType(new IdentityrefType(findFullQName(modules, module, idref), idref.getPath())); + } else { + resolveTypeWithContext(nodeToResolve, modules, module, context); + } + } + } + } + + /** + * Resolve unknown type of node. It is assumed that type of node is either + * UnknownType or ExtendedType with UnknownType as base type. + * + * @param nodeToResolve + * node with type to resolve + * @param modules + * all loaded modules + * @param module + * current module + */ private void resolveType(final TypeAwareBuilder nodeToResolve, - final Map> modules, final ModuleBuilder builder) { + final Map> modules, final ModuleBuilder module) { TypeDefinitionBuilder resolvedType = null; final int line = nodeToResolve.getLine(); final TypeDefinition nodeToResolveType = nodeToResolve.getType(); final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName(); - final ModuleBuilder dependentModule = findDependentModule(modules, builder, unknownTypeQName.getPrefix(), line); + final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, unknownTypeQName.getPrefix(), + line); final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(), - dependentModule, unknownTypeQName.getLocalName(), builder.getName(), line); + dependentModule, unknownTypeQName.getLocalName(), module.getName(), line); if (nodeToResolveType instanceof ExtendedType) { final ExtendedType extType = (ExtendedType) nodeToResolveType; - final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(nodeToResolve, targetTypeBuilder, - extType, modules, builder); + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType, + modules, module, nodeToResolve.getLine()); resolvedType = newType; } else { resolvedType = targetTypeBuilder; } // validate constraints - final TypeConstraints constraints = findConstraints(nodeToResolve, new TypeConstraints(builder.getName(), - nodeToResolve.getLine()), modules, builder); + final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve, + new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, null); constraints.validateConstraints(); nodeToResolve.setTypedef(resolvedType); } + /** + * Resolve unknown type of node. It is assumed that type of node is either + * UnknownType or ExtendedType with UnknownType as base type. + * + * @param nodeToResolve + * node with type to resolve + * @param modules + * all loaded modules + * @param module + * current module + * @param context + * SchemaContext containing already resolved modules + */ + private void resolveTypeWithContext(final TypeAwareBuilder nodeToResolve, + final Map> modules, final ModuleBuilder module, + final SchemaContext context) { + TypeDefinitionBuilder resolvedType = null; + final int line = nodeToResolve.getLine(); + final TypeDefinition nodeToResolveType = nodeToResolve.getType(); + final QName unknownTypeQName = nodeToResolveType.getBaseType().getQName(); + final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, + unknownTypeQName.getPrefix(), line); + + if (dependentModuleBuilder == null) { + final Module dependentModule = findModuleFromContext(context, module, unknownTypeQName.getPrefix(), line); + final Set> types = dependentModule.getTypeDefinitions(); + final TypeDefinition type = findTypeByName(types, unknownTypeQName.getLocalName()); + + if (nodeToResolveType instanceof ExtendedType) { + final ExtendedType extType = (ExtendedType) nodeToResolveType; + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, module, + nodeToResolve.getLine()); + + nodeToResolve.setTypedef(newType); + } else { + if(nodeToResolve instanceof TypeDefinitionBuilder) { + TypeDefinitionBuilder tdb = (TypeDefinitionBuilder)nodeToResolve; + TypeConstraints tc = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints(module.getName(), nodeToResolve.getLine()), modules, module, context); + tdb.setLengths(tc.getLength()); + tdb.setPatterns(tc.getPatterns()); + tdb.setRanges(tc.getRange()); + tdb.setFractionDigits(tc.getFractionDigits()); + } + nodeToResolve.setType(type); + } + + } else { + final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(nodeToResolve.getPath(), + dependentModuleBuilder, unknownTypeQName.getLocalName(), module.getName(), line); + + if (nodeToResolveType instanceof ExtendedType) { + final ExtendedType extType = (ExtendedType) nodeToResolveType; + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, extType, + modules, module, nodeToResolve.getLine()); + resolvedType = newType; + } else { + resolvedType = targetTypeBuilder; + } + + // validate constraints + final TypeConstraints constraints = findConstraintsFromTypeBuilder(nodeToResolve, new TypeConstraints( + module.getName(), nodeToResolve.getLine()), modules, module, context); + constraints.validateConstraints(); + + nodeToResolve.setTypedef(resolvedType); + } + } + private void resolveTypeUnion(final UnionTypeBuilder union, final Map> modules, final ModuleBuilder builder) { @@ -321,24 +512,24 @@ public final class YangParserImpl implements YangModelParser { for (TypeDefinition unionType : unionTypes) { if (unionType instanceof UnknownType) { final UnknownType ut = (UnknownType) unionType; - final ModuleBuilder dependentModule = findDependentModule(modules, builder, ut.getQName().getPrefix(), - union.getLine()); + final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName() + .getPrefix(), union.getLine()); final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(), dependentModule, ut.getQName().getLocalName(), builder.getName(), union.getLine()); union.setTypedef(resolvedType); toRemove.add(ut); } else if (unionType instanceof ExtendedType) { final ExtendedType extType = (ExtendedType) unionType; - TypeDefinition extTypeBase = extType.getBaseType(); + final TypeDefinition extTypeBase = extType.getBaseType(); if (extTypeBase instanceof UnknownType) { final UnknownType ut = (UnknownType) extTypeBase; - final ModuleBuilder dependentModule = findDependentModule(modules, builder, ut.getQName() + final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, ut.getQName() .getPrefix(), union.getLine()); final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(), dependentModule, ut.getQName().getLocalName(), builder.getName(), union.getLine()); - final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(targetTypeBuilder, - targetTypeBuilder, extType, modules, builder); + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, + extType, modules, builder, union.getLine()); union.setTypedef(newType); toRemove.add(extType); @@ -348,173 +539,150 @@ public final class YangParserImpl implements YangModelParser { unionTypes.removeAll(toRemove); } - private TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeAwareBuilder nodeToResolve, - final TypeDefinitionBuilder newBaseType, final ExtendedType oldExtendedType, - final Map> modules, final ModuleBuilder builder) { - final TypeConstraints constraints = findConstraints(nodeToResolve, new TypeConstraints(builder.getName(), - nodeToResolve.getLine()), modules, builder); - final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), - nodeToResolve.getLine()); - newType.setTypedef(newBaseType); - newType.setPath(oldExtendedType.getPath()); - newType.setDescription(oldExtendedType.getDescription()); - newType.setReference(oldExtendedType.getReference()); - newType.setStatus(oldExtendedType.getStatus()); - newType.setLengths(constraints.getLength()); - newType.setPatterns(constraints.getPatterns()); - newType.setRanges(constraints.getRange()); - newType.setFractionDigits(constraints.getFractionDigits()); - newType.setUnits(oldExtendedType.getUnits()); - newType.setDefaultValue(oldExtendedType.getDefaultValue()); - newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes()); - return newType; - } - - private TypeConstraints findConstraints(final TypeAwareBuilder nodeToResolve, final TypeConstraints constraints, - final Map> modules, final ModuleBuilder builder) { - - // union type cannot be restricted - if (nodeToResolve instanceof UnionTypeBuilder) { - return constraints; - } - - if (nodeToResolve instanceof TypeDefinitionBuilder) { - TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve; - constraints.addFractionDigits(typedefToResolve.getFractionDigits()); - constraints.addLengths(typedefToResolve.getLengths()); - constraints.addPatterns(typedefToResolve.getPatterns()); - constraints.addRanges(typedefToResolve.getRanges()); - } + private void resolveTypeUnionWithContext(final UnionTypeBuilder union, + final Map> modules, final ModuleBuilder builder, + final SchemaContext context) { - TypeDefinition type = nodeToResolve.getType(); - if (type == null) { - return findConstraints(nodeToResolve.getTypedef(), constraints, modules, builder); - } else { - if (type instanceof UnknownType) { - ModuleBuilder dependentModule = findDependentModule(modules, builder, type.getQName().getPrefix(), - nodeToResolve.getLine()); - TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule, type - .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine()); - return findConstraints(tdb, constraints, modules, dependentModule); - } else if (type instanceof ExtendedType) { - ExtendedType extType = (ExtendedType) type; - constraints.addFractionDigits(extType.getFractionDigits()); - constraints.addLengths(extType.getLengths()); - constraints.addPatterns(extType.getPatterns()); - constraints.addRanges(extType.getRanges()); - - TypeDefinition base = extType.getBaseType(); - if (base instanceof UnknownType) { - ModuleBuilder dependentModule = findDependentModule(modules, builder, base.getQName().getPrefix(), - nodeToResolve.getLine()); - TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule, - base.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine()); - return findConstraints(tdb, constraints, modules, dependentModule); + final List> unionTypes = union.getTypes(); + final List> toRemove = new ArrayList>(); + for (TypeDefinition unionType : unionTypes) { + if (unionType instanceof UnknownType) { + final UnknownType ut = (UnknownType) unionType; + final QName utQName = ut.getQName(); + final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder, + utQName.getPrefix(), union.getLine()); + + if (dependentModuleBuilder == null) { + Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(), + union.getLine()); + Set> types = dependentModule.getTypeDefinitions(); + TypeDefinition type = findTypeByName(types, utQName.getLocalName()); + union.setType(type); + toRemove.add(ut); } else { - // it has to be base yang type - mergeConstraints(type, constraints); - return constraints; + final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(union.getPath(), + dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine()); + union.setTypedef(resolvedType); + toRemove.add(ut); + } + + } else if (unionType instanceof ExtendedType) { + final ExtendedType extType = (ExtendedType) unionType; + TypeDefinition extTypeBase = extType.getBaseType(); + if (extTypeBase instanceof UnknownType) { + final UnknownType ut = (UnknownType) extTypeBase; + final QName utQName = ut.getQName(); + final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder, + utQName.getPrefix(), union.getLine()); + + if (dependentModuleBuilder == null) { + final Module dependentModule = findModuleFromContext(context, builder, utQName.getPrefix(), + union.getLine()); + Set> types = dependentModule.getTypeDefinitions(); + TypeDefinition type = findTypeByName(types, utQName.getLocalName()); + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(type, extType, builder, 0); + + union.setTypedef(newType); + toRemove.add(extType); + } else { + final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(union.getPath(), + dependentModuleBuilder, utQName.getLocalName(), builder.getName(), union.getLine()); + + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseTypeBuilder(targetTypeBuilder, + extType, modules, builder, union.getLine()); + + union.setTypedef(newType); + toRemove.add(extType); + } } - } else { - // it is base yang type - mergeConstraints(type, constraints); - return constraints; } } + unionTypes.removeAll(toRemove); } /** - * Search for type definition builder by name. + * Go through all augment definitions and resolve them. It is expected that + * modules are already sorted by their dependencies. This method also finds + * augment target node and add child nodes to it. * - * @param dirtyNodeSchemaPath - * schema path of node which contains unresolved type - * @param dependentModule - * module which should contains referenced type - * @param typeName - * name of type definition - * @param currentModuleName - * name of current module - * @param line - * current line in yang model - * @return + * @param modules + * all available modules */ - private TypeDefinitionBuilder findTypeDefinitionBuilder(SchemaPath dirtyNodeSchemaPath, - final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) { - final List path = dirtyNodeSchemaPath.getPath(); - TypeDefinitionBuilder result = null; - - Set typedefs = dependentModule.getModuleTypedefs(); - result = findTdb(typedefs, typeName); - - if (result == null) { - Builder currentNode = null; - final List currentPath = new ArrayList(); - currentPath.add(dependentModule.getName()); - - for (int i = 0; i < path.size(); i++) { - QName qname = path.get(i); - currentPath.add(qname.getLocalName()); - currentNode = dependentModule.getModuleNode(currentPath); - - if (currentNode instanceof RpcDefinitionBuilder) { - typedefs = ((RpcDefinitionBuilder) currentNode).getTypeDefinitions(); - } else if (currentNode instanceof DataNodeContainerBuilder) { - typedefs = ((DataNodeContainerBuilder) currentNode).getTypeDefinitions(); - } else { - typedefs = Collections.emptySet(); - } - - result = findTdb(typedefs, typeName); - if (result != null) { - break; - } + private void resolveAugments(final Map> modules) { + final List allModulesList = new ArrayList(); + final Set allModulesSet = new HashSet(); + for (Map.Entry> entry : modules.entrySet()) { + for (Map.Entry inner : entry.getValue().entrySet()) { + allModulesList.add(inner.getValue()); + allModulesSet.add(inner.getValue()); } } - if (result != null) { - return result; - } - throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found."); - } - - private TypeDefinitionBuilder findTdb(Set types, String name) { - for (TypeDefinitionBuilder td : types) { - if (td.getQName().getLocalName().equals(name)) { - return td; + for (int i = 0; i < allModulesList.size(); i++) { + final ModuleBuilder module = allModulesList.get(i); + // try to resolve augments in module + resolveAugment(modules, module); + // while all augments are not resolved + final Iterator allModulesIterator = allModulesSet.iterator(); + while (!(module.getAugmentsResolved() == module.getAugments().size())) { + ModuleBuilder nextModule = null; + // try resolve other module augments + try { + nextModule = allModulesIterator.next(); + resolveAugment(modules, nextModule); + } catch (NoSuchElementException e) { + throw new YangParseException("Failed to resolve augments in module '" + module.getName() + "'.", e); + } + // then try to resolve first module again + resolveAugment(modules, module); } } - return null; } /** - * Pull restriction from referenced type and add them to given constraints + * Tries to resolve augments in given module. If augment target node is not + * found, do nothing. * - * @param referencedType - * @param constraints + * @param modules + * all available modules + * @param module + * current module */ - private void mergeConstraints(final TypeDefinition referencedType, final TypeConstraints constraints) { + private void resolveAugment(final Map> modules, final ModuleBuilder module) { + if (module.getAugmentsResolved() < module.getAugments().size()) { + for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) { + + if (!augmentBuilder.isResolved()) { + final SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath(); + final List path = augmentTargetSchemaPath.getPath(); + + final QName qname = path.get(0); + String prefix = qname.getPrefix(); + if (prefix == null) { + prefix = module.getPrefix(); + } - if (referencedType instanceof DecimalTypeDefinition) { - constraints.addRanges(((DecimalTypeDefinition) referencedType).getRangeStatements()); - constraints.addFractionDigits(((DecimalTypeDefinition) referencedType).getFractionDigits()); - } else if (referencedType instanceof IntegerTypeDefinition) { - constraints.addRanges(((IntegerTypeDefinition) referencedType).getRangeStatements()); - } else if (referencedType instanceof StringTypeDefinition) { - constraints.addPatterns(((StringTypeDefinition) referencedType).getPatterns()); - constraints.addLengths(((StringTypeDefinition) referencedType).getLengthStatements()); - } else if (referencedType instanceof BinaryTypeDefinition) { - constraints.addLengths(((BinaryTypeDefinition) referencedType).getLengthConstraints()); + final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, + augmentBuilder.getLine()); + processAugmentation(augmentBuilder, path, module, qname, dependentModule); + } + + } } } /** - * Go through all augment definitions and resolve them. This method also - * finds augment target node and add child nodes to it. + * Go through all augment definitions and resolve them. This method works in + * same way as {@link #resolveAugments(Map)} except that if target node is not + * found in loaded modules, it search for target node in given context. * * @param modules - * all available modules + * all loaded modules + * @param context + * SchemaContext containing already resolved modules */ - private void resolveAugments(final Map> modules) { + private void resolveAugmentsWithContext(final Map> modules, + final SchemaContext context) { final List allModulesList = new ArrayList(); final Set allModulesSet = new HashSet(); for (Map.Entry> entry : modules.entrySet()) { @@ -527,7 +695,7 @@ public final class YangParserImpl implements YangModelParser { for (int i = 0; i < allModulesList.size(); i++) { final ModuleBuilder module = allModulesList.get(i); // try to resolve augments in module - resolveAugment(modules, module); + resolveAugmentWithContext(modules, module, context); // while all augments are not resolved final Iterator allModulesIterator = allModulesSet.iterator(); while (!(module.getAugmentsResolved() == module.getAugments().size())) { @@ -535,83 +703,50 @@ public final class YangParserImpl implements YangModelParser { // try resolve other module augments try { nextModule = allModulesIterator.next(); - resolveAugment(modules, nextModule); + resolveAugmentWithContext(modules, nextModule, context); } catch (NoSuchElementException e) { throw new YangParseException("Failed to resolve augments in module '" + module.getName() + "'.", e); } // then try to resolve first module again - resolveAugment(modules, module); + resolveAugmentWithContext(modules, module, context); } } } /** + * Tries to resolve augments in given module. If augment target node is not + * found, do nothing. * * @param modules * all available modules * @param module * current module */ - private void resolveAugment(final Map> modules, final ModuleBuilder module) { + private void resolveAugmentWithContext(final Map> modules, + final ModuleBuilder module, final SchemaContext context) { if (module.getAugmentsResolved() < module.getAugments().size()) { + for (AugmentationSchemaBuilder augmentBuilder : module.getAugments()) { + final int line = augmentBuilder.getLine(); if (!augmentBuilder.isResolved()) { - final SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath(); - final List path = augmentTargetSchemaPath.getPath(); - + final List path = augmentBuilder.getTargetPath().getPath(); final QName qname = path.get(0); String prefix = qname.getPrefix(); if (prefix == null) { prefix = module.getPrefix(); } - DataSchemaNodeBuilder currentParent = null; - final ModuleBuilder dependentModule = findDependentModule(modules, module, prefix, - augmentBuilder.getLine()); - for (DataSchemaNodeBuilder child : dependentModule.getChildNodes()) { - final QName childQName = child.getQName(); - if (childQName.getLocalName().equals(qname.getLocalName())) { - currentParent = child; - break; - } - } - - if (currentParent == null) { + // try to find augment target module in loaded modules... + final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, prefix, + line); + if (dependentModuleBuilder == null) { + // perform augmentation on module from context and + // continue to next augment + processAugmentationOnContext(augmentBuilder, path, module, prefix, line, context); continue; - } - - for (int i = 1; i < path.size(); i++) { - final QName currentQName = path.get(i); - DataSchemaNodeBuilder newParent = null; - for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodes()) { - final QName childQName = child.getQName(); - if (childQName.getLocalName().equals(currentQName.getLocalName())) { - newParent = child; - break; - } - } - if (newParent == null) { - break; // node not found, quit search - } else { - currentParent = newParent; - } - } - - final QName currentQName = currentParent.getQName(); - final QName lastAugmentPathElement = path.get(path.size() - 1); - if (currentQName.getLocalName().equals(lastAugmentPathElement.getLocalName())) { - - if (currentParent instanceof ChoiceBuilder) { - ParserUtils.fillAugmentTarget(augmentBuilder, (ChoiceBuilder) currentParent); - } else { - ParserUtils.fillAugmentTarget(augmentBuilder, (DataNodeContainerBuilder) currentParent); - } - ((AugmentationTargetBuilder) currentParent).addAugmentation(augmentBuilder); - SchemaPath oldPath = currentParent.getPath(); - augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); - augmentBuilder.setResolved(true); - module.augmentResolved(); + } else { + processAugmentation(augmentBuilder, path, module, qname, dependentModuleBuilder); } } @@ -643,7 +778,7 @@ public final class YangParserImpl implements YangModelParser { baseIdentityPrefix = module.getPrefix(); baseIdentityLocalName = baseIdentityName; } - final ModuleBuilder dependentModule = findDependentModule(modules, module, baseIdentityPrefix, + final ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, baseIdentityPrefix, identity.getLine()); final Set dependentModuleIdentities = dependentModule.getIdentities(); @@ -656,6 +791,59 @@ public final class YangParserImpl implements YangModelParser { } } + /** + * Go through identity statements defined in current module and resolve + * their 'base' statement. Method tries to find base identity in given + * modules. If base identity is not found, method will search it in context. + * + * @param modules + * all loaded modules + * @param module + * current module + * @param context + * SchemaContext containing already resolved modules + */ + private void resolveIdentitiesWithContext(final Map> modules, + final ModuleBuilder module, SchemaContext context) { + final Set identities = module.getIdentities(); + for (IdentitySchemaNodeBuilder identity : identities) { + final String baseIdentityName = identity.getBaseIdentityName(); + if (baseIdentityName != null) { + String baseIdentityPrefix = null; + String baseIdentityLocalName = null; + if (baseIdentityName.contains(":")) { + final String[] splitted = baseIdentityName.split(":"); + baseIdentityPrefix = splitted[0]; + baseIdentityLocalName = splitted[1]; + } else { + baseIdentityPrefix = module.getPrefix(); + baseIdentityLocalName = baseIdentityName; + } + final ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, + baseIdentityPrefix, identity.getLine()); + + if (dependentModuleBuilder == null) { + final Module dependentModule = findModuleFromContext(context, module, baseIdentityPrefix, + identity.getLine()); + final Set dependentModuleIdentities = dependentModule.getIdentities(); + for (IdentitySchemaNode idNode : dependentModuleIdentities) { + if (idNode.getQName().getLocalName().equals(baseIdentityLocalName)) { + identity.setBaseIdentity(idNode); + } + } + } else { + final Set dependentModuleIdentities = dependentModuleBuilder + .getIdentities(); + for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { + if (idBuilder.getQName().getLocalName().equals(baseIdentityLocalName)) { + identity.setBaseIdentity(idBuilder); + } + } + } + } + } + } + /** * Go through uses statements defined in current module and resolve their * refine statements. @@ -665,56 +853,78 @@ public final class YangParserImpl implements YangModelParser { * @param module * module being resolved */ - private void resolveUsesRefines(final Map> modules, final ModuleBuilder module) { + private void resolveUsesRefine(final Map> modules, final ModuleBuilder module) { final Map, UsesNodeBuilder> moduleUses = module.getUsesNodes(); for (Map.Entry, UsesNodeBuilder> entry : moduleUses.entrySet()) { final UsesNodeBuilder usesNode = entry.getValue(); final int line = usesNode.getLine(); - - GroupingBuilder targetGrouping = getTargetGrouping(usesNode, modules, module); + final GroupingBuilder targetGrouping = getTargetGroupingFromModules(usesNode, modules, module); usesNode.setGroupingPath(targetGrouping.getPath()); - for (RefineHolder refine : usesNode.getRefines()) { - SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy(targetGrouping, refine, modules, module); - ParserUtils.checkRefine(refineTarget, refine); - ParserUtils.refineDefault(refineTarget, refine, line); - if (refineTarget instanceof LeafSchemaNodeBuilder) { - final LeafSchemaNodeBuilder leaf = (LeafSchemaNodeBuilder) refineTarget; - ParserUtils.refineLeaf(leaf, refine, line); - usesNode.addRefineNode(leaf); - } else if (refineTarget instanceof ContainerSchemaNodeBuilder) { - final ContainerSchemaNodeBuilder container = (ContainerSchemaNodeBuilder) refineTarget; - ParserUtils.refineContainer(container, refine, line); - usesNode.addRefineNode(container); - } else if (refineTarget instanceof ListSchemaNodeBuilder) { - final ListSchemaNodeBuilder list = (ListSchemaNodeBuilder) refineTarget; - ParserUtils.refineList(list, refine, line); - usesNode.addRefineNode(list); - } else if (refineTarget instanceof LeafListSchemaNodeBuilder) { - final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) refineTarget; - ParserUtils.refineLeafList(leafList, refine, line); - usesNode.addRefineNode(leafList); - } else if (refineTarget instanceof ChoiceBuilder) { - final ChoiceBuilder choice = (ChoiceBuilder) refineTarget; - ParserUtils.refineChoice(choice, refine, line); - usesNode.addRefineNode(choice); - } else if (refineTarget instanceof AnyXmlBuilder) { - final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget; - ParserUtils.refineAnyxml(anyXml, refine, line); - usesNode.addRefineNode(anyXml); - } else if (refineTarget instanceof GroupingBuilder) { - usesNode.addRefineNode(refineTarget); - } else if (refineTarget instanceof TypeDefinitionBuilder) { - usesNode.addRefineNode(refineTarget); + final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder(targetGrouping, + refine, module.getName()); + RefineUtils.performRefine(nodeToRefine, refine, line); + usesNode.addRefineNode(nodeToRefine); + } + } + } + + /** + * Tries to search target grouping in given modules and resolve refine + * nodes. If grouping is not found in modules, method tries to find it in + * modules from context. + * + * @param modules + * all loaded modules + * @param module + * current module + * @param context + * SchemaContext containing already resolved modules + */ + private void resolveUsesRefineWithContext(final Map> modules, + final ModuleBuilder module, SchemaContext context) { + final Map, UsesNodeBuilder> moduleUses = module.getUsesNodes(); + for (Map.Entry, UsesNodeBuilder> entry : moduleUses.entrySet()) { + final UsesNodeBuilder usesNode = entry.getValue(); + final int line = usesNode.getLine(); + + final GroupingBuilder targetGroupingBuilder = getTargetGroupingFromModules(usesNode, modules, module); + if (targetGroupingBuilder == null) { + final GroupingDefinition targetGrouping = getTargetGroupingFromContext(usesNode, module, context); + usesNode.setGroupingPath(targetGrouping.getPath()); + for (RefineHolder refine : usesNode.getRefines()) { + final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingDefinition( + targetGrouping, refine, module.getName()); + RefineUtils.performRefine(nodeToRefine, refine, line); + usesNode.addRefineNode(nodeToRefine); + } + } else { + usesNode.setGroupingPath(targetGroupingBuilder.getPath()); + for (RefineHolder refine : usesNode.getRefines()) { + final SchemaNodeBuilder nodeToRefine = RefineUtils.getRefineNodeFromGroupingBuilder( + targetGroupingBuilder, refine, module.getName()); + RefineUtils.performRefine(nodeToRefine, refine, line); + usesNode.addRefineNode(nodeToRefine); } } } } - private GroupingBuilder getTargetGrouping(final UsesNodeBuilder usesBuilder, + /** + * Search given modules for grouping by name defined in uses node. + * + * @param usesBuilder + * builder of uses statement + * @param modules + * all loaded modules + * @param module + * current module + * @return grouping with given name if found, null otherwise + */ + private GroupingBuilder getTargetGroupingFromModules(final UsesNodeBuilder usesBuilder, final Map> modules, final ModuleBuilder module) { final int line = usesBuilder.getLine(); - String groupingString = usesBuilder.getGroupingName(); + final String groupingString = usesBuilder.getGroupingName(); String groupingPrefix; String groupingName; @@ -734,13 +944,17 @@ public final class YangParserImpl implements YangModelParser { if (groupingPrefix.equals(module.getPrefix())) { dependentModule = module; } else { - dependentModule = findDependentModule(modules, module, groupingPrefix, line); + dependentModule = findDependentModuleBuilder(modules, module, groupingPrefix, line); + } + + if (dependentModule == null) { + return null; } List path = usesBuilder.getPath().getPath(); GroupingBuilder result = null; Set groupings = dependentModule.getModuleGroupings(); - result = findGrouping(groupings, groupingName); + result = findGroupingBuilder(groupings, groupingName); if (result == null) { Builder currentNode = null; @@ -760,111 +974,48 @@ public final class YangParserImpl implements YangModelParser { groupings = Collections.emptySet(); } - result = findGrouping(groupings, groupingName); + result = findGroupingBuilder(groupings, groupingName); if (result != null) { break; } } } - if (result != null) { - return result; - } - throw new YangParseException(module.getName(), line, "Referenced grouping '" + groupingName + "' not found."); - } - - private GroupingBuilder findGrouping(Set groupings, String name) { - for (GroupingBuilder grouping : groupings) { - if (grouping.getQName().getLocalName().equals(name)) { - return grouping; - } - } - return null; + return result; } /** - * Find original builder of node to refine and return copy of this builder. - *

- * We must create and use a copy of builder to preserve original builder - * state, because this object will be refined (modified) and later added to - * {@link UsesNodeBuilder}. - *

+ * Search context for grouping by name defined in uses node. * - * @param groupingPath - * path to grouping which contains node to refine - * @param refine - * refine object containing informations about refine - * @param modules - * all loaded modules + * @param usesBuilder + * builder of uses statement * @param module * current module - * @return copy of node to be refined if it is present in grouping, null - * otherwise + * @param context + * SchemaContext containing already resolved modules + * @return grouping with given name if found, null otherwise */ - private SchemaNodeBuilder getRefineNodeBuilderCopy(final GroupingBuilder targetGrouping, final RefineHolder refine, - final Map> modules, final ModuleBuilder module) { - Builder result = null; - final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine, modules, module); - if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) { - result = ParserUtils.copyLeafBuilder((LeafSchemaNodeBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) { - result = ParserUtils.copyContainerBuilder((ContainerSchemaNodeBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof ListSchemaNodeBuilder) { - result = ParserUtils.copyListBuilder((ListSchemaNodeBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof LeafListSchemaNodeBuilder) { - result = ParserUtils.copyLeafListBuilder((LeafListSchemaNodeBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof ChoiceBuilder) { - result = ParserUtils.copyChoiceBuilder((ChoiceBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof AnyXmlBuilder) { - result = ParserUtils.copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof GroupingBuilder) { - result = ParserUtils.copyGroupingBuilder((GroupingBuilder) lookedUpBuilder); - } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) { - result = ParserUtils.copyTypedefBuilder((TypeDefinitionBuilderImpl) lookedUpBuilder); - } else { - throw new YangParseException(module.getName(), refine.getLine(), "Target '" + refine.getName() - + "' can not be refined"); - } - return (SchemaNodeBuilder) result; - } + private GroupingDefinition getTargetGroupingFromContext(final UsesNodeBuilder usesBuilder, + final ModuleBuilder module, SchemaContext context) { + final int line = usesBuilder.getLine(); + String groupingString = usesBuilder.getGroupingName(); + String groupingPrefix; + String groupingName; - /** - * Find builder of refine node. - * - * @param groupingPath - * path to grouping which contains node to refine - * @param refine - * object containing refine information - * @param modules - * all loaded modules - * @param module - * current module - * @return Builder object of refine node if it is present in grouping, null - * otherwise - */ - private Builder findRefineTargetBuilder(final GroupingBuilder builder, final RefineHolder refine, - final Map> modules, final ModuleBuilder module) { - final String refineNodeName = refine.getName(); - Builder result = builder.getChildNode(refineNodeName); - if (result == null) { - Set grps = builder.getGroupings(); - for (GroupingBuilder gr : grps) { - if (gr.getQName().getLocalName().equals(refineNodeName)) { - result = gr; - break; - } - } - } - if (result == null) { - Set typedefs = builder.getTypeDefinitions(); - for (TypeDefinitionBuilder typedef : typedefs) { - if (typedef.getQName().getLocalName().equals(refineNodeName)) { - result = typedef; - break; - } + if (groupingString.contains(":")) { + String[] splitted = groupingString.split(":"); + if (splitted.length != 2 || groupingString.contains("/")) { + throw new YangParseException(module.getName(), line, "Invalid name of target grouping"); } + groupingPrefix = splitted[0]; + groupingName = splitted[1]; + } else { + groupingPrefix = module.getPrefix(); + groupingName = groupingString; } - return result; + + Module dependentModule = findModuleFromContext(context, module, groupingPrefix, line); + return findGroupingDefinition(dependentModule.getGroupings(), groupingName); } private QName findFullQName(final Map> modules, final ModuleBuilder module, @@ -879,7 +1030,7 @@ public final class YangParserImpl implements YangModelParser { } String prefix = splittedBase[0]; String name = splittedBase[1]; - ModuleBuilder dependentModule = findDependentModule(modules, module, prefix, idref.getLine()); + ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, prefix, idref.getLine()); result = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), prefix, name); } else { result = new QName(module.getNamespace(), module.getRevision(), module.getPrefix(), baseString); @@ -892,7 +1043,7 @@ public final class YangParserImpl implements YangModelParser { QName nodeType = usnb.getNodeType(); if (nodeType.getNamespace() == null || nodeType.getRevision() == null) { try { - ModuleBuilder dependentModule = findDependentModule(modules, module, nodeType.getPrefix(), + ModuleBuilder dependentModule = findDependentModuleBuilder(modules, module, nodeType.getPrefix(), usnb.getLine()); QName newNodeType = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), nodeType.getPrefix(), nodeType.getLocalName()); @@ -904,51 +1055,33 @@ public final class YangParserImpl implements YangModelParser { } } - /** - * Find dependent module based on given prefix - * - * @param modules - * all available modules - * @param module - * current module - * @param prefix - * target module prefix - * @param line - * current line in yang model - * @return - */ - private ModuleBuilder findDependentModule(final Map> modules, - final ModuleBuilder module, final String prefix, final int line) { - ModuleBuilder dependentModule = null; - Date dependentModuleRevision = null; - - if (prefix.equals(module.getPrefix())) { - dependentModule = module; - } else { - final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(module, prefix); - if (dependentModuleImport == null) { - throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'."); - } - final String dependentModuleName = dependentModuleImport.getModuleName(); - dependentModuleRevision = dependentModuleImport.getRevision(); + private void resolveUnknownNodesWithContext(final Map> modules, + final ModuleBuilder module, SchemaContext context) { + for (UnknownSchemaNodeBuilder unknownNodeBuilder : module.getUnknownNodes()) { + QName nodeType = unknownNodeBuilder.getNodeType(); + if (nodeType.getNamespace() == null || nodeType.getRevision() == null) { + try { + ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, module, + nodeType.getPrefix(), unknownNodeBuilder.getLine()); + + QName newNodeType = null; + if (dependentModuleBuilder == null) { + Module dependentModule = findModuleFromContext(context, module, nodeType.getPrefix(), + unknownNodeBuilder.getLine()); + newNodeType = new QName(dependentModule.getNamespace(), dependentModule.getRevision(), + nodeType.getPrefix(), nodeType.getLocalName()); + } else { + newNodeType = new QName(dependentModuleBuilder.getNamespace(), + dependentModuleBuilder.getRevision(), nodeType.getPrefix(), nodeType.getLocalName()); + } - final TreeMap moduleBuildersByRevision = modules.get(dependentModuleName); - if (moduleBuildersByRevision == null) { - throw new YangParseException(module.getName(), line, "Failed to find dependent module '" - + dependentModuleName + "'."); - } - if (dependentModuleRevision == null) { - dependentModule = moduleBuildersByRevision.lastEntry().getValue(); - } else { - dependentModule = moduleBuildersByRevision.get(dependentModuleRevision); + unknownNodeBuilder.setNodeType(newNodeType); + } catch (YangParseException e) { + logger.debug(module.getName(), unknownNodeBuilder.getLine(), "Failed to find unknown node type: " + + nodeType); + } } } - - if (dependentModule == null) { - throw new YangParseException(module.getName(), line, "Failed to find dependent module with prefix '" - + prefix + "' and revision '" + dependentModuleRevision + "'."); - } - return dependentModule; } } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java index 8cf9cea0cf..5c42b290a0 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ModuleDependencySort.java @@ -7,7 +7,9 @@ */ package org.opendaylight.controller.yang.parser.util; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -15,6 +17,7 @@ import java.util.Set; import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.ModuleImport; +import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder; import org.opendaylight.controller.yang.parser.impl.YangParserListenerImpl; import org.opendaylight.controller.yang.parser.util.TopologicalSort.Node; @@ -58,6 +61,26 @@ public final class ModuleDependencySort { }); } + public static List sortWithContext(SchemaContext context, ModuleBuilder... builders) { + List modules = new ArrayList(); + Collections.addAll(modules, builders); + modules.addAll(context.getModules()); + + List sorted = sortInternal(modules); + // Cast to ModuleBuilder from Node if possible and return + return Lists.transform(sorted, new Function() { + + @Override + public ModuleBuilder apply(Node input) { + if(((ModuleNodeImpl) input).getReference() instanceof ModuleBuilder) { + return (ModuleBuilder) ((ModuleNodeImpl) input).getReference(); + } else { + return null; + } + } + }); + } + /** * Topological sort of module dependency graph. * diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java index d38bc5e7ad..ba3599ca97 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java @@ -7,14 +7,33 @@ */ package org.opendaylight.controller.yang.parser.util; -import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.controller.yang.model.api.ChoiceCaseNode; +import org.opendaylight.controller.yang.model.api.ChoiceNode; +import org.opendaylight.controller.yang.model.api.ConstraintDefinition; +import org.opendaylight.controller.yang.model.api.ContainerSchemaNode; +import org.opendaylight.controller.yang.model.api.DataNodeContainer; +import org.opendaylight.controller.yang.model.api.DataSchemaNode; +import org.opendaylight.controller.yang.model.api.GroupingDefinition; +import org.opendaylight.controller.yang.model.api.LeafListSchemaNode; +import org.opendaylight.controller.yang.model.api.LeafSchemaNode; +import org.opendaylight.controller.yang.model.api.ListSchemaNode; +import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.ModuleImport; import org.opendaylight.controller.yang.model.api.MustDefinition; +import org.opendaylight.controller.yang.model.api.NotificationDefinition; +import org.opendaylight.controller.yang.model.api.RevisionAwareXPath; +import org.opendaylight.controller.yang.model.api.SchemaContext; +import org.opendaylight.controller.yang.model.api.SchemaNode; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition; @@ -49,8 +68,14 @@ import org.opendaylight.controller.yang.model.util.Int64; import org.opendaylight.controller.yang.model.util.Int8; import org.opendaylight.controller.yang.model.util.Leafref; import org.opendaylight.controller.yang.model.util.StringType; +import org.opendaylight.controller.yang.model.util.Uint16; +import org.opendaylight.controller.yang.model.util.Uint32; +import org.opendaylight.controller.yang.model.util.Uint64; +import org.opendaylight.controller.yang.model.util.Uint8; import org.opendaylight.controller.yang.model.util.UnionType; +import org.opendaylight.controller.yang.model.util.UnknownType; import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder; +import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder; import org.opendaylight.controller.yang.parser.builder.api.Builder; import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder; import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; @@ -61,15 +86,23 @@ import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder.ChoiceNodeImpl; import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ChoiceCaseBuilder.ChoiceCaseNodeImpl; import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder.ContainerSchemaNodeImpl; import org.opendaylight.controller.yang.parser.builder.impl.GroupingBuilderImpl; import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder.ListSchemaNodeImpl; import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.NotificationBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.NotificationBuilder.NotificationDefinitionImpl; +import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder; import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl; +import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.UsesNodeBuilderImpl; @@ -80,15 +113,14 @@ public final class ParserUtils { /** * Get module import referenced by given prefix. - * + * * @param builder * module to search * @param prefix * prefix associated with import * @return ModuleImport based on given prefix */ - public static ModuleImport getModuleImport(final ModuleBuilder builder, - final String prefix) { + public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) { ModuleImport moduleImport = null; for (ModuleImport mi : builder.getModuleImports()) { if (mi.getPrefix().equals(prefix)) { @@ -99,9 +131,170 @@ public final class ParserUtils { return moduleImport; } + /** + * Find dependent module based on given prefix + * + * @param modules + * all available modules + * @param module + * current module + * @param prefix + * target module prefix + * @param line + * current line in yang model + * @return + */ + public static ModuleBuilder findDependentModuleBuilder(final Map> modules, + final ModuleBuilder module, final String prefix, final int line) { + ModuleBuilder dependentModule = null; + Date dependentModuleRevision = null; + + if (prefix.equals(module.getPrefix())) { + dependentModule = module; + } else { + final ModuleImport dependentModuleImport = getModuleImport(module, prefix); + if (dependentModuleImport == null) { + throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'."); + } + final String dependentModuleName = dependentModuleImport.getModuleName(); + dependentModuleRevision = dependentModuleImport.getRevision(); + + final TreeMap moduleBuildersByRevision = modules.get(dependentModuleName); + if (moduleBuildersByRevision == null) { + return null; + } + if (dependentModuleRevision == null) { + dependentModule = moduleBuildersByRevision.lastEntry().getValue(); + } else { + dependentModule = moduleBuildersByRevision.get(dependentModuleRevision); + } + } + return dependentModule; + } + + /** + * Find module from context based on prefix. + * + * @param context + * schema context + * @param currentModule + * current module + * @param prefix + * current prefix used to reference dependent module + * @param line + * current line in yang model + * @return module based on given prefix if found in context, null otherwise + */ + public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule, + final String prefix, final int line) { + TreeMap modulesByRevision = new TreeMap(); + + Date dependentModuleRevision = null; + + final ModuleImport dependentModuleImport = ParserUtils.getModuleImport(currentModule, prefix); + if (dependentModuleImport == null) { + throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'."); + } + final String dependentModuleName = dependentModuleImport.getModuleName(); + dependentModuleRevision = dependentModuleImport.getRevision(); + + for (Module contextModule : context.getModules()) { + if (contextModule.getName().equals(dependentModuleName)) { + Date revision = contextModule.getRevision(); + if (revision == null) { + revision = new Date(0L); + } + modulesByRevision.put(revision, contextModule); + break; + } + } + + Module result = null; + if (dependentModuleRevision == null) { + result = modulesByRevision.get(modulesByRevision.firstKey()); + } else { + result = modulesByRevision.get(dependentModuleRevision); + } + + return result; + } + + /** + * Find grouping by name. + * + * @param groupings + * collection of grouping builders to search + * @param name + * name of grouping + * @return grouping with given name if present in collection, null otherwise + */ + public static GroupingBuilder findGroupingBuilder(Set groupings, String name) { + for (GroupingBuilder grouping : groupings) { + if (grouping.getQName().getLocalName().equals(name)) { + return grouping; + } + } + return null; + } + + /** + * Find grouping by name. + * + * @param groupings + * collection of grouping definitions to search + * @param name + * name of grouping + * @return grouping with given name if present in collection, null otherwise + */ + public static GroupingDefinition findGroupingDefinition(Set groupings, String name) { + for (GroupingDefinition grouping : groupings) { + if (grouping.getQName().getLocalName().equals(name)) { + return grouping; + } + } + return null; + } + + /** + * Search types for type with given name. + * + * @param types + * types to search + * @param name + * name of type + * @return type with given name if present in collection, null otherwise + */ + public static TypeDefinitionBuilder findTypedefBuilderByName(Set types, String name) { + for (TypeDefinitionBuilder td : types) { + if (td.getQName().getLocalName().equals(name)) { + return td; + } + } + return null; + } + + /** + * Find type by name. + * + * @param types + * collection of types + * @param typeName + * type name + * @return type with given name if it is present in collection, null + * otherwise + */ + public static TypeDefinition findTypeByName(Set> types, String typeName) { + for (TypeDefinition type : types) { + if (type.getQName().getLocalName().equals(typeName)) { + return type; + } + } + return null; + } + /** * Parse uses path. - * + * * @param usesPath * as String * @return SchemaPath from given String @@ -117,8 +310,7 @@ public final class ParserUtils { if (splittedElement.length == 1) { name = new QName(null, null, null, splittedElement[0]); } else { - name = new QName(null, null, splittedElement[0], - splittedElement[1]); + name = new QName(null, null, splittedElement[0], splittedElement[1]); } path.add(name); } @@ -126,15 +318,103 @@ public final class ParserUtils { return new SchemaPath(path, absolute); } + /** + * Pull restriction from type and add them to constraints. + * + * @param type + * @param constraints + */ + public static void mergeConstraints(final TypeDefinition type, final TypeConstraints constraints) { + if (type instanceof DecimalTypeDefinition) { + constraints.addRanges(((DecimalTypeDefinition) type).getRangeStatements()); + constraints.addFractionDigits(((DecimalTypeDefinition) type).getFractionDigits()); + } else if (type instanceof IntegerTypeDefinition) { + constraints.addRanges(((IntegerTypeDefinition) type).getRangeStatements()); + } else if (type instanceof StringTypeDefinition) { + constraints.addPatterns(((StringTypeDefinition) type).getPatterns()); + constraints.addLengths(((StringTypeDefinition) type).getLengthStatements()); + } else if (type instanceof BinaryTypeDefinition) { + constraints.addLengths(((BinaryTypeDefinition) type).getLengthConstraints()); + } + } + + /** + * 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.getChildNode(refineNodeName); + // search groupings + if (result == null) { + Set grps = grouping.getGroupings(); + for (GroupingBuilder gr : grps) { + if (gr.getQName().getLocalName().equals(refineNodeName)) { + result = gr; + break; + } + } + } + // search typedefs + if (result == null) { + Set typedefs = grouping.getTypeDefinitions(); + 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. - * + * * @param augment + * builder of augment statement * @param target + * augmentation target node */ - public static void fillAugmentTarget( - final AugmentationSchemaBuilder augment, - final DataNodeContainerBuilder target) { + public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) { for (DataSchemaNodeBuilder builder : augment.getChildNodes()) { builder.setAugmenting(true); correctAugmentChildPath(builder, target.getPath()); @@ -142,8 +422,15 @@ public final class ParserUtils { } } - public static void fillAugmentTarget( - final AugmentationSchemaBuilder augment, final ChoiceBuilder target) { + /** + * Add all augment's child nodes to given target. + * + * @param augment + * builder of augment statement + * @param target + * augmentation target choice node + */ + public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final ChoiceBuilder target) { for (DataSchemaNodeBuilder builder : augment.getChildNodes()) { builder.setAugmenting(true); correctAugmentChildPath(builder, target.getPath()); @@ -151,21 +438,16 @@ public final class ParserUtils { } } - private static void correctAugmentChildPath( - final DataSchemaNodeBuilder childNode, - final SchemaPath parentSchemaPath) { - + private static void correctAugmentChildPath(final DataSchemaNodeBuilder childNode, final SchemaPath parentSchemaPath) { // set correct path - List targetNodePath = new ArrayList( - parentSchemaPath.getPath()); + List targetNodePath = new ArrayList(parentSchemaPath.getPath()); targetNodePath.add(childNode.getQName()); childNode.setPath(new SchemaPath(targetNodePath, true)); // set correct path for all child nodes if (childNode instanceof DataNodeContainerBuilder) { DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) childNode; - for (DataSchemaNodeBuilder child : dataNodeContainer - .getChildNodes()) { + for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodes()) { correctAugmentChildPath(child, childNode.getPath()); } } @@ -179,14 +461,13 @@ public final class ParserUtils { /** * Repair schema path of node type. - * + * * @param node * node which contains type statement * @param parentSchemaPath * schema path of parent node */ - private static void correctTypeAwareNodePath( - TypeAwareBuilder node, SchemaPath parentSchemaPath) { + private static void correctTypeAwareNodePath(final TypeAwareBuilder node, final SchemaPath parentSchemaPath) { final QName nodeBuilderQName = node.getQName(); final TypeDefinition nodeType = node.getType(); @@ -198,11 +479,7 @@ public final class ParserUtils { if (nodeType != null) { if (nodeType instanceof ExtendedType) { ExtendedType et = (ExtendedType) nodeType; - if (nodeType - .getQName() - .getLocalName() - .equals(nodeType.getBaseType().getQName() - .getLocalName())) { + if (nodeType.getQName().getLocalName().equals(nodeType.getBaseType().getQName().getLocalName())) { fd = et.getFractionDigits(); lengths = et.getLengths(); patterns = et.getPatterns(); @@ -212,8 +489,7 @@ public final class ParserUtils { } } } - TypeDefinition newType = createCorrectTypeDefinition( - parentSchemaPath, nodeBuilderQName, nodeType); + TypeDefinition newType = createCorrectTypeDefinition(parentSchemaPath, nodeBuilderQName, nodeType); node.setType(newType); } else { TypeDefinitionBuilder nodeBuilderTypedef = node.getTypedef(); @@ -226,11 +502,9 @@ public final class ParserUtils { String tdbTypeName = nodeBuilderTypedef.getQName().getLocalName(); String baseTypeName = null; if (nodeBuilderTypedef.getType() == null) { - baseTypeName = nodeBuilderTypedef.getTypedef().getQName() - .getLocalName(); + baseTypeName = nodeBuilderTypedef.getTypedef().getQName().getLocalName(); } else { - baseTypeName = nodeBuilderTypedef.getType().getQName() - .getLocalName(); + baseTypeName = nodeBuilderTypedef.getType().getQName().getLocalName(); } if (!(tdbTypeName.equals(baseTypeName))) { return; @@ -240,8 +514,7 @@ public final class ParserUtils { return; } - SchemaPath newSchemaPath = createNewSchemaPath( - nodeBuilderTypedef.getPath(), nodeBuilderQName, + SchemaPath newSchemaPath = createNewSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName, nodeBuilderTypedef.getQName()); nodeBuilderTypedef.setPath(newSchemaPath); } @@ -249,7 +522,7 @@ public final class ParserUtils { /** * Check if there are some constraints. - * + * * @param fd * fraction digits * @param lengths @@ -260,12 +533,9 @@ public final class ParserUtils { * range constraints * @return true, if any of constraints are present, false otherwise */ - private static boolean hasConstraints(final Integer fd, - final List lengths, - final List patterns, - final List ranges) { - if (fd == null && (lengths == null || lengths.isEmpty()) - && (patterns == null || patterns.isEmpty()) + private static boolean hasConstraints(final Integer fd, final List lengths, + final List patterns, final List ranges) { + if (fd == null && (lengths == null || lengths.isEmpty()) && (patterns == null || patterns.isEmpty()) && (ranges == null || ranges.isEmpty())) { return false; } else { @@ -273,122 +543,106 @@ public final class ParserUtils { } } - private static TypeDefinition createCorrectTypeDefinition( - SchemaPath parentSchemaPath, QName nodeQName, + private static TypeDefinition createCorrectTypeDefinition(SchemaPath parentSchemaPath, QName nodeQName, TypeDefinition nodeType) { + QName nodeTypeQName = nodeType.getQName(); + SchemaPath newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeTypeQName); TypeDefinition result = null; - SchemaPath newSchemaPath = null; + if (nodeType != null) { if (nodeType instanceof BinaryTypeDefinition) { BinaryTypeDefinition binType = (BinaryTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, binType.getQName()); - List bytes = (List) binType.getDefaultValue(); + + // List bytes = (List) binType.getDefaultValue(); + // workaround to get rid of 'Unchecked cast' warning + List bytes = new ArrayList(); + Object defaultValue = binType.getDefaultValue(); + if (defaultValue instanceof List) { + for (Object o : List.class.cast(defaultValue)) { + if (o instanceof Byte) { + bytes.add((Byte) o); + } + } + } result = new BinaryType(newSchemaPath, bytes); } else if (nodeType instanceof BitsTypeDefinition) { BitsTypeDefinition bitsType = (BitsTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, nodeType.getQName()); result = new BitsType(newSchemaPath, bitsType.getBits()); } else if (nodeType instanceof BooleanTypeDefinition) { - BooleanTypeDefinition booleanType = (BooleanTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, booleanType.getQName()); result = new BooleanType(newSchemaPath); } else if (nodeType instanceof DecimalTypeDefinition) { DecimalTypeDefinition decimalType = (DecimalTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, decimalType.getQName()); - result = new Decimal64(newSchemaPath, - decimalType.getFractionDigits()); + result = new Decimal64(newSchemaPath, decimalType.getFractionDigits()); } else if (nodeType instanceof EmptyTypeDefinition) { - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, nodeType.getQName()); result = new EmptyType(newSchemaPath); } else if (nodeType instanceof EnumTypeDefinition) { EnumTypeDefinition enumType = (EnumTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, enumType.getQName()); - result = new EnumerationType(newSchemaPath, - (EnumPair) enumType.getDefaultValue(), - enumType.getValues()); + result = new EnumerationType(newSchemaPath, (EnumPair) enumType.getDefaultValue(), enumType.getValues()); } else if (nodeType instanceof IdentityrefTypeDefinition) { IdentityrefTypeDefinition idrefType = (IdentityrefTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, idrefType.getQName()); - result = new IdentityrefType(idrefType.getIdentity(), - newSchemaPath); + result = new IdentityrefType(idrefType.getIdentity(), newSchemaPath); } else if (nodeType instanceof InstanceIdentifierTypeDefinition) { InstanceIdentifierTypeDefinition instIdType = (InstanceIdentifierTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, instIdType.getQName()); - return new InstanceIdentifier(newSchemaPath, - instIdType.getPathStatement(), + return new InstanceIdentifier(newSchemaPath, instIdType.getPathStatement(), instIdType.requireInstance()); } else if (nodeType instanceof StringTypeDefinition) { - result = createNewStringType(parentSchemaPath, nodeQName, - (StringTypeDefinition) nodeType); + result = createNewStringType(parentSchemaPath, nodeQName, (StringTypeDefinition) nodeType); } else if (nodeType instanceof IntegerTypeDefinition) { - result = createNewIntType(parentSchemaPath, nodeQName, - (IntegerTypeDefinition) nodeType); + result = createNewIntType(parentSchemaPath, nodeQName, (IntegerTypeDefinition) nodeType); } else if (nodeType instanceof UnsignedIntegerTypeDefinition) { - result = createNewUintType(parentSchemaPath, nodeQName, - (UnsignedIntegerTypeDefinition) nodeType); + result = createNewUintType(parentSchemaPath, nodeQName, (UnsignedIntegerTypeDefinition) nodeType); } else if (nodeType instanceof LeafrefTypeDefinition) { - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, nodeType.getQName()); - result = new Leafref(newSchemaPath, - ((LeafrefTypeDefinition) nodeType).getPathStatement()); + result = new Leafref(newSchemaPath, ((LeafrefTypeDefinition) nodeType).getPathStatement()); } else if (nodeType instanceof UnionTypeDefinition) { UnionTypeDefinition unionType = (UnionTypeDefinition) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, unionType.getQName()); return new UnionType(newSchemaPath, unionType.getTypes()); } else if (nodeType instanceof ExtendedType) { ExtendedType extType = (ExtendedType) nodeType; - newSchemaPath = createNewSchemaPath(parentSchemaPath, - nodeQName, extType.getQName()); - result = createNewExtendedType(newSchemaPath, extType); + result = createNewExtendedType(extType, newSchemaPath); } } return result; } - private static TypeDefinition createNewExtendedType( - SchemaPath newSchemaPath, ExtendedType oldExtendedType) { - QName qname = oldExtendedType.getQName(); - TypeDefinition baseType = oldExtendedType.getBaseType(); - String desc = oldExtendedType.getDescription(); - String ref = oldExtendedType.getReference(); - ExtendedType.Builder builder = new ExtendedType.Builder(qname, - baseType, desc, ref, newSchemaPath); - builder.status(oldExtendedType.getStatus()); - builder.lengths(oldExtendedType.getLengths()); - builder.patterns(oldExtendedType.getPatterns()); - builder.ranges(oldExtendedType.getRanges()); - builder.fractionDigits(oldExtendedType.getFractionDigits()); - builder.unknownSchemaNodes(oldExtendedType.getUnknownSchemaNodes()); + /** + * Create new ExtendedType based on given type and with schema path. + * + * @param newPath + * schema path for new type + * @param oldType + * type based + * @return + */ + private static ExtendedType createNewExtendedType(final ExtendedType oldType, final SchemaPath newPath) { + QName qname = oldType.getQName(); + TypeDefinition baseType = oldType.getBaseType(); + String desc = oldType.getDescription(); + String ref = oldType.getReference(); + ExtendedType.Builder builder = new ExtendedType.Builder(qname, baseType, desc, ref, newPath); + builder.status(oldType.getStatus()); + builder.lengths(oldType.getLengths()); + builder.patterns(oldType.getPatterns()); + builder.ranges(oldType.getRanges()); + builder.fractionDigits(oldType.getFractionDigits()); + builder.unknownSchemaNodes(oldType.getUnknownSchemaNodes()); return builder.build(); } - private static TypeDefinition createNewStringType(SchemaPath schemaPath, - QName nodeQName, StringTypeDefinition nodeType) { - List path = schemaPath.getPath(); - List newPath = new ArrayList(path); + private static StringTypeDefinition createNewStringType(final SchemaPath schemaPath, final QName nodeQName, + final StringTypeDefinition nodeType) { + final List path = schemaPath.getPath(); + final List newPath = new ArrayList(path); newPath.add(nodeQName); newPath.add(nodeType.getQName()); - SchemaPath newSchemaPath = new SchemaPath(newPath, - schemaPath.isAbsolute()); - + final SchemaPath newSchemaPath = new SchemaPath(newPath, schemaPath.isAbsolute()); return new StringType(newSchemaPath); } - private static TypeDefinition createNewIntType(SchemaPath schemaPath, - QName nodeQName, IntegerTypeDefinition type) { - QName typeQName = type.getQName(); - SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, - typeQName); - String localName = typeQName.getLocalName(); + private static IntegerTypeDefinition createNewIntType(final SchemaPath schemaPath, final QName nodeQName, + final IntegerTypeDefinition type) { + final QName typeQName = type.getQName(); + final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName); + final String localName = typeQName.getLocalName(); if ("int8".equals(localName)) { return new Int8(newSchemaPath); @@ -403,335 +657,55 @@ public final class ParserUtils { } } - private static TypeDefinition createNewUintType(SchemaPath schemaPath, - QName nodeQName, UnsignedIntegerTypeDefinition type) { - QName typeQName = type.getQName(); - SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, - typeQName); - String localName = typeQName.getLocalName(); + private static UnsignedIntegerTypeDefinition createNewUintType(final SchemaPath schemaPath, final QName nodeQName, + final UnsignedIntegerTypeDefinition type) { + final QName typeQName = type.getQName(); + final SchemaPath newSchemaPath = createNewSchemaPath(schemaPath, nodeQName, typeQName); + final String localName = typeQName.getLocalName(); if ("uint8".equals(localName)) { - return new Int8(newSchemaPath); + return new Uint8(newSchemaPath); } else if ("uint16".equals(localName)) { - return new Int16(newSchemaPath); + return new Uint16(newSchemaPath); } else if ("uint32".equals(localName)) { - return new Int32(newSchemaPath); + return new Uint32(newSchemaPath); } else if ("uint64".equals(localName)) { - return new Int64(newSchemaPath); + return new Uint64(newSchemaPath); } else { return null; } } - private static SchemaPath createNewSchemaPath(SchemaPath schemaPath, - QName currentQName, QName qname) { + private static SchemaPath createNewSchemaPath(final SchemaPath schemaPath, final QName currentQName, + final QName qname) { List newPath = new ArrayList(schemaPath.getPath()); newPath.add(currentQName); newPath.add(qname); return new SchemaPath(newPath, schemaPath.isAbsolute()); } - public static void refineLeaf(LeafSchemaNodeBuilder leaf, - RefineHolder refine, int line) { - String defaultStr = refine.getDefaultStr(); - Boolean mandatory = refine.isMandatory(); - MustDefinition must = refine.getMust(); - List unknownNodes = refine.getUnknownNodes(); - - if (defaultStr != null && !("".equals(defaultStr))) { - leaf.setDefaultStr(defaultStr); - } - if (mandatory != null) { - leaf.getConstraints().setMandatory(mandatory); - } - if (must != null) { - leaf.getConstraints().addMustDefinition(must); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - leaf.addUnknownSchemaNode(unknown); - } - } - } - - public static void refineContainer(ContainerSchemaNodeBuilder container, - RefineHolder refine, int line) { - Boolean presence = refine.isPresence(); - MustDefinition must = refine.getMust(); - List unknownNodes = refine.getUnknownNodes(); - - if (presence != null) { - container.setPresence(presence); - } - if (must != null) { - container.getConstraints().addMustDefinition(must); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - container.addUnknownSchemaNode(unknown); - } - } - } - - public static void refineList(ListSchemaNodeBuilder list, - RefineHolder refine, int line) { - MustDefinition must = refine.getMust(); - Integer min = refine.getMinElements(); - Integer max = refine.getMaxElements(); - List unknownNodes = refine.getUnknownNodes(); - - if (must != null) { - list.getConstraints().addMustDefinition(must); - } - if (min != null) { - list.getConstraints().setMinElements(min); - } - if (max != null) { - list.getConstraints().setMaxElements(max); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - list.addUnknownSchemaNode(unknown); - } - } - } - - public static void refineLeafList(LeafListSchemaNodeBuilder leafList, - RefineHolder refine, int line) { - MustDefinition must = refine.getMust(); - Integer min = refine.getMinElements(); - Integer max = refine.getMaxElements(); - List unknownNodes = refine.getUnknownNodes(); - - if (must != null) { - leafList.getConstraints().addMustDefinition(must); - } - if (min != null) { - leafList.getConstraints().setMinElements(min); - } - if (max != null) { - leafList.getConstraints().setMaxElements(max); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - leafList.addUnknownSchemaNode(unknown); - } - } - } - - public static void refineChoice(ChoiceBuilder choice, RefineHolder refine, - int line) { - String defaultStr = refine.getDefaultStr(); - Boolean mandatory = refine.isMandatory(); - List unknownNodes = refine.getUnknownNodes(); - - if (defaultStr != null) { - choice.setDefaultCase(defaultStr); - } - if (mandatory != null) { - choice.getConstraints().setMandatory(mandatory); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - choice.addUnknownSchemaNode(unknown); - } - } - } - - public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine, - int line) { - Boolean mandatory = refine.isMandatory(); - MustDefinition must = refine.getMust(); - List unknownNodes = refine.getUnknownNodes(); - - if (mandatory != null) { - anyXml.getConstraints().setMandatory(mandatory); - } - if (must != null) { - anyXml.getConstraints().addMustDefinition(must); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - anyXml.addUnknownSchemaNode(unknown); - } - } - } - - public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) { - String name = node.getQName().getLocalName(); - int line = refine.getLine(); - - String defaultStr = refine.getDefaultStr(); - Boolean mandatory = refine.isMandatory(); - Boolean presence = refine.isPresence(); - MustDefinition must = refine.getMust(); - Integer min = refine.getMinElements(); - Integer max = refine.getMaxElements(); - - if (node instanceof AnyXmlBuilder) { - checkRefineDefault(node, defaultStr, line); - checkRefinePresence(node, presence, line); - checkRefineMinMax(name, line, min, max); - } else if (node instanceof ChoiceBuilder) { - checkRefinePresence(node, presence, line); - checkRefineMust(node, must, line); - checkRefineMinMax(name, line, min, max); - } else if (node instanceof ContainerSchemaNodeBuilder) { - checkRefineDefault(node, defaultStr, line); - checkRefineMandatory(node, mandatory, line); - checkRefineMust(node, must, line); - checkRefineMinMax(name, line, min, max); - } else if (node instanceof LeafSchemaNodeBuilder) { - checkRefinePresence(node, presence, line); - checkRefineMinMax(name, line, min, max); - } else if (node instanceof LeafListSchemaNodeBuilder - || node instanceof ListSchemaNodeBuilder) { - checkRefineDefault(node, defaultStr, line); - checkRefinePresence(node, presence, line); - checkRefineMandatory(node, mandatory, line); - } else if (node instanceof GroupingBuilder - || node instanceof TypeDefinitionBuilder - || node instanceof UsesNodeBuilder) { - checkRefineDefault(node, defaultStr, line); - checkRefinePresence(node, presence, line); - checkRefineMandatory(node, mandatory, line); - checkRefineMust(node, must, line); - checkRefineMinMax(name, line, min, max); - } - } - - private static void checkRefineDefault(SchemaNodeBuilder node, - String defaultStr, int line) { - if (defaultStr != null) { - throw new YangParseException(line, "Can not refine 'default' for '" - + node.getQName().getLocalName() + "'."); - } - } - - private static void checkRefineMandatory(SchemaNodeBuilder node, - Boolean mandatory, int line) { - if (mandatory != null) { - throw new YangParseException(line, - "Can not refine 'mandatory' for '" - + node.getQName().getLocalName() + "'."); - } - } - - private static void checkRefinePresence(SchemaNodeBuilder node, - Boolean presence, int line) { - if (presence != null) { - throw new YangParseException(line, - "Can not refine 'presence' for '" - + node.getQName().getLocalName() + "'."); - } - } - - private static void checkRefineMust(SchemaNodeBuilder node, - MustDefinition must, int line) { - if (must != null) { - throw new YangParseException(line, "Can not refine 'must' for '" - + node.getQName().getLocalName() + "'."); - } - } - - private static void checkRefineMinMax(String refineTargetName, - int refineLine, Integer min, Integer max) { - if (min != null || max != null) { - throw new YangParseException(refineLine, - "Can not refine 'min-elements' or 'max-elements' for '" - + refineTargetName + "'."); - } - } - - /** - * Perform refine operation of following parameters: - *
    - *
  • description
  • - *
  • reference
  • - *
  • config
  • - *
- * - * These parameters may be refined for any node. - * - * @param node - * node to refine - * @param refine - * refine holder containing values to refine - * @param line - * current line in yang model - */ - public static void refineDefault(Builder node, RefineHolder refine, int line) { - Class cls = node.getClass(); - - String description = refine.getDescription(); - if (description != null) { - try { - Method method = cls.getDeclaredMethod("setDescription", - String.class); - method.invoke(node, description); - } catch (Exception e) { - throw new YangParseException(line, - "Cannot refine description in " + cls.getName(), e); - } - } - - String reference = refine.getReference(); - if (reference != null) { - try { - Method method = cls.getDeclaredMethod("setReference", - String.class); - method.invoke(node, reference); - } catch (Exception e) { - throw new YangParseException(line, - "Cannot refine reference in " + cls.getName(), e); - } - } - - Boolean config = refine.isConfig(); - if (config != null) { - try { - Method method = cls.getDeclaredMethod("setConfiguration", - Boolean.TYPE); - method.invoke(node, config); - } catch (Exception e) { - throw new YangParseException(line, "Cannot refine config in " - + cls.getName(), e); - } - } - } - - public static LeafSchemaNodeBuilder copyLeafBuilder( - final LeafSchemaNodeBuilder old) { - final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder( - old.getQName(), old.getLine()); + public static LeafSchemaNodeBuilder copyLeafBuilder(final LeafSchemaNodeBuilder old) { + final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(old.getQName(), old.getLine()); final TypeDefinition type = old.getType(); - if (type == null) { copy.setTypedef(old.getTypedef()); } else { copy.setType(type); } - copy.setPath(old.getPath()); - copyConstraints(old, copy); + copyDataSchemaNodeArgs(old, copy); + copyConstraintsFromBuilder(old, copy); for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { copy.addUnknownSchemaNode(unknown); } - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - copy.setAugmenting(old.isAugmenting()); - copy.setConfiguration(old.isConfiguration()); copy.setDefaultStr(old.getDefaultStr()); copy.setUnits(old.getUnits()); return copy; } - public static ContainerSchemaNodeBuilder copyContainerBuilder( - final ContainerSchemaNodeBuilder old) { - final ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder( - old.getQName(), old.getLine()); - copy.setPath(old.getPath()); - copyConstraints(old, copy); + public static ContainerSchemaNodeBuilder copyContainerBuilder(final ContainerSchemaNodeBuilder old) { + final ContainerSchemaNodeBuilder copy = new ContainerSchemaNodeBuilder(old.getQName(), old.getLine()); + copyDataSchemaNodeArgs(old, copy); + copyConstraintsFromBuilder(old, copy); for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { copy.addUnknownSchemaNode(unknown); } @@ -750,21 +724,14 @@ public final class ParserUtils { for (UsesNodeBuilder use : old.getUsesNodes()) { copy.addUsesNode(use); } - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - copy.setAugmenting(old.isAugmenting()); - copy.setConfiguration(old.isConfiguration()); copy.setPresence(old.isPresence()); return copy; } - public static ListSchemaNodeBuilder copyListBuilder( - final ListSchemaNodeBuilder old) { - final ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder( - old.getQName(), old.getLine()); - copy.setPath(old.getPath()); - copyConstraints(old, copy); + public static ListSchemaNodeBuilder copyListBuilder(final ListSchemaNodeBuilder old) { + final ListSchemaNodeBuilder copy = new ListSchemaNodeBuilder(old.getQName(), old.getLine()); + copyDataSchemaNodeArgs(old, copy); + copyConstraintsFromBuilder(old, copy); for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { copy.addUnknownSchemaNode(unknown); } @@ -783,21 +750,14 @@ public final class ParserUtils { for (UsesNodeBuilder use : old.getUsesNodes()) { copy.addUsesNode(use); } - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - copy.setAugmenting(old.isAugmenting()); - copy.setConfiguration(old.isConfiguration()); copy.setUserOrdered(old.isUserOrdered()); return copy; } - public static LeafListSchemaNodeBuilder copyLeafListBuilder( - final LeafListSchemaNodeBuilder old) { - final LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder( - old.getQName(), old.getLine()); - copy.setPath(old.getPath()); - copyConstraints(old, copy); + public static LeafListSchemaNodeBuilder copyLeafListBuilder(final LeafListSchemaNodeBuilder old) { + final LeafListSchemaNodeBuilder copy = new LeafListSchemaNodeBuilder(old.getQName(), old.getLine()); + copyDataSchemaNodeArgs(old, copy); + copyConstraintsFromBuilder(old, copy); final TypeDefinition type = old.getType(); if (type == null) { copy.setTypedef(old.getTypedef()); @@ -807,20 +767,14 @@ public final class ParserUtils { for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { copy.addUnknownSchemaNode(unknown); } - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - copy.setAugmenting(old.isAugmenting()); - copy.setConfiguration(old.isConfiguration()); copy.setUserOrdered(old.isUserOrdered()); return copy; } public static ChoiceBuilder copyChoiceBuilder(final ChoiceBuilder old) { - final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(), - old.getLine()); - copy.setPath(old.getPath()); - copyConstraints(old, copy); + final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(), old.getLine()); + copyDataSchemaNodeArgs(old, copy); + copyConstraintsFromBuilder(old, copy); for (ChoiceCaseBuilder caseBuilder : old.getCases()) { copy.addChildNode(caseBuilder); } @@ -828,32 +782,21 @@ public final class ParserUtils { copy.addUnknownSchemaNode(unknown); } copy.setDefaultCase(old.getDefaultCase()); - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - copy.setAugmenting(old.isAugmenting()); - copy.setConfiguration(old.isConfiguration()); return copy; } public static AnyXmlBuilder copyAnyXmlBuilder(final AnyXmlBuilder old) { - final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(), - old.getLine()); - copy.setPath(old.getPath()); - copyConstraints(old, copy); + final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(), old.getLine()); + copyDataSchemaNodeArgs(old, copy); + copyConstraintsFromBuilder(old, copy); for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { copy.addUnknownSchemaNode(unknown); } - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - copy.setConfiguration(old.isConfiguration()); return copy; } public static GroupingBuilder copyGroupingBuilder(final GroupingBuilder old) { - final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(), - old.getLine()); + final GroupingBuilder copy = new GroupingBuilderImpl(old.getQName(), old.getLine()); copy.setPath(old.getPath()); for (DataSchemaNodeBuilder child : old.getChildNodes()) { copy.addChildNode(child); @@ -876,10 +819,8 @@ public final class ParserUtils { return copy; } - public static TypeDefinitionBuilderImpl copyTypedefBuilder( - TypeDefinitionBuilderImpl old) { - final TypeDefinitionBuilderImpl copy = new TypeDefinitionBuilderImpl( - old.getQName(), old.getLine()); + public static TypeDefinitionBuilderImpl copyTypedefBuilder(final TypeDefinitionBuilderImpl old) { + final TypeDefinitionBuilderImpl copy = new TypeDefinitionBuilderImpl(old.getQName(), old.getLine()); copy.setPath(old.getPath()); copy.setDefaultValue(old.getDefaultValue()); copy.setUnits(old.getUnits()); @@ -905,9 +846,8 @@ public final class ParserUtils { return copy; } - public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) { - final UsesNodeBuilder copy = new UsesNodeBuilderImpl( - old.getGroupingName(), old.getLine()); + public static UsesNodeBuilder copyUsesNodeBuilder(final UsesNodeBuilder old) { + final UsesNodeBuilder copy = new UsesNodeBuilderImpl(old.getGroupingName(), old.getLine()); for (AugmentationSchemaBuilder augment : old.getAugmentations()) { copy.addAugment(augment); } @@ -918,7 +858,25 @@ public final class ParserUtils { return copy; } - private static void copyConstraints(final DataSchemaNodeBuilder oldBuilder, + private static void copyDataSchemaNodeArgs(final DataSchemaNodeBuilder oldBuilder, + final DataSchemaNodeBuilder newBuilder) { + newBuilder.setPath(oldBuilder.getPath()); + newBuilder.setDescription(oldBuilder.getDescription()); + newBuilder.setReference(oldBuilder.getReference()); + newBuilder.setStatus(oldBuilder.getStatus()); + newBuilder.setAugmenting(oldBuilder.isAugmenting()); + if (!(oldBuilder instanceof ChoiceCaseNode)) { + newBuilder.setConfiguration(oldBuilder.isConfiguration()); + } + } + + /** + * Copy constraints from old builder to new builder. + * + * @param oldBuilder + * @param newBuilder + */ + private static void copyConstraintsFromBuilder(final DataSchemaNodeBuilder oldBuilder, final DataSchemaNodeBuilder newBuilder) { final ConstraintsBuilder oldConstraints = oldBuilder.getConstraints(); final ConstraintsBuilder newConstraints = newBuilder.getConstraints(); @@ -931,4 +889,528 @@ public final class ParserUtils { newConstraints.setMaxElements(oldConstraints.getMaxElements()); } + /** + * Create LeafSchemaNodeBuilder from given LeafSchemaNode. + * + * @param leaf + * leaf from which to create builder + * @param line + * line in module + * @return builder object from leaf + */ + public static LeafSchemaNodeBuilder createLeafBuilder(LeafSchemaNode leaf, int line) { + final LeafSchemaNodeBuilder builder = new LeafSchemaNodeBuilder(leaf.getQName(), line); + convertDataSchemaNode(leaf, builder); + final TypeDefinition type = leaf.getType(); + builder.setType(type); + builder.setPath(leaf.getPath()); + builder.setUnknownNodes(leaf.getUnknownSchemaNodes()); + builder.setDefaultStr(leaf.getDefault()); + builder.setUnits(leaf.getUnits()); + return builder; + } + + public static ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, int line) { + final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(container.getQName(), line); + convertDataSchemaNode(container, builder); + builder.setUnknownNodes(container.getUnknownSchemaNodes()); + builder.setChildNodes(container.getChildNodes()); + builder.setGroupings(container.getGroupings()); + builder.setTypedefs(container.getTypeDefinitions()); + builder.setAugmentations(container.getAvailableAugmentations()); + builder.setUsesnodes(container.getUses()); + builder.setPresence(container.isPresenceContainer()); + return builder; + } + + public static ListSchemaNodeBuilder createList(ListSchemaNode list, int line) { + ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(list.getQName(), line); + convertDataSchemaNode(list, builder); + builder.setUnknownNodes(list.getUnknownSchemaNodes()); + builder.setTypedefs(list.getTypeDefinitions()); + builder.setChildNodes(list.getChildNodes()); + builder.setGroupings(list.getGroupings()); + builder.setAugmentations(list.getAvailableAugmentations()); + builder.setUsesnodes(list.getUses()); + builder.setUserOrdered(builder.isUserOrdered()); + return builder; + } + + public static LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, int line) { + final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(leafList.getQName(), line); + convertDataSchemaNode(leafList, builder); + builder.setType(leafList.getType()); + builder.setUnknownNodes(leafList.getUnknownSchemaNodes()); + builder.setUserOrdered(leafList.isUserOrdered()); + return builder; + } + + public static ChoiceBuilder createChoice(ChoiceNode choice, int line) { + final ChoiceBuilder builder = new ChoiceBuilder(choice.getQName(), line); + convertDataSchemaNode(choice, builder); + builder.setCases(choice.getCases()); + builder.setUnknownNodes(choice.getUnknownSchemaNodes()); + builder.setDefaultCase(choice.getDefaultCase()); + return builder; + } + + public static AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, int line) { + final AnyXmlBuilder builder = new AnyXmlBuilder(anyxml.getQName(), line); + convertDataSchemaNode(anyxml, builder); + builder.setUnknownNodes(anyxml.getUnknownSchemaNodes()); + return builder; + } + + public static GroupingBuilder createGrouping(GroupingDefinition grouping, int line) { + final GroupingBuilderImpl builder = new GroupingBuilderImpl(grouping.getQName(), line); + builder.setPath(grouping.getPath()); + builder.setChildNodes(grouping.getChildNodes()); + builder.setGroupings(grouping.getGroupings()); + builder.setTypedefs(grouping.getTypeDefinitions()); + builder.setUsesnodes(grouping.getUses()); + builder.setUnknownNodes(grouping.getUnknownSchemaNodes()); + builder.setDescription(grouping.getDescription()); + builder.setReference(grouping.getReference()); + builder.setStatus(grouping.getStatus()); + return builder; + } + + public static TypeDefinitionBuilder createTypedef(ExtendedType typedef, int line) { + final TypeDefinitionBuilderImpl builder = new TypeDefinitionBuilderImpl(typedef.getQName(), line); + builder.setPath(typedef.getPath()); + builder.setDefaultValue(typedef.getDefaultValue()); + builder.setUnits(typedef.getUnits()); + builder.setDescription(typedef.getDescription()); + builder.setReference(typedef.getReference()); + builder.setStatus(typedef.getStatus()); + builder.setRanges(typedef.getRanges()); + builder.setLengths(typedef.getLengths()); + builder.setPatterns(typedef.getPatterns()); + builder.setFractionDigits(typedef.getFractionDigits()); + final TypeDefinition type = typedef.getBaseType(); + builder.setType(type); + builder.setUnits(typedef.getUnits()); + builder.setUnknownNodes(typedef.getUnknownSchemaNodes()); + return builder; + } + + /** + * Set DataSchemaNode arguments to builder object + * + * @param node + * node from which arguments should be read + * @param builder + * builder to which arguments should be set + */ + private static void convertDataSchemaNode(DataSchemaNode node, DataSchemaNodeBuilder builder) { + builder.setPath(node.getPath()); + builder.setDescription(node.getDescription()); + builder.setReference(node.getReference()); + builder.setStatus(node.getStatus()); + builder.setAugmenting(node.isAugmenting()); + if (!(node instanceof ChoiceCaseNode)) { + builder.setConfiguration(node.isConfiguration()); + } + copyConstraintsFromDefinition(node.getConstraints(), builder.getConstraints()); + } + + /** + * Copy constraints from constraints definition to constraints builder. + * + * @param nodeConstraints + * definition from which constraints will be copied + * @param constraints + * builder to which constraints will be added + */ + private static void copyConstraintsFromDefinition(final ConstraintDefinition nodeConstraints, + final ConstraintsBuilder constraints) { + final RevisionAwareXPath when = nodeConstraints.getWhenCondition(); + final Set must = nodeConstraints.getMustConstraints(); + + if (when != null) { + constraints.addWhenCondition(when.toString()); + } + if (must != null) { + for (MustDefinition md : must) { + constraints.addMustDefinition(md); + } + } + constraints.setMandatory(nodeConstraints.isMandatory()); + constraints.setMinElements(nodeConstraints.getMinElements()); + constraints.setMaxElements(nodeConstraints.getMaxElements()); + } + + public static void processAugmentationOnContext(final AugmentationSchemaBuilder augmentBuilder, + final List path, final ModuleBuilder module, final String prefix, final int line, + final SchemaContext context) { + final Module dependentModule = findModuleFromContext(context, module, prefix, line); + if (dependentModule == null) { + throw new YangParseException(module.getName(), line, "Failed to find referenced module with prefix " + + prefix + "."); + } + SchemaNode node = dependentModule.getDataChildByName(path.get(0).getLocalName()); + if (node == null) { + Set notifications = dependentModule.getNotifications(); + for (NotificationDefinition ntf : notifications) { + if (ntf.getQName().getLocalName().equals(path.get(0).getLocalName())) { + node = ntf; + break; + } + } + } + if (node == null) { + return; + } + + for (int i = 1; i < path.size(); i++) { + if (node instanceof DataNodeContainer) { + DataNodeContainer ref = (DataNodeContainer) node; + node = ref.getDataChildByName(path.get(i).getLocalName()); + } + } + if (node == null) { + return; + } + + if (node instanceof ContainerSchemaNodeImpl) { + // includes container, input and output statement + ContainerSchemaNodeImpl c = (ContainerSchemaNodeImpl) node; + ContainerSchemaNodeBuilder cb = c.toBuilder(); + fillAugmentTarget(augmentBuilder, cb); + ((AugmentationTargetBuilder) cb).addAugmentation(augmentBuilder); + SchemaPath oldPath = cb.getPath(); + cb.rebuild(); + augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augmentBuilder.setResolved(true); + module.augmentResolved(); + } else if (node instanceof ListSchemaNodeImpl) { + ListSchemaNodeImpl l = (ListSchemaNodeImpl) node; + ListSchemaNodeBuilder lb = l.toBuilder(); + fillAugmentTarget(augmentBuilder, lb); + ((AugmentationTargetBuilder) lb).addAugmentation(augmentBuilder); + SchemaPath oldPath = lb.getPath(); + lb.rebuild(); + augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augmentBuilder.setResolved(true); + module.augmentResolved(); + } else if (node instanceof ChoiceNodeImpl) { + ChoiceNodeImpl ch = (ChoiceNodeImpl) node; + ChoiceBuilder chb = ch.toBuilder(); + fillAugmentTarget(augmentBuilder, chb); + ((AugmentationTargetBuilder) chb).addAugmentation(augmentBuilder); + SchemaPath oldPath = chb.getPath(); + chb.rebuild(); + augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augmentBuilder.setResolved(true); + module.augmentResolved(); + } else if (node instanceof ChoiceCaseNodeImpl) { + ChoiceCaseNodeImpl chc = (ChoiceCaseNodeImpl) node; + ChoiceCaseBuilder chcb = chc.toBuilder(); + fillAugmentTarget(augmentBuilder, chcb); + ((AugmentationTargetBuilder) chcb).addAugmentation(augmentBuilder); + SchemaPath oldPath = chcb.getPath(); + chcb.rebuild(); + augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augmentBuilder.setResolved(true); + module.augmentResolved(); + } else if (node instanceof NotificationDefinitionImpl) { + NotificationDefinitionImpl nd = (NotificationDefinitionImpl) node; + NotificationBuilder nb = nd.toBuilder(); + fillAugmentTarget(augmentBuilder, nb); + ((AugmentationTargetBuilder) nb).addAugmentation(augmentBuilder); + SchemaPath oldPath = nb.getPath(); + nb.rebuild(); + augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augmentBuilder.setResolved(true); + module.augmentResolved(); + } else { + throw new YangParseException(module.getName(), line, "Target of type " + node.getClass() + + " can not be augmented."); + } + } + + public static void processAugmentation(final AugmentationSchemaBuilder augmentBuilder, final List path, + final ModuleBuilder module, final QName qname, final ModuleBuilder dependentModuleBuilder) { + DataSchemaNodeBuilder currentParent = null; + for (DataSchemaNodeBuilder child : dependentModuleBuilder.getChildNodes()) { + final QName childQName = child.getQName(); + if (childQName.getLocalName().equals(qname.getLocalName())) { + currentParent = child; + break; + } + } + + if (currentParent == null) { + return; + } + + for (int i = 1; i < path.size(); i++) { + final QName currentQName = path.get(i); + DataSchemaNodeBuilder newParent = null; + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodes()) { + final QName childQName = child.getQName(); + if (childQName.getLocalName().equals(currentQName.getLocalName())) { + newParent = child; + break; + } + } + if (newParent == null) { + break; // node not found, quit search + } else { + currentParent = newParent; + } + } + + final String currentName = currentParent.getQName().getLocalName(); + final String lastAugmentPathElementName = path.get(path.size() - 1).getLocalName(); + if (currentName.equals(lastAugmentPathElementName)) { + + if (currentParent instanceof ChoiceBuilder) { + fillAugmentTarget(augmentBuilder, (ChoiceBuilder) currentParent); + } else { + fillAugmentTarget(augmentBuilder, (DataNodeContainerBuilder) currentParent); + } + ((AugmentationTargetBuilder) currentParent).addAugmentation(augmentBuilder); + SchemaPath oldPath = currentParent.getPath(); + augmentBuilder.setTargetPath(new SchemaPath(oldPath.getPath(), oldPath.isAbsolute())); + augmentBuilder.setResolved(true); + module.augmentResolved(); + } + } + + /** + * Create new type builder based on old type with new base type. + * + * @param newBaseType + * new base type builder + * @param oldExtendedType + * old type + * @param modules + * all loaded modules + * @param module + * current module + * @param line + * current line in module + * @return new type builder based on old type with new base type + */ + public static TypeDefinitionBuilder extendedTypeWithNewBaseTypeBuilder(final TypeDefinitionBuilder newBaseType, + final ExtendedType oldExtendedType, final Map> modules, + final ModuleBuilder module, final int line) { + final TypeConstraints tc = new TypeConstraints(module.getName(), line); + tc.addFractionDigits(oldExtendedType.getFractionDigits()); + tc.addLengths(oldExtendedType.getLengths()); + tc.addPatterns(oldExtendedType.getPatterns()); + tc.addRanges(oldExtendedType.getRanges()); + + final TypeConstraints constraints = findConstraintsFromTypeBuilder(newBaseType, tc, modules, module, null); + final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line); + newType.setTypedef(newBaseType); + newType.setPath(oldExtendedType.getPath()); + newType.setDescription(oldExtendedType.getDescription()); + newType.setReference(oldExtendedType.getReference()); + newType.setStatus(oldExtendedType.getStatus()); + newType.setLengths(constraints.getLength()); + newType.setPatterns(constraints.getPatterns()); + newType.setRanges(constraints.getRange()); + newType.setFractionDigits(constraints.getFractionDigits()); + newType.setUnits(oldExtendedType.getUnits()); + newType.setDefaultValue(oldExtendedType.getDefaultValue()); + newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes()); + return newType; + } + + /** + * Create new type builder based on old type with new base type. + * + * @param newBaseType + * new base type + * @param oldExtendedType + * old type + * @param modules + * all loaded modules + * @param module + * current module + * @param line + * current line in module + * @return new type builder based on old type with new base type + */ + public static TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeDefinition newBaseType, + final ExtendedType oldExtendedType, final ModuleBuilder module, final int line) { + final TypeConstraints tc = new TypeConstraints(module.getName(), line); + + final TypeConstraints constraints = findConstraintsFromTypeDefinition(newBaseType, tc); + final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(oldExtendedType.getQName(), line); + newType.setType(newBaseType); + newType.setPath(oldExtendedType.getPath()); + newType.setDescription(oldExtendedType.getDescription()); + newType.setReference(oldExtendedType.getReference()); + newType.setStatus(oldExtendedType.getStatus()); + newType.setLengths(constraints.getLength()); + newType.setPatterns(constraints.getPatterns()); + newType.setRanges(constraints.getRange()); + newType.setFractionDigits(constraints.getFractionDigits()); + newType.setUnits(oldExtendedType.getUnits()); + newType.setDefaultValue(oldExtendedType.getDefaultValue()); + newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes()); + return newType; + } + + /** + * Pull restrictions from type and add them to constraints. + * + * @param typeToResolve + * type from which constraints will be read + * @param constraints + * constraints object to which constraints will be added + * @return constraints contstraints object containing constraints from given + * type + */ + private static TypeConstraints findConstraintsFromTypeDefinition(final TypeDefinition typeToResolve, + final TypeConstraints constraints) { + // union type cannot be restricted + if (typeToResolve instanceof UnionTypeDefinition) { + return constraints; + } + if (typeToResolve instanceof ExtendedType) { + ExtendedType extType = (ExtendedType) typeToResolve; + constraints.addFractionDigits(extType.getFractionDigits()); + constraints.addLengths(extType.getLengths()); + constraints.addPatterns(extType.getPatterns()); + constraints.addRanges(extType.getRanges()); + return findConstraintsFromTypeDefinition(extType.getBaseType(), constraints); + } else { + mergeConstraints(typeToResolve, constraints); + return constraints; + } + } + + public static TypeConstraints findConstraintsFromTypeBuilder(final TypeAwareBuilder nodeToResolve, + final TypeConstraints constraints, final Map> modules, + final ModuleBuilder builder, final SchemaContext context) { + + // union type cannot be restricted + if (nodeToResolve instanceof UnionTypeBuilder) { + return constraints; + } + + if (nodeToResolve instanceof TypeDefinitionBuilder) { + TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve; + constraints.addFractionDigits(typedefToResolve.getFractionDigits()); + constraints.addLengths(typedefToResolve.getLengths()); + constraints.addPatterns(typedefToResolve.getPatterns()); + constraints.addRanges(typedefToResolve.getRanges()); + } + + TypeDefinition type = nodeToResolve.getType(); + if (type == null) { + return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context); + } else { + QName qname = type.getQName(); + if (type instanceof UnknownType) { + ModuleBuilder dependentModuleBuilder = findDependentModuleBuilder(modules, builder, qname.getPrefix(), + nodeToResolve.getLine()); + if (dependentModuleBuilder == null) { + if (context == null) { + throw new YangParseException(builder.getName(), nodeToResolve.getLine(), + "Failed to resolved type constraints."); + } + Module dm = findModuleFromContext(context, builder, qname.getPrefix(), nodeToResolve.getLine()); + TypeDefinition t = findTypeByName(dm.getTypeDefinitions(), qname.getLocalName()); + if (t instanceof ExtendedType) { + ExtendedType extType = (ExtendedType) t; + constraints.addFractionDigits(extType.getFractionDigits()); + constraints.addLengths(extType.getLengths()); + constraints.addPatterns(extType.getPatterns()); + constraints.addRanges(extType.getRanges()); + return constraints; + } else { + mergeConstraints(t, constraints); + return constraints; + } + } else { + TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), + dependentModuleBuilder, qname.getLocalName(), builder.getName(), nodeToResolve.getLine()); + return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModuleBuilder, context); + } + } else if (type instanceof ExtendedType) { + ExtendedType extType = (ExtendedType) type; + constraints.addFractionDigits(extType.getFractionDigits()); + constraints.addLengths(extType.getLengths()); + constraints.addPatterns(extType.getPatterns()); + constraints.addRanges(extType.getRanges()); + + TypeDefinition base = extType.getBaseType(); + if (base instanceof UnknownType) { + ModuleBuilder dependentModule = findDependentModuleBuilder(modules, builder, base.getQName() + .getPrefix(), nodeToResolve.getLine()); + TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(nodeToResolve.getPath(), dependentModule, + base.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine()); + return findConstraintsFromTypeBuilder(tdb, constraints, modules, dependentModule, context); + } else { + // it has to be base yang type + mergeConstraints(type, constraints); + return constraints; + } + } else { + // it is base yang type + mergeConstraints(type, constraints); + return constraints; + } + } + } + + /** + * Search for type definition builder by name. + * + * @param dirtyNodeSchemaPath + * schema path of node which contains unresolved type + * @param dependentModule + * module which should contains referenced type + * @param typeName + * name of type definition + * @param currentModuleName + * name of current module + * @param line + * current line in yang model + * @return + */ + public static TypeDefinitionBuilder findTypeDefinitionBuilder(final SchemaPath dirtyNodeSchemaPath, + final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) { + final List path = dirtyNodeSchemaPath.getPath(); + TypeDefinitionBuilder result = null; + + Set typedefs = dependentModule.getModuleTypedefs(); + result = findTypedefBuilderByName(typedefs, typeName); + + if (result == null) { + Builder currentNode = null; + final List currentPath = new ArrayList(); + currentPath.add(dependentModule.getName()); + + for (int i = 0; i < path.size(); i++) { + QName qname = path.get(i); + currentPath.add(qname.getLocalName()); + currentNode = dependentModule.getModuleNode(currentPath); + + if (currentNode instanceof RpcDefinitionBuilder) { + typedefs = ((RpcDefinitionBuilder) currentNode).getTypeDefinitions(); + } else if (currentNode instanceof DataNodeContainerBuilder) { + typedefs = ((DataNodeContainerBuilder) currentNode).getTypeDefinitions(); + } else { + typedefs = Collections.emptySet(); + } + + result = findTypedefBuilderByName(typedefs, typeName); + if (result != null) { + break; + } + } + } + + if (result != null) { + return result; + } + throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found."); + } + } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java new file mode 100644 index 0000000000..8db4e8e6fd --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/RefineUtils.java @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.yang.parser.util; + +import static org.opendaylight.controller.yang.parser.util.ParserUtils.*; + +import java.lang.reflect.Method; +import java.util.List; + +import org.opendaylight.controller.yang.model.api.AnyXmlSchemaNode; +import org.opendaylight.controller.yang.model.api.ChoiceNode; +import org.opendaylight.controller.yang.model.api.ContainerSchemaNode; +import org.opendaylight.controller.yang.model.api.GroupingDefinition; +import org.opendaylight.controller.yang.model.api.LeafListSchemaNode; +import org.opendaylight.controller.yang.model.api.LeafSchemaNode; +import org.opendaylight.controller.yang.model.api.ListSchemaNode; +import org.opendaylight.controller.yang.model.api.MustDefinition; +import org.opendaylight.controller.yang.model.api.TypeDefinition; +import org.opendaylight.controller.yang.model.util.ExtendedType; +import org.opendaylight.controller.yang.parser.builder.api.Builder; +import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder; +import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder; +import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.AnyXmlBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ChoiceBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ContainerSchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl; +import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder; + +/** + * Utility class with helper methods to perform operations tied to refine + * process. + */ +public class RefineUtils { + + private RefineUtils() { + } + + /** + * Find original builder of node to refine and return copy of this builder. + *

+ * We must create and use a copy of builder to preserve original builder + * state, because this object will be refined (modified) and later added to + * {@link UsesNodeBuilder}. + *

+ * + * @param targetGrouping + * builder of grouping which should contains node to refine + * @param refine + * refine object containing informations about refine + * @param moduleName + * current module name + * @return + */ + public static SchemaNodeBuilder getRefineNodeFromGroupingBuilder(final GroupingBuilder targetGrouping, + final RefineHolder refine, final String moduleName) { + Builder result = null; + final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine.getName()); + if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) { + result = copyLeafBuilder((LeafSchemaNodeBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof ContainerSchemaNodeBuilder) { + result = copyContainerBuilder((ContainerSchemaNodeBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof ListSchemaNodeBuilder) { + result = copyListBuilder((ListSchemaNodeBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof LeafListSchemaNodeBuilder) { + result = copyLeafListBuilder((LeafListSchemaNodeBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof ChoiceBuilder) { + result = copyChoiceBuilder((ChoiceBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof AnyXmlBuilder) { + result = copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof GroupingBuilder) { + result = copyGroupingBuilder((GroupingBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) { + result = copyTypedefBuilder((TypeDefinitionBuilderImpl) lookedUpBuilder); + } else { + throw new YangParseException(moduleName, refine.getLine(), "Target '" + refine.getName() + + "' can not be refined"); + } + return (SchemaNodeBuilder) result; + } + + /** + * Create builder object from refine target node. + * + * @param grouping + * grouping which should contains node to refine + * @param refine + * refine object containing informations about refine + * @param moduleName + * current module name + * @return + */ + public static SchemaNodeBuilder getRefineNodeFromGroupingDefinition(final GroupingDefinition grouping, + final RefineHolder refine, final String moduleName) { + SchemaNodeBuilder result = null; + final int line = refine.getLine(); + final Object lookedUpNode = findRefineTargetNode(grouping, refine.getName()); + if (lookedUpNode instanceof LeafSchemaNode) { + result = createLeafBuilder((LeafSchemaNode) lookedUpNode, line); + } else if (lookedUpNode instanceof ContainerSchemaNode) { + result = createContainer((ContainerSchemaNode) lookedUpNode, line); + } else if (lookedUpNode instanceof ListSchemaNode) { + result = createList((ListSchemaNode) lookedUpNode, line); + } else if (lookedUpNode instanceof LeafListSchemaNode) { + result = createLeafList((LeafListSchemaNode) lookedUpNode, line); + } else if (lookedUpNode instanceof ChoiceNode) { + result = createChoice((ChoiceNode) lookedUpNode, line); + } else if (lookedUpNode instanceof AnyXmlSchemaNode) { + result = createAnyXml((AnyXmlSchemaNode) lookedUpNode, line); + } else if (lookedUpNode instanceof GroupingDefinition) { + result = createGrouping((GroupingDefinition) lookedUpNode, line); + } else if (lookedUpNode instanceof TypeDefinition) { + result = createTypedef((ExtendedType) lookedUpNode, line); + } else { + throw new YangParseException(moduleName, line, "Target '" + refine.getName() + "' can not be refined"); + } + return result; + } + + public static void refineLeaf(LeafSchemaNodeBuilder leaf, RefineHolder refine, int line) { + String defaultStr = refine.getDefaultStr(); + Boolean mandatory = refine.isMandatory(); + MustDefinition must = refine.getMust(); + List unknownNodes = refine.getUnknownNodes(); + + if (defaultStr != null && !("".equals(defaultStr))) { + leaf.setDefaultStr(defaultStr); + } + if (mandatory != null) { + leaf.getConstraints().setMandatory(mandatory); + } + if (must != null) { + leaf.getConstraints().addMustDefinition(must); + } + if (unknownNodes != null) { + for (UnknownSchemaNodeBuilder unknown : unknownNodes) { + leaf.addUnknownSchemaNode(unknown); + } + } + } + + public static void refineContainer(ContainerSchemaNodeBuilder container, RefineHolder refine, int line) { + Boolean presence = refine.isPresence(); + MustDefinition must = refine.getMust(); + List unknownNodes = refine.getUnknownNodes(); + + if (presence != null) { + container.setPresence(presence); + } + if (must != null) { + container.getConstraints().addMustDefinition(must); + } + if (unknownNodes != null) { + for (UnknownSchemaNodeBuilder unknown : unknownNodes) { + container.addUnknownSchemaNode(unknown); + } + } + } + + public static void refineList(ListSchemaNodeBuilder list, RefineHolder refine, int line) { + MustDefinition must = refine.getMust(); + Integer min = refine.getMinElements(); + Integer max = refine.getMaxElements(); + List unknownNodes = refine.getUnknownNodes(); + + if (must != null) { + list.getConstraints().addMustDefinition(must); + } + if (min != null) { + list.getConstraints().setMinElements(min); + } + if (max != null) { + list.getConstraints().setMaxElements(max); + } + if (unknownNodes != null) { + for (UnknownSchemaNodeBuilder unknown : unknownNodes) { + list.addUnknownSchemaNode(unknown); + } + } + } + + public static void refineLeafList(LeafListSchemaNodeBuilder leafList, RefineHolder refine, int line) { + MustDefinition must = refine.getMust(); + Integer min = refine.getMinElements(); + Integer max = refine.getMaxElements(); + List unknownNodes = refine.getUnknownNodes(); + + if (must != null) { + leafList.getConstraints().addMustDefinition(must); + } + if (min != null) { + leafList.getConstraints().setMinElements(min); + } + if (max != null) { + leafList.getConstraints().setMaxElements(max); + } + if (unknownNodes != null) { + for (UnknownSchemaNodeBuilder unknown : unknownNodes) { + leafList.addUnknownSchemaNode(unknown); + } + } + } + + public static void refineChoice(ChoiceBuilder choice, RefineHolder refine, int line) { + String defaultStr = refine.getDefaultStr(); + Boolean mandatory = refine.isMandatory(); + List unknownNodes = refine.getUnknownNodes(); + + if (defaultStr != null) { + choice.setDefaultCase(defaultStr); + } + if (mandatory != null) { + choice.getConstraints().setMandatory(mandatory); + } + if (unknownNodes != null) { + for (UnknownSchemaNodeBuilder unknown : unknownNodes) { + choice.addUnknownSchemaNode(unknown); + } + } + } + + public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine, int line) { + Boolean mandatory = refine.isMandatory(); + MustDefinition must = refine.getMust(); + List unknownNodes = refine.getUnknownNodes(); + + if (mandatory != null) { + anyXml.getConstraints().setMandatory(mandatory); + } + if (must != null) { + anyXml.getConstraints().addMustDefinition(must); + } + if (unknownNodes != null) { + for (UnknownSchemaNodeBuilder unknown : unknownNodes) { + anyXml.addUnknownSchemaNode(unknown); + } + } + } + + /** + * Check if refine can be performed on given node. + * + * @param node + * node to refine + * @param refine + * refine object containing information about refine process + */ + public static void checkRefine(SchemaNodeBuilder node, RefineHolder refine) { + String name = node.getQName().getLocalName(); + int line = refine.getLine(); + + String defaultStr = refine.getDefaultStr(); + Boolean mandatory = refine.isMandatory(); + Boolean presence = refine.isPresence(); + MustDefinition must = refine.getMust(); + Integer min = refine.getMinElements(); + Integer max = refine.getMaxElements(); + + if (node instanceof AnyXmlBuilder) { + checkRefineDefault(node, defaultStr, line); + checkRefinePresence(node, presence, line); + checkRefineMinMax(name, line, min, max); + } else if (node instanceof ChoiceBuilder) { + checkRefinePresence(node, presence, line); + checkRefineMust(node, must, line); + checkRefineMinMax(name, line, min, max); + } else if (node instanceof ContainerSchemaNodeBuilder) { + checkRefineDefault(node, defaultStr, line); + checkRefineMandatory(node, mandatory, line); + checkRefineMust(node, must, line); + checkRefineMinMax(name, line, min, max); + } else if (node instanceof LeafSchemaNodeBuilder) { + checkRefinePresence(node, presence, line); + checkRefineMinMax(name, line, min, max); + } else if (node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder) { + checkRefineDefault(node, defaultStr, line); + checkRefinePresence(node, presence, line); + checkRefineMandatory(node, mandatory, line); + } else if (node instanceof GroupingBuilder || node instanceof TypeDefinitionBuilder + || node instanceof UsesNodeBuilder) { + checkRefineDefault(node, defaultStr, line); + checkRefinePresence(node, presence, line); + checkRefineMandatory(node, mandatory, line); + checkRefineMust(node, must, line); + checkRefineMinMax(name, line, min, max); + } + } + + private static void checkRefineDefault(SchemaNodeBuilder node, String defaultStr, int line) { + if (defaultStr != null) { + throw new YangParseException(line, "Can not refine 'default' for '" + node.getQName().getLocalName() + "'."); + } + } + + private static void checkRefineMandatory(SchemaNodeBuilder node, Boolean mandatory, int line) { + if (mandatory != null) { + throw new YangParseException(line, "Can not refine 'mandatory' for '" + node.getQName().getLocalName() + + "'."); + } + } + + private static void checkRefinePresence(SchemaNodeBuilder node, Boolean presence, int line) { + if (presence != null) { + throw new YangParseException(line, "Can not refine 'presence' for '" + node.getQName().getLocalName() + + "'."); + } + } + + private static void checkRefineMust(SchemaNodeBuilder node, MustDefinition must, int line) { + if (must != null) { + throw new YangParseException(line, "Can not refine 'must' for '" + node.getQName().getLocalName() + "'."); + } + } + + private static void checkRefineMinMax(String refineTargetName, int refineLine, Integer min, Integer max) { + if (min != null || max != null) { + throw new YangParseException(refineLine, "Can not refine 'min-elements' or 'max-elements' for '" + + refineTargetName + "'."); + } + } + + /** + * Perform refine operation of following parameters: + *
    + *
  • description
  • + *
  • reference
  • + *
  • config
  • + *
+ * + * These parameters may be refined for any node. + * + * @param node + * node to refine + * @param refine + * refine object containing information about refine process + * @param line + * current line in yang model + */ + public static void refineDefault(final Builder node, final RefineHolder refine, final int line) { + Class cls = node.getClass(); + + String description = refine.getDescription(); + if (description != null) { + try { + Method method = cls.getDeclaredMethod("setDescription", String.class); + method.invoke(node, description); + } catch (Exception e) { + throw new YangParseException(line, "Cannot refine description in " + cls.getName(), e); + } + } + + String reference = refine.getReference(); + if (reference != null) { + try { + Method method = cls.getDeclaredMethod("setReference", String.class); + method.invoke(node, reference); + } catch (Exception e) { + throw new YangParseException(line, "Cannot refine reference in " + cls.getName(), e); + } + } + + Boolean config = refine.isConfig(); + if (config != null) { + try { + Method method = cls.getDeclaredMethod("setConfiguration", Boolean.TYPE); + method.invoke(node, config); + } catch (Exception e) { + throw new YangParseException(line, "Cannot refine config in " + cls.getName(), e); + } + } + } + + /** + * Perform refine operation on given node. + * + * @param nodeToRefine + * builder of node to refine + * @param refine + * refine object containing information about refine process + * @param line + * current line in yang model + */ + public static void performRefine(SchemaNodeBuilder nodeToRefine, RefineHolder refine, int line) { + checkRefine(nodeToRefine, refine); + refineDefault(nodeToRefine, refine, line); + if (nodeToRefine instanceof LeafSchemaNodeBuilder) { + refineLeaf((LeafSchemaNodeBuilder) nodeToRefine, refine, line); + } else if (nodeToRefine instanceof ContainerSchemaNodeBuilder) { + refineContainer((ContainerSchemaNodeBuilder) nodeToRefine, refine, line); + } else if (nodeToRefine instanceof ListSchemaNodeBuilder) { + refineList((ListSchemaNodeBuilder) nodeToRefine, refine, line); + } else if (nodeToRefine instanceof LeafListSchemaNodeBuilder) { + refineLeafList((LeafListSchemaNodeBuilder) nodeToRefine, refine, line); + } else if (nodeToRefine instanceof ChoiceBuilder) { + refineChoice((ChoiceBuilder) nodeToRefine, refine, line); + } else if (nodeToRefine instanceof AnyXmlBuilder) { + refineAnyxml((AnyXmlBuilder) nodeToRefine, refine, line); + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java index ae405c06a8..5423e486db 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java @@ -672,16 +672,13 @@ public final class YangModelBuilderUtil { private static List getPatternConstraint(final Type_body_stmtsContext ctx) { List patterns = new ArrayList(); - outer: for (int j = 0; j < ctx.getChildCount(); j++) { + for (int j = 0; j < ctx.getChildCount(); j++) { ParseTree stringRestrChild = ctx.getChild(j); if (stringRestrChild instanceof String_restrictionsContext) { for (int k = 0; k < stringRestrChild.getChildCount(); k++) { ParseTree lengthChild = stringRestrChild.getChild(k); if (lengthChild instanceof Pattern_stmtContext) { patterns.add(parsePatternConstraint((Pattern_stmtContext) lengthChild)); - if (k == lengthChild.getChildCount() - 1) { - break outer; - } } } } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java index 26c2c61b98..fed8cde965 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java @@ -25,6 +25,7 @@ import java.util.Set; import org.opendaylight.controller.yang.common.QName; import org.opendaylight.controller.yang.model.api.Module; import org.opendaylight.controller.yang.model.api.ModuleImport; +import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.TypeDefinition; import org.opendaylight.controller.yang.model.parser.api.YangModelParser; @@ -69,6 +70,25 @@ final class TestUtils { return modules.iterator().next(); } + public static Module loadModuleWithContext(final InputStream stream, final SchemaContext context) throws IOException { + final YangModelParser parser = new YangParserImpl(); + final List input = Collections.singletonList(stream); + final Set modules = new HashSet(parser.parseYangModelsFromStreams(input, context)); + stream.close(); + return modules.iterator().next(); + } + + public static Set loadModulesWithContext(final List input, final SchemaContext context) throws IOException { + final YangModelParser parser = new YangParserImpl(); + final Set modules = new HashSet(parser.parseYangModelsFromStreams(input, context)); + for(InputStream is : input) { + if(is != null) { + is.close(); + } + } + return modules; + } + public static Module findModule(Set modules, String moduleName) { Module result = null; for (Module module : modules) { diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java new file mode 100644 index 0000000000..ff32ee1fa8 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserWithContextTest.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.yang.parser.impl; + +import static org.junit.Assert.*; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.net.URI; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; +import org.opendaylight.controller.yang.common.QName; +import org.opendaylight.controller.yang.model.api.ContainerSchemaNode; +import org.opendaylight.controller.yang.model.api.DataSchemaNode; +import org.opendaylight.controller.yang.model.api.GroupingDefinition; +import org.opendaylight.controller.yang.model.api.IdentitySchemaNode; +import org.opendaylight.controller.yang.model.api.LeafSchemaNode; +import org.opendaylight.controller.yang.model.api.ListSchemaNode; +import org.opendaylight.controller.yang.model.api.Module; +import org.opendaylight.controller.yang.model.api.MustDefinition; +import org.opendaylight.controller.yang.model.api.SchemaContext; +import org.opendaylight.controller.yang.model.api.SchemaNode; +import org.opendaylight.controller.yang.model.api.SchemaPath; +import org.opendaylight.controller.yang.model.api.TypeDefinition; +import org.opendaylight.controller.yang.model.api.UnknownSchemaNode; +import org.opendaylight.controller.yang.model.api.UsesNode; +import org.opendaylight.controller.yang.model.api.type.RangeConstraint; +import org.opendaylight.controller.yang.model.util.ExtendedType; + +import com.google.common.collect.Lists; + +public class YangParserWithContextTest { + private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + private final YangParserImpl parser = new YangParserImpl(); + + @Test + public void testTypeFromContext() throws Exception { + SchemaContext context = null; + String resource = "/types/ietf-inet-types@2010-09-24.yang"; + InputStream stream = new FileInputStream(getClass().getResource(resource).getPath()); + context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream))); + stream.close(); + + Module module = null; + resource = "/context-test/test1.yang"; + InputStream stream2 = new FileInputStream(getClass().getResource(resource).getPath()); + module = TestUtils.loadModuleWithContext(stream2, context); + stream2.close(); + assertNotNull(module); + + LeafSchemaNode leaf = (LeafSchemaNode) module.getDataChildByName("id"); + + ExtendedType leafType = (ExtendedType) leaf.getType(); + QName qname = leafType.getQName(); + assertEquals(URI.create("urn:simple.demo.test1"), qname.getNamespace()); + assertEquals(simpleDateFormat.parse("2013-06-18"), qname.getRevision()); + assertEquals("t1", qname.getPrefix()); + assertEquals("port-number", qname.getLocalName()); + + ExtendedType leafBaseType = (ExtendedType) leafType.getBaseType(); + qname = leafBaseType.getQName(); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-inet-types"), qname.getNamespace()); + assertEquals(simpleDateFormat.parse("2010-09-24"), qname.getRevision()); + assertEquals("inet", qname.getPrefix()); + assertEquals("port-number", qname.getLocalName()); + + ExtendedType dscpExt = (ExtendedType)TestUtils.findTypedef(module.getTypeDefinitions(), "dscp-ext"); + List ranges = dscpExt.getRanges(); + assertEquals(1, ranges.size()); + RangeConstraint range = ranges.get(0); + assertEquals(0L, range.getMin()); + assertEquals(63L, range.getMax()); + + } + + @Test + public void testUsesGroupingFromContext() throws Exception { + SchemaContext context = null; + try (InputStream stream = new FileInputStream(getClass().getResource("/model/testfile2.yang").getPath())) { + context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream))); + } + Module module = null; + try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test2.yang").getPath())) { + module = TestUtils.loadModuleWithContext(stream, context); + } + assertNotNull(module); + + ContainerSchemaNode peer = (ContainerSchemaNode) module.getDataChildByName("peer"); + ContainerSchemaNode destination = (ContainerSchemaNode) peer.getDataChildByName("destination"); + Set usesNodes = destination.getUses(); + assertEquals(1, usesNodes.size()); + UsesNode usesNode = usesNodes.iterator().next(); + + // test grouping path + List path = new ArrayList(); + QName qname = new QName(URI.create("urn:simple.types.data.demo"), simpleDateFormat.parse("2013-02-27"), "t2", + "target"); + path.add(qname); + SchemaPath expectedPath = new SchemaPath(path, true); + assertEquals(expectedPath, usesNode.getGroupingPath()); + + // test refine + Map refines = usesNode.getRefines(); + assertEquals(5, 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) { + refineLeaf = (LeafSchemaNode) value; + } else if (value instanceof ContainerSchemaNode) { + 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; + } + } + + // leaf address + assertNotNull(refineLeaf); + assertEquals("address", refineLeaf.getQName().getLocalName()); + assertEquals("description of address defined by refine", refineLeaf.getDescription()); + assertEquals("address reference added by refine", refineLeaf.getReference()); + assertFalse(refineLeaf.isConfiguration()); + assertTrue(refineLeaf.getConstraints().isMandatory()); + Set leafMustConstraints = refineLeaf.getConstraints().getMustConstraints(); + assertEquals(1, leafMustConstraints.size()); + MustDefinition leafMust = leafMustConstraints.iterator().next(); + assertEquals("\"ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)\"", leafMust.toString()); + + // container port + assertNotNull(refineContainer); + Set mustConstraints = refineContainer.getConstraints().getMustConstraints(); + assertTrue(mustConstraints.isEmpty()); + assertEquals("description of port defined by refine", refineContainer.getDescription()); + assertEquals("port reference added by refine", refineContainer.getReference()); + assertFalse(refineContainer.isConfiguration()); + assertTrue(refineContainer.isPresenceContainer()); + + // list addresses + assertNotNull(refineList); + assertEquals("description of addresses defined by refine", refineList.getDescription()); + assertEquals("addresses reference added by refine", refineList.getReference()); + 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 + public void testIdentity() throws Exception { + SchemaContext context = null; + try (InputStream stream = new FileInputStream(getClass().getResource("/types/custom-types-test@2012-4-4.yang") + .getPath())) { + context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream))); + } + Module module = null; + try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test3.yang").getPath())) { + module = TestUtils.loadModuleWithContext(stream, context); + } + assertNotNull(module); + + Set identities = module.getIdentities(); + assertEquals(1, identities.size()); + + IdentitySchemaNode identity = identities.iterator().next(); + QName idQName = identity.getQName(); + assertEquals(URI.create("urn:simple.demo.test3"), idQName.getNamespace()); + assertEquals(simpleDateFormat.parse("2013-06-18"), idQName.getRevision()); + assertEquals("t3", idQName.getPrefix()); + assertEquals("pt", idQName.getLocalName()); + + IdentitySchemaNode baseIdentity = identity.getBaseIdentity(); + QName idBaseQName = baseIdentity.getQName(); + assertEquals(URI.create("urn:simple.container.demo"), idBaseQName.getNamespace()); + assertEquals(simpleDateFormat.parse("2012-04-16"), idBaseQName.getRevision()); + assertEquals("iit", idBaseQName.getPrefix()); + assertEquals("service-type", idBaseQName.getLocalName()); + } + + @Test + public void testUnknownNodes() throws Exception { + SchemaContext context = null; + try (InputStream stream = new FileInputStream(getClass().getResource("/types/custom-types-test@2012-4-4.yang").getPath())) { + context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream))); + } + + Module module = null; + try (InputStream stream = new FileInputStream(getClass().getResource("/context-test/test3.yang").getPath())) { + module = TestUtils.loadModuleWithContext(stream, context); + } + + ContainerSchemaNode network = (ContainerSchemaNode) module.getDataChildByName("network"); + List unknownNodes = network.getUnknownSchemaNodes(); + assertEquals(1, unknownNodes.size()); + + UnknownSchemaNode un = unknownNodes.iterator().next(); + QName unType = un.getNodeType(); + assertEquals(URI.create("urn:simple.container.demo"), unType.getNamespace()); + assertEquals(simpleDateFormat.parse("2012-04-16"), unType.getRevision()); + assertEquals("custom", unType.getPrefix()); + assertEquals("mountpoint", unType.getLocalName()); + assertEquals("point", un.getNodeParameter()); + } + + @Test + public void testAugment() throws Exception { + // load first module + SchemaContext context = null; + String resource = "/context-augment-test/test4.yang"; + + try (InputStream stream = new FileInputStream(getClass().getResource(resource).getPath())) { + context = parser.resolveSchemaContext(TestUtils.loadModules(Lists.newArrayList(stream))); + } + + Set contextModules = context.getModules(); + Module t3 = TestUtils.findModule(contextModules, "test4"); + ContainerSchemaNode interfaces = (ContainerSchemaNode) t3.getDataChildByName("interfaces"); + ListSchemaNode ifEntry = (ListSchemaNode) interfaces.getDataChildByName("ifEntry"); + + // load another modules and parse them against already existing context + Set modules = null; + try (InputStream stream1 = new FileInputStream(getClass().getResource("/context-augment-test/test1.yang") + .getPath()); + InputStream stream2 = new FileInputStream(getClass().getResource("/context-augment-test/test2.yang") + .getPath()); + InputStream stream3 = new FileInputStream(getClass().getResource("/context-augment-test/test3.yang") + .getPath())) { + List input = Lists.newArrayList(stream1, stream2, stream3); + modules = TestUtils.loadModulesWithContext(input, context); + } + assertNotNull(modules); + + // test augmentation process + ContainerSchemaNode augmentHolder = (ContainerSchemaNode) ifEntry.getDataChildByName("augment-holder"); + assertNotNull(augmentHolder); + DataSchemaNode ds0 = augmentHolder.getDataChildByName("ds0ChannelNumber"); + assertNotNull(ds0); + DataSchemaNode interfaceId = augmentHolder.getDataChildByName("interface-id"); + assertNotNull(interfaceId); + DataSchemaNode higherLayerIf = augmentHolder.getDataChildByName("higher-layer-if"); + assertNotNull(higherLayerIf); + ContainerSchemaNode schemas = (ContainerSchemaNode) augmentHolder.getDataChildByName("schemas"); + assertNotNull(schemas); + assertNotNull(schemas.getDataChildByName("id")); + + // test augment target after augmentation: check if it is same instance + ListSchemaNode ifEntryAfterAugment = (ListSchemaNode) interfaces.getDataChildByName("ifEntry"); + assertTrue(ifEntry == ifEntryAfterAugment); + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang new file mode 100644 index 0000000000..04468fbffc --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test1.yang @@ -0,0 +1,34 @@ +module test1 { + + yang-version 1; + namespace "urn:simple.demo.test1"; + prefix "t1"; + + import test3 { + prefix "t3"; + revision-date 2013-06-18; + } + + import test2 { + prefix "t2"; + revision-date 2013-06-18; + } + + import test4 { + prefix "t4"; + revision-date 2013-06-18; + } + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + augment "/t4:interfaces/t4:ifEntry/t2:augment-holder/t3:schemas" { + when "if:ifType='ds0'"; + leaf id { + type string; + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang new file mode 100644 index 0000000000..44bdf66fbf --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test2.yang @@ -0,0 +1,41 @@ +module test2 { + + yang-version 1; + namespace "urn:simple.demo.test2"; + prefix "t2"; + + import test3 { + prefix "t3"; + revision-date 2013-06-18; + } + + import test4 { + prefix "t4"; + revision-date 2013-06-18; + } + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + augment "/t4:interfaces/t4:ifEntry/t3:augment-holder" { + when "if:ifType='ds0'"; + leaf ds0ChannelNumber { + type string; + } + leaf interface-id { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + } + leaf-list higher-layer-if { + type leafref { + path "/if:interfaces/if:interface/if:higher-layer-if"; + } + } + container schemas { + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang new file mode 100644 index 0000000000..f954153714 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test3.yang @@ -0,0 +1,24 @@ +module test3 { + + yang-version 1; + namespace "urn:simple.demo.test3"; + prefix "t3"; + + import test4 { + prefix "t4"; + revision-date 2013-06-18; + } + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + augment "/t4:interfaces/t4:ifEntry" { + when "if:ifType='ds0'"; + container augment-holder { + description "Description for augment holder"; + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang new file mode 100644 index 0000000000..9d57a9e6e2 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-augment-test/test4.yang @@ -0,0 +1,27 @@ +module test4 { + + yang-version 1; + namespace "urn:simple.demo.test4"; + prefix "t4"; + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + container interfaces { + list ifEntry { + key "ifIndex"; + leaf ifIndex { + type uint32; + units minutes; + } + leaf ifMtu { + type int32; + } + min-elements 1; + max-elements 11; + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang new file mode 100644 index 0000000000..1ba514279d --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test1.yang @@ -0,0 +1,29 @@ +module test1 { + + yang-version 1; + namespace "urn:simple.demo.test1"; + prefix "t1"; + + import ietf-inet-types { + prefix "inet"; + revision-date 2010-09-24; + } + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + typedef dscp-ext { + type inet:dscp { + range "min..max"; + } + } + + leaf id { + type inet:port-number { + range "0..65536"; + } + } + +} diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang new file mode 100644 index 0000000000..74704d5c22 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test2.yang @@ -0,0 +1,54 @@ +module test2 { + + yang-version 1; + namespace "urn:simple.demo.test2"; + prefix "t2"; + + import types2 { + prefix "data"; + } + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + container peer { + container destination { + uses data:target { + refine address { + default "1.2.3.4"; + description "description of address defined by refine"; + reference "address reference added by refine"; + config false; + mandatory true; + must "ifType != 'ethernet' or " + + "(ifType = 'ethernet' and ifMTU = 1500)" { + error-message "An ethernet MTU must be 1500"; + } + } + refine port { + description "description of port defined by refine"; + reference "port reference added by refine"; + config false; + presence "presence is required"; + } + refine addresses { + description "description of addresses defined by refine"; + reference "addresses reference added by refine"; + config false; + 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/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang new file mode 100644 index 0000000000..b597aab478 --- /dev/null +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/context-test/test3.yang @@ -0,0 +1,32 @@ +module test3 { + + yang-version 1; + namespace "urn:simple.demo.test3"; + prefix "t3"; + + import custom-types-test { + prefix "custom"; + } + + organization "opendaylight"; + contact "WILL-BE-DEFINED-LATER"; + revision 2013-06-18 { + } + + identity pt { + base custom:service-type; + } + + container network { + custom:mountpoint point { + mnt:target-ref target; + } + + description "network-description"; + reference "network-reference"; + status obsolete; + config true; + presence "some presence text"; + } + +} diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java index 03a8962d55..ee4163da48 100644 --- a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java +++ b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/ChoiceNode.java @@ -19,7 +19,7 @@ public interface ChoiceNode extends DataSchemaNode, AugmentationTarget { * @return ChoiceCaseNode objects defined in this node */ Set getCases(); - + String getDefaultCase(); } diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java index f2171480a0..51dd9f6507 100644 --- a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java +++ b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/Module.java @@ -48,4 +48,6 @@ public interface Module extends DataNodeContainer { List getExtensionSchemaNodes(); + List getUnknownSchemaNodes(); + } diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java index 8e7686cf3b..b3e06777c5 100644 --- a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java +++ b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/NotificationDefinition.java @@ -8,9 +8,9 @@ package org.opendaylight.controller.yang.model.api; /** - * Interface describing YANG 'notification' statement. The - * notification statement is used to define a NETCONF notification. + * Interface describing YANG 'notification' statement. The notification + * statement is used to define a NETCONF notification. */ -public interface NotificationDefinition extends SchemaNode, DataNodeContainer { +public interface NotificationDefinition extends SchemaNode, DataNodeContainer, AugmentationTarget { } diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/AbstractUnsignedInteger.java b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/AbstractUnsignedInteger.java index 79b211f263..ad903e9e52 100644 --- a/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/AbstractUnsignedInteger.java +++ b/opendaylight/sal/yang-prototype/yang/yang-model-util/src/main/java/org/opendaylight/controller/yang/model/util/AbstractUnsignedInteger.java @@ -19,7 +19,7 @@ import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefini * interface which represents UNSIGNED Integer values defined in Yang language.
* The integer built-in types in Yang are uint8, uint16, uint32, and uint64. * They represent unsigned integers of different sizes: - * + * *
    *
  • uint8 - represents integer values between 0 and 255, inclusively.
  • *
  • uint16 - represents integer values between 0 and 65535, inclusively.
  • @@ -28,7 +28,7 @@ import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefini *
  • uint64 - represents integer values between 0 and 18446744073709551615, * inclusively.
  • *
- * + * */ public abstract class AbstractUnsignedInteger implements UnsignedIntegerTypeDefinition { private static final long MIN_VALUE = 0; @@ -40,7 +40,7 @@ public abstract class AbstractUnsignedInteger implements UnsignedIntegerTypeDefi private final List rangeStatements; /** - * + * * @param actualPath * @param namespace * @param revision -- 2.36.6