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.DecimalTypeDefinition;
44 import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
45 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
46 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
47 import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
48 import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
49 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
50 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationSchemaBuilder;
51 import org.opendaylight.controller.yang.model.parser.builder.api.AugmentationTargetBuilder;
52 import org.opendaylight.controller.yang.model.parser.builder.api.ChildNodeBuilder;
53 import org.opendaylight.controller.yang.model.parser.builder.api.DataSchemaNodeBuilder;
54 import org.opendaylight.controller.yang.model.parser.builder.api.TypeAwareBuilder;
55 import org.opendaylight.controller.yang.model.parser.builder.api.TypeDefinitionBuilder;
56 import org.opendaylight.controller.yang.model.parser.builder.impl.IdentitySchemaNodeBuilder;
57 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
58 import org.opendaylight.controller.yang.model.parser.builder.impl.TypedefBuilder;
59 import org.opendaylight.controller.yang.model.parser.builder.impl.UnionTypeBuilder;
60 import org.opendaylight.controller.yang.model.parser.util.TypeConstraints;
61 import org.opendaylight.controller.yang.model.parser.util.YangParseException;
62 import org.opendaylight.controller.yang.model.util.ExtendedType;
63 import org.opendaylight.controller.yang.model.util.UnknownType;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 public class YangModelParserImpl implements YangModelParser {
69 private static final Logger logger = LoggerFactory
70 .getLogger(YangModelParserImpl.class);
73 public Module parseYangModel(final String yangFile) {
74 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFile);
75 final Set<Module> result = build(modules);
76 return result.iterator().next();
80 public Set<Module> parseYangModels(final String... yangFiles) {
81 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangFiles);
82 return build(modules);
86 public Set<Module> parseYangModelsFromStreams(
87 final InputStream... yangModelStreams) {
88 final Map<String, TreeMap<Date, ModuleBuilder>> modules = resolveModuleBuildersFromStreams(yangModelStreams);
89 return build(modules);
93 public SchemaContext resolveSchemaContext(final Set<Module> modules) {
94 return new SchemaContextImpl(modules);
97 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
98 String... yangFiles) {
99 InputStream[] streams = new InputStream[yangFiles.length];
100 FileInputStream inStream = null;
101 for (int i = 0; i < yangFiles.length; i++) {
102 final String yangFileName = yangFiles[i];
103 final File yangFile = new File(yangFileName);
105 inStream = new FileInputStream(yangFile);
106 } catch (FileNotFoundException e) {
107 logger.warn("Exception while reading yang stream: " + inStream,
110 streams[i] = inStream;
112 return resolveModuleBuildersFromStreams(streams);
115 private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuildersFromStreams(
116 InputStream... yangFiles) {
117 final Map<String, TreeMap<Date, ModuleBuilder>> modules = new HashMap<String, TreeMap<Date, ModuleBuilder>>();
118 final ParseTreeWalker walker = new ParseTreeWalker();
119 final List<ParseTree> trees = parseStreams(yangFiles);
120 final ModuleBuilder[] builders = new ModuleBuilder[trees.size()];
122 YangModelParserListenerImpl yangModelParser = null;
123 for (int i = 0; i < trees.size(); i++) {
124 yangModelParser = new YangModelParserListenerImpl();
125 walker.walk(yangModelParser, trees.get(i));
126 builders[i] = yangModelParser.getModuleBuilder();
129 for (ModuleBuilder builder : builders) {
130 final String builderName = builder.getName();
131 Date builderRevision = builder.getRevision();
132 if (builderRevision == null) {
133 builderRevision = createEpochTime();
135 TreeMap<Date, ModuleBuilder> builderByRevision = modules
137 if (builderByRevision == null) {
138 builderByRevision = new TreeMap<Date, ModuleBuilder>();
140 builderByRevision.put(builderRevision, builder);
141 modules.put(builderName, builderByRevision);
146 private List<ParseTree> parseStreams(InputStream... yangStreams) {
147 final List<ParseTree> trees = new ArrayList<ParseTree>();
148 for (InputStream yangStream : yangStreams) {
149 trees.add(parseStream(yangStream));
154 private ParseTree parseStream(InputStream yangStream) {
155 ParseTree result = null;
157 final ANTLRInputStream input = new ANTLRInputStream(yangStream);
158 final YangLexer lexer = new YangLexer(input);
159 final CommonTokenStream tokens = new CommonTokenStream(lexer);
160 final YangParser parser = new YangParser(tokens);
161 result = parser.yang();
162 } catch (IOException e) {
163 logger.warn("Exception while reading yang file: " + yangStream, e);
168 private Set<Module> build(Map<String, TreeMap<Date, ModuleBuilder>> modules) {
170 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
172 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
174 ModuleBuilder moduleBuilder = childEntry.getValue();
175 validateModule(modules, moduleBuilder);
180 final Set<Module> result = new HashSet<Module>();
181 for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
183 final Map<Date, Module> modulesByRevision = new HashMap<Date, Module>();
184 for (Map.Entry<Date, ModuleBuilder> childEntry : entry.getValue()
186 ModuleBuilder moduleBuilder = childEntry.getValue();
187 Module module = moduleBuilder.build();
188 modulesByRevision.put(childEntry.getKey(), module);
195 private void validateModule(
196 Map<String, TreeMap<Date, ModuleBuilder>> modules,
197 ModuleBuilder builder) {
198 resolveDirtyNodes(modules, builder);
199 resolveAugments(modules, builder);
200 resolveIdentities(modules, builder);
204 * Search for dirty nodes (node which contains UnknownType) and resolve
208 * all available modules
212 private void resolveDirtyNodes(
213 Map<String, TreeMap<Date, ModuleBuilder>> modules,
214 ModuleBuilder module) {
215 final Map<List<String>, TypeAwareBuilder> dirtyNodes = module
217 if (!dirtyNodes.isEmpty()) {
218 for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
221 TypeAwareBuilder typeToResolve = entry.getValue();
222 if (typeToResolve instanceof UnionTypeBuilder) {
223 UnionTypeBuilder union = (UnionTypeBuilder) typeToResolve;
224 List<TypeDefinition<?>> unionTypes = union.getTypes();
225 List<UnknownType> toRemove = new ArrayList<UnknownType>();
226 for (TypeDefinition<?> td : unionTypes) {
227 if (td instanceof UnknownType) {
228 UnknownType unknownType = (UnknownType) td;
229 TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
230 typeToResolve, unknownType, modules, module);
231 union.setType(resolvedType);
232 toRemove.add(unknownType);
235 unionTypes.removeAll(toRemove);
237 TypeDefinitionBuilder resolvedType = findTargetType(
238 typeToResolve, modules, module);
239 typeToResolve.setType(resolvedType);
245 private TypeDefinitionBuilder findTargetType(
246 TypeAwareBuilder typeToResolve,
247 Map<String, TreeMap<Date, ModuleBuilder>> modules,
248 ModuleBuilder builder) {
249 TypeConstraints constraints = new TypeConstraints();
251 TypeDefinitionBuilder targetType = findTypedef(typeToResolve, modules,
253 TypeConstraints tConstraints = findConstraints(typeToResolve,
254 constraints, modules, builder);
255 targetType.setRanges(tConstraints.getRange());
256 targetType.setLengths(tConstraints.getLength());
257 targetType.setPatterns(tConstraints.getPatterns());
258 targetType.setFractionDigits(tConstraints.getFractionDigits());
263 private TypeDefinitionBuilder findTargetTypeUnion(
264 TypeAwareBuilder typeToResolve, UnknownType unknownType,
265 Map<String, TreeMap<Date, ModuleBuilder>> modules,
266 ModuleBuilder builder) {
267 TypeConstraints constraints = new TypeConstraints();
269 TypeDefinitionBuilder targetType = findTypedefUnion(typeToResolve,
270 unknownType, modules, builder);
271 TypeConstraints tConstraints = findConstraints(typeToResolve,
272 constraints, modules, builder);
273 targetType.setRanges(tConstraints.getRange());
274 targetType.setLengths(tConstraints.getLength());
275 targetType.setPatterns(tConstraints.getPatterns());
276 targetType.setFractionDigits(tConstraints.getFractionDigits());
281 private TypeDefinitionBuilder findTypedef(TypeAwareBuilder typeToResolve,
282 Map<String, TreeMap<Date, ModuleBuilder>> modules,
283 ModuleBuilder builder) {
285 TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
286 if (baseTypeToResolve != null
287 && !(baseTypeToResolve instanceof UnknownType)) {
288 return (TypeDefinitionBuilder) typeToResolve;
291 UnknownType unknownType = (UnknownType) typeToResolve.getType();
293 QName unknownTypeQName = unknownType.getQName();
294 String unknownTypeName = unknownTypeQName.getLocalName();
295 String unknownTypePrefix = unknownTypeQName.getPrefix();
297 // search for module which contains referenced typedef
298 ModuleBuilder dependentModule = findDependentModule(modules, builder,
300 TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
301 dependentModule.getModuleTypedefs(), unknownTypeName);
303 TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
304 lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
305 TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
306 lookedUpBuilderCopy, modules, dependentModule);
310 private TypeDefinitionBuilder findTypedefUnion(
311 TypeAwareBuilder typeToResolve, UnknownType unknownType,
312 Map<String, TreeMap<Date, ModuleBuilder>> modules,
313 ModuleBuilder builder) {
315 TypeDefinition<?> baseTypeToResolve = typeToResolve.getType();
316 if (baseTypeToResolve != null
317 && !(baseTypeToResolve instanceof UnknownType)) {
318 return (TypeDefinitionBuilder) typeToResolve;
321 QName unknownTypeQName = unknownType.getQName();
322 String unknownTypeName = unknownTypeQName.getLocalName();
323 String unknownTypePrefix = unknownTypeQName.getPrefix();
325 // search for module which contains referenced typedef
326 ModuleBuilder dependentModule = findDependentModule(modules, builder,
328 TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
329 dependentModule.getModuleTypedefs(), unknownTypeName);
331 TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
332 lookedUpBuilder, typeToResolve instanceof TypeDefinitionBuilder);
333 TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
334 lookedUpBuilderCopy, modules, dependentModule);
338 private TypeDefinitionBuilder copyTypedefBuilder(TypeDefinitionBuilder old,
339 boolean seekByTypedefBuilder) {
340 if (old instanceof UnionTypeBuilder) {
341 UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
342 UnionTypeBuilder newUnion = new UnionTypeBuilder();
343 for (TypeDefinition<?> td : oldUnion.getTypes()) {
344 newUnion.setType(td);
346 for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
347 newUnion.setType(copyTypedefBuilder(tdb, true));
352 QName oldQName = old.getQName();
353 QName newQName = new QName(oldQName.getNamespace(),
354 oldQName.getRevision(), oldQName.getPrefix(),
355 oldQName.getLocalName());
356 TypeDefinitionBuilder tdb = new TypedefBuilder(newQName);
358 tdb.setRanges(old.getRanges());
359 tdb.setLengths(old.getLengths());
360 tdb.setPatterns(old.getPatterns());
362 TypeDefinition<?> oldType = old.getType();
363 if (oldType == null) {
364 tdb.setType(old.getTypedef());
366 tdb.setType(oldType);
369 if (!seekByTypedefBuilder) {
370 tdb.setDescription(old.getDescription());
371 tdb.setReference(old.getReference());
372 tdb.setStatus(old.getStatus());
373 tdb.setDefaultValue(old.getDefaultValue());
374 tdb.setUnits(old.getUnits());
379 private TypeDefinitionBuilder resolveCopiedBuilder(
380 TypeDefinitionBuilder copied,
381 Map<String, TreeMap<Date, ModuleBuilder>> modules,
382 ModuleBuilder builder) {
384 if (copied instanceof UnionTypeBuilder) {
385 UnionTypeBuilder union = (UnionTypeBuilder) copied;
386 List<TypeDefinition<?>> unionTypes = union.getTypes();
387 List<UnknownType> toRemove = new ArrayList<UnknownType>();
388 for (TypeDefinition<?> td : unionTypes) {
389 if (td instanceof UnknownType) {
390 UnknownType unknownType = (UnknownType) td;
391 TypeDefinitionBuilder resolvedType = findTargetTypeUnion(
392 union, unknownType, modules, builder);
393 union.setType(resolvedType);
394 toRemove.add(unknownType);
397 unionTypes.removeAll(toRemove);
402 TypeDefinition<?> base = copied.getType();
403 TypeDefinitionBuilder baseTdb = copied.getTypedef();
404 if (base != null && !(base instanceof UnknownType)) {
406 } else if (base instanceof UnknownType) {
407 UnknownType unknownType = (UnknownType) base;
408 QName unknownTypeQName = unknownType.getQName();
409 String unknownTypePrefix = unknownTypeQName.getPrefix();
410 ModuleBuilder dependentModule = findDependentModule(modules,
411 builder, unknownTypePrefix);
412 TypeDefinitionBuilder unknownTypeBuilder = findTypedef(copied,
413 modules, dependentModule);
414 copied.setType(unknownTypeBuilder);
416 } else if (base == null && baseTdb != null) {
417 // make a copy of baseTypeDef and call again
418 TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder(baseTdb,
420 TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
421 baseTdbCopy, modules, builder);
422 copied.setType(baseTdbCopyResolved);
425 throw new IllegalStateException(
426 "TypeDefinitionBuilder in unexpected state");
430 private TypeDefinitionBuilder findTypedef(QName unknownTypeQName,
431 Map<String, TreeMap<Date, ModuleBuilder>> modules,
432 ModuleBuilder builder) {
434 String unknownTypeName = unknownTypeQName.getLocalName();
435 String unknownTypePrefix = unknownTypeQName.getPrefix();
437 // search for module which contains referenced typedef
438 ModuleBuilder dependentModule = findDependentModule(modules, builder,
441 TypeDefinitionBuilder lookedUpBuilder = findTypedefBuilder(
442 dependentModule.getModuleTypedefs(), unknownTypeName);
444 TypeDefinitionBuilder copied = copyTypedefBuilder(lookedUpBuilder, true);
448 private TypeConstraints findConstraints(TypeAwareBuilder typeToResolve,
449 TypeConstraints constraints,
450 Map<String, TreeMap<Date, ModuleBuilder>> modules,
451 ModuleBuilder builder) {
453 // union type cannot be restricted
454 if (typeToResolve instanceof UnionTypeBuilder) {
458 // if referenced type is UnknownType again, search recursively with
459 // current constraints
460 TypeDefinition<?> referencedType = typeToResolve.getType();
461 if (referencedType == null) {
462 TypeDefinitionBuilder tdb = (TypeDefinitionBuilder) typeToResolve;
463 final List<RangeConstraint> ranges = tdb.getRanges();
464 constraints.addRanges(ranges);
465 final List<LengthConstraint> lengths = tdb.getLengths();
466 constraints.addLengths(lengths);
467 final List<PatternConstraint> patterns = tdb.getPatterns();
468 constraints.addPatterns(patterns);
469 final Integer fractionDigits = tdb.getFractionDigits();
470 constraints.setFractionDigits(fractionDigits);
472 } else if (referencedType instanceof ExtendedType) {
473 ExtendedType ext = (ExtendedType) referencedType;
474 final List<RangeConstraint> ranges = ext.getRanges();
475 constraints.addRanges(ranges);
476 final List<LengthConstraint> lengths = ext.getLengths();
477 constraints.addLengths(lengths);
478 final List<PatternConstraint> patterns = ext.getPatterns();
479 constraints.addPatterns(patterns);
480 final Integer fractionDigits = ext.getFractionDigits();
481 constraints.setFractionDigits(fractionDigits);
482 return findConstraints(
483 findTypedef(ext.getQName(), modules, builder), constraints,
485 } else if (referencedType instanceof UnknownType) {
486 UnknownType unknown = (UnknownType) referencedType;
488 final List<RangeConstraint> ranges = unknown.getRangeStatements();
489 constraints.addRanges(ranges);
490 final List<LengthConstraint> lengths = unknown
491 .getLengthStatements();
492 constraints.addLengths(lengths);
493 final List<PatternConstraint> patterns = unknown.getPatterns();
494 constraints.addPatterns(patterns);
495 final Integer fractionDigits = unknown.getFractionDigits();
496 constraints.setFractionDigits(fractionDigits);
498 String unknownTypePrefix = unknown.getQName().getPrefix();
499 if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) {
500 unknownTypePrefix = builder.getPrefix();
502 ModuleBuilder dependentModule = findDependentModule(modules,
503 builder, unknown.getQName().getPrefix());
504 TypeDefinitionBuilder unknownTypeBuilder = findTypedef(
505 unknown.getQName(), modules, builder);
506 return findConstraints(unknownTypeBuilder, constraints, modules,
509 // HANDLE BASE YANG TYPE
510 mergeConstraints(referencedType, constraints);
517 * Go through all typedef statements from given module and search for one
521 * typedef statements to search
523 * name of searched typedef
524 * @return typedef with name equals to given name
526 private TypeDefinitionBuilder findTypedefBuilder(
527 Set<TypeDefinitionBuilder> typedefs, String name) {
528 TypeDefinitionBuilder result = null;
529 for (TypeDefinitionBuilder td : typedefs) {
530 if (td.getQName().getLocalName().equals(name)) {
535 if (result == null) {
536 throw new YangParseException(
537 "Target module does not contain typedef '" + name + "'.");
543 * Pull restriction from referenced type and add them to given constraints
545 * @param referencedType
548 private void mergeConstraints(TypeDefinition<?> referencedType,
549 TypeConstraints constraints) {
551 if (referencedType instanceof DecimalTypeDefinition) {
552 constraints.addRanges(((DecimalTypeDefinition) referencedType)
553 .getRangeStatements());
555 .setFractionDigits(((DecimalTypeDefinition) referencedType)
556 .getFractionDigits());
557 } else if (referencedType instanceof IntegerTypeDefinition) {
558 constraints.addRanges(((IntegerTypeDefinition) referencedType)
559 .getRangeStatements());
560 } else if (referencedType instanceof StringTypeDefinition) {
561 constraints.addPatterns(((StringTypeDefinition) referencedType)
563 constraints.addLengths(((StringTypeDefinition) referencedType)
564 .getLengthStatements());
565 } else if (referencedType instanceof BinaryTypeDefinition) {
566 constraints.addLengths(((BinaryTypeDefinition) referencedType)
567 .getLengthConstraints());
572 * Go through all augmentation definitions and resolve them. This means find
573 * referenced node and add child nodes to it.
576 * all available modules
580 private void resolveAugments(
581 Map<String, TreeMap<Date, ModuleBuilder>> modules,
582 ModuleBuilder module) {
583 Set<AugmentationSchemaBuilder> augmentBuilders = module
586 Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();
587 for (AugmentationSchemaBuilder augmentBuilder : augmentBuilders) {
588 SchemaPath augmentTargetSchemaPath = augmentBuilder.getTargetPath();
589 String prefix = null;
590 List<String> augmentTargetPath = new ArrayList<String>();
592 for (QName pathPart : augmentTargetSchemaPath.getPath()) {
593 prefix = pathPart.getPrefix();
594 augmentTargetPath.add(pathPart.getLocalName());
596 ModuleBuilder dependentModule = findDependentModule(modules,
598 augmentTargetPath.add(0, dependentModule.getName());
600 AugmentationTargetBuilder augmentTarget = (AugmentationTargetBuilder) dependentModule
601 .getNode(augmentTargetPath);
602 AugmentationSchema result = augmentBuilder.build();
603 augmentTarget.addAugmentation(result);
604 fillAugmentTarget(augmentBuilder, (ChildNodeBuilder) augmentTarget);
605 augments.add(result);
607 module.setAugmentations(augments);
611 * Add all augment's child nodes to given target.
616 private void fillAugmentTarget(AugmentationSchemaBuilder augment,
617 ChildNodeBuilder target) {
618 for (DataSchemaNodeBuilder builder : augment.getChildNodes()) {
619 builder.setAugmenting(true);
620 target.addChildNode(builder);
625 * Go through identity statements defined in current module and resolve
626 * their 'base' statement if present.
631 * module being resolved
633 private void resolveIdentities(
634 Map<String, TreeMap<Date, ModuleBuilder>> modules,
635 ModuleBuilder module) {
636 Set<IdentitySchemaNodeBuilder> identities = module.getAddedIdentities();
637 for (IdentitySchemaNodeBuilder identity : identities) {
638 String baseIdentityName = identity.getBaseIdentityName();
639 if (baseIdentityName != null) {
640 String baseIdentityPrefix = null;
641 String baseIdentityLocalName = null;
642 if (baseIdentityName.contains(":")) {
643 String[] splitted = baseIdentityName.split(":");
644 baseIdentityPrefix = splitted[0];
645 baseIdentityLocalName = splitted[1];
647 baseIdentityPrefix = module.getPrefix();
648 baseIdentityLocalName = baseIdentityName;
650 ModuleBuilder dependentModule = findDependentModule(modules,
651 module, baseIdentityPrefix);
653 Set<IdentitySchemaNodeBuilder> dependentModuleIdentities = dependentModule
654 .getAddedIdentities();
655 for (IdentitySchemaNodeBuilder idBuilder : dependentModuleIdentities) {
656 if (idBuilder.getQName().getLocalName()
657 .equals(baseIdentityLocalName)) {
658 identity.setBaseIdentity(idBuilder);
666 * Find dependent module based on given prefix
669 * all available modules
673 * target module prefix
676 private ModuleBuilder findDependentModule(
677 Map<String, TreeMap<Date, ModuleBuilder>> modules,
678 ModuleBuilder module, String prefix) {
679 ModuleBuilder dependentModule = null;
680 Date dependentModuleRevision = null;
682 if (prefix.equals(module.getPrefix())) {
683 dependentModule = module;
685 ModuleImport dependentModuleImport = getModuleImport(module, prefix);
686 if (dependentModuleImport == null) {
687 throw new YangParseException("No import found with prefix '"
688 + prefix + "' in module " + module.getName() + "'.");
690 String dependentModuleName = dependentModuleImport.getModuleName();
691 dependentModuleRevision = dependentModuleImport.getRevision();
693 TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules
694 .get(dependentModuleName);
695 if (dependentModuleRevision == null) {
696 dependentModule = moduleBuildersByRevision.lastEntry()
699 dependentModule = moduleBuildersByRevision
700 .get(dependentModuleRevision);
704 if (dependentModule == null) {
705 throw new YangParseException(
706 "Failed to find dependent module with prefix '" + prefix
707 + "' and revision '" + dependentModuleRevision
710 return dependentModule;
714 * Get module import referenced by given prefix.
719 * prefix associated with import
720 * @return ModuleImport based on given prefix
722 private ModuleImport getModuleImport(ModuleBuilder builder, String prefix) {
723 ModuleImport moduleImport = null;
724 for (ModuleImport mi : builder.getModuleImports()) {
725 if (mi.getPrefix().equals(prefix)) {
733 private Date createEpochTime() {
734 Calendar calendar = Calendar.getInstance();
735 calendar.setTimeInMillis(0);
736 return calendar.getTime();
739 private static class SchemaContextImpl implements SchemaContext {
740 private final Set<Module> modules;
742 private SchemaContextImpl(Set<Module> modules) {
743 this.modules = modules;
747 public Set<DataSchemaNode> getDataDefinitions() {
748 final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
749 for (Module m : modules) {
750 dataDefs.addAll(m.getChildNodes());
756 public Set<Module> getModules() {
761 public Set<NotificationDefinition> getNotifications() {
762 final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
763 for (Module m : modules) {
764 notifications.addAll(m.getNotifications());
766 return notifications;
770 public Set<RpcDefinition> getOperations() {
771 final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
772 for (Module m : modules) {
773 rpcs.addAll(m.getRpcs());
779 public Set<ExtensionDefinition> getExtensions() {
780 final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
781 for (Module m : modules) {
782 extensions.addAll(m.getExtensionSchemaNodes());