2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.yang.model.parser.impl;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.IOException;
14 import java.io.InputStream;
15 import java.util.ArrayList;
16 import java.util.Calendar;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
23 import java.util.TreeMap;
25 import org.antlr.v4.runtime.ANTLRInputStream;
26 import org.antlr.v4.runtime.CommonTokenStream;
27 import org.antlr.v4.runtime.tree.ParseTree;
28 import org.antlr.v4.runtime.tree.ParseTreeWalker;
29 import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
30 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
31 import org.opendaylight.controller.yang.common.QName;
32 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
33 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
34 import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
35 import org.opendaylight.controller.yang.model.api.Module;
36 import org.opendaylight.controller.yang.model.api.ModuleImport;
37 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
38 import org.opendaylight.controller.yang.model.api.RpcDefinition;
39 import org.opendaylight.controller.yang.model.api.SchemaContext;
40 import org.opendaylight.controller.yang.model.api.SchemaPath;
41 import org.opendaylight.controller.yang.model.api.TypeDefinition;
42 import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
43 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition;
44 import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
45 import org.opendaylight.controller.yang.model.api.type.InstanceIdentifierTypeDefinition;
46 import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
47 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
48 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
49 import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
50 import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
51 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
52 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
53 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;
54 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationTargetBuilder;
55 import org.opendaylight.controller.yang.model.parser.builder.api.ChildNodeBuilder;
56 import org.opendaylight.controller.yang.model.parser.builder.api.DataSchemaNodeBuilder;
57 import org.opendaylight.controller.yang.model.parser.builder.api.TypeAwareBuilder;
58 import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder;
59 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
60 import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder;
61 import org.opendaylight.controller.yang.model.util.BaseConstraints;
62 import org.opendaylight.controller.yang.model.util.BinaryType;
63 import org.opendaylight.controller.yang.model.util.BitsType;
64 import org.opendaylight.controller.yang.model.util.StringType;
65 import org.opendaylight.controller.yang.model.util.UnknownType;
66 import org.opendaylight.controller.yang.model.util.YangTypesConverter;
67 import org.slf4j.Logger;
68 import org.slf4j.LoggerFactory;
70 public class YangModelParserImpl implements YangModelParser {
72 private static final Logger logger = LoggerFactory
73 .getLogger(YangModelParserImpl.class);
76 public Module parseYangModel(String yangFile) {
77 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFile);
78 Set<Module> result = build(modules);
79 return result.iterator().next();
83 public Set<Module> parseYangModels(String... yangFiles) {
84 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFiles);
85 Set<Module> result = build(modules);
90 public Set<Module> parseYangModelsFromStreams(
91 InputStream... yangModelStreams) {
92 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangModelStreams);
93 Set<Module> result = build(modules);
98 public SchemaContext resolveSchemaContext(Set<Module> modules) {
99 return new SchemaContextImpl(modules);
102 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
103 String... yangFiles) {
104 InputStream[] streams = new InputStream[yangFiles.length];
105 for(int i = 0; i < yangFiles.length; i++) {
106 final String yangFileName = yangFiles[i];
107 final File yangFile = new File(yangFileName);
108 FileInputStream inStream = null;
110 inStream = new FileInputStream(yangFile);
111 } catch(FileNotFoundException e) {
112 logger.warn("Exception while reading yang stream: " + inStream, e);
114 streams[i] = inStream;
116 return resolveModuleBuildersFromStreams(streams);
119 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
120 InputStream... yangFiles) {
121 final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
123 final YangModelParserListenerImpl yangModelParser = new YangModelParserListenerImpl();
124 final ParseTreeWalker walker = new ParseTreeWalker();
126 List<ParseTree> trees = parseStreams(yangFiles);
128 ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
130 for (int i = 0; i < trees.size(); i++) {
131 walker.walk(yangModelParser, trees.get(i));
132 builders[i] = yangModelParser.getModuleBuilder();
135 for (ModuleBuilder builder : builders) {
136 final String builderName = builder.getName();
137 Date builderRevision = builder.getRevision();
138 if (builderRevision == null) {
139 builderRevision = createEpochTime();
142 TreeMap<Date, ModuleBuilder> builderByRevision = modules
144 if (builderByRevision == null) {
145 builderByRevision = new TreeMap<Date, ModuleBuilder>();
147 builderByRevision.put(builderRevision, builder);
149 modules.put(builderName, builderByRevision);
154 private List<ParseTree> parseStreams(InputStream... yangStreams) {
155 List<ParseTree> trees = new ArrayList<ParseTree>();
156 for (InputStream yangStream : yangStreams) {
157 trees.add(parseStream(yangStream));
162 private ParseTree parseStream(InputStream yangStream) {
163 ParseTree result = null;
165 final ANTLRInputStream input = new ANTLRInputStream(yangStream);
166 final YangLexer lexer = new YangLexer(input);
167 final CommonTokenStream tokens = new CommonTokenStream(lexer);
168 final YangParser parser = new YangParser(tokens);
169 result = parser.yang();
170 } catch (IOException e) {
171 logger.warn("Exception while reading yang file: " + yangStream, e);
176 private Set<Module> build(Map<String, TreeMap<Date, ModuleBuilder>> modules) {
178 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
180 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
182 ModuleBuilder moduleBuilder = childEntry.getValue();
183 validateBuilder(modules, moduleBuilder);
187 final Set<Module> result = new HashSet<Module>();
188 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
190 final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
191 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
193 ModuleBuilder moduleBuilder = childEntry.getValue();
194 modulesByRevision.put(childEntry.getKey(),
195 moduleBuilder.build());
196 result.add(moduleBuilder.build());
203 private void validateBuilder(
204 Map<String, TreeMap<Date, ModuleBuilder>> modules,
205 ModuleBuilder builder) {
206 resolveTypedefs(modules, builder);
207 resolveAugments(modules, builder);
211 * Search for dirty nodes (node which contains UnknownType) and resolve
215 * all available modules
219 private void resolveTypedefs(
220 Map<String, TreeMap<Date, ModuleBuilder>> modules,
221 ModuleBuilder module) {
222 Map<List<String>, TypeAwareBuilder> dirtyNodes = module
224 if (dirtyNodes.size() == 0) {
227 for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
229 TypeAwareBuilder typeToResolve = entry.getValue();
231 if (typeToResolve instanceof UnionTypeBuilder) {
232 resolveUnionTypeBuilder(modules, module,
233 (UnionTypeBuilder) typeToResolve);
235 UnknownType ut = (UnknownType) typeToResolve.getType();
236 TypeDefinition<?> resolvedType = findTargetType(ut,
238 typeToResolve.setType(resolvedType);
244 private UnionTypeBuilder resolveUnionTypeBuilder(
245 Map<String, TreeMap<Date, ModuleBuilder>> modules,
246 ModuleBuilder builder, UnionTypeBuilder unionTypeBuilderToResolve) {
248 List<TypeDefinition<?>> resolvedTypes = new ArrayList<TypeDefinition<?>>();
249 List<TypeDefinition<?>> typesToRemove = new ArrayList<TypeDefinition<?>>();
251 for (TypeDefinition<?> td : unionTypeBuilderToResolve.getTypes()) {
252 if (td instanceof UnknownType) {
253 TypeDefinition<?> resolvedType = findTargetType(
254 (UnknownType) td, modules, builder);
255 resolvedTypes.add(resolvedType);
256 typesToRemove.add(td);
260 List<TypeDefinition<?>> unionTypeBuilderTypes = unionTypeBuilderToResolve
262 unionTypeBuilderTypes.addAll(resolvedTypes);
263 unionTypeBuilderTypes.removeAll(typesToRemove);
265 return unionTypeBuilderToResolve;
268 private TypeDefinition<?> findTargetType(UnknownType ut,
269 Map<String, TreeMap<Date, ModuleBuilder>> modules,
270 ModuleBuilder builder) {
272 Map<TypeDefinitionBuilder, TypeConstraints> foundedTypeDefinitionBuilder = findTypeDefinitionBuilderWithConstraints(
273 modules, ut, builder);
274 TypeDefinitionBuilder targetType = foundedTypeDefinitionBuilder
275 .entrySet().iterator().next().getKey();
276 TypeConstraints constraints = foundedTypeDefinitionBuilder.entrySet()
277 .iterator().next().getValue();
279 TypeDefinition<?> targetTypeBaseType = targetType.getBaseType();
280 String targetTypeBaseTypeName = targetTypeBaseType.getQName()
284 List<RangeConstraint> ranges = ut.getRangeStatements();
285 resolveRanges(ranges, targetType, modules, builder);
288 List<LengthConstraint> lengths = ut.getLengthStatements();
289 resolveLengths(lengths, targetType, modules, builder);
292 List<PatternConstraint> patterns = ut.getPatterns();
295 Integer fractionDigits = ut.getFractionDigits();
297 // MERGE CONSTRAINTS (enumeration and leafref omitted
299 // they have no restrictions)
300 if (targetTypeBaseType instanceof DecimalTypeDefinition) {
301 List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
302 fullRanges.addAll(constraints.getRanges());
303 fullRanges.addAll(ranges);
304 Integer fd = fractionDigits == null ? constraints
305 .getFractionDigits() : fractionDigits;
306 targetTypeBaseType = YangTypesConverter
307 .javaTypeForBaseYangDecimal64Type(fullRanges, fd);
308 } else if (targetTypeBaseType instanceof IntegerTypeDefinition) {
309 List<RangeConstraint> fullRanges = new ArrayList<RangeConstraint>();
310 fullRanges.addAll(constraints.getRanges());
311 fullRanges.addAll(ranges);
312 if (targetTypeBaseTypeName.startsWith("int")) {
313 targetTypeBaseType = YangTypesConverter
314 .javaTypeForBaseYangSignedIntegerType(
315 targetTypeBaseTypeName, fullRanges);
317 targetTypeBaseType = YangTypesConverter
318 .javaTypeForBaseYangUnsignedIntegerType(
319 targetTypeBaseTypeName, fullRanges);
321 } else if (targetTypeBaseType instanceof StringTypeDefinition) {
322 List<LengthConstraint> fullLengths = new ArrayList<LengthConstraint>();
323 fullLengths.addAll(constraints.getLengths());
324 fullLengths.addAll(lengths);
325 List<PatternConstraint> fullPatterns = new ArrayList<PatternConstraint>();
326 fullPatterns.addAll(constraints.getPatterns());
327 fullPatterns.addAll(patterns);
328 targetTypeBaseType = new StringType(fullLengths, fullPatterns);
329 } else if (targetTypeBaseType instanceof BitsTypeDefinition) {
330 BitsTypeDefinition bitsType = (BitsTypeDefinition) targetTypeBaseType;
331 List<Bit> bits = bitsType.getBits();
332 targetTypeBaseType = new BitsType(bits);
333 } else if (targetTypeBaseType instanceof BinaryTypeDefinition) {
334 targetTypeBaseType = new BinaryType(null, lengths, null);
335 } else if (targetTypeBaseTypeName.equals("instance-identifier")) {
336 // TODO: instance-identifier
338 * boolean requireInstance = isRequireInstance(typeBody); type = new
339 * InstanceIdentifier(null, requireInstance);
343 return targetTypeBaseType;
346 private TypeDefinitionBuilder findTypeDefinitionBuilder(
347 Map<String, TreeMap<Date, ModuleBuilder>> modules,
348 UnknownType unknownType, ModuleBuilder builder) {
349 Map<TypeDefinitionBuilder, TypeConstraints> result = findTypeDefinitionBuilderWithConstraints(
350 modules, unknownType, builder);
351 return result.entrySet().iterator().next().getKey();
354 private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
355 Map<String, TreeMap<Date, ModuleBuilder>> modules,
356 UnknownType unknownType, ModuleBuilder builder) {
357 return findTypeDefinitionBuilderWithConstraints(new TypeConstraints(),
358 modules, unknownType, builder);
362 * Traverse through all referenced types chain until base YANG type is
365 * @param constraints current type constraints
366 * @param modules all available modules
367 * @param unknownType unknown type
368 * @param builder current module
369 * @return map, where key is type referenced and value is its constraints
371 private Map<TypeDefinitionBuilder, TypeConstraints> findTypeDefinitionBuilderWithConstraints(
372 TypeConstraints constraints,
373 Map<String, TreeMap<Date, ModuleBuilder>> modules,
374 UnknownType unknownType, ModuleBuilder builder) {
375 Map<TypeDefinitionBuilder, TypeConstraints> result = new HashMap<TypeDefinitionBuilder, TypeConstraints>();
377 // TypeDefinition<?> unknownType = typeBuilder.getType();
378 QName unknownTypeQName = unknownType.getQName();
379 String unknownTypeName = unknownTypeQName.getLocalName();
380 String unknownTypePrefix = unknownTypeQName.getPrefix();
382 // search for module which contains referenced typedef
383 ModuleBuilder dependentModuleBuilder;
384 if (unknownTypePrefix.equals(builder.getPrefix())) {
385 dependentModuleBuilder = builder;
387 ModuleImport dependentModuleImport = getModuleImport(builder,
389 String dependentModuleName = dependentModuleImport.getModuleName();
390 Date dependentModuleRevision = dependentModuleImport.getRevision();
391 TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
392 .get(dependentModuleName);
393 if (dependentModuleRevision == null) {
394 dependentModuleBuilder = moduleBuildersByRevision.lastEntry()
397 dependentModuleBuilder = moduleBuildersByRevision
398 .get(dependentModuleRevision);
402 // pull all typedef statements from dependent module...
403 final Set<TypeDefinitionBuilder> typedefs = dependentModuleBuilder
404 .getModuleTypedefs();
405 // and search for referenced typedef
406 TypeDefinitionBuilder lookedUpBuilder = null;
407 for (TypeDefinitionBuilder tdb : typedefs) {
408 QName qname = tdb.getQName();
409 if (qname.getLocalName().equals(unknownTypeName)) {
410 lookedUpBuilder = tdb;
415 // if referenced type is UnknownType again, search recursively with
416 // current constraints
417 TypeDefinition<?> referencedType = lookedUpBuilder.getBaseType();
418 if (referencedType instanceof UnknownType) {
419 UnknownType unknown = (UnknownType) lookedUpBuilder.getBaseType();
421 final List<RangeConstraint> ranges = unknown.getRangeStatements();
422 constraints.addRanges(ranges);
423 final List<LengthConstraint> lengths = unknown
424 .getLengthStatements();
425 constraints.addLengths(lengths);
426 final List<PatternConstraint> patterns = unknown.getPatterns();
427 constraints.addPatterns(patterns);
428 return findTypeDefinitionBuilderWithConstraints(constraints,
429 modules, unknown, dependentModuleBuilder);
431 // pull restriction from this base type and add them to
433 if (referencedType instanceof DecimalTypeDefinition) {
434 constraints.addRanges(((DecimalTypeDefinition) referencedType)
435 .getRangeStatements());
437 .setFractionDigits(((DecimalTypeDefinition) referencedType)
438 .getFractionDigits());
439 } else if (referencedType instanceof IntegerTypeDefinition) {
440 constraints.addRanges(((IntegerTypeDefinition) referencedType)
441 .getRangeStatements());
442 } else if (referencedType instanceof StringTypeDefinition) {
443 constraints.addPatterns(((StringTypeDefinition) referencedType)
445 } else if (referencedType instanceof BinaryTypeDefinition) {
446 constraints.addLengths(((BinaryTypeDefinition) referencedType)
447 .getLengthConstraints());
448 } else if (referencedType instanceof InstanceIdentifierTypeDefinition) {
449 // TODO: instance-identifier
452 result.put(lookedUpBuilder, constraints);
458 * Go through all augmentation definitions and resolve them. This means find
459 * referenced node and add child nodes to it.
462 * all available modules
466 private void resolveAugments(
467 Map<String, TreeMap<Date, ModuleBuilder>> modules,
468 ModuleBuilder module) {
469 Set<AugmentationSchemaBuilder> augmentBuilders = module
472 Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();
473 for (AugmentationSchemaBuilder augmentBuilder : augmentBuilders) {
474 SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
475 String prefix = null;
476 List<String> augmentTargetPath = new ArrayList<String>();
477 for (QName pathPart : augmentTargetSchemaPath.getPath()) {
478 prefix = pathPart.getPrefix();
479 augmentTargetPath.add(pathPart.getLocalName());
481 ModuleImport dependentModuleImport = getModuleImport(module,
483 String dependentModuleName = dependentModuleImport.getModuleName();
484 augmentTargetPath.add(0, dependentModuleName);
486 Date dependentModuleRevision = dependentModuleImport.getRevision();
488 TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
489 .get(dependentModuleName);
490 ModuleBuilder dependentModule;
491 if (dependentModuleRevision == null) {
492 dependentModule = moduleBuildersByRevision.lastEntry()
495 dependentModule = moduleBuildersByRevision
496 .get(dependentModuleRevision);
499 AugmentationTargetBuilder augmentTarget = (AugmentationTargetBuilder) dependentModule
500 .getNode(augmentTargetPath);
501 AugmentationSchema result = augmentBuilder.build();
502 augmentTarget.addAugmentation(result);
503 fillAugmentTarget(augmentBuilder, (ChildNodeBuilder) augmentTarget);
504 augments.add(result);
506 module.setAugmentations(augments);
510 * Add all augment's child nodes to given target.
515 private void fillAugmentTarget(AugmentationSchemaBuilder augment,
516 ChildNodeBuilder target) {
517 for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
518 builder.setAugmenting(true);
519 target.addChildNode(builder);
524 * Get module import referenced by given prefix.
529 * prefix associated with import
530 * @return ModuleImport based on given prefix
532 private ModuleImport getModuleImport(ModuleBuilder builder, String prefix) {
533 ModuleImport moduleImport = null;
534 for (ModuleImport mi : builder.getModuleImports()) {
535 if (mi.getPrefix().equals(prefix)) {
544 * Helper method for resolving special 'min' or 'max' values in range
547 * @param ranges ranges to resolve
548 * @param targetType target type
549 * @param modules all available modules
550 * @param builder current module
552 private void resolveRanges(List<RangeConstraint> ranges,
553 TypeDefinitionBuilder targetType,
554 Map<String, TreeMap<Date, ModuleBuilder>> modules,
555 ModuleBuilder builder) {
556 if (ranges != null && ranges.size() > 0) {
557 Long min = (Long) ranges.get(0).getMin();
558 Long max = (Long) ranges.get(ranges.size() - 1).getMax();
559 // if range contains one of the special values 'min' or 'max'
560 if (min.equals(Long.MIN_VALUE) || max.equals(Long.MAX_VALUE)) {
561 Long[] values = parseRangeConstraint(targetType, modules,
563 if (min.equals(Long.MIN_VALUE)) {
565 RangeConstraint oldFirst = ranges.get(0);
566 RangeConstraint newFirst = BaseConstraints.rangeConstraint(
567 min, oldFirst.getMax(), oldFirst.getDescription(),
568 oldFirst.getReference());
569 ranges.set(0, newFirst);
571 if (max.equals(Long.MAX_VALUE)) {
573 RangeConstraint oldLast = ranges.get(ranges.size() - 1);
574 RangeConstraint newLast = BaseConstraints.rangeConstraint(
575 oldLast.getMin(), max, oldLast.getDescription(),
576 oldLast.getReference());
577 ranges.set(ranges.size() - 1, newLast);
584 * Helper method for resolving special 'min' or 'max' values in length
587 * @param lengths lengths to resolve
588 * @param targetType target type
589 * @param modules all available modules
590 * @param builder current module
592 private void resolveLengths(List<LengthConstraint> lengths,
593 TypeDefinitionBuilder targetType,
594 Map<String, TreeMap<Date, ModuleBuilder>> modules,
595 ModuleBuilder builder) {
596 if (lengths != null && lengths.size() > 0) {
597 Long min = lengths.get(0).getMin();
598 Long max = lengths.get(lengths.size() - 1).getMax();
599 // if length contains one of the special values 'min' or 'max'
600 if (min.equals(Long.MIN_VALUE) || max.equals(Long.MAX_VALUE)) {
601 Long[] values = parseRangeConstraint(targetType, modules,
603 if (min.equals(Long.MIN_VALUE)) {
605 LengthConstraint oldFirst = lengths.get(0);
606 LengthConstraint newFirst = BaseConstraints
607 .lengthConstraint(min, oldFirst.getMax(),
608 oldFirst.getDescription(),
609 oldFirst.getReference());
610 lengths.set(0, newFirst);
612 if (max.equals(Long.MAX_VALUE)) {
614 LengthConstraint oldLast = lengths.get(lengths.size() - 1);
615 LengthConstraint newLast = BaseConstraints
616 .lengthConstraint(oldLast.getMin(), max,
617 oldLast.getDescription(),
618 oldLast.getReference());
619 lengths.set(lengths.size() - 1, newLast);
625 private Long[] parseRangeConstraint(TypeDefinitionBuilder targetType,
626 Map<String, TreeMap<Date, ModuleBuilder>> modules,
627 ModuleBuilder builder) {
628 TypeDefinition<?> targetBaseType = targetType.getBaseType();
630 if (targetBaseType instanceof IntegerTypeDefinition) {
631 IntegerTypeDefinition itd = (IntegerTypeDefinition) targetBaseType;
632 List<RangeConstraint> ranges = itd.getRangeStatements();
633 Long min = (Long) ranges.get(0).getMin();
634 Long max = (Long) ranges.get(ranges.size() - 1).getMax();
635 return new Long[] { min, max };
636 } else if (targetBaseType instanceof DecimalTypeDefinition) {
637 DecimalTypeDefinition dtd = (DecimalTypeDefinition) targetBaseType;
638 List<RangeConstraint> ranges = dtd.getRangeStatements();
639 Long min = (Long) ranges.get(0).getMin();
640 Long max = (Long) ranges.get(ranges.size() - 1).getMax();
641 return new Long[] { min, max };
643 return parseRangeConstraint(
644 findTypeDefinitionBuilder(modules,
645 (UnknownType) targetBaseType, builder), modules,
650 private Date createEpochTime() {
651 Calendar c = Calendar.getInstance();
652 c.setTimeInMillis(0);
656 private static class SchemaContextImpl implements SchemaContext {
657 private final Set<Module> modules;
659 private SchemaContextImpl(Set<Module> modules) {
660 this.modules = modules;
664 public Set<DataSchemaNode> getDataDefinitions() {
665 final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
666 for (Module m : modules) {
667 dataDefs.addAll(m.getChildNodes());
673 public Set<Module> getModules() {
678 public Set<NotificationDefinition> getNotifications() {
679 final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
680 for (Module m : modules) {
681 notifications.addAll(m.getNotifications());
683 return notifications;
687 public Set<RpcDefinition> getOperations() {
688 final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
689 for (Module m : modules) {
690 rpcs.addAll(m.getRpcs());
696 public Set<ExtensionDefinition> getExtensions() {
697 final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
698 for (Module m : modules) {
699 extensions.addAll(m.getExtensionSchemaNodes());
705 private static class TypeConstraints {
706 private final List<RangeConstraint> ranges = new ArrayList<RangeConstraint>();
707 private final List<LengthConstraint> lengths = new ArrayList<LengthConstraint>();
708 private final List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
709 private Integer fractionDigits;
711 public List<RangeConstraint> getRanges() {
715 public void addRanges(List<RangeConstraint> ranges) {
716 this.ranges.addAll(0, ranges);
719 public List<LengthConstraint> getLengths() {
723 public void addLengths(List<LengthConstraint> lengths) {
724 this.lengths.addAll(0, lengths);
727 public List<PatternConstraint> getPatterns() {
731 public void addPatterns(List<PatternConstraint> patterns) {
732 this.patterns.addAll(0, patterns);
735 public Integer getFractionDigits() {
736 return fractionDigits;
739 public void setFractionDigits(Integer fractionDigits) {
740 if (fractionDigits != null) {
741 this.fractionDigits = fractionDigits;