import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import org.opendaylight.controller.yang.model.parser.builder.api.TypeAwareBuilder;
import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder;
import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public Module parseYangModel(String yangFile) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = loadFiles(yangFile);
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFile);
Set<Module> result = build(modules);
return result.iterator().next();
}
@Override
public Set<Module> parseYangModels(String... yangFiles) {
- final Map<String, TreeMap<Date, ModuleBuilder>> modules = loadFiles(yangFiles);
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFiles);
+ Set<Module> result = build(modules);
+ return result;
+ }
+
+ @Override
+ public Set<Module> parseYangModelsFromStreams(
+ InputStream... yangModelStreams) {
+ final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangModelStreams);
Set<Module> result = build(modules);
return result;
}
return new SchemaContextImpl(modules);
}
- private Map<String, TreeMap<Date, ModuleBuilder>> loadFiles(
+ private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
String... yangFiles) {
+ InputStream[] streams = new InputStream[yangFiles.length];
+ for(int i = 0; i < yangFiles.length; i++) {
+ final String yangFileName = yangFiles[i];
+ final File yangFile = new File(yangFileName);
+ FileInputStream inStream = null;
+ try {
+ inStream = new FileInputStream(yangFile);
+ } catch(FileNotFoundException e) {
+ logger.warn("Exception while reading yang stream: " + inStream, e);
+ }
+ streams[i] = inStream;
+ }
+ return resolveModuleBuildersFromStreams(streams);
+ }
+
+ private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
+ InputStream... yangFiles) {
final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl();
final ParseTreeWalker walker = new ParseTreeWalker();
- List<ParseTree> trees = parseFiles(yangFiles);
+ List<ParseTree> trees = parseStreams(yangFiles);
ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
return modules;
}
- private List<ParseTree> parseFiles(String... yangFileNames) {
+ private List<ParseTree> parseStreams(InputStream... yangStreams) {
List<ParseTree> trees = new ArrayList<ParseTree>();
- for (String fileName : yangFileNames) {
- trees.add(parseFile(fileName));
+ for (InputStream yangStream : yangStreams) {
+ trees.add(parseStream(yangStream));
}
return trees;
}
- private ParseTree parseFile(String yangFileName) {
+ private ParseTree parseStream(InputStream yangStream) {
ParseTree result = null;
try {
- final File yangFile = new File(yangFileName);
- final FileInputStream inStream = new FileInputStream(yangFile);
- final ANTLRInputStream input = new ANTLRInputStream(inStream);
+ final ANTLRInputStream input = new ANTLRInputStream(yangStream);
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: " + yangFileName, e);
+ logger.warn("Exception while reading yang file: " + yangStream, e);
}
return result;
}
*
* @param modules
* all available modules
- * @param builder
+ * @param module
* current module
*/
private void resolveTypedefs(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- Map<List<String>, TypeAwareBuilder> dirtyNodes = builder
+ ModuleBuilder module) {
+ Map<List<String>, TypeAwareBuilder> dirtyNodes = module
.getDirtyNodes();
if (dirtyNodes.size() == 0) {
return;
for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
.entrySet()) {
TypeAwareBuilder typeToResolve = entry.getValue();
- Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
- modules, entry.getValue(), builder);
- TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
- .entrySet().iterator().next().getKey();
- TypeConstraints constraints = foundedTypeDefinitionBuilder
- .entrySet().iterator().next().getValue();
-
- UnknownType ut = (UnknownType) typeToResolve.getType();
-
- // RANGE
- List<RangeConstraint> ranges = ut.getRangeStatements();
- resolveRanges(ranges, typeToResolve, targetType, modules,
- builder);
- // LENGTH
- List<LengthConstraint> lengths = ut.getLengthStatements();
- resolveLengths(lengths, typeToResolve, targetType, modules,
- builder);
-
- // PATTERN
- List<PatternConstraint> patterns = ut.getPatterns();
-
- // Fraction Digits
- Integer fractionDigits = ut.getFractionDigits();
-
- TypeDefinition<?> type = targetType.getBaseType();
- String typeName = type.getQName().getLocalName();
-
- // MERGE CONSTRAINTS (enumeration and leafref omitted because
- // they have no restrictions)
- if (type instanceof DecimalTypeDefinition) {
- List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
- fullRanges.addAll(constraints.getRanges());
- fullRanges.addAll(ranges);
- Integer fd = fractionDigits == null ? constraints
- .getFractionDigits() : fractionDigits;
- type = YangTypesConverter.javaTypeForBaseYangDecimal64Type(
- fullRanges, fd);
- } else if (type instanceof IntegerTypeDefinition) {
- List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
- fullRanges.addAll(constraints.getRanges());
- fullRanges.addAll(ranges);
- if (typeName.startsWith("int")) {
- type = YangTypesConverter
- .javaTypeForBaseYangSignedIntegerType(typeName,
- fullRanges);
- } else {
- type = YangTypesConverter
- .javaTypeForBaseYangUnsignedIntegerType(
- typeName, fullRanges);
- }
- } else if (type instanceof StringTypeDefinition) {
- List<LengthConstraint> fullLengths = new ArrayList<LengthConstraint>();
- fullLengths.addAll(constraints.getLengths());
- fullLengths.addAll(lengths);
- List<PatternConstraint> fullPatterns = new ArrayList<PatternConstraint>();
- fullPatterns.addAll(constraints.getPatterns());
- fullPatterns.addAll(patterns);
- type = new StringType(fullLengths, fullPatterns);
- } else if (type instanceof BitsTypeDefinition) {
- // TODO: add 'length' restriction to BitsType
- BitsTypeDefinition bitsType = (BitsTypeDefinition) type;
- List<Bit> bits = bitsType.getBits();
- type = new BitsType(bits);
- } else if (type instanceof BinaryTypeDefinition) {
- type = new BinaryType(null, lengths, null);
- } else if (typeName.equals("instance-identifier")) {
- // TODO: instance-identifier
- /*
- * boolean requireInstance = isRequireInstance(typeBody);
- * type = new InstanceIdentifier(null, requireInstance);
- */
+ if (typeToResolve instanceof UnionTypeBuilder) {
+ resolveUnionTypeBuilder(modules, module,
+ (UnionTypeBuilder) typeToResolve);
+ } else {
+ UnknownType ut = (UnknownType) typeToResolve.getType();
+ TypeDefinition<?> resolvedType = findTargetType(ut,
+ modules, module);
+ typeToResolve.setType(resolvedType);
}
- typeToResolve.setType(type);
}
}
}
+ private UnionTypeBuilder resolveUnionTypeBuilder(
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder, UnionTypeBuilder unionTypeBuilderToResolve) {
+
+ List<TypeDefinition<?>> resolvedTypes = new ArrayList<TypeDefinition<?>>();
+ List<TypeDefinition<?>> typesToRemove = new ArrayList<TypeDefinition<?>>();
+
+ for (TypeDefinition<?> td : unionTypeBuilderToResolve.getTypes()) {
+ if (td instanceof UnknownType) {
+ TypeDefinition<?> resolvedType = findTargetType(
+ (UnknownType) td, modules, builder);
+ resolvedTypes.add(resolvedType);
+ typesToRemove.add(td);
+ }
+ }
+
+ List<TypeDefinition<?>> unionTypeBuilderTypes = unionTypeBuilderToResolve
+ .getTypes();
+ unionTypeBuilderTypes.addAll(resolvedTypes);
+ unionTypeBuilderTypes.removeAll(typesToRemove);
+
+ return unionTypeBuilderToResolve;
+ }
+
+ private TypeDefinition<?> findTargetType(UnknownType ut,
+ Map<String, TreeMap<Date, ModuleBuilder>> modules,
+ ModuleBuilder builder) {
+
+ Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
+ modules, ut, builder);
+ TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
+ .entrySet().iterator().next().getKey();
+ TypeConstraints constraints = foundedTypeDefinitionBuilder.entrySet()
+ .iterator().next().getValue();
+
+ TypeDefinition<?> targetTypeBaseType = targetType.getBaseType();
+ String targetTypeBaseTypeName = targetTypeBaseType.getQName()
+ .getLocalName();
+
+ // RANGE
+ List<RangeConstraint> ranges = ut.getRangeStatements();
+ resolveRanges(ranges, targetType, modules, builder);
+
+ // LENGTH
+ List<LengthConstraint> lengths = ut.getLengthStatements();
+ resolveLengths(lengths, targetType, modules, builder);
+
+ // PATTERN
+ List<PatternConstraint> patterns = ut.getPatterns();
+
+ // Fraction Digits
+ Integer fractionDigits = ut.getFractionDigits();
+
+ // MERGE CONSTRAINTS (enumeration and leafref omitted
+ // because
+ // they have no restrictions)
+ if (targetTypeBaseType instanceof DecimalTypeDefinition) {
+ List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
+ fullRanges.addAll(constraints.getRanges());
+ fullRanges.addAll(ranges);
+ Integer fd = fractionDigits == null ? constraints
+ .getFractionDigits() : fractionDigits;
+ targetTypeBaseType = YangTypesConverter
+ .javaTypeForBaseYangDecimal64Type(fullRanges, fd);
+ } else if (targetTypeBaseType instanceof IntegerTypeDefinition) {
+ List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
+ fullRanges.addAll(constraints.getRanges());
+ fullRanges.addAll(ranges);
+ if (targetTypeBaseTypeName.startsWith("int")) {
+ targetTypeBaseType = YangTypesConverter
+ .javaTypeForBaseYangSignedIntegerType(
+ targetTypeBaseTypeName, fullRanges);
+ } else {
+ targetTypeBaseType = YangTypesConverter
+ .javaTypeForBaseYangUnsignedIntegerType(
+ targetTypeBaseTypeName, fullRanges);
+ }
+ } else if (targetTypeBaseType instanceof StringTypeDefinition) {
+ List<LengthConstraint> fullLengths = new ArrayList<LengthConstraint>();
+ fullLengths.addAll(constraints.getLengths());
+ fullLengths.addAll(lengths);
+ List<PatternConstraint> fullPatterns = new ArrayList<PatternConstraint>();
+ fullPatterns.addAll(constraints.getPatterns());
+ fullPatterns.addAll(patterns);
+ targetTypeBaseType = new StringType(fullLengths, fullPatterns);
+ } else if (targetTypeBaseType instanceof BitsTypeDefinition) {
+ BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType;
+ List<Bit> bits = bitsType.getBits();
+ targetTypeBaseType = new BitsType(bits);
+ } else if (targetTypeBaseType instanceof BinaryTypeDefinition) {
+ targetTypeBaseType = new BinaryType(null, lengths, null);
+ } else if (targetTypeBaseTypeName.equals("instance-identifier")) {
+ // TODO: instance-identifier
+ /*
+ * boolean requireInstance = isRequireInstance(typeBody); type = new
+ * InstanceIdentifier(null, requireInstance);
+ */
+ }
+
+ return targetTypeBaseType;
+ }
+
private TypeDefinitionBuilder findTypeDefinitionBuilder(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- TypeAwareBuilder typeBuilder, ModuleBuilder builder) {
+ UnknownType unknownType, ModuleBuilder builder) {
Map<TypeDefinitionBuilder, TypeConstraints> result = findTypeDefinitionBuilderWithConstraints(
- modules, typeBuilder, builder);
+ modules, unknownType, builder);
return result.entrySet().iterator().next().getKey();
}
private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- TypeAwareBuilder typeBuilder, ModuleBuilder builder) {
+ UnknownType unknownType, ModuleBuilder builder) {
return findTypeDefinitionBuilderWithConstraints(new TypeConstraints(),
- modules, typeBuilder, builder);
+ modules, unknownType, builder);
}
/**
* Traverse through all referenced types chain until base YANG type is
* founded.
*
- * @param constraints
- * current type constraints
- * @param modules
- * all available modules
- * @param typeBuilder
- * type builder which contains type
- * @param builder
- * current module
+ * @param constraints current type constraints
+ * @param modules all available modules
+ * @param unknownType unknown type
+ * @param builder current module
* @return map, where key is type referenced and value is its constraints
*/
private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
TypeConstraints constraints,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- TypeAwareBuilder typeBuilder, ModuleBuilder builder) {
+ UnknownType unknownType, ModuleBuilder builder) {
Map<TypeDefinitionBuilder, TypeConstraints> result = new HashMap<TypeDefinitionBuilder, TypeConstraints>();
- UnknownType type = (UnknownType) typeBuilder.getType();
- QName typeQName = type.getQName();
- String typeName = type.getQName().getLocalName();
- String prefix = typeQName.getPrefix();
+ // TypeDefinition<?> unknownType = typeBuilder.getType();
+ QName unknownTypeQName = unknownType.getQName();
+ String unknownTypeName = unknownTypeQName.getLocalName();
+ String unknownTypePrefix = unknownTypeQName.getPrefix();
// search for module which contains referenced typedef
ModuleBuilder dependentModuleBuilder;
- if (prefix.equals(builder.getPrefix())) {
+ if (unknownTypePrefix.equals(builder.getPrefix())) {
dependentModuleBuilder = builder;
} else {
ModuleImport dependentModuleImport = getModuleImport(builder,
- prefix);
+ unknownTypePrefix);
String dependentModuleName = dependentModuleImport.getModuleName();
Date dependentModuleRevision = dependentModuleImport.getRevision();
TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
TypeDefinitionBuilder lookedUpBuilder = null;
for (TypeDefinitionBuilder tdb : typedefs) {
QName qname = tdb.getQName();
- if (qname.getLocalName().equals(typeName)) {
+ if (qname.getLocalName().equals(unknownTypeName)) {
lookedUpBuilder = tdb;
break;
}
final List<PatternConstraint> patterns = unknown.getPatterns();
constraints.addPatterns(patterns);
return findTypeDefinitionBuilderWithConstraints(constraints,
- modules, (TypeAwareBuilder) lookedUpBuilder,
- dependentModuleBuilder);
+ modules, unknown, dependentModuleBuilder);
} else {
// pull restriction from this base type and add them to
// 'constraints'
} else if (referencedType instanceof StringTypeDefinition) {
constraints.addPatterns(((StringTypeDefinition) referencedType)
.getPatterns());
- } else if (referencedType instanceof BitsTypeDefinition) {
- // TODO: add 'length' restriction to BitsType
} else if (referencedType instanceof BinaryTypeDefinition) {
- // TODO
+ constraints.addLengths(((BinaryTypeDefinition) referencedType)
+ .getLengthConstraints());
} else if (referencedType instanceof InstanceIdentifierTypeDefinition) {
// TODO: instance-identifier
}
result.put(lookedUpBuilder, constraints);
- // return lookedUpBuilder;
return result;
}
}
*
* @param modules
* all available modules
- * @param builder
+ * @param module
* current module
*/
private void resolveAugments(
Map<String, TreeMap<Date, ModuleBuilder>> modules,
- ModuleBuilder builder) {
- Set<AugmentationSchemaBuilder> augmentBuilders = builder
+ ModuleBuilder module) {
+ Set<AugmentationSchemaBuilder> augmentBuilders = module
.getAddedAugments();
Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();
prefix = pathPart.getPrefix();
augmentTargetPath.add(pathPart.getLocalName());
}
- ModuleImport dependentModuleImport = getModuleImport(builder,
+ ModuleImport dependentModuleImport = getModuleImport(module,
prefix);
String dependentModuleName = dependentModuleImport.getModuleName();
augmentTargetPath.add(0, dependentModuleName);
fillAugmentTarget(augmentBuilder, (ChildNodeBuilder) augmentTarget);
augments.add(result);
}
- builder.setAugmentations(augments);
+ module.setAugmentations(augments);
}
/**
* Helper method for resolving special 'min' or 'max' values in range
* constraint
*
- * @param ranges
- * ranges to resolve
- * @param typeToResolve
- * type to resolve
- * @param targetType
- * target type
- * @param modules
- * all available modules
- * @param builder
- * current module
+ * @param ranges ranges to resolve
+ * @param targetType target type
+ * @param modules all available modules
+ * @param builder current module
*/
private void resolveRanges(List<RangeConstraint> ranges,
- TypeAwareBuilder typeToResolve, TypeDefinitionBuilder targetType,
+ TypeDefinitionBuilder targetType,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder builder) {
if (ranges != null && ranges.size() > 0) {
Long max = (Long) ranges.get(ranges.size() - 1).getMax();
// if range contains one of the special values 'min' or 'max'
if (min.equals(Long.MIN_VALUE) || max.equals(Long.MAX_VALUE)) {
- Long[] values = parseRangeConstraint(typeToResolve, targetType,
- modules, builder);
+ Long[] values = parseRangeConstraint(targetType, modules,
+ builder);
if (min.equals(Long.MIN_VALUE)) {
min = values[0];
RangeConstraint oldFirst = ranges.get(0);
* Helper method for resolving special 'min' or 'max' values in length
* constraint
*
- * @param ranges
- * ranges to resolve
- * @param typeToResolve
- * type to resolve
- * @param targetType
- * target type
- * @param modules
- * all available modules
- * @param builder
- * current module
+ * @param lengths lengths to resolve
+ * @param targetType target type
+ * @param modules all available modules
+ * @param builder current module
*/
private void resolveLengths(List<LengthConstraint> lengths,
- TypeAwareBuilder typeToResolve, TypeDefinitionBuilder targetType,
+ TypeDefinitionBuilder targetType,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder builder) {
if (lengths != null && lengths.size() > 0) {
Long max = lengths.get(lengths.size() - 1).getMax();
// if length contains one of the special values 'min' or 'max'
if (min.equals(Long.MIN_VALUE) || max.equals(Long.MAX_VALUE)) {
- Long[] values = parseRangeConstraint(typeToResolve, targetType,
- modules, builder);
+ Long[] values = parseRangeConstraint(targetType, modules,
+ builder);
if (min.equals(Long.MIN_VALUE)) {
min = values[0];
LengthConstraint oldFirst = lengths.get(0);
}
}
- private Long[] parseRangeConstraint(TypeAwareBuilder typeToResolve,
- TypeDefinitionBuilder targetType,
+ private Long[] parseRangeConstraint(TypeDefinitionBuilder targetType,
Map<String, TreeMap<Date, ModuleBuilder>> modules,
ModuleBuilder builder) {
TypeDefinition<?> targetBaseType = targetType.getBaseType();
Long max = (Long) ranges.get(ranges.size() - 1).getMax();
return new Long[] { min, max };
} else {
- return parseRangeConstraint(typeToResolve,
- findTypeDefinitionBuilder(modules, typeToResolve, builder),
- modules, builder);
+ return parseRangeConstraint(
+ findTypeDefinitionBuilder(modules,
+ (UnknownType) targetBaseType, builder), modules,
+ builder);
}
}