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;
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;
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;
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;
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;
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<Module> parseYangModels(final List<File> yangFiles) {
+ public Map<File, Module> parseYangModelsMapped(List<File> yangFiles) {
if (yangFiles != null) {
- final List<InputStream> inputStreams = new ArrayList<InputStream>();
+ final Map<InputStream, File> 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<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(inputStreams);
- return build(modules);
+
+ Map<ModuleBuilder, InputStream> builderToStreamMap = Maps
+ .newHashMap();
+
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(
+ Lists.newArrayList(inputStreams.keySet()),
+ builderToStreamMap);
+ // return new LinkedHashSet<Module>(build(modules).values());
+
+ Map<File, Module> retVal = Maps.newLinkedHashMap();
+ Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
+
+ for (Entry<ModuleBuilder, Module> builderToModule : builderToModuleMap
+ .entrySet()) {
+ retVal.put(inputStreams.get(builderToStreamMap
+ .get(builderToModule.getKey())), builderToModule
+ .getValue());
+ }
+
+ return retVal;
}
- return Collections.emptySet();
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Set<Module> parseYangModels(final List<File> yangFiles) {
+ return Sets.newLinkedHashSet(parseYangModelsMapped(yangFiles).values());
}
@Override
public Set<Module> parseYangModelsFromStreams(
final List<InputStream> yangModelStreams) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(yangModelStreams);
- return build(modules);
+ return Sets.newHashSet(parseYangModelsFromStreamsMapped(
+ yangModelStreams).values());
+ }
+
+ @Override
+ public Map<InputStream, Module> parseYangModelsFromStreamsMapped(
+ final List<InputStream> yangModelStreams) {
+ Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
+
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuilders(
+ yangModelStreams, builderToStreamMap);
+ Map<InputStream, Module> retVal = Maps.newLinkedHashMap();
+ Map<ModuleBuilder, Module> builderToModuleMap = build(modules);
+
+ for (Entry<ModuleBuilder, Module> builderToModule : builderToModuleMap
+ .entrySet()) {
+ retVal.put(builderToStreamMap.get(builderToModule.getKey()),
+ builderToModule.getValue());
+ }
+ return retVal;
}
@Override
return new SchemaContextImpl(modules);
}
- private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
- final List<InputStream> yangFileStreams) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
+ private ModuleBuilder[] parseModuleBuilders(List<InputStream> inputStreams,
+ Map<ModuleBuilder, InputStream> streamToBuilderMap) {
+
final ParseTreeWalker walker = new ParseTreeWalker();
- final List<ParseTree> trees = parseStreams(yangFileStreams);
+ final List<ParseTree> trees = parseStreams(inputStreams);
final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
// validate yang
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<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
+ final List<InputStream> yangFileStreams,
+ Map<ModuleBuilder, InputStream> 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<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
// module dependency graph sorted
- List<ModuleSimple> 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<ModuleBuilder> orderedBuilders = new ArrayList<ModuleBuilder>();
- 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<ModuleBuilder> sorted = ModuleDependencySort.sort(builders);
- for (ModuleBuilder builder : orderedBuilders) {
+ for (ModuleBuilder builder : sorted) {
final String builderName = builder.getName();
Date builderRevision = builder.getRevision();
if (builderRevision == null) {
return result;
}
- private Set<Module> build(
+ private Map<ModuleBuilder, Module> build(
final Map<String, TreeMap<Date, ModuleBuilder>> modules) {
// fix unresolved nodes
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
resolveAugments(modules);
// build
- final Set<Module> result = new LinkedHashSet<Module>();
+ // 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<ModuleBuilder, Module> result = new LinkedHashMap<ModuleBuilder, Module>();
for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
.entrySet()) {
final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
final ModuleBuilder moduleBuilder = childEntry.getValue();
final Module module = moduleBuilder.build();
modulesByRevision.put(childEntry.getKey(), module);
- result.add(module);
+ result.put(moduleBuilder, module);
}
}
return result;
final ModuleBuilder builder) {
resolveDirtyNodes(modules, builder);
resolveIdentities(modules, builder);
- resolveUses(modules, builder);
+ resolveUsesRefines(modules, builder);
resolveUnknownNodes(modules, builder);
}
if (!dirtyNodes.isEmpty()) {
for (Map.Entry<List<String>, 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<TypeDefinition<?>> unionTypes = union.getTypes();
- final List<UnknownType> toRemove = new ArrayList<UnknownType>();
- 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<String, TreeMap<Date, ModuleBuilder>> 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,
- final Map<String, TreeMap<Date, ModuleBuilder>> 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,
+ private void resolveType(final TypeAwareBuilder nodeToResolve,
final Map<String, TreeMap<Date, ModuleBuilder>> 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<String, TreeMap<Date, ModuleBuilder>> 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);
+ resolvedType = targetTypeBuilder;
}
-
- if (!seekByTypedefBuilder) {
- tdb.setDescription(old.getDescription());
- tdb.setReference(old.getReference());
- tdb.setStatus(old.getStatus());
- tdb.setDefaultValue(old.getDefaultValue());
- tdb.setUnits(old.getUnits());
- }
- return tdb;
+ nodeToResolve.setTypedef(resolvedType);
}
- private TypeDefinitionBuilder resolveCopiedBuilder(
- final TypeDefinitionBuilder copy,
+ private void resolveTypeUnion(final UnionTypeBuilder union,
final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder builder) {
- if (copy instanceof UnionTypeBuilder) {
- final UnionTypeBuilder union = (UnionTypeBuilder) copy;
- final List<TypeDefinition<?>> unionTypes = union.getTypes();
- final List<UnknownType> toRemove = new ArrayList<UnknownType>();
- 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<TypeDefinition<?>> unionTypes = union.getTypes();
+ final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
+ 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<String, TreeMap<Date, ModuleBuilder>> 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(
final TypeConstraints constraints,
final Map<String, TreeMap<Date, ModuleBuilder>> 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<RangeConstraint> ranges = Collections.emptyList();
- List<LengthConstraint> lengths = Collections.emptyList();
- List<PatternConstraint> 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<QName> path = dirtyNodeSchemaPath.getPath();
TypeDefinitionBuilder result = null;
- final Set<TypeDefinitionBuilder> typedefs = dependentModule
+
+ Set<TypeDefinitionBuilder> 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<String> currentPath = new ArrayList<String>();
+ 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<TypeDefinitionBuilder> types,
+ String name) {
+ for (TypeDefinitionBuilder td : types) {
+ if (td.getQName().getLocalName().equals(name)) {
+ return td;
+ }
+ }
+ return null;
}
/**
constraints.addRanges(((DecimalTypeDefinition) referencedType)
.getRangeStatements());
constraints
- .setFractionDigits(((DecimalTypeDefinition) referencedType)
+ .addFractionDigits(((DecimalTypeDefinition) referencedType)
.getFractionDigits());
} else if (referencedType instanceof IntegerTypeDefinition) {
constraints.addRanges(((IntegerTypeDefinition) referencedType)
}
/**
- * 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
// while all augments are not resolved
final Iterator<ModuleBuilder> allModulesIterator = allModulesSet
.iterator();
- while (!(module.getAugmentsResolved() == module.getAddedAugments()
+ while (!(module.getAugmentsResolved() == module.getAugments()
.size())) {
ModuleBuilder nextModule = null;
// try resolve other module augments
private void resolveAugment(
final Map<String, TreeMap<Date, ModuleBuilder>> 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<QName> 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();
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(
.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();
final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder module) {
final Set<IdentitySchemaNodeBuilder> identities = module
- .getAddedIdentities();
+ .getIdentities();
for (IdentitySchemaNodeBuilder identity : identities) {
final String baseIdentityName = identity.getBaseIdentityName();
if (baseIdentityName != null) {
modules, module, baseIdentityPrefix, identity.getLine());
final Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule
- .getAddedIdentities();
+ .getIdentities();
for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
if (idBuilder.getQName().getLocalName()
.equals(baseIdentityLocalName)) {
* @param module
* module being resolved
*/
- private void resolveUses(
+ private void resolveUsesRefines(
final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder module) {
final Map<List<String>, UsesNodeBuilder> moduleUses = module
- .getAddedUsesNodes();
+ .getUsesNodes();
for (Map.Entry<List<String>, UsesNodeBuilder> entry : moduleUses
.entrySet()) {
final List<String> 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<UnknownSchemaNodeBuilder> 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.
+ * <p>
+ * 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}.
+ * </p>
*
* @param groupingPath
* path to grouping which contains node to refine
* 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<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder module) {
Builder result = null;
} 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;
}
/**
*
* @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
final RefineHolder refine,
final Map<String, TreeMap<Date, ModuleBuilder>> modules,
final ModuleBuilder module) {
+ final String refineNodeName = refine.getName();
final SchemaPath path = ParserUtils.parseUsesPath(groupingPath);
final List<String> builderPath = new ArrayList<String>();
String prefix = null;
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<GroupingBuilder> grps = builder.getGroupings();
+ for (GroupingBuilder gr : grps) {
+ if (gr.getQName().getLocalName().equals(refineNodeName)) {
+ result = gr;
+ break;
+ }
+ }
+ }
+ if (result == null) {
+ Set<TypeDefinitionBuilder> typedefs = builder.getTypeDefinitions();
+ for (TypeDefinitionBuilder typedef : typedefs) {
+ if (typedef.getQName().getLocalName().equals(refineNodeName)) {
+ result = typedef;
+ break;
+ }
+ }
+ }
+ return result;
}
private QName findFullQName(
private void resolveUnknownNodes(
final Map<String, TreeMap<Date, ModuleBuilder>> 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) {
* current module
* @param prefix
* target module prefix
+ * @param line
+ * current line in yang model
* @return
*/
private ModuleBuilder findDependentModule(
return dependentModule;
}
- private static class SchemaContextImpl implements SchemaContext {
- private final Set<Module> modules;
-
- private SchemaContextImpl(final Set<Module> modules) {
- this.modules = modules;
- }
-
- @Override
- public Set<DataSchemaNode> getDataDefinitions() {
- final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
- for (Module m : modules) {
- dataDefs.addAll(m.getChildNodes());
- }
- return dataDefs;
- }
-
- @Override
- public Set<Module> getModules() {
- return modules;
- }
-
- @Override
- public Set<NotificationDefinition> getNotifications() {
- final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
- for (Module m : modules) {
- notifications.addAll(m.getNotifications());
- }
- return notifications;
- }
-
- @Override
- public Set<RpcDefinition> getOperations() {
- final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
- for (Module m : modules) {
- rpcs.addAll(m.getRpcs());
- }
- return rpcs;
- }
-
- @Override
- public Set<ExtensionDefinition> getExtensions() {
- final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
- 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;
- }
- }
-
}