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=94437170f4be3c8ef91ae774debd26cb1d4f8963;hb=ff1b4a79cca00743a00c3b0b1100bd0ab2b2fb31;hp=7c2aa6692b8df09ec97a9e70f92a65726613e1b4;hpb=e877f7f9e4ed90d2a199aad8f28e46daa4686d4c;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..94437170f4 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; @@ -20,9 +19,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Set; import java.util.TreeMap; @@ -34,22 +33,14 @@ 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; import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition; import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition; import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition; -import org.opendaylight.controller.yang.model.api.type.LengthConstraint; -import org.opendaylight.controller.yang.model.api.type.PatternConstraint; -import org.opendaylight.controller.yang.model.api.type.RangeConstraint; import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition; import org.opendaylight.controller.yang.model.parser.api.YangModelParser; import org.opendaylight.controller.yang.model.util.ExtendedType; @@ -58,9 +49,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 +65,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,35 +78,80 @@ import org.opendaylight.controller.yang.validator.YangModelBasicValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class YangParserImpl implements YangModelParser { +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +public final class YangParserImpl implements YangModelParser { private static final Logger logger = LoggerFactory .getLogger(YangParserImpl.class); @Override - public Set parseYangModels(final List yangFiles) { + public Map parseYangModelsMapped(List yangFiles) { if (yangFiles != null) { - final List inputStreams = new ArrayList(); + final Map inputStreams = Maps.newHashMap(); for (final File yangFile : yangFiles) { try { - inputStreams.add(new FileInputStream(yangFile)); + inputStreams.put(new FileInputStream(yangFile), yangFile); } catch (FileNotFoundException e) { logger.warn("Exception while reading yang file: " + yangFile.getName(), e); } } - final Map> modules = resolveModuleBuilders(inputStreams); - return build(modules); + + Map builderToStreamMap = Maps + .newHashMap(); + + final Map> modules = resolveModuleBuilders( + Lists.newArrayList(inputStreams.keySet()), + builderToStreamMap); + // return new LinkedHashSet(build(modules).values()); + + Map retVal = Maps.newLinkedHashMap(); + Map builderToModuleMap = build(modules); + + for (Entry builderToModule : builderToModuleMap + .entrySet()) { + retVal.put(inputStreams.get(builderToStreamMap + .get(builderToModule.getKey())), builderToModule + .getValue()); + } + + return retVal; } - return Collections.emptySet(); + return Collections.emptyMap(); + } + + @Override + public Set parseYangModels(final List yangFiles) { + return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values()); } @Override public Set parseYangModelsFromStreams( final List yangModelStreams) { - final Map> modules = resolveModuleBuilders(yangModelStreams); - return build(modules); + return Sets.newHashSet(parseYangModelsFromStreamsMapped( + yangModelStreams).values()); + } + + @Override + public Map parseYangModelsFromStreamsMapped( + final List yangModelStreams) { + Map builderToStreamMap = Maps.newHashMap(); + + final Map> modules = resolveModuleBuilders( + yangModelStreams, builderToStreamMap); + Map retVal = Maps.newLinkedHashMap(); + Map builderToModuleMap = build(modules); + + for (Entry builderToModule : builderToModuleMap + .entrySet()) { + retVal.put(builderToStreamMap.get(builderToModule.getKey()), + builderToModule.getValue()); + } + return retVal; } @Override @@ -122,11 +159,11 @@ public class YangParserImpl implements YangModelParser { return new SchemaContextImpl(modules); } - private Map> resolveModuleBuilders( - final List yangFileStreams) { - final Map> modules = new LinkedHashMap>(); + private ModuleBuilder[] parseModuleBuilders(List inputStreams, + Map streamToBuilderMap) { + final ParseTreeWalker walker = new ParseTreeWalker(); - final List trees = parseStreams(yangFileStreams); + final List trees = parseStreams(inputStreams); final ModuleBuilder[] builders = new ModuleBuilder[trees.size()]; // validate yang @@ -136,28 +173,30 @@ public class YangParserImpl implements YangModelParser { for (int i = 0; i < trees.size(); i++) { yangModelParser = new YangParserListenerImpl(); walker.walk(yangModelParser, trees.get(i)); - builders[i] = yangModelParser.getModuleBuilder(); + ModuleBuilder moduleBuilder = yangModelParser.getModuleBuilder(); + + // We expect the order of trees and streams has to be the same + streamToBuilderMap.put(moduleBuilder, inputStreams.get(i)); + builders[i] = moduleBuilder; } + return builders; + } + + private Map> resolveModuleBuilders( + final List yangFileStreams, + Map streamToBuilderMap) { + + final ModuleBuilder[] builders = parseModuleBuilders(yangFileStreams, + streamToBuilderMap); + + // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER + // of items stored in map. + final LinkedHashMap> modules = new LinkedHashMap>(); // 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) { @@ -189,6 +228,7 @@ public class YangParserImpl implements YangModelParser { final YangLexer lexer = new YangLexer(input); final CommonTokenStream tokens = new CommonTokenStream(lexer); final YangParser parser = new YangParser(tokens); + result = parser.yang(); } catch (IOException e) { logger.warn("Exception while reading yang file: " + yangStream, e); @@ -196,7 +236,7 @@ public class YangParserImpl implements YangModelParser { return result; } - private Set build( + private Map build( final Map> modules) { // fix unresolved nodes for (Map.Entry> entry : modules @@ -210,7 +250,10 @@ public class YangParserImpl implements YangModelParser { resolveAugments(modules); // build - final Set result = new LinkedHashSet(); + // LinkedHashMap MUST be used otherwise the values will not maintain + // order! + // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html + final Map result = new LinkedHashMap(); for (Map.Entry> entry : modules .entrySet()) { final Map modulesByRevision = new HashMap(); @@ -219,7 +262,7 @@ public class YangParserImpl implements YangModelParser { final ModuleBuilder moduleBuilder = childEntry.getValue(); final Module module = moduleBuilder.build(); modulesByRevision.put(childEntry.getKey(), module); - result.add(module); + result.put(moduleBuilder, module); } } return result; @@ -230,7 +273,7 @@ public class YangParserImpl implements YangModelParser { final ModuleBuilder builder) { resolveDirtyNodes(modules, builder); resolveIdentities(modules, builder); - resolveUses(modules, builder); + resolveUsesRefines(modules, builder); resolveUnknownNodes(modules, builder); } @@ -251,237 +294,116 @@ public class YangParserImpl implements YangModelParser { if (!dirtyNodes.isEmpty()) { for (Map.Entry, TypeAwareBuilder> entry : dirtyNodes .entrySet()) { - final TypeAwareBuilder nodeToResolve = entry.getValue(); - // different handling for union types + if (nodeToResolve instanceof UnionTypeBuilder) { - final UnionTypeBuilder union = (UnionTypeBuilder) nodeToResolve; - final List> unionTypes = union.getTypes(); - final List toRemove = new ArrayList(); - for (TypeDefinition td : unionTypes) { - if (td instanceof UnknownType) { - final UnknownType unknownType = (UnknownType) td; - final TypeDefinitionBuilder resolvedType = resolveTypeUnion( - nodeToResolve, unknownType, modules, module); - union.setType(resolvedType); - toRemove.add(unknownType); - } - } - unionTypes.removeAll(toRemove); + // special handling for union types + resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules, + module); } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) { + // special handling for identityref types IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve .getTypedef(); nodeToResolve.setType(new IdentityrefType(findFullQName( modules, module, idref), idref.getPath())); } else { - final TypeDefinitionBuilder resolvedType = resolveType( - nodeToResolve, modules, module); - nodeToResolve.setType(resolvedType); + resolveType(nodeToResolve, modules, module); } } } } - private TypeDefinitionBuilder resolveType( - final TypeAwareBuilder typeToResolve, - final Map> modules, - final ModuleBuilder builder) { - final TypeConstraints constraints = new TypeConstraints(); - - final TypeDefinitionBuilder targetType = getTypedefBuilder( - typeToResolve, 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()); - - return targetType; - } - - private TypeDefinitionBuilder resolveTypeUnion( - final TypeAwareBuilder typeToResolve, - final UnknownType unknownType, + private void resolveType(final TypeAwareBuilder nodeToResolve, final Map> modules, final ModuleBuilder builder) { - final TypeConstraints constraints = new TypeConstraints(); - - final TypeDefinitionBuilder targetType = 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()); - - return targetType; - } - - private TypeDefinitionBuilder getTypedefBuilder( - final TypeAwareBuilder nodeToResolve, - final Map> modules, - final ModuleBuilder builder) { - - final TypeDefinition nodeToResolveBase = nodeToResolve.getType(); - if (nodeToResolveBase != null - && !(nodeToResolveBase instanceof UnknownType)) { - return (TypeDefinitionBuilder) nodeToResolve; - } - - final UnknownType unknownType = (UnknownType) nodeToResolve.getType(); - final QName unknownTypeQName = unknownType.getQName(); - - // search for module which contains referenced typedef + TypeDefinitionBuilder resolvedType = null; + final int line = nodeToResolve.getLine(); + final TypeDefinition typedefType = nodeToResolve.getType(); + final QName unknownTypeQName = typedefType.getBaseType().getQName(); final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknownTypeQName.getPrefix(), nodeToResolve.getLine()); - final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName( - dependentModule, unknownTypeQName.getLocalName(), - builder.getName(), nodeToResolve.getLine()); - - final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder( - lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder); - final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder( - lookedUpBuilderCopy, modules, dependentModule); - return resolvedCopy; - } - - private TypeDefinitionBuilder getUnionBuilder( - final TypeAwareBuilder nodeToResolve, - final UnknownType unknownType, - final Map> modules, - final ModuleBuilder module) { - - final TypeDefinition baseTypeToResolve = nodeToResolve.getType(); - if (baseTypeToResolve != null - && !(baseTypeToResolve instanceof UnknownType)) { - return (TypeDefinitionBuilder) nodeToResolve; - } - - final QName unknownTypeQName = unknownType.getQName(); - // search for module which contains referenced typedef - final ModuleBuilder dependentModule = findDependentModule(modules, - module, unknownTypeQName.getPrefix(), nodeToResolve.getLine()); - final TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilderByName( - dependentModule, unknownTypeQName.getLocalName(), - module.getName(), nodeToResolve.getLine()); - - final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder( - lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder); - final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder( - lookedUpBuilderCopy, modules, dependentModule); - return resolvedCopy; - } + builder, unknownTypeQName.getPrefix(), line); - private TypeDefinitionBuilder copyTypedefBuilder( - final TypeDefinitionBuilder old, final boolean seekByTypedefBuilder) { - if (old instanceof UnionTypeBuilder) { - final UnionTypeBuilder oldUnion = (UnionTypeBuilder) old; - final UnionTypeBuilder newUnion = new UnionTypeBuilder( - oldUnion.getActualPath(), oldUnion.getNamespace(), - oldUnion.getRevision(), old.getLine()); - for (TypeDefinition td : oldUnion.getTypes()) { - newUnion.setType(td); - } - for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) { - newUnion.setType(copyTypedefBuilder(tdb, true)); - } - return newUnion; - } + final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder( + nodeToResolve.getPath(), dependentModule, + unknownTypeQName.getLocalName(), builder.getName(), line); - final QName oldName = old.getQName(); - final QName newName = new QName(oldName.getNamespace(), - oldName.getRevision(), oldName.getPrefix(), - oldName.getLocalName()); - final TypeDefinitionBuilder tdb = new TypedefBuilder(newName, - old.getLine()); - - tdb.setRanges(old.getRanges()); - tdb.setLengths(old.getLengths()); - tdb.setPatterns(old.getPatterns()); - tdb.setFractionDigits(old.getFractionDigits()); - tdb.setPath(old.getPath()); - - final TypeDefinition oldType = old.getType(); - if (oldType == null) { - tdb.setType(old.getTypedef()); + if (typedefType instanceof ExtendedType) { + final ExtendedType extType = (ExtendedType) typedefType; + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType( + nodeToResolve, targetTypeBuilder, extType, modules, builder); + resolvedType = newType; } else { - tdb.setType(oldType); - } - - if (!seekByTypedefBuilder) { - tdb.setDescription(old.getDescription()); - tdb.setReference(old.getReference()); - tdb.setStatus(old.getStatus()); - tdb.setDefaultValue(old.getDefaultValue()); - tdb.setUnits(old.getUnits()); + resolvedType = targetTypeBuilder; } - return tdb; + nodeToResolve.setTypedef(resolvedType); } - private TypeDefinitionBuilder resolveCopiedBuilder( - final TypeDefinitionBuilder copy, + private void resolveTypeUnion(final UnionTypeBuilder union, final Map> modules, final ModuleBuilder builder) { - if (copy instanceof UnionTypeBuilder) { - final UnionTypeBuilder union = (UnionTypeBuilder) copy; - final List> unionTypes = union.getTypes(); - final List toRemove = new ArrayList(); - for (TypeDefinition td : unionTypes) { - if (td instanceof UnknownType) { - final UnknownType unknownType = (UnknownType) td; - final TypeDefinitionBuilder resolvedType = resolveTypeUnion( - union, unknownType, modules, builder); - union.setType(resolvedType); - toRemove.add(unknownType); + final List> unionTypes = union.getTypes(); + final List> toRemove = new ArrayList>(); + for (TypeDefinition unionType : unionTypes) { + if (unionType instanceof UnknownType) { + final UnknownType ut = (UnknownType) unionType; + final ModuleBuilder dependentModule = findDependentModule( + modules, builder, ut.getQName().getPrefix(), + union.getLine()); + final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder( + union.getPath(), dependentModule, ut.getQName() + .getLocalName(), builder.getName(), + union.getLine()); + union.setTypedef(resolvedType); + toRemove.add(ut); + } else if (unionType instanceof ExtendedType) { + final ExtendedType extType = (ExtendedType) unionType; + TypeDefinition extTypeBase = extType.getBaseType(); + if (extTypeBase instanceof UnknownType) { + final UnknownType ut = (UnknownType) extTypeBase; + final ModuleBuilder dependentModule = findDependentModule( + modules, builder, ut.getQName().getPrefix(), + union.getLine()); + final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder( + union.getPath(), dependentModule, ut.getQName() + .getLocalName(), builder.getName(), + union.getLine()); + + final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType( + targetTypeBuilder, targetTypeBuilder, extType, + modules, builder); + + union.setTypedef(newType); + toRemove.add(extType); } } - unionTypes.removeAll(toRemove); - - return union; - } - - final TypeDefinition base = copy.getType(); - final TypeDefinitionBuilder baseTdb = copy.getTypedef(); - if (base != null && !(base instanceof UnknownType)) { - return copy; - } else if (base instanceof UnknownType) { - final UnknownType unknownType = (UnknownType) base; - final QName unknownTypeQName = unknownType.getQName(); - final String unknownTypePrefix = unknownTypeQName.getPrefix(); - final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknownTypePrefix, copy.getLine()); - final TypeDefinitionBuilder utBuilder = getTypedefBuilder(copy, - modules, dependentModule); - copy.setType(utBuilder); - return copy; - } else if (base == null && baseTdb != null) { - // make a copy of baseTypeDef and call again - final TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder( - baseTdb, true); - final TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder( - baseTdbCopy, modules, builder); - copy.setType(baseTdbCopyResolved); - return copy; - } else { - throw new IllegalStateException("Failed to resolve type " - + copy.getQName().getLocalName()); } + unionTypes.removeAll(toRemove); } - private TypeDefinitionBuilder findTypedefBuilder( - final QName unknownTypeQName, + private TypeDefinitionBuilder extendedTypeWithNewBaseType( + final TypeAwareBuilder nodeToResolve, + final TypeDefinitionBuilder newBaseType, + final ExtendedType oldExtendedType, 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); + final ModuleBuilder builder) { + final TypeConstraints constraints = findConstraints(nodeToResolve, + new TypeConstraints(), modules, builder); + final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl( + oldExtendedType.getQName(), nodeToResolve.getLine()); + newType.setTypedef(newBaseType); + newType.setPath(oldExtendedType.getPath()); + newType.setDescription(oldExtendedType.getDescription()); + newType.setReference(oldExtendedType.getReference()); + newType.setStatus(oldExtendedType.getStatus()); + newType.setLengths(constraints.getLength()); + newType.setPatterns(constraints.getPatterns()); + newType.setRanges(constraints.getRange()); + newType.setFractionDigits(constraints.getFractionDigits()); + newType.setUnits(oldExtendedType.getUnits()); + newType.setDefaultValue(oldExtendedType.getDefaultValue()); + newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes()); + return newType; } private TypeConstraints findConstraints( @@ -489,101 +411,134 @@ public class YangParserImpl implements YangModelParser { final TypeConstraints constraints, final Map> modules, final ModuleBuilder builder) { + // union type cannot be restricted if (nodeToResolve instanceof UnionTypeBuilder) { return constraints; } - // if referenced type is UnknownType again, search recursively with - // current constraints - final TypeDefinition referencedType = nodeToResolve.getType(); - List ranges = Collections.emptyList(); - List lengths = Collections.emptyList(); - List patterns = Collections.emptyList(); - Integer fractionDigits = null; - if (referencedType == null) { - final TypeDefinitionBuilder tdb = nodeToResolve.getTypedef(); - ranges = tdb.getRanges(); - constraints.addRanges(ranges); - lengths = tdb.getLengths(); - constraints.addLengths(lengths); - patterns = tdb.getPatterns(); - constraints.addPatterns(patterns); - fractionDigits = tdb.getFractionDigits(); - constraints.setFractionDigits(fractionDigits); - return constraints; - } else if (referencedType instanceof ExtendedType) { - final ExtendedType ext = (ExtendedType) referencedType; - ranges = ext.getRanges(); - constraints.addRanges(ranges); - lengths = ext.getLengths(); - constraints.addLengths(lengths); - patterns = ext.getPatterns(); - constraints.addPatterns(patterns); - fractionDigits = ext.getFractionDigits(); - constraints.setFractionDigits(fractionDigits); - return findConstraints( - findTypedefBuilder(ext.getQName(), modules, builder, - nodeToResolve.getLine()), constraints, modules, - builder); - } else if (referencedType instanceof UnknownType) { - final UnknownType unknown = (UnknownType) referencedType; - ranges = unknown.getRangeStatements(); - constraints.addRanges(ranges); - lengths = unknown.getLengthStatements(); - constraints.addLengths(lengths); - patterns = unknown.getPatterns(); - constraints.addPatterns(patterns); - fractionDigits = unknown.getFractionDigits(); - constraints.setFractionDigits(fractionDigits); - - String unknownTypePrefix = unknown.getQName().getPrefix(); - if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) { - unknownTypePrefix = builder.getPrefix(); - } - final ModuleBuilder dependentModule = findDependentModule(modules, - builder, unknown.getQName().getPrefix(), - nodeToResolve.getLine()); - final TypeDefinitionBuilder utBuilder = findTypedefBuilder( - unknown.getQName(), modules, builder, - nodeToResolve.getLine()); - return findConstraints(utBuilder, constraints, modules, - dependentModule); + if (nodeToResolve instanceof TypeDefinitionBuilder) { + TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve; + constraints.addFractionDigits(typedefToResolve.getFractionDigits()); + constraints.addLengths(typedefToResolve.getLengths()); + constraints.addPatterns(typedefToResolve.getPatterns()); + constraints.addRanges(typedefToResolve.getRanges()); + } + + TypeDefinition type = nodeToResolve.getType(); + if (type == null) { + return findConstraints(nodeToResolve.getTypedef(), constraints, + modules, builder); } else { - // HANDLE BASE YANG TYPE - mergeConstraints(referencedType, constraints); - return constraints; + if (type instanceof UnknownType) { + ModuleBuilder dependentModule = findDependentModule(modules, + builder, type.getQName().getPrefix(), + nodeToResolve.getLine()); + TypeDefinitionBuilder tdb = findTypeDefinitionBuilder( + nodeToResolve.getPath(), dependentModule, type + .getQName().getLocalName(), builder.getName(), + nodeToResolve.getLine()); + return findConstraints(tdb, constraints, modules, + dependentModule); + } else if (type instanceof ExtendedType) { + ExtendedType extType = (ExtendedType) type; + constraints.addFractionDigits(extType.getFractionDigits()); + constraints.addLengths(extType.getLengths()); + constraints.addPatterns(extType.getPatterns()); + constraints.addRanges(extType.getRanges()); + + TypeDefinition base = extType.getBaseType(); + if (base instanceof UnknownType) { + ModuleBuilder dependentModule = findDependentModule( + modules, builder, base.getQName().getPrefix(), + nodeToResolve.getLine()); + TypeDefinitionBuilder tdb = findTypeDefinitionBuilder( + nodeToResolve.getPath(), dependentModule, base + .getQName().getLocalName(), + builder.getName(), nodeToResolve.getLine()); + return findConstraints(tdb, constraints, modules, + dependentModule); + } else { + // it has to be base yang type + mergeConstraints(type, constraints); + return constraints; + } + } else { + // it is base yang type + mergeConstraints(type, constraints); + return constraints; + } } } /** - * 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; } /** @@ -599,7 +554,7 @@ public class YangParserImpl implements YangModelParser { constraints.addRanges(((DecimalTypeDefinition) referencedType) .getRangeStatements()); constraints - .setFractionDigits(((DecimalTypeDefinition) referencedType) + .addFractionDigits(((DecimalTypeDefinition) referencedType) .getFractionDigits()); } else if (referencedType instanceof IntegerTypeDefinition) { constraints.addRanges(((IntegerTypeDefinition) referencedType) @@ -616,8 +571,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 +597,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 +625,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 +649,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 +681,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 +716,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 +734,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 +754,140 @@ 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); + GroupingBuilder targetGrouping = getTargetGrouping(usesNode, modules, module); + usesNode.setGroupingPath(targetGrouping.getPath()); 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( + targetGrouping, 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); + } + } + } + } + + private GroupingBuilder getTargetGrouping( + final UsesNodeBuilder usesBuilder, + final Map> modules, + final ModuleBuilder module) { + final int line = usesBuilder.getLine(); + String groupingString = usesBuilder.getGroupingName(); + String groupingPrefix; + String groupingName; + + if(groupingString.contains(":")) { + String[] splitted = groupingString.split(":"); + if(splitted.length != 2 || groupingString.contains("/")) { + throw new YangParseException(module.getName(), line, "Invalid name of target grouping"); + } + groupingPrefix = splitted[0]; + groupingName = splitted[1]; + } else { + groupingPrefix = module.getPrefix(); + groupingName = groupingString; + } + + ModuleBuilder dependentModule = null; + if(groupingPrefix.equals(module.getPrefix())) { + dependentModule = module; + } else { + dependentModule = findDependentModule(modules, module, groupingPrefix, line); + } + + + List path = usesBuilder.getPath().getPath(); + GroupingBuilder result = null; + Set groupings = dependentModule.getModuleGroupings(); + result = findGrouping(groupings, groupingName); + + 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) { + groupings = ((RpcDefinitionBuilder) currentNode).getGroupings(); + } else if (currentNode instanceof DataNodeContainerBuilder) { + groupings = ((DataNodeContainerBuilder) currentNode).getGroupings(); + } else { + groupings = Collections.emptySet(); + } + + result = findGrouping(groupings, groupingName); + if (result != null) { + break; } } } + + if (result != null) { + return result; + } + throw new YangParseException(module.getName(), line, + "Referenced grouping '" + groupingName + "' not found."); + } + + private GroupingBuilder findGrouping(Set groupings, + String name) { + for (GroupingBuilder grouping : groupings) { + if (grouping.getQName().getLocalName().equals(name)) { + return grouping; + } + } + return null; } /** - * 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,15 +897,15 @@ 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 GroupingBuilder targetGrouping, final RefineHolder refine, final Map> modules, final ModuleBuilder module) { Builder result = null; - final Builder lookedUpBuilder = findRefineTargetBuilder(groupingPath, + final Builder lookedUpBuilder = findRefineTargetBuilder(targetGrouping, refine, modules, module); if (lookedUpBuilder instanceof LeafSchemaNodeBuilder) { result = ParserUtils @@ -950,11 +925,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 +943,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 @@ -971,29 +952,31 @@ public class YangParserImpl implements YangModelParser { * @return Builder object of refine node if it is present in grouping, null * otherwise */ - private Builder findRefineTargetBuilder(final String groupingPath, + private Builder findRefineTargetBuilder(final GroupingBuilder builder, final RefineHolder refine, final Map> modules, final ModuleBuilder module) { - final SchemaPath path = ParserUtils.parseUsesPath(groupingPath); - final List builderPath = new ArrayList(); - String prefix = null; - for (QName qname : path.getPath()) { - builderPath.add(qname.getLocalName()); - prefix = qname.getPrefix(); + final String refineNodeName = refine.getName(); + Builder result = builder.getChildNode(refineNodeName); + if (result == null) { + Set grps = builder.getGroupings(); + for (GroupingBuilder gr : grps) { + if (gr.getQName().getLocalName().equals(refineNodeName)) { + result = gr; + break; + } + } } - if (prefix == null) { - prefix = module.getPrefix(); + if (result == null) { + Set typedefs = builder.getTypeDefinitions(); + for (TypeDefinitionBuilder typedef : typedefs) { + if (typedef.getQName().getLocalName().equals(refineNodeName)) { + result = typedef; + break; + } + } } - - 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); - - return builder.getChildNode(refine.getName()); + return result; } private QName findFullQName( @@ -1023,7 +1006,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 +1036,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 +1084,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; - } - } - }