X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fsal%2Fyang-prototype%2Fcode-generator%2Fyang-model-parser-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fyang%2Fparser%2Fimpl%2FYangParserImpl.java;h=ac2b5334fb3ec66e0cf8915fee70101f5da2e8bc;hb=7e82c13539bf01ba2c00989ced01a96cb7a0214e;hp=7c2aa6692b8df09ec97a9e70f92a65726613e1b4;hpb=551de69b62f95b31032e18f355770d8f3fc9423b;p=controller.git 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 7c2aa6692b..ac2b5334fb 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 @@ -12,7 +12,6 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.Date; @@ -34,13 +33,8 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.opendaylight.controller.antlrv4.code.gen.YangLexer; import org.opendaylight.controller.antlrv4.code.gen.YangParser; import org.opendaylight.controller.yang.common.QName; -import org.opendaylight.controller.yang.model.api.DataSchemaNode; -import org.opendaylight.controller.yang.model.api.ExtensionDefinition; 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.RpcDefinition; import org.opendaylight.controller.yang.model.api.SchemaContext; import org.opendaylight.controller.yang.model.api.SchemaPath; import org.opendaylight.controller.yang.model.api.TypeDefinition; @@ -58,9 +52,10 @@ 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.ChildNodeBuilder; +import org.opendaylight.controller.yang.parser.builder.api.DataNodeContainerBuilder; import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder; +import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.api.TypeAwareBuilder; import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder; import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder; @@ -73,11 +68,11 @@ import org.opendaylight.controller.yang.parser.builder.impl.LeafListSchemaNodeBu import org.opendaylight.controller.yang.parser.builder.impl.LeafSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ListSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder; -import org.opendaylight.controller.yang.parser.builder.impl.TypedefBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.RpcDefinitionBuilder; +import org.opendaylight.controller.yang.parser.builder.impl.TypeDefinitionBuilderImpl; import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder; import org.opendaylight.controller.yang.parser.builder.impl.UnknownSchemaNodeBuilder; import org.opendaylight.controller.yang.parser.util.ModuleDependencySort; -import org.opendaylight.controller.yang.parser.util.ModuleDependencySort.ModuleSimple; import org.opendaylight.controller.yang.parser.util.ParserUtils; import org.opendaylight.controller.yang.parser.util.RefineHolder; import org.opendaylight.controller.yang.parser.util.TypeConstraints; @@ -86,7 +81,7 @@ import org.opendaylight.controller.yang.validator.YangModelBasicValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class YangParserImpl implements YangModelParser { +public final class YangParserImpl implements YangModelParser { private static final Logger logger = LoggerFactory .getLogger(YangParserImpl.class); @@ -124,6 +119,8 @@ public class YangParserImpl implements YangModelParser { private Map> resolveModuleBuilders( final List yangFileStreams) { + // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER + // of items stored in map. final Map> modules = new LinkedHashMap>(); final ParseTreeWalker walker = new ParseTreeWalker(); final List trees = parseStreams(yangFileStreams); @@ -140,24 +137,9 @@ public class YangParserImpl implements YangModelParser { } // module dependency graph sorted - List sorted = new ModuleDependencySort(builders).sort(); - - // TODO FIX THIS ASAP! - // FIXME this is just temp workaround the ModuleDependencySort MUST - // RETURN ordered List - // of SORTED and DEPENDECNY RESOLVED MODULE BUILDERS!!!!!! - final List orderedBuilders = new ArrayList(); - for (final ModuleSimple ms : sorted) { - for (int i = 0; i < builders.length; ++i) { - if (ms.getName().equals(builders[i].getName()) - && ms.getRevision().equals(builders[i].getRevision())) { - orderedBuilders.add(builders[i]); - } - } - } - // FIXME END OF WORKAROUND + List sorted = ModuleDependencySort.sort(builders); - for (ModuleBuilder builder : orderedBuilders) { + for (ModuleBuilder builder : sorted) { final String builderName = builder.getName(); Date builderRevision = builder.getRevision(); if (builderRevision == null) { @@ -210,6 +192,9 @@ public class YangParserImpl implements YangModelParser { resolveAugments(modules); // build + // LinkedHashSet MUST be used otherwise the Set will not maintain + // order! + // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html final Set result = new LinkedHashSet(); for (Map.Entry> entry : modules .entrySet()) { @@ -230,7 +215,7 @@ public class YangParserImpl implements YangModelParser { final ModuleBuilder builder) { resolveDirtyNodes(modules, builder); resolveIdentities(modules, builder); - resolveUses(modules, builder); + resolveUsesRefines(modules, builder); resolveUnknownNodes(modules, builder); } @@ -263,12 +248,13 @@ public class YangParserImpl implements YangModelParser { final UnknownType unknownType = (UnknownType) td; final TypeDefinitionBuilder resolvedType = resolveTypeUnion( nodeToResolve, unknownType, modules, module); - union.setType(resolvedType); + union.setTypedef(resolvedType); toRemove.add(unknownType); } } unionTypes.removeAll(toRemove); } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { + // different handling for identityref types IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve .getTypedef(); nodeToResolve.setType(new IdentityrefType(findFullQName( @@ -276,28 +262,28 @@ public class YangParserImpl implements YangModelParser { } else { final TypeDefinitionBuilder resolvedType = resolveType( nodeToResolve, modules, module); - nodeToResolve.setType(resolvedType); + nodeToResolve.setTypedef(resolvedType); } } } } private TypeDefinitionBuilder resolveType( - final TypeAwareBuilder typeToResolve, + final TypeAwareBuilder nodeToResolve, final Map> modules, final ModuleBuilder builder) { final TypeConstraints constraints = new TypeConstraints(); - final TypeDefinitionBuilder targetType = getTypedefBuilder( - typeToResolve, modules, builder); - final TypeConstraints tConstraints = findConstraints(typeToResolve, + final TypeDefinitionBuilder targetTypeBuilder = getTypeDefinitionBuilderFromDirtyNode( + nodeToResolve, modules, builder); + final TypeConstraints tConstraints = findConstraints(nodeToResolve, constraints, modules, builder); - targetType.setRanges(tConstraints.getRange()); - targetType.setLengths(tConstraints.getLength()); - targetType.setPatterns(tConstraints.getPatterns()); - targetType.setFractionDigits(tConstraints.getFractionDigits()); + targetTypeBuilder.setRanges(tConstraints.getRange()); + targetTypeBuilder.setLengths(tConstraints.getLength()); + targetTypeBuilder.setPatterns(tConstraints.getPatterns()); + targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits()); - return targetType; + return targetTypeBuilder; } private TypeDefinitionBuilder resolveTypeUnion( @@ -307,38 +293,34 @@ public class YangParserImpl implements YangModelParser { final ModuleBuilder builder) { final TypeConstraints constraints = new TypeConstraints(); - final TypeDefinitionBuilder targetType = getUnionBuilder(typeToResolve, - unknownType, modules, builder); + final TypeDefinitionBuilder targetTypeBuilder = getUnionBuilder( + typeToResolve, unknownType, modules, builder); final TypeConstraints tConstraints = findConstraints(typeToResolve, constraints, modules, builder); - targetType.setRanges(tConstraints.getRange()); - targetType.setLengths(tConstraints.getLength()); - targetType.setPatterns(tConstraints.getPatterns()); - targetType.setFractionDigits(tConstraints.getFractionDigits()); + targetTypeBuilder.setRanges(tConstraints.getRange()); + targetTypeBuilder.setLengths(tConstraints.getLength()); + targetTypeBuilder.setPatterns(tConstraints.getPatterns()); + targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits()); - return targetType; + return targetTypeBuilder; } - private TypeDefinitionBuilder getTypedefBuilder( + private TypeDefinitionBuilder getTypeDefinitionBuilderFromDirtyNode( final TypeAwareBuilder nodeToResolve, final Map> modules, - final ModuleBuilder builder) { - - final TypeDefinition nodeToResolveBase = nodeToResolve.getType(); - if (nodeToResolveBase != null - && !(nodeToResolveBase instanceof UnknownType)) { - return (TypeDefinitionBuilder) nodeToResolve; - } + final ModuleBuilder module) { final UnknownType unknownType = (UnknownType) nodeToResolve.getType(); final QName unknownTypeQName = unknownType.getQName(); // search for module which contains referenced typedef final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknownTypeQName.getPrefix(), nodeToResolve.getLine()); - final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName( - dependentModule, unknownTypeQName.getLocalName(), - builder.getName(), nodeToResolve.getLine()); + 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); @@ -363,9 +345,10 @@ public class YangParserImpl implements YangModelParser { // search for module which contains referenced typedef final ModuleBuilder dependentModule = findDependentModule(modules, module, unknownTypeQName.getPrefix(), nodeToResolve.getLine()); - final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName( - dependentModule, unknownTypeQName.getLocalName(), - module.getName(), nodeToResolve.getLine()); + final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder( + nodeToResolve.getPath(), dependentModule, + unknownTypeQName.getLocalName(), module.getName(), + nodeToResolve.getLine()); final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder( lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder); @@ -379,14 +362,14 @@ public class YangParserImpl implements YangModelParser { if (old instanceof UnionTypeBuilder) { final UnionTypeBuilder oldUnion = (UnionTypeBuilder) old; final UnionTypeBuilder newUnion = new UnionTypeBuilder( - oldUnion.getActualPath(), oldUnion.getNamespace(), - oldUnion.getRevision(), old.getLine()); + old.getLine()); for (TypeDefinition td : oldUnion.getTypes()) { newUnion.setType(td); } for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) { - newUnion.setType(copyTypedefBuilder(tdb, true)); + newUnion.setTypedef(copyTypedefBuilder(tdb, true)); } + newUnion.setPath(old.getPath()); return newUnion; } @@ -394,8 +377,8 @@ public class YangParserImpl implements YangModelParser { final QName newName = new QName(oldName.getNamespace(), oldName.getRevision(), oldName.getPrefix(), oldName.getLocalName()); - final TypeDefinitionBuilder tdb = new TypedefBuilder(newName, - old.getLine()); + final TypeDefinitionBuilder tdb = new TypeDefinitionBuilderImpl( + newName, old.getLine()); tdb.setRanges(old.getRanges()); tdb.setLengths(old.getLengths()); @@ -405,7 +388,7 @@ public class YangParserImpl implements YangModelParser { final TypeDefinition oldType = old.getType(); if (oldType == null) { - tdb.setType(old.getTypedef()); + tdb.setTypedef(old.getTypedef()); } else { tdb.setType(oldType); } @@ -434,7 +417,7 @@ public class YangParserImpl implements YangModelParser { final UnknownType unknownType = (UnknownType) td; final TypeDefinitionBuilder resolvedType = resolveTypeUnion( union, unknownType, modules, builder); - union.setType(resolvedType); + union.setTypedef(resolvedType); toRemove.add(unknownType); } } @@ -453,9 +436,9 @@ public class YangParserImpl implements YangModelParser { final String unknownTypePrefix = unknownTypeQName.getPrefix(); final ModuleBuilder dependentModule = findDependentModule(modules, builder, unknownTypePrefix, copy.getLine()); - final TypeDefinitionBuilder utBuilder = getTypedefBuilder(copy, - modules, dependentModule); - copy.setType(utBuilder); + 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 @@ -463,27 +446,14 @@ public class YangParserImpl implements YangModelParser { baseTdb, true); final TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder( baseTdbCopy, modules, builder); - copy.setType(baseTdbCopyResolved); + copy.setTypedef(baseTdbCopyResolved); return copy; } else { - throw new IllegalStateException("Failed to resolve type " - + copy.getQName().getLocalName()); + throw new YangParseException(copy.getLine(), + "Failed to resolve type " + copy.getQName().getLocalName()); } } - private TypeDefinitionBuilder findTypedefBuilder( - final QName unknownTypeQName, - final Map> modules, - final ModuleBuilder builder, int line) { - // search for module which contains referenced typedef - final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknownTypeQName.getPrefix(), line); - final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName( - dependentModule, unknownTypeQName.getLocalName(), - builder.getName(), line); - return copyTypedefBuilder(lookedUpBuilder, true); - } - private TypeConstraints findConstraints( final TypeAwareBuilder nodeToResolve, final TypeConstraints constraints, @@ -523,7 +493,8 @@ public class YangParserImpl implements YangModelParser { fractionDigits = ext.getFractionDigits(); constraints.setFractionDigits(fractionDigits); return findConstraints( - findTypedefBuilder(ext.getQName(), modules, builder, + findTypeDefinitionBuilder(nodeToResolve.getPath(), builder, + ext.getQName().getLocalName(), builder.getName(), nodeToResolve.getLine()), constraints, modules, builder); } else if (referencedType instanceof UnknownType) { @@ -544,8 +515,9 @@ public class YangParserImpl implements YangModelParser { final ModuleBuilder dependentModule = findDependentModule(modules, builder, unknown.getQName().getPrefix(), nodeToResolve.getLine()); - final TypeDefinitionBuilder utBuilder = findTypedefBuilder( - unknown.getQName(), modules, builder, + final TypeDefinitionBuilder utBuilder = findTypeDefinitionBuilder( + nodeToResolve.getPath(), dependentModule, unknown + .getQName().getLocalName(), builder.getName(), nodeToResolve.getLine()); return findConstraints(utBuilder, constraints, modules, dependentModule); @@ -557,33 +529,73 @@ public class YangParserImpl implements YangModelParser { } /** - * Go through all typedef statements from given module and search for one - * with given name + * Search for type definition builder by name. * - * @param typedefs - * typedef statements to search - * @param name - * name of searched typedef - * @return typedef with name equals to given 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 */ - private TypeDefinitionBuilder findTypedefBuilderByName( - final ModuleBuilder dependentModule, final String name, + private TypeDefinitionBuilder findTypeDefinitionBuilder( + SchemaPath dirtyNodeSchemaPath, + final ModuleBuilder dependentModule, final String typeName, final String currentModuleName, final int line) { + final List path = dirtyNodeSchemaPath.getPath(); TypeDefinitionBuilder result = null; - final Set typedefs = dependentModule + + Set typedefs = dependentModule .getModuleTypedefs(); - for (TypeDefinitionBuilder td : typedefs) { - if (td.getQName().getLocalName().equals(name)) { - result = td; - break; + result = findTdb(typedefs, typeName); + + if (result == null) { + Builder currentNode = null; + final List currentPath = new ArrayList(); + currentPath.add(dependentModule.getName()); + + for (int i = 0; i < path.size(); i++) { + QName qname = path.get(i); + currentPath.add(qname.getLocalName()); + currentNode = dependentModule.getModuleNode(currentPath); + + if (currentNode instanceof RpcDefinitionBuilder) { + typedefs = ((RpcDefinitionBuilder) currentNode) + .getTypeDefinitions(); + } else if (currentNode instanceof DataNodeContainerBuilder) { + typedefs = ((DataNodeContainerBuilder) currentNode) + .getTypeDefinitions(); + } else { + typedefs = Collections.emptySet(); + } + + result = findTdb(typedefs, typeName); + if (result != null) { + break; + } } } - if (result == null) { - throw new YangParseException(currentModuleName, line, - "Target module '" + dependentModule.getName() - + "' does not contain typedef '" + name + "'."); + + if (result != null) { + return result; } - return result; + throw new YangParseException(currentModuleName, line, + "Referenced type '" + typeName + "' not found."); + } + + private TypeDefinitionBuilder findTdb(Set types, + String name) { + for (TypeDefinitionBuilder td : types) { + if (td.getQName().getLocalName().equals(name)) { + return td; + } + } + return null; } /** @@ -616,8 +628,8 @@ public class YangParserImpl implements YangModelParser { } /** - * Go through all augmentation definitions and resolve them. This method - * also finds referenced node and add child nodes to it. + * Go through all augment definitions and resolve them. This method also + * finds augment target node and add child nodes to it. * * @param modules * all available modules @@ -642,7 +654,7 @@ public class YangParserImpl implements YangModelParser { // while all augments are not resolved final Iterator allModulesIterator = allModulesSet .iterator(); - while (!(module.getAugmentsResolved() == module.getAddedAugments() + while (!(module.getAugmentsResolved() == module.getAugments() .size())) { ModuleBuilder nextModule = null; // try resolve other module augments @@ -670,17 +682,16 @@ public class YangParserImpl implements YangModelParser { private void resolveAugment( final Map> modules, final ModuleBuilder module) { - if (module.getAugmentsResolved() < module.getAddedAugments().size()) { + if (module.getAugmentsResolved() < module.getAugments().size()) { for (AugmentationSchemaBuilder augmentBuilder : module - .getAddedAugments()) { + .getAugments()) { if (!augmentBuilder.isResolved()) { final SchemaPath augmentTargetSchemaPath = augmentBuilder .getTargetPath(); final List path = augmentTargetSchemaPath.getPath(); - int i = 0; - final QName qname = path.get(i); + final QName qname = path.get(0); String prefix = qname.getPrefix(); if (prefix == null) { prefix = module.getPrefix(); @@ -695,15 +706,18 @@ public class YangParserImpl implements YangModelParser { if (childQName.getLocalName().equals( qname.getLocalName())) { currentParent = child; - i++; break; } } - for (; i < path.size(); i++) { + if (currentParent == null) { + continue; + } + + for (int i = 1; i < path.size(); i++) { final QName currentQName = path.get(i); DataSchemaNodeBuilder newParent = null; - for (DataSchemaNodeBuilder child : ((ChildNodeBuilder) currentParent) + for (DataSchemaNodeBuilder child : ((DataNodeContainerBuilder) currentParent) .getChildNodes()) { final QName childQName = child.getQName(); if (childQName.getLocalName().equals( @@ -724,8 +738,14 @@ public class YangParserImpl implements YangModelParser { .get(path.size() - 1); if (currentQName.getLocalName().equals( lastAugmentPathElement.getLocalName())) { - ParserUtils.fillAugmentTarget(augmentBuilder, - (ChildNodeBuilder) currentParent); + + if(currentParent instanceof ChoiceBuilder) { + ParserUtils.fillAugmentTarget(augmentBuilder, + (ChoiceBuilder) currentParent); + } else { + ParserUtils.fillAugmentTarget(augmentBuilder, + (DataNodeContainerBuilder) currentParent); + } ((AugmentationTargetBuilder) currentParent) .addAugmentation(augmentBuilder); SchemaPath oldPath = currentParent.getPath(); @@ -753,7 +773,7 @@ public class YangParserImpl implements YangModelParser { final Map> modules, final ModuleBuilder module) { final Set identities = module - .getAddedIdentities(); + .getIdentities(); for (IdentitySchemaNodeBuilder identity : identities) { final String baseIdentityName = identity.getBaseIdentityName(); if (baseIdentityName != null) { @@ -771,7 +791,7 @@ public class YangParserImpl implements YangModelParser { modules, module, baseIdentityPrefix, identity.getLine()); final Set dependentModuleIdentities = dependentModule - .getAddedIdentities(); + .getIdentities(); for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) { if (idBuilder.getQName().getLocalName() .equals(baseIdentityLocalName)) { @@ -791,128 +811,64 @@ public class YangParserImpl implements YangModelParser { * @param module * module being resolved */ - private void resolveUses( + private void resolveUsesRefines( final Map> modules, final ModuleBuilder module) { final Map, UsesNodeBuilder> moduleUses = module - .getAddedUsesNodes(); + .getUsesNodes(); for (Map.Entry, UsesNodeBuilder> entry : moduleUses .entrySet()) { final List key = entry.getKey(); final UsesNodeBuilder usesNode = entry.getValue(); + final int line = usesNode.getLine(); final String groupingName = key.get(key.size() - 1); for (RefineHolder refine : usesNode.getRefines()) { - // refine statements - final String defaultStr = refine.getDefaultStr(); - final Boolean mandatory = refine.isMandatory(); - final MustDefinition must = refine.getMust(); - final Boolean presence = refine.isPresence(); - final Integer min = refine.getMinElements(); - final Integer max = refine.getMaxElements(); - final List unknownNodes = refine - .getUnknownNodes(); - - Builder refineTarget = getRefineTargetBuilder(groupingName, - refine, modules, module); + SchemaNodeBuilder refineTarget = getRefineNodeBuilderCopy( + groupingName, refine, modules, module); + ParserUtils.checkRefine(refineTarget, refine); + ParserUtils.refineDefault(refineTarget, refine, line); if (refineTarget instanceof LeafSchemaNodeBuilder) { final LeafSchemaNodeBuilder leaf = (LeafSchemaNodeBuilder) refineTarget; - 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); - } - } + ParserUtils.refineLeaf(leaf, refine, line); usesNode.addRefineNode(leaf); } else if (refineTarget instanceof ContainerSchemaNodeBuilder) { final ContainerSchemaNodeBuilder container = (ContainerSchemaNodeBuilder) refineTarget; - if (presence != null) { - container.setPresence(presence); - } - if (must != null) { - container.getConstraints().addMustDefinition(must); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - container.addUnknownSchemaNode(unknown); - } - } + ParserUtils.refineContainer(container, refine, line); usesNode.addRefineNode(container); } else if (refineTarget instanceof ListSchemaNodeBuilder) { final ListSchemaNodeBuilder list = (ListSchemaNodeBuilder) refineTarget; - 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); - } - } + ParserUtils.refineList(list, refine, line); + usesNode.addRefineNode(list); } else if (refineTarget instanceof LeafListSchemaNodeBuilder) { - final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) getRefineTargetBuilder( - groupingName, refine, modules, module); - if (must != null) { - leafList.getConstraints().addMustDefinition(must); - } - if (min != null) { - leafList.getConstraints().setMinElements(min); - } - if (max != null) { - leafList.getConstraints().setMaxElements(max); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - leafList.addUnknownSchemaNode(unknown); - } - } + final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) refineTarget; + ParserUtils.refineLeafList(leafList, refine, line); + usesNode.addRefineNode(leafList); } else if (refineTarget instanceof ChoiceBuilder) { final ChoiceBuilder choice = (ChoiceBuilder) refineTarget; - if (defaultStr != null) { - choice.setDefaultCase(defaultStr); - } - if (mandatory != null) { - choice.getConstraints().setMandatory(mandatory); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - choice.addUnknownSchemaNode(unknown); - } - } + ParserUtils.refineChoice(choice, refine, line); + usesNode.addRefineNode(choice); } else if (refineTarget instanceof AnyXmlBuilder) { final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget; - if (mandatory != null) { - anyXml.getConstraints().setMandatory(mandatory); - } - if (must != null) { - anyXml.getConstraints().addMustDefinition(must); - } - if (unknownNodes != null) { - for (UnknownSchemaNodeBuilder unknown : unknownNodes) { - anyXml.addUnknownSchemaNode(unknown); - } - } + ParserUtils.refineAnyxml(anyXml, refine, line); + usesNode.addRefineNode(anyXml); + } else if (refineTarget instanceof GroupingBuilder) { + usesNode.addRefineNode(refineTarget); + } else if (refineTarget instanceof TypeDefinitionBuilder) { + usesNode.addRefineNode(refineTarget); } } } } /** - * Find original builder of refine node and return copy of this builder. + * Find original builder of node to refine and return copy of this builder. + *

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

* * @param groupingPath * path to grouping which contains node to refine @@ -922,11 +878,11 @@ public class YangParserImpl implements YangModelParser { * all loaded modules * @param module * current module - * @return copy of Builder object of node to be refined if it is present in - * grouping, null otherwise + * @return copy of node to be refined if it is present in grouping, null + * otherwise */ - private Builder getRefineTargetBuilder(final String groupingPath, - final RefineHolder refine, + private SchemaNodeBuilder getRefineNodeBuilderCopy( + final String groupingPath, final RefineHolder refine, final Map> modules, final ModuleBuilder module) { Builder result = null; @@ -950,11 +906,17 @@ public class YangParserImpl implements YangModelParser { } else if (lookedUpBuilder instanceof AnyXmlBuilder) { result = ParserUtils .copyAnyXmlBuilder((AnyXmlBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof GroupingBuilder) { + result = ParserUtils + .copyGroupingBuilder((GroupingBuilder) lookedUpBuilder); + } else if (lookedUpBuilder instanceof TypeDefinitionBuilder) { + result = ParserUtils + .copyTypedefBuilder((TypeDefinitionBuilderImpl) lookedUpBuilder); } else { throw new YangParseException(module.getName(), refine.getLine(), "Target '" + refine.getName() + "' can not be refined"); } - return result; + return (SchemaNodeBuilder) result; } /** @@ -962,8 +924,8 @@ public class YangParserImpl implements YangModelParser { * * @param groupingPath * path to grouping which contains node to refine - * @param refineNodeName - * name of node to be refined + * @param refine + * object containing refine information * @param modules * all loaded modules * @param module @@ -975,6 +937,7 @@ public class YangParserImpl implements YangModelParser { final RefineHolder refine, final Map> modules, final ModuleBuilder module) { + final String refineNodeName = refine.getName(); final SchemaPath path = ParserUtils.parseUsesPath(groupingPath); final List builderPath = new ArrayList(); String prefix = null; @@ -988,12 +951,30 @@ public class YangParserImpl implements YangModelParser { final ModuleBuilder dependentModule = findDependentModule(modules, module, prefix, refine.getLine()); - builderPath.add(0, "grouping"); builderPath.add(0, dependentModule.getName()); - final GroupingBuilder builder = (GroupingBuilder) dependentModule - .getNode(builderPath); + final GroupingBuilder builder = dependentModule + .getGrouping(builderPath); - return builder.getChildNode(refine.getName()); + Builder result = builder.getChildNode(refineNodeName); + if (result == null) { + Set grps = builder.getGroupings(); + for (GroupingBuilder gr : grps) { + if (gr.getQName().getLocalName().equals(refineNodeName)) { + result = gr; + break; + } + } + } + if (result == null) { + Set typedefs = builder.getTypeDefinitions(); + for (TypeDefinitionBuilder typedef : typedefs) { + if (typedef.getQName().getLocalName().equals(refineNodeName)) { + result = typedef; + break; + } + } + } + return result; } private QName findFullQName( @@ -1023,7 +1004,7 @@ public class YangParserImpl implements YangModelParser { private void resolveUnknownNodes( final Map> modules, final ModuleBuilder module) { - for (UnknownSchemaNodeBuilder usnb : module.getAddedUnknownNodes()) { + for (UnknownSchemaNodeBuilder usnb : module.getUnknownNodes()) { QName nodeType = usnb.getNodeType(); if (nodeType.getNamespace() == null || nodeType.getRevision() == null) { @@ -1053,6 +1034,8 @@ public class YangParserImpl implements YangModelParser { * current module * @param prefix * target module prefix + * @param line + * current line in yang model * @return */ private ModuleBuilder findDependentModule( @@ -1099,82 +1082,4 @@ public class YangParserImpl implements YangModelParser { return dependentModule; } - private static class SchemaContextImpl implements SchemaContext { - private final Set modules; - - private SchemaContextImpl(final Set modules) { - this.modules = modules; - } - - @Override - public Set getDataDefinitions() { - final Set dataDefs = new HashSet(); - for (Module m : modules) { - dataDefs.addAll(m.getChildNodes()); - } - return dataDefs; - } - - @Override - public Set getModules() { - return modules; - } - - @Override - public Set getNotifications() { - final Set notifications = new HashSet(); - for (Module m : modules) { - notifications.addAll(m.getNotifications()); - } - return notifications; - } - - @Override - public Set getOperations() { - final Set rpcs = new HashSet(); - for (Module m : modules) { - rpcs.addAll(m.getRpcs()); - } - return rpcs; - } - - @Override - public Set getExtensions() { - final Set extensions = new HashSet(); - for (Module m : modules) { - extensions.addAll(m.getExtensionSchemaNodes()); - } - return extensions; - } - - @Override - public Module findModuleByName(final String name, final Date revision) { - if (name != null) { - for (final Module module : modules) { - if (revision == null) { - if (module.getName().equals(name)) { - return module; - } - } else if (module.getName().equals(name) - && module.getRevision().equals(revision)) { - return module; - } - } - } - return null; - } - - @Override - public Module findModuleByNamespace(final URI namespace) { - if (namespace != null) { - for (final Module module : modules) { - if (module.getNamespace().equals(namespace)) { - return module; - } - } - } - return null; - } - } - }