From: Martin Vitez Date: Tue, 11 Jun 2013 09:55:29 +0000 (+0200) Subject: Fixed parsing of typedef statement. Refactored YangParserImpl to improve code readabi... X-Git-Tag: releasepom-0.1.0~378 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=00ebaa790e2bffbf3b05f52e842c28c6ae6df248 Fixed parsing of typedef statement. Refactored YangParserImpl to improve code readability. Added methods to LeafSchemaNode interface. Updated tests. Change-Id: I63c84a5c0c3c4f6c68b8c2dabdcbb66266496000 Signed-off-by: Martin Vitez --- 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 6940e91e38..67e4c6fb72 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 @@ -71,7 +71,6 @@ public class ModuleBuilder implements Builder { private final Map, GroupingBuilder> addedGroupings = new HashMap, GroupingBuilder>(); private final List addedAugments = new ArrayList(); private final Map, UsesNodeBuilder> addedUsesNodes = new HashMap, UsesNodeBuilder>(); - //private final Map, RefineHolder> addedRefines = new HashMap, RefineHolder>(); private final Map, RpcDefinitionBuilder> addedRpcs = new HashMap, RpcDefinitionBuilder>(); private final Set addedNotifications = new HashSet(); private final Set addedIdentities = new HashSet(); @@ -177,6 +176,14 @@ public class ModuleBuilder implements Builder { actualPath.pop(); } + public Builder getActualNode() { + if (actualPath.isEmpty()) { + return null; + } else { + return actualPath.get(0); + } + } + public Builder getModuleNode(final List path) { return childNodes.get(path); } @@ -756,6 +763,11 @@ public class ModuleBuilder implements Builder { return builder; } + @Override + public String toString() { + return ModuleBuilder.class.getSimpleName() + "[" + name + "]"; + } + private final class ModuleImpl implements Module { private URI namespace; private final String name; @@ -1101,8 +1113,7 @@ public class ModuleBuilder implements Builder { if (parent instanceof AugmentationSchemaBuilder) { nodeBuilder.setAugmenting(true); } - ((DataNodeContainerBuilder) parent) - .addChildNode(nodeBuilder); + ((DataNodeContainerBuilder) parent).addChildNode(nodeBuilder); } else if (parent instanceof ChoiceBuilder) { ((ChoiceBuilder) parent).addChildNode(nodeBuilder); } else { diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java index d60dbbb615..a8628eae72 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java @@ -32,6 +32,7 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder private SchemaPath schemaPath; private final List addedUnknownNodes = new ArrayList(); + private List unknownNodes; private List ranges = Collections.emptyList(); private List lengths = Collections.emptyList(); private List patterns = Collections.emptyList(); @@ -73,9 +74,11 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder typeBuilder.fractionDigits(fractionDigits); // 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()); + } } typeBuilder.unknownSchemaNodes(unknownNodes); result = typeBuilder.build(); @@ -164,6 +167,10 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder addedUnknownNodes.add(unknownNode); } + public void setUnknownNodes(List unknownNodes) { + this.unknownNodes = unknownNodes; + } + @Override public List getRanges() { return ranges; 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 401189b1d1..95b52a0a4a 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 @@ -41,15 +41,11 @@ 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.LengthConstraint; -import org.opendaylight.controller.yang.model.api.type.PatternConstraint; -import org.opendaylight.controller.yang.model.api.type.RangeConstraint; 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.model.util.YangTypesConverter; 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; @@ -297,222 +293,116 @@ public final class YangParserImpl implements YangModelParser { if (!dirtyNodes.isEmpty()) { for (Map.Entry, TypeAwareBuilder> entry : dirtyNodes .entrySet()) { - final TypeAwareBuilder nodeToResolve = entry.getValue(); - // different handling for union types + if (nodeToResolve instanceof UnionTypeBuilder) { - final UnionTypeBuilder union = (UnionTypeBuilder) nodeToResolve; - final List> unionTypes = union.getTypes(); - final List toRemove = new ArrayList(); - for (TypeDefinition td : unionTypes) { - if (td instanceof UnknownType) { - final UnknownType unknownType = (UnknownType) td; - final TypeDefinitionBuilder resolvedType = resolveTypeUnion( - nodeToResolve, unknownType, modules, module); - union.setTypedef(resolvedType); - toRemove.add(unknownType); - } - } - unionTypes.removeAll(toRemove); + // special handling for union types + resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules, + module); } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { - // different handling for identityref types + // special handling for identityref types IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve .getTypedef(); nodeToResolve.setType(new IdentityrefType(findFullQName( modules, module, idref), idref.getPath())); } else { - final TypeDefinitionBuilder resolvedType = resolveType( - nodeToResolve, modules, module); - nodeToResolve.setTypedef(resolvedType); + resolveType(nodeToResolve, modules, module); } } } } - private TypeDefinitionBuilder resolveType( - final TypeAwareBuilder nodeToResolve, - final Map> modules, - final ModuleBuilder builder) { - final TypeConstraints constraints = new TypeConstraints(); - - final TypeDefinitionBuilder targetTypeBuilder = getTypeDefinitionBuilderFromDirtyNode( - nodeToResolve, modules, builder); - final TypeConstraints tConstraints = findConstraints(nodeToResolve, - constraints, modules, builder); - targetTypeBuilder.setRanges(tConstraints.getRange()); - targetTypeBuilder.setLengths(tConstraints.getLength()); - targetTypeBuilder.setPatterns(tConstraints.getPatterns()); - targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits()); - - return targetTypeBuilder; - } - - private TypeDefinitionBuilder resolveTypeUnion( - final TypeAwareBuilder typeToResolve, - final UnknownType unknownType, + private void resolveType(final TypeAwareBuilder nodeToResolve, final Map> modules, final ModuleBuilder builder) { - final TypeConstraints constraints = new TypeConstraints(); - - final TypeDefinitionBuilder targetTypeBuilder = getUnionBuilder( - typeToResolve, unknownType, modules, builder); - final TypeConstraints tConstraints = findConstraints(typeToResolve, - constraints, modules, builder); - targetTypeBuilder.setRanges(tConstraints.getRange()); - targetTypeBuilder.setLengths(tConstraints.getLength()); - targetTypeBuilder.setPatterns(tConstraints.getPatterns()); - targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits()); - - return targetTypeBuilder; - } - - private TypeDefinitionBuilder getTypeDefinitionBuilderFromDirtyNode( - final TypeAwareBuilder nodeToResolve, - final Map> modules, - final ModuleBuilder module) { - - final UnknownType unknownType = (UnknownType) nodeToResolve.getType(); - final QName unknownTypeQName = unknownType.getQName(); - - // search for module which contains referenced typedef + TypeDefinitionBuilder resolvedType = null; + final int line = nodeToResolve.getLine(); + final TypeDefinition typedefType = nodeToResolve.getType(); + final QName unknownTypeQName = typedefType.getBaseType().getQName(); final ModuleBuilder dependentModule = findDependentModule(modules, - module, unknownTypeQName.getPrefix(), nodeToResolve.getLine()); - - final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder( - nodeToResolve.getPath(), dependentModule, - unknownTypeQName.getLocalName(), module.getName(), - nodeToResolve.getLine()); - - final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder( - lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder); - final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder( - lookedUpBuilderCopy, modules, dependentModule); - return resolvedCopy; - } - - private TypeDefinitionBuilder getUnionBuilder( - final TypeAwareBuilder nodeToResolve, - final UnknownType unknownType, - final Map> modules, - final ModuleBuilder module) { - - final TypeDefinition baseTypeToResolve = nodeToResolve.getType(); - if (baseTypeToResolve != null - && !(baseTypeToResolve instanceof UnknownType)) { - return (TypeDefinitionBuilder) nodeToResolve; - } + builder, unknownTypeQName.getPrefix(), line); - final QName unknownTypeQName = unknownType.getQName(); - // search for module which contains referenced typedef - final ModuleBuilder dependentModule = findDependentModule(modules, - module, unknownTypeQName.getPrefix(), nodeToResolve.getLine()); - final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder( + final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder( nodeToResolve.getPath(), dependentModule, - unknownTypeQName.getLocalName(), module.getName(), - nodeToResolve.getLine()); - - final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder( - lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder); - final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder( - lookedUpBuilderCopy, modules, dependentModule); - return resolvedCopy; - } + unknownTypeQName.getLocalName(), builder.getName(), line); - private TypeDefinitionBuilder copyTypedefBuilder( - final TypeDefinitionBuilder old, final boolean seekByTypedefBuilder) { - if (old instanceof UnionTypeBuilder) { - final UnionTypeBuilder oldUnion = (UnionTypeBuilder) old; - final UnionTypeBuilder newUnion = new UnionTypeBuilder( - old.getLine()); - for (TypeDefinition td : oldUnion.getTypes()) { - newUnion.setType(td); - } - for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) { - newUnion.setTypedef(copyTypedefBuilder(tdb, true)); - } - newUnion.setPath(old.getPath()); - return newUnion; - } - - final QName oldName = old.getQName(); - final QName newName = new QName(oldName.getNamespace(), - oldName.getRevision(), oldName.getPrefix(), - oldName.getLocalName()); - final TypeDefinitionBuilder tdb = new TypeDefinitionBuilderImpl( - newName, old.getLine()); - - tdb.setRanges(old.getRanges()); - tdb.setLengths(old.getLengths()); - tdb.setPatterns(old.getPatterns()); - tdb.setFractionDigits(old.getFractionDigits()); - tdb.setPath(old.getPath()); - - final TypeDefinition oldType = old.getType(); - if (oldType == null) { - tdb.setTypedef(old.getTypedef()); + if (typedefType instanceof ExtendedType) { + final ExtendedType extType = (ExtendedType) typedefType; + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType( + nodeToResolve, targetTypeBuilder, extType, modules, builder); + resolvedType = newType; } else { - tdb.setType(oldType); + resolvedType = targetTypeBuilder; } - - if (!seekByTypedefBuilder) { - tdb.setDescription(old.getDescription()); - tdb.setReference(old.getReference()); - tdb.setStatus(old.getStatus()); - tdb.setDefaultValue(old.getDefaultValue()); - tdb.setUnits(old.getUnits()); - } - return tdb; + nodeToResolve.setTypedef(resolvedType); } - private TypeDefinitionBuilder resolveCopiedBuilder( - final TypeDefinitionBuilder copy, + private void resolveTypeUnion(final UnionTypeBuilder union, final Map> modules, final ModuleBuilder builder) { - if (copy instanceof UnionTypeBuilder) { - final UnionTypeBuilder union = (UnionTypeBuilder) copy; - final List> unionTypes = union.getTypes(); - final List toRemove = new ArrayList(); - for (TypeDefinition td : unionTypes) { - if (td instanceof UnknownType) { - final UnknownType unknownType = (UnknownType) td; - final TypeDefinitionBuilder resolvedType = resolveTypeUnion( - union, unknownType, modules, builder); - union.setTypedef(resolvedType); - toRemove.add(unknownType); + final List> unionTypes = union.getTypes(); + final List> toRemove = new ArrayList>(); + 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 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(); + if (extTypeBase instanceof UnknownType) { + final UnknownType ut = (UnknownType) extTypeBase; + final ModuleBuilder dependentModule = findDependentModule( + 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); + + union.setTypedef(newType); + toRemove.add(extType); } } - unionTypes.removeAll(toRemove); - - return union; } + unionTypes.removeAll(toRemove); + } - final TypeDefinition base = copy.getType(); - final TypeDefinitionBuilder baseTdb = copy.getTypedef(); - if (base != null && !(base instanceof UnknownType)) { - return copy; - } else if (base instanceof UnknownType) { - final UnknownType unknownType = (UnknownType) base; - final QName unknownTypeQName = unknownType.getQName(); - final String unknownTypePrefix = unknownTypeQName.getPrefix(); - final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknownTypePrefix, copy.getLine()); - final TypeDefinitionBuilder utBuilder = getTypeDefinitionBuilderFromDirtyNode( - copy, modules, dependentModule); - copy.setTypedef(utBuilder); - return copy; - } else if (base == null && baseTdb != null) { - // make a copy of baseTypeDef and call again - final TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder( - baseTdb, true); - final TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder( - baseTdbCopy, modules, builder); - copy.setTypedef(baseTdbCopyResolved); - return copy; - } else { - throw new YangParseException(copy.getLine(), - "Failed to resolve type " + copy.getQName().getLocalName()); - } + 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(), 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( @@ -520,77 +410,63 @@ public final class YangParserImpl implements YangModelParser { final TypeConstraints constraints, final Map> modules, final ModuleBuilder builder) { + // union type cannot be restricted if (nodeToResolve instanceof UnionTypeBuilder) { return constraints; } - // if referenced type is UnknownType again, search recursively with - // current constraints - final TypeDefinition referencedType = nodeToResolve.getType(); - List ranges = Collections.emptyList(); - List lengths = Collections.emptyList(); - List patterns = Collections.emptyList(); - Integer fractionDigits = null; - if (referencedType == null) { - final TypeDefinitionBuilder tdb = nodeToResolve.getTypedef(); - ranges = tdb.getRanges(); - constraints.addRanges(ranges); - lengths = tdb.getLengths(); - constraints.addLengths(lengths); - patterns = tdb.getPatterns(); - constraints.addPatterns(patterns); - fractionDigits = tdb.getFractionDigits(); - constraints.setFractionDigits(fractionDigits); - return constraints; - } else if (referencedType instanceof ExtendedType) { - final ExtendedType ext = (ExtendedType) referencedType; - ranges = ext.getRanges(); - constraints.addRanges(ranges); - lengths = ext.getLengths(); - constraints.addLengths(lengths); - patterns = ext.getPatterns(); - constraints.addPatterns(patterns); - fractionDigits = ext.getFractionDigits(); - constraints.setFractionDigits(fractionDigits); - if(YangTypesConverter.isBaseYangType(ext.getBaseType().getQName().getLocalName())) { - mergeConstraints(ext.getBaseType(), constraints); - 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 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); + } else { + // it has to be base yang type + mergeConstraints(type, constraints); + return constraints; + } } else { - return findConstraints( - findTypeDefinitionBuilder(nodeToResolve.getPath(), builder, - ext.getQName().getLocalName(), builder.getName(), - nodeToResolve.getLine()), constraints, modules, - builder); - } - } else if (referencedType instanceof UnknownType) { - final UnknownType unknown = (UnknownType) referencedType; - ranges = unknown.getRangeStatements(); - constraints.addRanges(ranges); - lengths = unknown.getLengthStatements(); - constraints.addLengths(lengths); - patterns = unknown.getPatterns(); - constraints.addPatterns(patterns); - fractionDigits = unknown.getFractionDigits(); - constraints.setFractionDigits(fractionDigits); - - String unknownTypePrefix = unknown.getQName().getPrefix(); - if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) { - unknownTypePrefix = builder.getPrefix(); + // it is base yang type + mergeConstraints(type, constraints); + return constraints; } - final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknown.getQName().getPrefix(), - nodeToResolve.getLine()); - final TypeDefinitionBuilder utBuilder = findTypeDefinitionBuilder( - nodeToResolve.getPath(), dependentModule, unknown - .getQName().getLocalName(), builder.getName(), - nodeToResolve.getLine()); - return findConstraints(utBuilder, constraints, modules, - dependentModule); - } else { - // HANDLE BASE YANG TYPE - mergeConstraints(referencedType, constraints); - return constraints; } } @@ -677,7 +553,7 @@ public final class YangParserImpl implements YangModelParser { constraints.addRanges(((DecimalTypeDefinition) referencedType) .getRangeStatements()); constraints - .setFractionDigits(((DecimalTypeDefinition) referencedType) + .addFractionDigits(((DecimalTypeDefinition) referencedType) .getFractionDigits()); } else if (referencedType instanceof IntegerTypeDefinition) { constraints.addRanges(((IntegerTypeDefinition) referencedType) diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java index d7394e6229..40a3289745 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java @@ -342,7 +342,6 @@ public final class YangParserListenerImpl extends YangParserBaseListener { if ("union".equals(typeName)) { List typePath = new ArrayList(actualPath); typePath.add(typeName); - SchemaPath p = createActualSchemaPath(typePath, namespace, revision, yangModelPrefix); UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType( @@ -357,12 +356,15 @@ public final class YangParserListenerImpl extends YangParserBaseListener { line); } else { type = parseTypeBody(typeName, typeBody, actualPath, - namespace, revision, yangModelPrefix); + namespace, revision, yangModelPrefix, + moduleBuilder.getActualNode()); moduleBuilder.setType(type, actualPath); } } } else { - type = parseUnknownTypeBody(typeQName, typeBody); + type = parseUnknownTypeBody(typeQName, typeBody, actualPath, + namespace, revision, yangModelPrefix, + moduleBuilder.getActualNode(), moduleBuilder); // mark parent node of this type statement as dirty moduleBuilder.addDirtyNode(actualPath); moduleBuilder.setType(type, actualPath); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java index 18e4c31ab9..670c1d573c 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java @@ -23,14 +23,14 @@ public final class TypeConstraints { private final List> ranges = new ArrayList>(); private final List> lengths = new ArrayList>(); private final List patterns = new ArrayList(); - private Integer fractionDigits; + private final List fractionDigits = new ArrayList(); List> getAllRanges() { return ranges; } public List getRange() { - if(ranges.isEmpty()) { + if (ranges.isEmpty()) { return Collections.emptyList(); } @@ -108,7 +108,7 @@ public final class TypeConstraints { } public List getLength() { - if(lengths.isEmpty()) { + if (lengths.isEmpty()) { return Collections.emptyList(); } @@ -190,13 +190,14 @@ public final class TypeConstraints { } public Integer getFractionDigits() { - return fractionDigits; + if (fractionDigits.isEmpty()) { + return null; + } + return fractionDigits.get(0); } - public void setFractionDigits(final Integer fractionDigits) { - if (this.fractionDigits == null) { - this.fractionDigits = fractionDigits; - } + public void addFractionDigits(final Integer fractionDigits) { + this.fractionDigits.add(fractionDigits); } } 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 f58ee740cf..1e55b24449 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 @@ -76,13 +76,17 @@ 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.type.BinaryTypeDefinition; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition; import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; +import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition; import org.opendaylight.controller.yang.model.api.type.LengthConstraint; import org.opendaylight.controller.yang.model.api.type.PatternConstraint; import org.opendaylight.controller.yang.model.api.type.RangeConstraint; +import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition; +import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefinition; import org.opendaylight.controller.yang.model.util.BaseConstraints; import org.opendaylight.controller.yang.model.util.BaseTypes; import org.opendaylight.controller.yang.model.util.BinaryType; @@ -103,8 +107,12 @@ 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.UnknownType; +import org.opendaylight.controller.yang.parser.builder.api.Builder; 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.impl.ConstraintsBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -964,19 +972,48 @@ public final class YangModelBuilderUtil { * @return UnknownType object with constraints from parsed type body */ public static TypeDefinition parseUnknownTypeBody(QName typedefQName, - Type_body_stmtsContext ctx) { + Type_body_stmtsContext ctx, final List actualPath, + final URI namespace, final Date revision, final String prefix, + Builder parent, ModuleBuilder moduleBuilder) { + String typeName = typedefQName.getLocalName(); + UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName); + if (ctx != null) { List rangeStatements = getRangeConstraints(ctx); List lengthStatements = getLengthConstraints(ctx); List patternStatements = getPatternConstraint(ctx); Integer fractionDigits = getFractionDigits(ctx); - unknownType.rangeStatements(rangeStatements); - unknownType.lengthStatements(lengthStatements); - unknownType.patterns(patternStatements); - unknownType.fractionDigits(fractionDigits); + if (parent instanceof TypeDefinitionBuilder) { + TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; + typedef.setRanges(rangeStatements); + typedef.setLengths(lengthStatements); + typedef.setPatterns(patternStatements); + typedef.setFractionDigits(fractionDigits); + return unknownType.build(); + } else { + TypeDefinition baseType = unknownType.build(); + TypeDefinition result = null; + QName qname = new QName(namespace, revision, prefix, typeName); + ExtendedType.Builder typeBuilder = null; + + SchemaPath schemaPath = createTypeSchemaPath(actualPath, + namespace, revision, prefix, typeName, false, false); + typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", + schemaPath); + + typeBuilder.ranges(rangeStatements); + typeBuilder.lengths(lengthStatements); + typeBuilder.patterns(patternStatements); + typeBuilder.fractionDigits(fractionDigits); + + result = typeBuilder.build(); + + return result; + } } + return unknownType.build(); } @@ -1000,7 +1037,7 @@ public final class YangModelBuilderUtil { public static TypeDefinition parseTypeBody(final String typeName, final Type_body_stmtsContext typeBody, final List actualPath, final URI namespace, - final Date revision, final String prefix) { + final Date revision, final String prefix, Builder parent) { TypeDefinition baseType = null; List rangeStatements = getRangeConstraints(typeBody); @@ -1010,40 +1047,56 @@ public final class YangModelBuilderUtil { List enumConstants = getEnumConstants( typeBody, actualPath, namespace, revision, prefix); + TypeConstraints constraints = new TypeConstraints(); + constraints.addFractionDigits(fractionDigits); + constraints.addLengths(lengthStatements); + constraints.addPatterns(patternStatements); + constraints.addRanges(rangeStatements); + SchemaPath baseTypePathFinal = createTypeSchemaPath(actualPath, namespace, revision, prefix, typeName, true, true); - SchemaPath baseTypePath = createTypeSchemaPath(actualPath, - namespace, revision, prefix, typeName, true, false); + SchemaPath baseTypePath = createTypeSchemaPath(actualPath, namespace, + revision, prefix, typeName, true, false); if ("decimal64".equals(typeName)) { if (rangeStatements.isEmpty()) { return new Decimal64(baseTypePathFinal, fractionDigits); } - baseType = new Decimal64(baseTypePath, fractionDigits); + Decimal64 decimalType = new Decimal64(baseTypePath, fractionDigits); + constraints.addRanges(decimalType.getRangeStatements()); + baseType = decimalType; } else if (typeName.startsWith("int")) { + IntegerTypeDefinition intType = null; if ("int8".equals(typeName)) { - baseType = new Int8(baseTypePath); + intType = new Int8(baseTypePath); } else if ("int16".equals(typeName)) { - baseType = new Int16(baseTypePath); + intType = new Int16(baseTypePath); } else if ("int32".equals(typeName)) { - baseType = new Int32(baseTypePath); + intType = new Int32(baseTypePath); } else if ("int64".equals(typeName)) { - baseType = new Int64(baseTypePath); + intType = new Int64(baseTypePath); } + constraints.addRanges(intType.getRangeStatements()); + baseType = intType; } else if (typeName.startsWith("uint")) { + UnsignedIntegerTypeDefinition uintType = null; if ("uint8".equals(typeName)) { - baseType = new Uint8(baseTypePath); + uintType = new Uint8(baseTypePath); } else if ("uint16".equals(typeName)) { - baseType = new Uint16(baseTypePath); + uintType = new Uint16(baseTypePath); } else if ("uint32".equals(typeName)) { - baseType = new Uint32(baseTypePath); + uintType = new Uint32(baseTypePath); } else if ("uint64".equals(typeName)) { - baseType = new Uint64(baseTypePath); + uintType = new Uint64(baseTypePath); } + constraints.addRanges(uintType.getRangeStatements()); + baseType = uintType; } else if ("enumeration".equals(typeName)) { return new EnumerationType(baseTypePathFinal, enumConstants); } else if ("string".equals(typeName)) { - baseType = new StringType(baseTypePath); + StringTypeDefinition stringType = new StringType(baseTypePath); + constraints.addLengths(stringType.getLengthStatements()); + baseType = stringType; } else if ("bits".equals(typeName)) { return new BitsType(baseTypePathFinal, getBits(typeBody, actualPath, namespace, revision, prefix)); @@ -1054,13 +1107,25 @@ public final class YangModelBuilderUtil { absolute); return new Leafref(baseTypePathFinal, xpath); } else if ("binary".equals(typeName)) { - baseType = new BinaryType(baseTypePath); + BinaryTypeDefinition binaryType = new BinaryType(baseTypePath); + constraints.addLengths(binaryType.getLengthConstraints()); + baseType = binaryType; } else if ("instance-identifier".equals(typeName)) { boolean requireInstance = isRequireInstance(typeBody); baseType = new InstanceIdentifier(baseTypePath, null, requireInstance); } + if (parent instanceof TypeDefinitionBuilder + && !(parent instanceof UnionTypeBuilder)) { + TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent; + typedef.setRanges(constraints.getRange()); + typedef.setLengths(constraints.getLength()); + typedef.setPatterns(constraints.getPatterns()); + typedef.setFractionDigits(constraints.getFractionDigits()); + return baseType; + } + TypeDefinition result = null; QName qname = new QName(namespace, revision, prefix, typeName); ExtendedType.Builder typeBuilder = null; @@ -1070,10 +1135,10 @@ public final class YangModelBuilderUtil { typeBuilder = new ExtendedType.Builder(qname, baseType, "", "", schemaPath); - typeBuilder.ranges(rangeStatements); - typeBuilder.lengths(lengthStatements); - typeBuilder.patterns(patternStatements); - typeBuilder.fractionDigits(fractionDigits); + typeBuilder.ranges(constraints.getRange()); + typeBuilder.lengths(constraints.getLength()); + typeBuilder.patterns(constraints.getPatterns()); + typeBuilder.fractionDigits(constraints.getFractionDigits()); result = typeBuilder.build(); return result; 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 d14c54219e..26c2c61b98 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 @@ -49,13 +49,9 @@ final class TestUtils { return parser.parseYangModels(testFiles); } - public static Set loadModules(String... pathToYangFile) throws IOException { - YangModelParser parser = new YangParserImpl(); - List input = new ArrayList(); - for(String path : pathToYangFile) { - input.add(TestUtils.class.getResourceAsStream(path)); - } - Set modules = new HashSet( + public static Set loadModules(List input) throws IOException { + final YangModelParser parser = new YangParserImpl(); + final Set modules = new HashSet( parser.parseYangModelsFromStreams(input)); for(InputStream stream : input) { stream.close(); @@ -63,11 +59,11 @@ final class TestUtils { return modules; } - public static Module loadModule(String pathToYangFile) throws IOException { - YangModelParser parser = new YangParserImpl(); - InputStream stream = TestUtils.class.getResourceAsStream(pathToYangFile); - List input = Collections.singletonList(stream); - Set modules = new HashSet( + public static Module loadModule(final InputStream stream) throws + IOException { + final YangModelParser parser = new YangParserImpl(); + final List input = Collections.singletonList(stream); + final Set modules = new HashSet( parser.parseYangModelsFromStreams(input)); stream.close(); return modules.iterator().next(); diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java index 461cc4b5c2..2c910ce3f6 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java @@ -26,6 +26,7 @@ import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit; import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair; import org.opendaylight.controller.yang.model.api.type.LengthConstraint; import org.opendaylight.controller.yang.model.api.type.PatternConstraint; +import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition; import org.opendaylight.controller.yang.model.util.BitsType; import org.opendaylight.controller.yang.model.util.EnumerationType; import org.opendaylight.controller.yang.model.util.ExtendedType; @@ -38,7 +39,8 @@ public class TypesResolutionTest { @Before public void init() throws FileNotFoundException { - testedModules = TestUtils.loadModules("src/test/resources/types"); + testedModules = TestUtils.loadModules(getClass().getResource + ("/types").getPath()); } @Test @@ -122,16 +124,19 @@ public class TypesResolutionTest { List> unionTypes = baseType.getTypes(); ExtendedType ipv4 = (ExtendedType) unionTypes.get(0); - ExtendedType ipv4Base = (ExtendedType) ipv4.getBaseType(); + assertTrue(ipv4.getBaseType() instanceof StringTypeDefinition); String expectedPattern = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}" + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" + "(%[\\p{N}\\p{L}]+)?"; - assertEquals(expectedPattern, ipv4Base.getPatterns().get(0) + assertEquals(expectedPattern, ipv4.getPatterns().get(0) .getRegularExpression()); + TypeDefinition ipv4Address = TestUtils.findTypedef(typedefs, "ipv4-address"); + assertEquals(ipv4Address, ipv4); + ExtendedType ipv6 = (ExtendedType) unionTypes.get(1); - ExtendedType ipv6Base = (ExtendedType) ipv6.getBaseType(); - List ipv6Patterns = ipv6Base.getPatterns(); + assertTrue(ipv6.getBaseType() instanceof StringTypeDefinition); + List ipv6Patterns = ipv6.getPatterns(); expectedPattern = "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}" + "((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|" + "(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}" @@ -140,6 +145,9 @@ public class TypesResolutionTest { assertEquals(expectedPattern, ipv6Patterns.get(0) .getRegularExpression()); + TypeDefinition ipv6Address = TestUtils.findTypedef(typedefs, "ipv6-address"); + assertEquals(ipv6Address, ipv6); + expectedPattern = "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|" + "((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)" + "(%.+)?"; assertEquals(expectedPattern, ipv6Patterns.get(1) @@ -150,18 +158,18 @@ public class TypesResolutionTest { public void testDomainName() { Module tested = TestUtils.findModule(testedModules, "ietf-inet-types"); Set> typedefs = tested.getTypeDefinitions(); - TypeDefinition type = TestUtils.findTypedef(typedefs, "domain-name"); - ExtendedType baseType = (ExtendedType) type.getBaseType(); - List patterns = baseType.getPatterns(); + ExtendedType type = (ExtendedType)TestUtils.findTypedef(typedefs, "domain-name"); + assertTrue(type.getBaseType() instanceof StringTypeDefinition); + List patterns = type.getPatterns(); assertEquals(1, patterns.size()); String expectedPattern = "((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*" + "([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)" + "|\\."; assertEquals(expectedPattern, patterns.get(0).getRegularExpression()); - List lengths = baseType.getLengths(); + List lengths = type.getLengths(); assertEquals(1, lengths.size()); - LengthConstraint length = baseType.getLengths().get(0); + LengthConstraint length = type.getLengths().get(0); assertEquals(1L, length.getMin()); assertEquals(253L, length.getMax()); } @@ -173,7 +181,8 @@ public class TypesResolutionTest { LeafSchemaNode leaf = (LeafSchemaNode) tested .getDataChildByName("inst-id-leaf1"); ExtendedType leafType = (ExtendedType) leaf.getType(); - InstanceIdentifier leafTypeBase = (InstanceIdentifier)leafType.getBaseType(); + InstanceIdentifier leafTypeBase = (InstanceIdentifier) leafType + .getBaseType(); assertFalse(leafTypeBase.requireInstance()); } @@ -300,6 +309,11 @@ public class TypesResolutionTest { ExtendedType testedType = (ExtendedType) TestUtils.findTypedef( typedefs, "object-identifier-128"); + List patterns = testedType.getPatterns(); + assertEquals(1, patterns.size()); + PatternConstraint pattern = patterns.get(0); + assertEquals("\\d*(\\.\\d*){1,127}", pattern.getRegularExpression()); + QName testedTypeQName = testedType.getQName(); assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-yang-types"), testedTypeQName.getNamespace()); @@ -309,15 +323,13 @@ public class TypesResolutionTest { assertEquals("object-identifier-128", testedTypeQName.getLocalName()); ExtendedType testedTypeBase = (ExtendedType) testedType.getBaseType(); + patterns = testedTypeBase.getPatterns(); + assertEquals(1, patterns.size()); - List patterns = testedTypeBase.getPatterns(); - assertEquals(2, patterns.size()); - PatternConstraint pattern1 = patterns.get(0); - assertEquals("\\d*(\\.\\d*){1,127}", pattern1.getRegularExpression()); - PatternConstraint pattern2 = patterns.get(1); + pattern = patterns.get(0); assertEquals( "(([0-1](\\.[1-3]?[0-9]))|(2\\.(0|([1-9]\\d*))))(\\.(0|([1-9]\\d*)))*", - pattern2.getRegularExpression()); + pattern.getRegularExpression()); QName testedTypeBaseQName = testedTypeBase.getQName(); assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-yang-types"), diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java index be44c6ff98..35bfb1bebf 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java @@ -9,7 +9,11 @@ package org.opendaylight.controller.yang.parser.impl; import static org.junit.Assert.*; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; import org.junit.Test; import org.opendaylight.controller.yang.parser.util.YangParseException; @@ -20,8 +24,11 @@ public class YangParserNegativeTest { @Test public void testInvalidImport() throws IOException { try { - TestUtils.loadModule("/negative-scenario/testfile1.yang"); - fail("ValidationException should by thrown"); + try (InputStream stream = new FileInputStream(getClass().getResource + ("/negative-scenario/testfile1.yang").getPath())) { + TestUtils.loadModule(stream); + fail("ValidationException should by thrown"); + } } catch(YangValidationException e) { assertTrue(e.getMessage().contains("Not existing module imported")); } @@ -30,8 +37,11 @@ public class YangParserNegativeTest { @Test public void testTypeNotFound() throws IOException { try { - TestUtils.loadModule("/negative-scenario/testfile2.yang"); - fail("YangParseException should by thrown"); + try (InputStream stream = new FileInputStream(getClass().getResource + ("/negative-scenario/testfile2.yang").getPath())) { + TestUtils.loadModule(stream); + fail("YangParseException should by thrown"); + } } catch(YangParseException e) { assertTrue(e.getMessage().contains("Error in module 'test2' on line 24: Referenced type 'int-ext' not found.")); } @@ -40,8 +50,19 @@ public class YangParserNegativeTest { @Test public void testInvalidAugmentTarget() throws IOException { try { - TestUtils.loadModules("/negative-scenario/testfile0.yang", "/negative-scenario/testfile3.yang"); - fail("YangParseException should by thrown"); + final List streams = new ArrayList<>(2); + try (InputStream testFile0 = new FileInputStream(getClass().getResource + ("/negative-scenario/testfile0.yang").getPath())) { + streams.add(testFile0); + try (InputStream testFile3 = new FileInputStream(getClass().getResource + ("/negative-scenario/testfile3.yang").getPath())) { + streams.add(testFile3); + assertEquals("Expected loaded files count is 2", 2, + streams.size()); + TestUtils.loadModules(streams); + fail("YangParseException should by thrown"); + } + } } catch(YangParseException e) { assertTrue(e.getMessage().contains("Failed to resolve augments in module 'test3'.")); } @@ -50,8 +71,11 @@ public class YangParserNegativeTest { @Test public void testInvalidRefine() throws IOException { try { - TestUtils.loadModule("/negative-scenario/testfile4.yang"); - fail("YangParseException should by thrown"); + try (InputStream stream = new FileInputStream(getClass().getResource + ("/negative-scenario/testfile4.yang").getPath())) { + TestUtils.loadModule(stream); + fail("YangParseException should by thrown"); + } } catch(YangParseException e) { assertTrue(e.getMessage().contains("Can not refine 'presence' for 'node'.")); } diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java index 23bb4a41d2..733b524cd3 100644 --- a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java +++ b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java @@ -16,7 +16,6 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -64,13 +63,14 @@ import org.opendaylight.controller.yang.model.util.Uint32; import org.opendaylight.controller.yang.model.util.UnionType; public class YangParserTest { - private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); + private final DateFormat simpleDateFormat = new SimpleDateFormat( + "yyyy-MM-dd"); private Set modules; @Before public void init() throws FileNotFoundException { - modules = TestUtils.loadModules("src/test/resources/model"); + modules = TestUtils.loadModules(getClass().getResource("/model").getPath()); assertEquals(3, modules.size()); } @@ -209,7 +209,7 @@ public class YangParserTest { // leaf if-name LeafSchemaNode ifName = (LeafSchemaNode) test .getDataChildByName("if-name"); - Leafref ifNameType = (Leafref)ifName.getType(); + Leafref ifNameType = (Leafref) ifName.getType(); QName qname = ifNameType.getQName(); URI baseYangTypeNS = URI.create("urn:ietf:params:xml:ns:yang:1"); @@ -219,9 +219,8 @@ public class YangParserTest { assertEquals("leafref", qname.getLocalName()); // leaf name - LeafSchemaNode name = (LeafSchemaNode) test - .getDataChildByName("name"); - StringType nameType = (StringType)name.getType(); + LeafSchemaNode name = (LeafSchemaNode) test.getDataChildByName("name"); + StringType nameType = (StringType) name.getType(); QName nameQName = nameType.getQName(); assertEquals(baseYangTypeNS, nameQName.getNamespace()); @@ -232,7 +231,7 @@ public class YangParserTest { // leaf count LeafSchemaNode count = (LeafSchemaNode) test .getDataChildByName("count"); - ExtendedType countType = (ExtendedType)count.getType(); + ExtendedType countType = (ExtendedType) count.getType(); QName countTypeQName = countType.getQName(); URI expectedNS = URI.create("urn:simple.types.data.demo"); @@ -242,7 +241,7 @@ public class YangParserTest { assertEquals("t2", countTypeQName.getPrefix()); assertEquals("int8", countTypeQName.getLocalName()); - Int8 countTypeBase = (Int8)countType.getBaseType(); + Int8 countTypeBase = (Int8) countType.getBaseType(); QName countTypeBaseQName = countTypeBase.getQName(); assertEquals(baseYangTypeNS, countTypeBaseQName.getNamespace()); @@ -341,17 +340,29 @@ public class YangParserTest { } @Test - public void testTypedefRangesResolving() { + public void testTypedefRangesResolving() throws ParseException { Module testModule = TestUtils.findModule(modules, "types1"); LeafSchemaNode testleaf = (LeafSchemaNode) testModule .getDataChildByName("testleaf"); ExtendedType leafType = (ExtendedType) testleaf.getType(); - assertEquals("my-type1", leafType.getQName().getLocalName()); - assertEquals("t2", leafType.getQName().getPrefix()); + QName leafTypeQName = leafType.getQName(); + assertEquals("my-type1", leafTypeQName.getLocalName()); + assertEquals("t1", leafTypeQName.getPrefix()); + assertEquals(URI.create("urn:simple.container.demo"), + leafTypeQName.getNamespace()); + Date expectedDate = simpleDateFormat.parse("2013-02-27"); + assertEquals(expectedDate, leafTypeQName.getRevision()); + assertEquals(1, leafType.getRanges().size()); + ExtendedType baseType = (ExtendedType) leafType.getBaseType(); - assertEquals("my-base-int32-type", baseType.getQName().getLocalName()); - assertEquals("t2", baseType.getQName().getPrefix()); + QName baseTypeQName = baseType.getQName(); + assertEquals("my-type1", baseTypeQName.getLocalName()); + assertEquals("t2", baseTypeQName.getPrefix()); + assertEquals(URI.create("urn:simple.types.data.demo"), + baseTypeQName.getNamespace()); + assertEquals(expectedDate, baseTypeQName.getRevision()); + assertEquals(2, baseType.getRanges().size()); List ranges = leafType.getRanges(); assertEquals(1, ranges.size()); @@ -371,28 +382,21 @@ public class YangParserTest { assertEquals("my-string-type-ext", testleafTypeQName.getLocalName()); assertEquals("t2", testleafTypeQName.getPrefix()); - Set expectedRegex = new HashSet(); - expectedRegex.add("[a-k]*"); - expectedRegex.add("[b-u]*"); - expectedRegex.add("[e-z]*"); - - Set actualRegex = new HashSet(); List patterns = testleafType.getPatterns(); - assertEquals(3, patterns.size()); - for (PatternConstraint pc : patterns) { - actualRegex.add(pc.getRegularExpression()); - } - assertEquals(expectedRegex, actualRegex); + assertEquals(1, patterns.size()); + PatternConstraint pattern = patterns.iterator().next(); + assertEquals("[e-z]*", pattern.getRegularExpression()); - TypeDefinition baseType = testleafType.getBaseType(); + ExtendedType baseType = (ExtendedType) testleafType.getBaseType(); assertEquals("my-string-type2", baseType.getQName().getLocalName()); - List lengths = testleafType.getLengths(); - assertEquals(1, lengths.size()); + patterns = baseType.getPatterns(); + assertEquals(1, patterns.size()); + pattern = patterns.iterator().next(); + assertEquals("[b-u]*", pattern.getRegularExpression()); - LengthConstraint length = lengths.get(0); - assertEquals(5L, length.getMin()); - assertEquals(10L, length.getMax()); + List lengths = testleafType.getLengths(); + assertTrue(lengths.isEmpty()); } @Test @@ -424,14 +428,14 @@ public class YangParserTest { ExtendedType baseType = (ExtendedType) testleafType.getBaseType(); assertEquals("my-base-int32-type", baseType.getQName().getLocalName()); - ExtendedType int32Type = (ExtendedType) baseType.getBaseType(); - Int32 int32TypeBase = (Int32)int32Type.getBaseType(); - QName qname = int32TypeBase.getQName(); - assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), qname.getNamespace()); + Int32 int32Type = (Int32) baseType.getBaseType(); + QName qname = int32Type.getQName(); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), + qname.getNamespace()); assertNull(qname.getRevision()); assertEquals("", qname.getPrefix()); assertEquals("int32", qname.getLocalName()); - List ranges = int32Type.getRanges(); + List ranges = baseType.getRanges(); assertEquals(1, ranges.size()); RangeConstraint range = ranges.get(0); assertEquals(2L, range.getMin()); @@ -447,8 +451,12 @@ public class YangParserTest { ExtendedType type = (ExtendedType) testleaf.getType(); assertEquals(4, (int) type.getFractionDigits()); - Decimal64 baseType = (Decimal64) type.getBaseType(); - assertEquals(6, (int) baseType.getFractionDigits()); + ExtendedType typeBase = (ExtendedType) type.getBaseType(); + assertEquals("my-decimal-type", typeBase.getQName().getLocalName()); + assertNull(typeBase.getFractionDigits()); + + Decimal64 decimal = (Decimal64) typeBase.getBaseType(); + assertEquals(6, (int) decimal.getFractionDigits()); } @Test @@ -872,7 +880,8 @@ public class YangParserTest { Set> types = test.getTypeDefinitions(); // my-base-int32-type - ExtendedType int32Typedef = (ExtendedType)TestUtils.findTypedef(types, "my-base-int32-type"); + ExtendedType int32Typedef = (ExtendedType) TestUtils.findTypedef(types, + "my-base-int32-type"); QName int32TypedefQName = int32Typedef.getQName(); URI expectedNS = URI.create("urn:simple.types.data.demo"); @@ -888,24 +897,10 @@ public class YangParserTest { assertEquals(int32TypedefQName, typePath.get(0)); // my-base-int32-type/int32 - ExtendedType int32Ext = (ExtendedType)int32Typedef.getBaseType(); - QName int32ExtQName = int32Ext.getQName(); - - assertEquals(expectedNS, int32ExtQName.getNamespace()); - assertEquals(expectedDate, int32ExtQName.getRevision()); - assertEquals("t2", int32ExtQName.getPrefix()); - assertEquals("int32", int32ExtQName.getLocalName()); - - SchemaPath int32ExtSchemaPath = int32Ext.getPath(); - List int32ExtPath = int32ExtSchemaPath.getPath(); - assertEquals(2, int32ExtPath.size()); - assertEquals(int32TypedefQName, int32ExtPath.get(0)); - assertEquals(int32ExtQName, int32ExtPath.get(1)); - - // my-base-int32-type/int32/int32 - Int32 int32 = (Int32)int32Ext.getBaseType(); + Int32 int32 = (Int32) int32Typedef.getBaseType(); QName int32QName = int32.getQName(); - assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), int32QName.getNamespace()); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), + int32QName.getNamespace()); assertNull(int32QName.getRevision()); assertEquals("", int32QName.getPrefix()); assertEquals("int32", int32QName.getLocalName()); @@ -914,7 +909,6 @@ public class YangParserTest { List int32Path = int32SchemaPath.getPath(); assertEquals(3, int32Path.size()); assertEquals(int32TypedefQName, int32Path.get(0)); - assertEquals(int32ExtQName, int32Path.get(1)); assertEquals(int32QName, int32Path.get(2)); } @@ -924,7 +918,8 @@ public class YangParserTest { Set> types = test.getTypeDefinitions(); // my-base-int32-type - ExtendedType myDecType = (ExtendedType)TestUtils.findTypedef(types, "my-decimal-type"); + ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types, + "my-decimal-type"); QName myDecTypeQName = myDecType.getQName(); URI expectedNS = URI.create("urn:simple.types.data.demo"); @@ -940,10 +935,11 @@ public class YangParserTest { assertEquals(myDecTypeQName, typePath.get(0)); // my-base-int32-type/int32 - Decimal64 dec64 = (Decimal64)myDecType.getBaseType(); + Decimal64 dec64 = (Decimal64) myDecType.getBaseType(); QName dec64QName = dec64.getQName(); - assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace()); + assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), + dec64QName.getNamespace()); assertNull(dec64QName.getRevision()); assertEquals("", dec64QName.getPrefix()); assertEquals("decimal64", dec64QName.getLocalName()); diff --git a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java index 9325cb8f0c..e3dd0ecd22 100644 --- a/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java +++ b/opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java @@ -20,4 +20,8 @@ public interface LeafSchemaNode extends DataSchemaNode { */ TypeDefinition getType(); + String getDefault(); + + String getUnits(); + }