X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fcode-generator%2Fyang-model-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fyang%2Fparser%2Futil%2FParserUtils.java;h=587c8bed4ef19272ce420e92d0ffca1b6aef0a1f;hp=e95a162de763811d1d9ead81d32df43aeb599827;hb=88187167a1b7928602fd8d72cb7d4dc2b38dfa70;hpb=0cfc417107d5b5b1bafdd7ee1fe8e3ba052d5488 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 e95a162de7..587c8bed4e 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,15 +7,34 @@ */ package org.opendaylight.controller.yang.parser.util; -import java.lang.reflect.Method; import java.util.ArrayList; +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.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.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.BooleanTypeDefinition; @@ -27,6 +46,9 @@ import org.opendaylight.controller.yang.model.api.type.IdentityrefTypeDefinition import org.opendaylight.controller.yang.model.api.type.InstanceIdentifierTypeDefinition; import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition; import org.opendaylight.controller.yang.model.api.type.LeafrefTypeDefinition; +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.UnionTypeDefinition; import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefinition; @@ -36,6 +58,7 @@ import org.opendaylight.controller.yang.model.util.BooleanType; import org.opendaylight.controller.yang.model.util.Decimal64; import org.opendaylight.controller.yang.model.util.EmptyType; import org.opendaylight.controller.yang.model.util.EnumerationType; +import org.opendaylight.controller.yang.model.util.ExtendedType; import org.opendaylight.controller.yang.model.util.IdentityrefType; import org.opendaylight.controller.yang.model.util.InstanceIdentifier; import org.opendaylight.controller.yang.model.util.Int16; @@ -44,35 +67,68 @@ 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; import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder; +import org.opendaylight.controller.yang.parser.builder.api.GroupingMember; 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.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; public final class ParserUtils { private ParserUtils() { } + /** + * Create new SchemaPath from given path and name. + * + * Append new qname to schema path created from name argument. New QName + * gets namespace, revision and prefix same as last qname in current schema + * path. + * + * @param schemaPath + * @param name + * @return + */ + public static SchemaPath createSchemaPath(SchemaPath schemaPath, String name) { + List path = new ArrayList(schemaPath.getPath()); + QName last = path.get(path.size() - 1); + QName newQName = new QName(last.getNamespace(), last.getRevision(), last.getPrefix(), name); + path.add(newQName); + return new SchemaPath(path, schemaPath.isAbsolute()); + } + /** * Get module import referenced by given prefix. * @@ -82,8 +138,7 @@ public final class ParserUtils { * 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)) { @@ -94,6 +149,167 @@ 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. * @@ -112,8 +328,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); } @@ -121,161 +336,370 @@ public final class ParserUtils { return new SchemaPath(path, absolute); } + /** + * Check if node is present in refine nodes. + * + * @param nodeQName + * qname of node + * @param refineNodes + * collections of refined nodes + * @return true, if node with given qname was found, false otherwise + */ + public static SchemaNodeBuilder getRefined(QName nodeQName, List refineNodes) { + for (SchemaNodeBuilder rn : refineNodes) { + if (rn.getQName().equals(nodeQName)) { + return rn; + } + } + return null; + } + + /** + * 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.getDataChildByName(refineNodeName); + // search groupings + if (result == null) { + Set grps = grouping.getGroupingBuilders(); + for (GroupingBuilder gr : grps) { + if (gr.getQName().getLocalName().equals(refineNodeName)) { + result = gr; + break; + } + } + } + // search typedefs + if (result == null) { + Set typedefs = grouping.getTypeDefinitionBuilders(); + for (TypeDefinitionBuilder typedef : typedefs) { + if (typedef.getQName().getLocalName().equals(refineNodeName)) { + result = typedef; + break; + } + } + } + return result; + } + + /** + * Find node in grouping by name. + * + * @param builder + * grouping to search + * @param refineNodeName + * name of node + * @return node with given name if present in grouping, null otherwise + */ + public static Object findRefineTargetNode(final GroupingDefinition builder, final String refineNodeName) { + Object result = builder.getDataChildByName(refineNodeName); + if (result == null) { + Set grps = builder.getGroupings(); + for (GroupingDefinition gr : grps) { + if (gr.getQName().getLocalName().equals(refineNodeName)) { + result = gr; + break; + } + } + } + if (result == null) { + Set> typedefs = builder.getTypeDefinitions(); + for (TypeDefinition typedef : typedefs) { + if (typedef.getQName().getLocalName().equals(refineNodeName)) { + result = typedef; + break; + } + } + } + return result; + } + /** * Add all augment's child nodes to given target. * * @param augment + * builder of augment statement * @param target + * augmentation target node */ - public static void fillAugmentTarget( - final AugmentationSchemaBuilder augment, - final DataNodeContainerBuilder target) { - for (DataSchemaNodeBuilder builder : augment.getChildNodes()) { + public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) { + boolean usesAugment = augment.getParent() instanceof UsesNodeBuilder; + for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) { builder.setAugmenting(true); - correctAugmentChildPath(augment, target.getPath()); + if (usesAugment) { + if (builder instanceof GroupingMember) { + ((GroupingMember) builder).setAddedByUses(true); + } + } + correctAugmentChildPath(builder, target.getPath()); target.addChildNode(builder); } } - public static void fillAugmentTarget( - final AugmentationSchemaBuilder augment, - final ChoiceBuilder target) { - for (DataSchemaNodeBuilder builder : augment.getChildNodes()) { + /** + * 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) { + boolean usesAugment = augment.getParent() instanceof UsesNodeBuilder; + for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) { builder.setAugmenting(true); - correctAugmentChildPath(augment, target.getPath()); + if (usesAugment) { + if (builder instanceof GroupingMember) { + ((GroupingMember) builder).setAddedByUses(true); + } + } + correctAugmentChildPath(builder, target.getPath()); target.addChildNode(builder); } } - private static void correctAugmentChildPath(final DataNodeContainerBuilder node, - final SchemaPath parentSchemaPath) { - for (DataSchemaNodeBuilder builder : node.getChildNodes()) { + private static void correctAugmentChildPath(final DataSchemaNodeBuilder childNode, final SchemaPath parentSchemaPath) { + // set correct path + List targetNodePath = new ArrayList(parentSchemaPath.getPath()); + targetNodePath.add(childNode.getQName()); + childNode.setPath(new SchemaPath(targetNodePath, true)); - // add correct path - List targetNodePath = new ArrayList( - parentSchemaPath.getPath()); - targetNodePath.add(builder.getQName()); - builder.setPath(new SchemaPath(targetNodePath, true)); + // set correct path for all child nodes + if (childNode instanceof DataNodeContainerBuilder) { + DataNodeContainerBuilder dataNodeContainer = (DataNodeContainerBuilder) childNode; + for (DataSchemaNodeBuilder child : dataNodeContainer.getChildNodeBuilders()) { + correctAugmentChildPath(child, childNode.getPath()); + } + } - if (builder instanceof DataNodeContainerBuilder) { - DataNodeContainerBuilder cnb = (DataNodeContainerBuilder) builder; - correctAugmentChildPath(cnb, builder.getPath()); + // set correct path for all cases + if (childNode instanceof ChoiceBuilder) { + ChoiceBuilder choiceBuilder = (ChoiceBuilder) childNode; + for (ChoiceCaseBuilder choiceCaseBuilder : choiceBuilder.getCases()) { + correctAugmentChildPath(choiceCaseBuilder, childNode.getPath()); } + } - // if child can contains type, correct path for this type too - if (builder instanceof TypeAwareBuilder) { - TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) builder; - QName nodeBuilderQName = nodeBuilder.getQName(); - TypeDefinition nodeBuilderType = nodeBuilder.getType(); - if (nodeBuilderType != null) { - TypeDefinition newType = createCorrectTypeDefinition( - parentSchemaPath, nodeBuilderQName, nodeBuilderType); - nodeBuilder.setType(newType); - } else { - TypeDefinitionBuilder nodeBuilderTypedef = nodeBuilder - .getTypedef(); - SchemaPath newSchemaPath = createNewSchemaPath( - nodeBuilderTypedef.getPath(), nodeBuilderQName, - nodeBuilderTypedef.getQName()); - nodeBuilderTypedef.setPath(newSchemaPath); + // if node can contains type, correct path for this type too + if (childNode instanceof TypeAwareBuilder) { + TypeAwareBuilder nodeBuilder = (TypeAwareBuilder) childNode; + correctTypeAwareNodePath(nodeBuilder, parentSchemaPath); + } + } + + /** + * Repair schema path of node type. + * + * @param node + * node which contains type statement + * @param parentSchemaPath + * schema path of parent node + */ + private static void correctTypeAwareNodePath(final TypeAwareBuilder node, final SchemaPath parentSchemaPath) { + final QName nodeBuilderQName = node.getQName(); + final TypeDefinition nodeType = node.getType(); + + Integer fd = null; + List lengths = null; + List patterns = null; + List ranges = null; + + if (nodeType != null) { + if (nodeType instanceof ExtendedType) { + ExtendedType et = (ExtendedType) nodeType; + if (nodeType.getQName().getLocalName().equals(nodeType.getBaseType().getQName().getLocalName())) { + fd = et.getFractionDigits(); + lengths = et.getLengths(); + patterns = et.getPatterns(); + ranges = et.getRanges(); + if (!hasConstraints(fd, lengths, patterns, ranges)) { + return; + } } } + TypeDefinition newType = createCorrectTypeDefinition(parentSchemaPath, nodeBuilderQName, nodeType); + node.setType(newType); + } else { + TypeDefinitionBuilder nodeBuilderTypedef = node.getTypedef(); + + fd = nodeBuilderTypedef.getFractionDigits(); + lengths = nodeBuilderTypedef.getLengths(); + patterns = nodeBuilderTypedef.getPatterns(); + ranges = nodeBuilderTypedef.getRanges(); + + String tdbTypeName = nodeBuilderTypedef.getQName().getLocalName(); + String baseTypeName = null; + if (nodeBuilderTypedef.getType() == null) { + baseTypeName = nodeBuilderTypedef.getTypedef().getQName().getLocalName(); + } else { + baseTypeName = nodeBuilderTypedef.getType().getQName().getLocalName(); + } + if (!(tdbTypeName.equals(baseTypeName))) { + return; + } + + if (!hasConstraints(fd, lengths, patterns, ranges)) { + return; + } + + SchemaPath newSchemaPath = createNewSchemaPath(nodeBuilderTypedef.getPath(), nodeBuilderQName, + nodeBuilderTypedef.getQName()); + nodeBuilderTypedef.setPath(newSchemaPath); } } - private static TypeDefinition createCorrectTypeDefinition( - SchemaPath parentSchemaPath, QName nodeQName, + /** + * Check if there are some constraints. + * + * @param fd + * fraction digits + * @param lengths + * length constraints + * @param patterns + * pattern constraints + * @param ranges + * 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()) + && (ranges == null || ranges.isEmpty())) { + return false; + } else { + return true; + } + } + + private static TypeDefinition createCorrectTypeDefinition(SchemaPath parentSchemaPath, QName nodeQName, TypeDefinition nodeType) { TypeDefinition result = null; - SchemaPath newSchemaPath = null; + if (nodeType != null) { + QName nodeTypeQName = nodeType.getQName(); + SchemaPath newSchemaPath = createNewSchemaPath(parentSchemaPath, nodeQName, nodeTypeQName); + 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()); } 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; + result = createNewExtendedType(extType, newSchemaPath); } } return result; } - private static TypeDefinition createNewStringType(SchemaPath schemaPath, - QName nodeQName, StringTypeDefinition nodeType) { - List path = schemaPath.getPath(); - List newPath = new ArrayList(path); + /** + * 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 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); @@ -290,532 +714,577 @@ 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(); + /** + * 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(), leaf.getPath(), line); + convertDataSchemaNode(leaf, builder); + builder.setConfiguration(leaf.isConfiguration()); + 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; + } - 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 ContainerSchemaNodeBuilder createContainer(ContainerSchemaNode container, int line) { + final ContainerSchemaNodeBuilder builder = new ContainerSchemaNodeBuilder(line, container.getQName(), + container.getPath()); + convertDataSchemaNode(container, builder); + builder.setConfiguration(container.isConfiguration()); + 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 void refineContainer(ContainerSchemaNodeBuilder container, - RefineHolder refine, int line) { - Boolean presence = refine.isPresence(); - MustDefinition must = refine.getMust(); - List unknownNodes = refine.getUnknownNodes(); + public static ListSchemaNodeBuilder createList(ListSchemaNode list, int line) { + ListSchemaNodeBuilder builder = new ListSchemaNodeBuilder(line, list.getQName(), list.getPath()); + convertDataSchemaNode(list, builder); + builder.setConfiguration(list.isConfiguration()); + 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; + } - 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 LeafListSchemaNodeBuilder createLeafList(LeafListSchemaNode leafList, int line) { + final LeafListSchemaNodeBuilder builder = new LeafListSchemaNodeBuilder(line, leafList.getQName(), + leafList.getPath()); + convertDataSchemaNode(leafList, builder); + builder.setConfiguration(leafList.isConfiguration()); + builder.setType(leafList.getType()); + builder.setUnknownNodes(leafList.getUnknownSchemaNodes()); + builder.setUserOrdered(leafList.isUserOrdered()); + return builder; } - 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(); + public static ChoiceBuilder createChoice(ChoiceNode choice, int line) { + final ChoiceBuilder builder = new ChoiceBuilder(line, choice.getQName()); + convertDataSchemaNode(choice, builder); + builder.setConfiguration(choice.isConfiguration()); + builder.setCases(choice.getCases()); + builder.setUnknownNodes(choice.getUnknownSchemaNodes()); + builder.setDefaultCase(choice.getDefaultCase()); + return builder; + } - 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 AnyXmlBuilder createAnyXml(AnyXmlSchemaNode anyxml, int line) { + final AnyXmlBuilder builder = new AnyXmlBuilder(line, anyxml.getQName(), anyxml.getPath()); + convertDataSchemaNode(anyxml, builder); + builder.setConfiguration(anyxml.isConfiguration()); + builder.setUnknownNodes(anyxml.getUnknownSchemaNodes()); + return builder; } - 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(); + 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; + } - if (must != null) { - leafList.getConstraints().addMustDefinition(must); - } - if (min != null) { - leafList.getConstraints().setMinElements(min); - } - if (max != null) { - leafList.getConstraints().setMaxElements(max); + 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; + } + + public static UnknownSchemaNodeBuilder createUnknownSchemaNode(UnknownSchemaNode unknownNode, int line) { + final UnknownSchemaNodeBuilder builder = new UnknownSchemaNodeBuilder(line, unknownNode.getQName()); + builder.setPath(unknownNode.getPath()); + builder.setUnknownNodes(unknownNode.getUnknownSchemaNodes()); + builder.setDescription(unknownNode.getDescription()); + builder.setReference(unknownNode.getReference()); + builder.setStatus(unknownNode.getStatus()); + builder.setAddedByUses(unknownNode.isAddedByUses()); + builder.setNodeType(unknownNode.getNodeType()); + builder.setNodeParameter(unknownNode.getNodeParameter()); + 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()); + 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 (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - leafList.addUnknownSchemaNode(unknown); + 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 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); + 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 (mandatory != null) { - choice.getConstraints().setMandatory(mandatory); + if (node == null) { + return; } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - choice.addUnknownSchemaNode(unknown); + + 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 refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine, - int line) { - Boolean mandatory = refine.isMandatory(); - MustDefinition must = refine.getMust(); - List unknownNodes = refine.getUnknownNodes(); + public static void processAugmentation(final AugmentationSchemaBuilder augmentBuilder, final List path, + final ModuleBuilder module, final ModuleBuilder dependentModuleBuilder) { + DataSchemaNodeBuilder currentParent = null; + for (DataSchemaNodeBuilder child : dependentModuleBuilder.getChildNodeBuilders()) { + final QName childQName = child.getQName(); + if (childQName.getLocalName().equals(path.get(0).getLocalName())) { + currentParent = child; + break; + } + } - if (mandatory != null) { - anyXml.getConstraints().setMandatory(mandatory); + if (currentParent == null) { + return; } - 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() + "'."); + + for (int i = 1; i < path.size(); i++) { + final QName currentQName = path.get(i); + DataSchemaNodeBuilder newParent = null; + if (currentParent instanceof DataNodeContainerBuilder) { + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent).getChildNodeBuilders()) { + final QName childQName = child.getQName(); + if (childQName.getLocalName().equals(currentQName.getLocalName())) { + newParent = child; + break; + } + } + } else if (currentParent instanceof ChoiceBuilder) { + for (ChoiceCaseBuilder caseBuilder : ((ChoiceBuilder) currentParent).getCases()) { + final QName caseQName = caseBuilder.getQName(); + if (caseQName.getLocalName().equals(currentQName.getLocalName())) { + newParent = caseBuilder; + break; + } + } + } + + if (newParent == null) { + break; // node not found, quit search + } else { + currentParent = newParent; + } } - } - 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 + "'."); + 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(); } } /** - * Perform refine operation of following parameters: - *
    - *
  • description
  • - *
  • reference
  • - *
  • config
  • - *
+ * Create new type builder based on old type with new base type. * - * These parameters may be refined for any node. + * @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 node - * node to refine - * @param refine - * refine holder containing values to refine + * @param newBaseType + * new base type + * @param oldExtendedType + * old type + * @param modules + * all loaded modules + * @param module + * current module * @param line - * current line in yang model + * current line in module + * @return new type builder based on old type with new base type */ - public static void refineDefault(Builder node, RefineHolder refine, int line) { - Class cls = node.getClass(); + public static TypeDefinitionBuilder extendedTypeWithNewBaseType(final TypeDefinition newBaseType, + final ExtendedType oldExtendedType, final ModuleBuilder module, final int line) { + final TypeConstraints tc = new TypeConstraints(module.getName(), line); - 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); - } - } + 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; + } - 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); - } + /** + * 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; } + } - 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 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; } - } - public static LeafSchemaNodeBuilder copyLeafBuilder( - final LeafSchemaNodeBuilder old) { - final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder( - old.getQName(), old.getLine()); - final TypeDefinition type = old.getType(); + 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) { - copy.setTypedef(old.getTypedef()); - } else { - copy.setType(type); - } - copy.setPath(old.getPath()); - copyConstraints(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); - for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { - copy.addUnknownSchemaNode(unknown); - } - for (DataSchemaNodeBuilder child : old.getChildNodes()) { - copy.addChildNode(child); - } - for (GroupingBuilder grouping : old.getGroupings()) { - copy.addGrouping(grouping); - } - for (TypeDefinitionBuilder typedef : old.getTypeDefinitions()) { - copy.addTypedef(typedef); - } - for (AugmentationSchemaBuilder augment : old.getAugmentations()) { - copy.addAugmentation(augment); - } - 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); - for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { - copy.addUnknownSchemaNode(unknown); - } - for (DataSchemaNodeBuilder child : old.getChildNodes()) { - copy.addChildNode(child); - } - for (GroupingBuilder grouping : old.getGroupings()) { - copy.addGrouping(grouping); - } - for (TypeDefinitionBuilder typedef : old.getTypeDefinitions()) { - copy.addTypedef(typedef); - } - for (AugmentationSchemaBuilder augment : old.getAugmentations()) { - copy.addAugmentation(augment); - } - 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); - final TypeDefinition type = old.getType(); - if (type == null) { - copy.setTypedef(old.getTypedef()); - } else { - copy.setType(type); - } - 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); - for (ChoiceCaseBuilder caseBuilder : old.getCases()) { - copy.addChildNode(caseBuilder); - } - for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { - 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); - 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()); - copy.setPath(old.getPath()); - for (DataSchemaNodeBuilder child : old.getChildNodes()) { - copy.addChildNode(child); - } - for (GroupingBuilder grouping : old.getGroupings()) { - copy.addGrouping(grouping); - } - for (TypeDefinitionBuilder typedef : old.getTypeDefinitions()) { - copy.addTypedef(typedef); - } - for (UsesNodeBuilder use : old.getUses()) { - copy.addUsesNode(use); - } - for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { - copy.addUnknownSchemaNode(unknown); - } - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - return copy; - } - - public static TypeDefinitionBuilderImpl copyTypedefBuilder( - TypeDefinitionBuilderImpl old) { - final TypeDefinitionBuilderImpl copy = new TypeDefinitionBuilderImpl( - old.getQName(), old.getLine()); - copy.setPath(old.getPath()); - copy.setDefaultValue(old.getDefaultValue()); - copy.setUnits(old.getUnits()); - copy.setDescription(old.getDescription()); - copy.setReference(old.getReference()); - copy.setStatus(old.getStatus()); - - copy.setRanges(old.getRanges()); - copy.setLengths(old.getLengths()); - copy.setPatterns(old.getPatterns()); - copy.setFractionDigits(old.getFractionDigits()); - - TypeDefinition type = old.getType(); - if (type == null) { - copy.setTypedef(old.getTypedef()); + return findConstraintsFromTypeBuilder(nodeToResolve.getTypedef(), constraints, modules, builder, context); } else { - copy.setType(old.getType()); - } - copy.setUnits(old.getUnits()); - for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) { - copy.addUnknownSchemaNode(unknown); + 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, 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, 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; + } } - return copy; } - public static UsesNodeBuilder copyUsesNodeBuilder(UsesNodeBuilder old) { - final UsesNodeBuilder copy = new UsesNodeBuilderImpl( - old.getGroupingPathString(), old.getLine()); - for (AugmentationSchemaBuilder augment : old.getAugmentations()) { - copy.addAugment(augment); + /** + * 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 TypeAwareBuilder nodeToResolve, + final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) { + + TypeDefinitionBuilder result = null; + + Set typedefs = dependentModule.getTypeDefinitionBuilders(); + result = findTypedefBuilderByName(typedefs, typeName); + if (result != null) { + return result; } - copy.setAugmenting(old.isAugmenting()); - for (SchemaNodeBuilder refineNode : old.getRefineNodes()) { - copy.addRefineNode(refineNode); + + Builder parent = nodeToResolve.getParent(); + while (parent != null) { + if (parent instanceof DataNodeContainerBuilder) { + typedefs = ((DataNodeContainerBuilder) parent).getTypeDefinitionBuilders(); + } else if (parent instanceof RpcDefinitionBuilder) { + typedefs = ((RpcDefinitionBuilder) parent).getTypeDefinitions(); + } + result = findTypedefBuilderByName(typedefs, typeName); + if (result == null) { + parent = parent.getParent(); + } else { + break; + } } - return copy; - } - private static void copyConstraints(final DataSchemaNodeBuilder oldBuilder, - final DataSchemaNodeBuilder newBuilder) { - final ConstraintsBuilder oldConstraints = oldBuilder.getConstraints(); - final ConstraintsBuilder newConstraints = newBuilder.getConstraints(); - newConstraints.addWhenCondition(oldConstraints.getWhenCondition()); - for (MustDefinition must : oldConstraints.getMustDefinitions()) { - newConstraints.addMustDefinition(must); + if (result == null) { + throw new YangParseException(currentModuleName, line, "Referenced type '" + typeName + "' not found."); } - newConstraints.setMandatory(oldConstraints.isMandatory()); - newConstraints.setMinElements(oldConstraints.getMinElements()); - newConstraints.setMaxElements(oldConstraints.getMaxElements()); + return result; } }