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;
16 import java.util.ArrayList;
17 import java.util.Calendar;
18 import java.util.Date;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
24 import java.util.TreeMap;
26 import org.antlr.v4.runtime.ANTLRInputStream;
27 import org.antlr.v4.runtime.CommonTokenStream;
28 import org.antlr.v4.runtime.tree.ParseTree;
29 import org.antlr.v4.runtime.tree.ParseTreeWalker;
30 import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
31 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
32 import org.opendaylight.controller.yang.common.QName;
33 import org.opendaylight.controller.yang.model.api.AugmentationSchema;
34 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
35 import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
36 import org.opendaylight.controller.yang.model.api.Module;
37 import org.opendaylight.controller.yang.model.api.ModuleImport;
38 import org.opendaylight.controller.yang.model.api.NotificationDefinition;
39 import org.opendaylight.controller.yang.model.api.RpcDefinition;
40 import org.opendaylight.controller.yang.model.api.SchemaContext;
41 import org.opendaylight.controller.yang.model.api.SchemaPath;
42 import org.opendaylight.controller.yang.model.api.TypeDefinition;
43 import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
44 import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
45 import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
46 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
47 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
48 import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
49 import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
50 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
51 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;
52 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationTargetBuilder;
53 import org.opendaylight.controller.yang.model.parser.builder.api.ChildNodeBuilder;
54 import org.opendaylight.controller.yang.model.parser.builder.api.DataSchemaNodeBuilder;
55 import org.opendaylight.controller.yang.model.parser.builder.api.TypeAwareBuilder;
56 import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder;
57 import org.opendaylight.controller.yang.model.parser.builder.impl.IdentitySchemaNodeBuilder;
58 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
59 import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;
60 import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder;
61 import org.opendaylight.controller.yang.model.parser.util.TypeConstraints;
62 import org.opendaylight.controller.yang.model.parser.util.YangParseException;
63 import org.opendaylight.controller.yang.model.util.ExtendedType;
64 import org.opendaylight.controller.yang.model.util.UnknownType;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
68 public class YangModelParserImpl implements YangModelParser {
70 private static final Logger logger = LoggerFactory
71 .getLogger(YangModelParserImpl.class);
74 public Module parseYangModel(final String yangFile) {
75 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFile);
76 final Set<Module> result = build(modules);
77 return result.iterator().next();
81 public Set<Module> parseYangModels(final String... yangFiles) {
82 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFiles);
83 return build(modules);
87 public Set<Module> parseYangModelsFromStreams(
88 final InputStream... yangModelStreams) {
89 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangModelStreams);
90 return build(modules);
94 public SchemaContext resolveSchemaContext(final Set<Module> modules) {
95 return new SchemaContextImpl(modules);
98 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
99 String... yangFiles) {
100 final InputStream[] streams = loadStreams(yangFiles);
102 if (streams != null) {
103 final Map<String, TreeMap<Date, ModuleBuilder>> result = resolveModuleBuildersFromStreams(streams);
104 cloaseStreams(streams);
106 if (result != null) {
110 return new HashMap<String, TreeMap<Date, ModuleBuilder>>();
113 private InputStream[] loadStreams(final String... yangFiles) {
114 final InputStream[] streams = new InputStream[yangFiles.length];
115 for (int i = 0; i < yangFiles.length; i++) {
116 final String yangFileName = yangFiles[i];
117 final File yangFile = new File(yangFileName);
119 streams[i] = new FileInputStream(yangFile);
120 } catch (FileNotFoundException e) {
121 logger.warn("Exception while reading yang stream: "
128 private void cloaseStreams(final InputStream[] streams) {
129 if (streams != null) {
130 for (int i = 0; i < streams.length; ++i) {
132 if (streams[i] != null) {
135 } catch (IOException e) {
136 logger.warn("Exception while closing yang stream: "
143 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
144 InputStream... yangFiles) {
145 final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
146 final ParseTreeWalker walker = new ParseTreeWalker();
147 final List<ParseTree> trees = parseStreams(yangFiles);
148 final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
151 // if validation fails with any file, do not continue and throw
\r
153 for (int i = 0; i < trees.size(); i++) {
\r
155 final YangModelValidationListener yangModelParser = new YangModelValidationListener();
\r
156 walker.walk(yangModelParser, trees.get(i));
\r
157 } catch (IllegalStateException e) {
\r
158 // wrap exception to add information about which file failed
\r
159 throw new YangValidationException(
\r
160 "Yang validation failed for file" + yangFiles[i], e);
\r
165 YangModelParserListenerImpl yangModelParser = null;
166 for (int i = 0; i < trees.size(); i++) {
167 yangModelParser = new YangModelParserListenerImpl();
168 walker.walk(yangModelParser, trees.get(i));
169 builders[i] = yangModelParser.getModuleBuilder();
172 for (ModuleBuilder builder : builders) {
173 final String builderName = builder.getName();
174 Date builderRevision = builder.getRevision();
175 if (builderRevision == null) {
176 builderRevision = createEpochTime();
178 TreeMap<Date, ModuleBuilder> builderByRevision = modules
180 if (builderByRevision == null) {
181 builderByRevision = new TreeMap<Date, ModuleBuilder>();
183 builderByRevision.put(builderRevision, builder);
184 modules.put(builderName, builderByRevision);
189 private List<ParseTree> parseStreams(InputStream... yangStreams) {
190 final List<ParseTree> trees = new ArrayList<ParseTree>();
191 for (InputStream yangStream : yangStreams) {
192 trees.add(parseStream(yangStream));
197 private ParseTree parseStream(InputStream yangStream) {
198 ParseTree result = null;
200 final ANTLRInputStream input = new ANTLRInputStream(yangStream);
201 final YangLexer lexer = new YangLexer(input);
202 final CommonTokenStream tokens = new CommonTokenStream(lexer);
203 final YangParser parser = new YangParser(tokens);
204 result = parser.yang();
205 } catch (IOException e) {
206 logger.warn("Exception while reading yang file: " + yangStream, e);
211 private Set<Module> build(Map<String, TreeMap<Date, ModuleBuilder>> modules) {
213 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
215 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
217 ModuleBuilder moduleBuilder = childEntry.getValue();
218 validateModule(modules, moduleBuilder);
223 final Set<Module> result = new HashSet<Module>();
224 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
226 final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
227 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
229 ModuleBuilder moduleBuilder = childEntry.getValue();
230 Module module = moduleBuilder.build();
231 modulesByRevision.put(childEntry.getKey(), module);
238 private void validateModule(
239 Map<String, TreeMap<Date, ModuleBuilder>> modules,
240 ModuleBuilder builder) {
241 resolveDirtyNodes(modules, builder);
242 resolveAugments(modules, builder);
243 resolveIdentities(modules, builder);
247 * Search for dirty nodes (node which contains UnknownType) and resolve
251 * all available modules
255 private void resolveDirtyNodes(
256 Map<String, TreeMap<Date, ModuleBuilder>> modules,
257 ModuleBuilder module) {
258 final Map<List<String>, TypeAwareBuilder> dirtyNodes = module
260 if (!dirtyNodes.isEmpty()) {
261 for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
264 TypeAwareBuilder typeToResolve = entry.getValue();
265 if (typeToResolve instanceof UnionTypeBuilder) {
266 UnionTypeBuilder union = (UnionTypeBuilder) typeToResolve;
267 List<TypeDefinition<?>> unionTypes = union.getTypes();
268 List<UnknownType> toRemove = new ArrayList<UnknownType>();
269 for (TypeDefinition<?> td : unionTypes) {
270 if (td instanceof UnknownType) {
271 UnknownType unknownType = (UnknownType) td;
272 TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
273 typeToResolve, unknownType, modules, module);
274 union.setType(resolvedType);
275 toRemove.add(unknownType);
278 unionTypes.removeAll(toRemove);
280 TypeDefinitionBuilder resolvedType = findTargetType(
281 typeToResolve, modules, module);
282 typeToResolve.setType(resolvedType);
288 private TypeDefinitionBuilder findTargetType(
289 TypeAwareBuilder typeToResolve,
290 Map<String, TreeMap<Date, ModuleBuilder>> modules,
291 ModuleBuilder builder) {
292 TypeConstraints constraints = new TypeConstraints();
294 TypeDefinitionBuilder targetType = findTypedef(typeToResolve, modules,
296 TypeConstraints tConstraints = findConstraints(typeToResolve,
297 constraints, modules, builder);
298 targetType.setRanges(tConstraints.getRange());
299 targetType.setLengths(tConstraints.getLength());
300 targetType.setPatterns(tConstraints.getPatterns());
301 targetType.setFractionDigits(tConstraints.getFractionDigits());
306 private TypeDefinitionBuilder findTargetTypeUnion(
307 TypeAwareBuilder typeToResolve, UnknownType unknownType,
308 Map<String, TreeMap<Date, ModuleBuilder>> modules,
309 ModuleBuilder builder) {
310 TypeConstraints constraints = new TypeConstraints();
312 TypeDefinitionBuilder targetType = findTypedefUnion(typeToResolve,
313 unknownType, modules, builder);
314 TypeConstraints tConstraints = findConstraints(typeToResolve,
315 constraints, modules, builder);
316 targetType.setRanges(tConstraints.getRange());
317 targetType.setLengths(tConstraints.getLength());
318 targetType.setPatterns(tConstraints.getPatterns());
319 targetType.setFractionDigits(tConstraints.getFractionDigits());
324 private TypeDefinitionBuilder findTypedef(TypeAwareBuilder typeToResolve,
325 Map<String, TreeMap<Date, ModuleBuilder>> modules,
326 ModuleBuilder builder) {
328 TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
329 if (baseTypeToResolve != null
330 && !(baseTypeToResolve instanceof UnknownType)) {
331 return (TypeDefinitionBuilder) typeToResolve;
334 UnknownType unknownType = (UnknownType) typeToResolve.getType();
336 QName unknownTypeQName = unknownType.getQName();
337 String unknownTypeName = unknownTypeQName.getLocalName();
338 String unknownTypePrefix = unknownTypeQName.getPrefix();
340 // search for module which contains referenced typedef
341 ModuleBuilder dependentModule = findDependentModule(modules, builder,
343 TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
344 dependentModule.getModuleTypedefs(), unknownTypeName);
346 TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
347 lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
348 TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
349 lookedUpBuilderCopy, modules, dependentModule);
353 private TypeDefinitionBuilder findTypedefUnion(
354 TypeAwareBuilder typeToResolve, UnknownType unknownType,
355 Map<String, TreeMap<Date, ModuleBuilder>> modules,
356 ModuleBuilder builder) {
358 TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
359 if (baseTypeToResolve != null
360 && !(baseTypeToResolve instanceof UnknownType)) {
361 return (TypeDefinitionBuilder) typeToResolve;
364 QName unknownTypeQName = unknownType.getQName();
365 String unknownTypeName = unknownTypeQName.getLocalName();
366 String unknownTypePrefix = unknownTypeQName.getPrefix();
368 // search for module which contains referenced typedef
369 ModuleBuilder dependentModule = findDependentModule(modules, builder,
371 TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
372 dependentModule.getModuleTypedefs(), unknownTypeName);
374 TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
375 lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
376 TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
377 lookedUpBuilderCopy, modules, dependentModule);
381 private TypeDefinitionBuilder copyTypedefBuilder(TypeDefinitionBuilder old,
382 boolean seekByTypedefBuilder) {
383 if (old instanceof UnionTypeBuilder) {
384 UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
385 UnionTypeBuilder newUnion = new UnionTypeBuilder();
386 for (TypeDefinition<?> td : oldUnion.getTypes()) {
387 newUnion.setType(td);
389 for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
390 newUnion.setType(copyTypedefBuilder(tdb, true));
395 QName oldQName = old.getQName();
396 QName newQName = new QName(oldQName.getNamespace(),
397 oldQName.getRevision(), oldQName.getPrefix(),
398 oldQName.getLocalName());
399 TypeDefinitionBuilder tdb = new TypedefBuilder(newQName);
401 tdb.setRanges(old.getRanges());
402 tdb.setLengths(old.getLengths());
403 tdb.setPatterns(old.getPatterns());
405 TypeDefinition<?> oldType = old.getType();
406 if (oldType == null) {
407 tdb.setType(old.getTypedef());
409 tdb.setType(oldType);
412 if (!seekByTypedefBuilder) {
413 tdb.setDescription(old.getDescription());
414 tdb.setReference(old.getReference());
415 tdb.setStatus(old.getStatus());
416 tdb.setDefaultValue(old.getDefaultValue());
417 tdb.setUnits(old.getUnits());
422 private TypeDefinitionBuilder resolveCopiedBuilder(
423 TypeDefinitionBuilder copied,
424 Map<String, TreeMap<Date, ModuleBuilder>> modules,
425 ModuleBuilder builder) {
427 if (copied instanceof UnionTypeBuilder) {
428 UnionTypeBuilder union = (UnionTypeBuilder) copied;
429 List<TypeDefinition<?>> unionTypes = union.getTypes();
430 List<UnknownType> toRemove = new ArrayList<UnknownType>();
431 for (TypeDefinition<?> td : unionTypes) {
432 if (td instanceof UnknownType) {
433 UnknownType unknownType = (UnknownType) td;
434 TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
435 union, unknownType, modules, builder);
436 union.setType(resolvedType);
437 toRemove.add(unknownType);
440 unionTypes.removeAll(toRemove);
445 TypeDefinition<?> base = copied.getType();
446 TypeDefinitionBuilder baseTdb = copied.getTypedef();
447 if (base != null && !(base instanceof UnknownType)) {
449 } else if (base instanceof UnknownType) {
450 UnknownType unknownType = (UnknownType) base;
451 QName unknownTypeQName = unknownType.getQName();
452 String unknownTypePrefix = unknownTypeQName.getPrefix();
453 ModuleBuilder dependentModule = findDependentModule(modules,
454 builder, unknownTypePrefix);
455 TypeDefinitionBuilder unknownTypeBuilder = findTypedef(copied,
456 modules, dependentModule);
457 copied.setType(unknownTypeBuilder);
459 } else if (base == null && baseTdb != null) {
460 // make a copy of baseTypeDef and call again
461 TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder(baseTdb,
463 TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
464 baseTdbCopy, modules, builder);
465 copied.setType(baseTdbCopyResolved);
468 throw new IllegalStateException(
469 "TypeDefinitionBuilder in unexpected state");
473 private TypeDefinitionBuilder findTypedef(QName unknownTypeQName,
474 Map<String, TreeMap<Date, ModuleBuilder>> modules,
475 ModuleBuilder builder) {
477 String unknownTypeName = unknownTypeQName.getLocalName();
478 String unknownTypePrefix = unknownTypeQName.getPrefix();
480 // search for module which contains referenced typedef
481 ModuleBuilder dependentModule = findDependentModule(modules, builder,
484 TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
485 dependentModule.getModuleTypedefs(), unknownTypeName);
487 TypeDefinitionBuilder copied = copyTypedefBuilder(lookedUpBuilder, true);
491 private TypeConstraints findConstraints(TypeAwareBuilder typeToResolve,
492 TypeConstraints constraints,
493 Map<String, TreeMap<Date, ModuleBuilder>> modules,
494 ModuleBuilder builder) {
496 // union type cannot be restricted
497 if (typeToResolve instanceof UnionTypeBuilder) {
501 // if referenced type is UnknownType again, search recursively with
502 // current constraints
503 TypeDefinition<?> referencedType = typeToResolve.getType();
504 if (referencedType == null) {
505 TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) typeToResolve;
506 final List<RangeConstraint> ranges = tdb.getRanges();
507 constraints.addRanges(ranges);
508 final List<LengthConstraint> lengths = tdb.getLengths();
509 constraints.addLengths(lengths);
510 final List<PatternConstraint> patterns = tdb.getPatterns();
511 constraints.addPatterns(patterns);
512 final Integer fractionDigits = tdb.getFractionDigits();
513 constraints.setFractionDigits(fractionDigits);
515 } else if (referencedType instanceof ExtendedType) {
516 ExtendedType ext = (ExtendedType) referencedType;
517 final List<RangeConstraint> ranges = ext.getRanges();
518 constraints.addRanges(ranges);
519 final List<LengthConstraint> lengths = ext.getLengths();
520 constraints.addLengths(lengths);
521 final List<PatternConstraint> patterns = ext.getPatterns();
522 constraints.addPatterns(patterns);
523 final Integer fractionDigits = ext.getFractionDigits();
524 constraints.setFractionDigits(fractionDigits);
525 return findConstraints(
526 findTypedef(ext.getQName(), modules, builder), constraints,
528 } else if (referencedType instanceof UnknownType) {
529 UnknownType unknown = (UnknownType) referencedType;
531 final List<RangeConstraint> ranges = unknown.getRangeStatements();
532 constraints.addRanges(ranges);
533 final List<LengthConstraint> lengths = unknown
534 .getLengthStatements();
535 constraints.addLengths(lengths);
536 final List<PatternConstraint> patterns = unknown.getPatterns();
537 constraints.addPatterns(patterns);
538 final Integer fractionDigits = unknown.getFractionDigits();
539 constraints.setFractionDigits(fractionDigits);
541 String unknownTypePrefix = unknown.getQName().getPrefix();
542 if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) {
543 unknownTypePrefix = builder.getPrefix();
545 ModuleBuilder dependentModule = findDependentModule(modules,
546 builder, unknown.getQName().getPrefix());
547 TypeDefinitionBuilder unknownTypeBuilder = findTypedef(
548 unknown.getQName(), modules, builder);
549 return findConstraints(unknownTypeBuilder, constraints, modules,
552 // HANDLE BASE YANG TYPE
553 mergeConstraints(referencedType, constraints);
560 * Go through all typedef statements from given module and search for one
564 * typedef statements to search
566 * name of searched typedef
567 * @return typedef with name equals to given name
569 private TypeDefinitionBuilder findTypedefBuilder(
570 Set<TypeDefinitionBuilder> typedefs, String name) {
571 TypeDefinitionBuilder result = null;
572 for (TypeDefinitionBuilder td : typedefs) {
573 if (td.getQName().getLocalName().equals(name)) {
578 if (result == null) {
579 throw new YangParseException(
580 "Target module does not contain typedef '" + name + "'.");
586 * Pull restriction from referenced type and add them to given constraints
588 * @param referencedType
591 private void mergeConstraints(TypeDefinition<?> referencedType,
592 TypeConstraints constraints) {
594 if (referencedType instanceof DecimalTypeDefinition) {
595 constraints.addRanges(((DecimalTypeDefinition) referencedType)
596 .getRangeStatements());
598 .setFractionDigits(((DecimalTypeDefinition) referencedType)
599 .getFractionDigits());
600 } else if (referencedType instanceof IntegerTypeDefinition) {
601 constraints.addRanges(((IntegerTypeDefinition) referencedType)
602 .getRangeStatements());
603 } else if (referencedType instanceof StringTypeDefinition) {
604 constraints.addPatterns(((StringTypeDefinition) referencedType)
606 constraints.addLengths(((StringTypeDefinition) referencedType)
607 .getLengthStatements());
608 } else if (referencedType instanceof BinaryTypeDefinition) {
609 constraints.addLengths(((BinaryTypeDefinition) referencedType)
610 .getLengthConstraints());
615 * Go through all augmentation definitions and resolve them. This means find
616 * referenced node and add child nodes to it.
619 * all available modules
623 private void resolveAugments(
624 Map<String, TreeMap<Date, ModuleBuilder>> modules,
625 ModuleBuilder module) {
626 Set<AugmentationSchemaBuilder> augmentBuilders = module
629 Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();
630 for (AugmentationSchemaBuilder augmentBuilder : augmentBuilders) {
631 SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
632 String prefix = null;
633 List<String> augmentTargetPath = new ArrayList<String>();
635 for (QName pathPart : augmentTargetSchemaPath.getPath()) {
636 prefix = pathPart.getPrefix();
637 augmentTargetPath.add(pathPart.getLocalName());
639 ModuleBuilder dependentModule = findDependentModule(modules,
641 augmentTargetPath.add(0, dependentModule.getName());
643 AugmentationTargetBuilder augmentTarget = (AugmentationTargetBuilder) dependentModule
644 .getNode(augmentTargetPath);
645 AugmentationSchema result = augmentBuilder.build();
646 augmentTarget.addAugmentation(result);
647 fillAugmentTarget(augmentBuilder, (ChildNodeBuilder) augmentTarget);
648 augments.add(result);
650 module.setAugmentations(augments);
654 * Add all augment's child nodes to given target.
659 private void fillAugmentTarget(AugmentationSchemaBuilder augment,
660 ChildNodeBuilder target) {
661 for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
662 builder.setAugmenting(true);
663 target.addChildNode(builder);
668 * Go through identity statements defined in current module and resolve
669 * their 'base' statement if present.
674 * module being resolved
676 private void resolveIdentities(
677 Map<String, TreeMap<Date, ModuleBuilder>> modules,
678 ModuleBuilder module) {
679 Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
680 for (IdentitySchemaNodeBuilder identity : identities) {
681 String baseIdentityName = identity.getBaseIdentityName();
682 if (baseIdentityName != null) {
683 String baseIdentityPrefix = null;
684 String baseIdentityLocalName = null;
685 if (baseIdentityName.contains(":")) {
686 String[] splitted = baseIdentityName.split(":");
687 baseIdentityPrefix = splitted[0];
688 baseIdentityLocalName = splitted[1];
690 baseIdentityPrefix = module.getPrefix();
691 baseIdentityLocalName = baseIdentityName;
693 ModuleBuilder dependentModule = findDependentModule(modules,
694 module, baseIdentityPrefix);
696 Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule
697 .getAddedIdentities();
698 for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
699 if (idBuilder.getQName().getLocalName()
700 .equals(baseIdentityLocalName)) {
701 identity.setBaseIdentity(idBuilder);
709 * Find dependent module based on given prefix
712 * all available modules
716 * target module prefix
719 private ModuleBuilder findDependentModule(
720 Map<String, TreeMap<Date, ModuleBuilder>> modules,
721 ModuleBuilder module, String prefix) {
722 ModuleBuilder dependentModule = null;
723 Date dependentModuleRevision = null;
725 if (prefix.equals(module.getPrefix())) {
726 dependentModule = module;
728 ModuleImport dependentModuleImport = getModuleImport(module, prefix);
729 if (dependentModuleImport == null) {
730 throw new YangParseException("No import found with prefix '"
731 + prefix + "' in module " + module.getName() + "'.");
733 String dependentModuleName = dependentModuleImport.getModuleName();
734 dependentModuleRevision = dependentModuleImport.getRevision();
736 TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
737 .get(dependentModuleName);
738 if (dependentModuleRevision == null) {
739 dependentModule = moduleBuildersByRevision.lastEntry()
742 dependentModule = moduleBuildersByRevision
743 .get(dependentModuleRevision);
747 if (dependentModule == null) {
748 throw new YangParseException(
749 "Failed to find dependent module with prefix '" + prefix
750 + "' and revision '" + dependentModuleRevision
753 return dependentModule;
757 * Get module import referenced by given prefix.
762 * prefix associated with import
763 * @return ModuleImport based on given prefix
765 private ModuleImport getModuleImport(ModuleBuilder builder, String prefix) {
766 ModuleImport moduleImport = null;
767 for (ModuleImport mi : builder.getModuleImports()) {
768 if (mi.getPrefix().equals(prefix)) {
776 private Date createEpochTime() {
777 Calendar calendar = Calendar.getInstance();
778 calendar.setTimeInMillis(0);
779 return calendar.getTime();
782 private static class SchemaContextImpl implements SchemaContext {
783 private final Set<Module> modules;
785 private SchemaContextImpl(Set<Module> modules) {
786 this.modules = modules;
790 public Set<DataSchemaNode> getDataDefinitions() {
791 final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
792 for (Module m : modules) {
793 dataDefs.addAll(m.getChildNodes());
799 public Set<Module> getModules() {
804 public Set<NotificationDefinition> getNotifications() {
805 final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
806 for (Module m : modules) {
807 notifications.addAll(m.getNotifications());
809 return notifications;
813 public Set<RpcDefinition> getOperations() {
814 final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
815 for (Module m : modules) {
816 rpcs.addAll(m.getRpcs());
822 public Set<ExtensionDefinition> getExtensions() {
823 final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
824 for (Module m : modules) {
825 extensions.addAll(m.getExtensionSchemaNodes());
831 public Module findModuleByName(final String name, final Date revision) {
832 if ((name != null) && (revision != null)) {
833 for (final Module module : modules) {
834 if (module.getName().equals(name)
835 && module.getRevision().equals(revision)) {
844 public Module findModuleByNamespace(URI namespace) {
845 if (namespace != null) {
846 for (final Module module : modules) {
847 if (module.getNamespace().equals(namespace)) {