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.yangtools.yang.parser.builder.impl;
10 import com.google.common.base.Function;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.base.Splitter;
14 import com.google.common.collect.Collections2;
15 import com.google.common.io.ByteSource;
16 import java.io.ByteArrayOutputStream;
18 import java.io.FileNotFoundException;
19 import java.io.IOException;
20 import java.io.InputStream;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Date;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
31 import java.util.TreeMap;
32 import org.apache.commons.io.IOUtils;
33 import org.opendaylight.yangtools.yang.common.QName;
34 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
36 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
37 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
38 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
39 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
41 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
42 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
43 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
44 import org.opendaylight.yangtools.yang.model.api.Module;
45 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
46 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
47 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
48 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
49 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
50 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
51 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationSchemaBuilder;
52 import org.opendaylight.yangtools.yang.parser.builder.api.AugmentationTargetBuilder;
53 import org.opendaylight.yangtools.yang.parser.builder.api.Builder;
54 import org.opendaylight.yangtools.yang.parser.builder.api.DataNodeContainerBuilder;
55 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
56 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingBuilder;
57 import org.opendaylight.yangtools.yang.parser.builder.api.GroupingMember;
58 import org.opendaylight.yangtools.yang.parser.builder.api.SchemaNodeBuilder;
59 import org.opendaylight.yangtools.yang.parser.builder.api.TypeDefinitionBuilder;
60 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
61 import org.opendaylight.yangtools.yang.parser.util.NamedByteArrayInputStream;
62 import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
63 import org.opendaylight.yangtools.yang.parser.util.YangParseException;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 public final class BuilderUtils {
69 private static final Logger LOG = LoggerFactory.getLogger(BuilderUtils.class);
70 private static final Splitter SLASH_SPLITTER = Splitter.on('/');
71 private static final Splitter COLON_SPLITTER = Splitter.on(':');
72 private static final String INPUT = "input";
73 private static final String OUTPUT = "output";
75 private BuilderUtils() {
78 public static Collection<ByteSource> streamsToByteSources(final Collection<InputStream> streams) throws IOException {
79 Collection<ByteSource> result = new HashSet<>();
80 for (InputStream stream : streams) {
81 result.add(new ByteSourceImpl(stream));
86 public static ByteSource fileToByteSource(final File file) {
87 return new ByteSource() {
89 public InputStream openStream() throws IOException {
90 return new NamedFileInputStream(file, file.getAbsolutePath());
95 public static Collection<ByteSource> filesToByteSources(final Collection<File> streams)
96 throws FileNotFoundException {
97 return Collections2.transform(streams, new Function<File, ByteSource>() {
99 public ByteSource apply(final File input) {
100 return new ByteSource() {
102 public InputStream openStream() throws IOException {
103 return new NamedFileInputStream(input, input.getAbsolutePath());
111 * Set string representation of source to ModuleBuilder.
113 * @param sourceToBuilder
114 * source to module mapping
116 public static void setSourceToBuilder(final Map<ByteSource, ModuleBuilder> sourceToBuilder) throws IOException {
117 for (Map.Entry<ByteSource, ModuleBuilder> entry : sourceToBuilder.entrySet()) {
118 ModuleBuilder builder = entry.getValue();
119 ByteSource source = entry.getKey();
121 String content = null;
122 InputStream stream = null;
124 stream = source.openStream();
125 content = IOUtils.toString(stream);
127 if (stream != null) {
130 } catch (IOException e) {
132 * Failed stream close does not prevent us from
133 * continuing to work correctly, we just report that and
136 LOG.warn("Failed to close stream {}. Leaving stream unclosed.", stream, e);
140 builder.setSource(content);
145 * Create new SchemaPath from given path and qname.
150 * one or more qnames added to base path
151 * @return new SchemaPath from given path and qname
153 * @deprecated Use {@link SchemaPath#createChild(QName...)} instead.
156 public static SchemaPath createSchemaPath(final SchemaPath schemaPath, final QName... qname) {
157 List<QName> path = new ArrayList<>(schemaPath.getPath());
158 path.addAll(Arrays.asList(qname));
159 return SchemaPath.create(path, schemaPath.isAbsolute());
163 * Get module import referenced by given prefix.
168 * prefix associated with import
169 * @return ModuleImport based on given prefix
171 public static ModuleImport getModuleImport(final ModuleBuilder builder, final String prefix) {
172 for (ModuleImport mi : builder.getModuleImports()) {
173 if (mi.getPrefix().equals(prefix)) {
182 * Find dependent module based on given prefix
185 * all available modules
189 * target module prefix
191 * current line in yang model
192 * @return module builder if found, null otherwise
194 public static ModuleBuilder findModuleFromBuilders(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
195 final ModuleBuilder module, final String prefix, final int line) {
196 ModuleBuilder dependentModule = null;
197 Date dependentModuleRevision = null;
199 if (prefix == null) {
200 dependentModule = module;
201 } else if (prefix.equals(module.getPrefix())) {
202 dependentModule = module;
204 ModuleImport dependentModuleImport = getModuleImport(module, prefix);
205 if (dependentModuleImport == null) {
206 throw new YangParseException(module.getName(), line, "No import found with prefix '" + prefix + "'.");
208 String dependentModuleName = dependentModuleImport.getModuleName();
209 dependentModuleRevision = dependentModuleImport.getRevision();
211 TreeMap<Date, ModuleBuilder> moduleBuildersByRevision = modules.get(dependentModuleName);
212 if (moduleBuildersByRevision == null) {
215 if (dependentModuleRevision == null) {
216 dependentModule = moduleBuildersByRevision.lastEntry().getValue();
218 dependentModule = moduleBuildersByRevision.get(dependentModuleRevision);
221 return dependentModule;
225 * Find module from context based on prefix.
229 * @param currentModule
232 * current prefix used to reference dependent module
234 * current line in yang model
235 * @return module based on given prefix if found in context, null otherwise
237 public static Module findModuleFromContext(final SchemaContext context, final ModuleBuilder currentModule,
238 final String prefix, final int line) {
239 if (context == null) {
240 throw new YangParseException(currentModule.getName(), line, "Cannot find module with prefix '" + prefix
243 TreeMap<Date, Module> modulesByRevision = new TreeMap<>();
245 ModuleImport dependentModuleImport = BuilderUtils.getModuleImport(currentModule, prefix);
246 if (dependentModuleImport == null) {
247 throw new YangParseException(currentModule.getName(), line, "No import found with prefix '" + prefix + "'.");
249 String dependentModuleName = dependentModuleImport.getModuleName();
250 Date dependentModuleRevision = dependentModuleImport.getRevision();
252 for (Module contextModule : context.getModules()) {
253 if (contextModule.getName().equals(dependentModuleName)) {
254 Date revision = contextModule.getRevision();
255 if (revision == null) {
256 revision = new Date(0L);
258 modulesByRevision.put(revision, contextModule);
262 Module result = null;
263 if (dependentModuleRevision == null) {
264 result = modulesByRevision.get(modulesByRevision.firstKey());
266 result = modulesByRevision.get(dependentModuleRevision);
272 * Parse XPath string.
276 * @return SchemaPath from given String
278 public static SchemaPath parseXPathString(final String xpathString) {
279 final boolean absolute = xpathString.indexOf('/') == 0;
281 final List<QName> path = new ArrayList<QName>();
282 for (String pathElement : SLASH_SPLITTER.split(xpathString)) {
283 if (pathElement.length() > 0) {
284 final Iterator<String> it = COLON_SPLITTER.split(pathElement).iterator();
285 final String s = it.next();
289 name = new QName(null, null, s, it.next());
291 name = new QName(null, null, null, s);
296 return SchemaPath.create(path, absolute);
300 * Add all augment's child nodes to given target.
303 * builder of augment statement
305 * augmentation target node
307 public static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final Builder target) {
308 if (target instanceof DataNodeContainerBuilder) {
309 fillAugmentTarget(augment, (DataNodeContainerBuilder) target);
310 } else if (target instanceof ChoiceBuilder) {
311 fillAugmentTarget(augment, (ChoiceBuilder) target);
313 throw new YangParseException(
314 augment.getModuleName(),
316 "Error in augment parsing: The target node MUST be either a container, list, choice, case, input, output, or notification node.");
321 * Add all augment's child nodes to given target.
324 * builder of augment statement
326 * augmentation target node
328 private static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final DataNodeContainerBuilder target) {
329 for (DataSchemaNodeBuilder child : augment.getChildNodeBuilders()) {
330 DataSchemaNodeBuilder childCopy = CopyUtils.copy(child, target, false);
331 if (augment.getParent() instanceof UsesNodeBuilder) {
332 setNodeAddedByUses(childCopy);
334 setNodeAugmenting(childCopy);
336 target.addChildNode(childCopy);
337 } catch (YangParseException e) {
339 // more descriptive message
340 throw new YangParseException(augment.getModuleName(), augment.getLine(),
341 "Failed to perform augmentation: " + e.getMessage());
347 * Add all augment's child nodes to given target.
350 * builder of augment statement
352 * augmentation target choice node
354 private static void fillAugmentTarget(final AugmentationSchemaBuilder augment, final ChoiceBuilder target) {
355 for (DataSchemaNodeBuilder builder : augment.getChildNodeBuilders()) {
356 DataSchemaNodeBuilder childCopy = CopyUtils.copy(builder, target, false);
357 if (augment.getParent() instanceof UsesNodeBuilder) {
358 setNodeAddedByUses(childCopy);
360 setNodeAugmenting(childCopy);
361 target.addCase(childCopy);
363 for (UsesNodeBuilder usesNode : augment.getUsesNodeBuilders()) {
364 if (usesNode != null) {
365 throw new YangParseException(augment.getModuleName(), augment.getLine(),
366 "Error in augment parsing: cannot augment choice with nodes from grouping");
372 * Set augmenting flag to true for node and all its child nodes.
376 private static void setNodeAugmenting(final DataSchemaNodeBuilder node) {
377 node.setAugmenting(true);
378 if (node instanceof DataNodeContainerBuilder) {
379 DataNodeContainerBuilder dataNodeChild = (DataNodeContainerBuilder) node;
380 for (DataSchemaNodeBuilder inner : dataNodeChild.getChildNodeBuilders()) {
381 setNodeAugmenting(inner);
383 } else if (node instanceof ChoiceBuilder) {
384 ChoiceBuilder choiceChild = (ChoiceBuilder) node;
385 for (ChoiceCaseBuilder inner : choiceChild.getCases()) {
386 setNodeAugmenting(inner);
392 * Set addedByUses flag to true for node and all its child nodes.
396 public static void setNodeAddedByUses(final GroupingMember node) {
397 node.setAddedByUses(true);
398 if (node instanceof DataNodeContainerBuilder) {
399 DataNodeContainerBuilder dataNodeChild = (DataNodeContainerBuilder) node;
400 for (DataSchemaNodeBuilder inner : dataNodeChild.getChildNodeBuilders()) {
401 setNodeAddedByUses(inner);
403 } else if (node instanceof ChoiceBuilder) {
404 ChoiceBuilder choiceChild = (ChoiceBuilder) node;
405 for (ChoiceCaseBuilder inner : choiceChild.getCases()) {
406 setNodeAddedByUses(inner);
412 * Set config flag to new value.
419 public static void setNodeConfig(final DataSchemaNodeBuilder node, final Boolean config) {
420 if (node instanceof ContainerSchemaNodeBuilder || node instanceof LeafSchemaNodeBuilder
421 || node instanceof LeafListSchemaNodeBuilder || node instanceof ListSchemaNodeBuilder
422 || node instanceof ChoiceBuilder || node instanceof AnyXmlBuilder) {
423 node.setConfiguration(config);
425 if (node instanceof DataNodeContainerBuilder) {
426 DataNodeContainerBuilder dataNodeChild = (DataNodeContainerBuilder) node;
427 for (DataSchemaNodeBuilder inner : dataNodeChild.getChildNodeBuilders()) {
428 setNodeConfig(inner, config);
430 } else if (node instanceof ChoiceBuilder) {
431 ChoiceBuilder choiceChild = (ChoiceBuilder) node;
432 for (ChoiceCaseBuilder inner : choiceChild.getCases()) {
433 setNodeConfig(inner, config);
438 public static DataSchemaNodeBuilder findSchemaNode(final List<QName> path, final SchemaNodeBuilder parentNode) {
439 DataSchemaNodeBuilder node = null;
440 SchemaNodeBuilder parent = parentNode;
442 while (i < path.size()) {
443 String name = path.get(i).getLocalName();
444 if (parent instanceof DataNodeContainerBuilder) {
445 node = ((DataNodeContainerBuilder) parent).getDataChildByName(name);
446 } else if (parent instanceof ChoiceBuilder) {
447 node = ((ChoiceBuilder) parent).getCaseNodeByName(name);
448 } else if (parent instanceof RpcDefinitionBuilder) {
449 if ("input".equals(name)) {
450 node = ((RpcDefinitionBuilder) parent).getInput();
451 } else if ("output".equals(name)) {
452 node = ((RpcDefinitionBuilder) parent).getOutput();
460 if (i < path.size() - 1) {
471 * Find a builder for node in data namespace of YANG module.
473 * Search is performed on full QName equals, this means builders and schema
474 * path MUST be resolved against imports and their namespaces.
476 * Search is done in data namespace, this means notification, rpc
477 * definitions and top level data definitions are considered as top-level
478 * items, from which it is possible to traverse.
482 * Schema Path to node
484 * ModuleBuilder to start lookup in
485 * @return Node Builder if found, {@link Optional#absent()} otherwise.
487 public static Optional<SchemaNodeBuilder> findSchemaNodeInModule(final SchemaPath schemaPath,
488 final ModuleBuilder module) {
489 Iterator<QName> path = schemaPath.getPathFromRoot().iterator();
490 Preconditions.checkArgument(path.hasNext(), "Schema Path must contain at least one element.");
491 QName first = path.next();
492 Optional<SchemaNodeBuilder> currentNode = getDataNamespaceChild(module, first);
494 while (currentNode.isPresent() && path.hasNext()) {
495 currentNode = findDataChild(currentNode.get(), path.next());
500 private static Optional<SchemaNodeBuilder> findDataChild(final SchemaNodeBuilder parent, final QName child) {
501 if (parent instanceof DataNodeContainerBuilder) {
502 return castOptional(SchemaNodeBuilder.class,
503 findDataChildInDataNodeContainer((DataNodeContainerBuilder) parent, child));
504 } else if (parent instanceof ChoiceBuilder) {
505 return castOptional(SchemaNodeBuilder.class, findCaseInChoice((ChoiceBuilder) parent, child));
506 } else if (parent instanceof RpcDefinitionBuilder) {
507 return castOptional(SchemaNodeBuilder.class, findContainerInRpc((RpcDefinitionBuilder) parent, child));
510 LOG.trace("Child {} not found in node {}", child, parent);
511 return Optional.absent();
516 * Casts optional from one argument to other.
519 * Class to be checked
524 private static <T> Optional<T> castOptional(final Class<T> cls, final Optional<?> optional) {
525 if (optional.isPresent()) {
526 Object value = optional.get();
527 if (cls.isInstance(value)) {
528 @SuppressWarnings("unchecked")
529 // Actually checked by outer if
530 T casted = (T) value;
531 return Optional.of(casted);
534 return Optional.absent();
539 * Gets input / output container from {@link RpcDefinitionBuilder} if QName
544 * RPC Definition builder
547 * @return Optional of input/output if defined and QName is input/output.
548 * Otherwise {@link Optional#absent()}.
550 private static Optional<ContainerSchemaNodeBuilder> findContainerInRpc(final RpcDefinitionBuilder parent, final QName child) {
551 if (INPUT.equals(child.getLocalName())) {
552 return Optional.of(parent.getInput());
553 } else if (OUTPUT.equals(child.getLocalName())) {
554 return Optional.of(parent.getOutput());
556 LOG.trace("Child {} not found in node {}", child, parent);
557 return Optional.absent();
561 * Finds case by QName in {@link ChoiceBuilder}
565 * DataNodeContainer in which lookup should be performed
568 * @return Optional of child if found.
571 private static Optional<ChoiceCaseBuilder> findCaseInChoice(final ChoiceBuilder parent, final QName child) {
572 for (ChoiceCaseBuilder caze : parent.getCases()) {
573 if (caze.getQName().equals(child)) {
574 return Optional.of(caze);
577 LOG.trace("Child {} not found in node {}", child, parent);
578 return Optional.absent();
582 * Finds direct child by QName in {@link DataNodeContainerBuilder}
586 * DataNodeContainer in which lookup should be performed
589 * @return Optional of child if found.
591 private static Optional<DataSchemaNodeBuilder> findDataChildInDataNodeContainer(final DataNodeContainerBuilder parent,
593 for (DataSchemaNodeBuilder childNode : parent.getChildNodeBuilders()) {
594 if (childNode.getQName().equals(child)) {
595 return Optional.of(childNode);
598 LOG.trace("Child {} not found in node {}", child, parent);
599 return Optional.absent();
604 * Find a child builder for node in data namespace of YANG module.
606 * Search is performed on full QName equals, this means builders and schema
607 * path MUST be resolved against imports and their namespaces.
609 * Search is done in data namespace, this means notification, rpc
610 * definitions and top level data definitions are considered as top-level
611 * items, from which it is possible to traverse.
617 * ModuleBuilder to start lookup in
618 * @return Node Builder if found, {@link Optional#absent()} otherwise.
620 private static Optional<SchemaNodeBuilder> getDataNamespaceChild(final ModuleBuilder module, final QName child) {
622 * First we do lookup in data tree, if node is found we return it.
624 final Optional<SchemaNodeBuilder> dataTreeNode = getDataChildByQName(module, child);
625 if (dataTreeNode.isPresent()) {
630 * We lookup in notifications
632 Set<NotificationBuilder> notifications = module.getAddedNotifications();
633 for (NotificationBuilder notification : notifications) {
634 if (notification.getQName().equals(child)) {
635 return Optional.<SchemaNodeBuilder> of(notification);
642 Set<RpcDefinitionBuilder> rpcs = module.getAddedRpcs();
643 for (RpcDefinitionBuilder rpc : rpcs) {
644 if (rpc.getQName().equals(child)) {
645 return Optional.<SchemaNodeBuilder> of(rpc);
648 LOG.trace("Child {} not found in data namespace of module {}", child, module);
649 return Optional.absent();
652 private static Optional<SchemaNodeBuilder> getDataChildByQName(final DataNodeContainerBuilder builder, final QName child) {
653 for (DataSchemaNodeBuilder childNode : builder.getChildNodeBuilders()) {
654 if (childNode.getQName().equals(child)) {
655 return Optional.<SchemaNodeBuilder> of(childNode);
658 LOG.trace("Child {} not found in node {}", child, builder);
659 return Optional.absent();
663 * Find augment target node and perform augmentation.
666 * @param firstNodeParent
667 * parent of first node in path
669 * path to augment target
670 * @return true if augmentation process succeed, false otherwise
672 public static boolean processAugmentation(final AugmentationSchemaBuilder augment,
673 final ModuleBuilder firstNodeParent) {
674 Optional<SchemaNodeBuilder> potentialTargetNode = findSchemaNodeInModule(augment.getTargetNodeSchemaPath(),
676 if (!potentialTargetNode.isPresent()) {
679 SchemaNodeBuilder targetNode = potentialTargetNode.get();
680 fillAugmentTarget(augment, targetNode);
681 Preconditions.checkState(targetNode instanceof AugmentationTargetBuilder,
682 "Node refered by augmentation must be valid augmentation target");
683 ((AugmentationTargetBuilder) targetNode).addAugmentation(augment);
684 augment.setResolved(true);
688 public static IdentitySchemaNodeBuilder findBaseIdentity(final Map<String, TreeMap<Date, ModuleBuilder>> modules,
689 final ModuleBuilder module, final String baseString, final int line) {
691 // FIXME: optimize indexOf() away?
692 if (baseString.indexOf(':') != -1) {
693 final Iterator<String> it = COLON_SPLITTER.split(baseString).iterator();
694 final String prefix = it.next();
695 final String name = it.next();
698 throw new YangParseException(module.getName(), line, "Failed to parse identityref base: " + baseString);
701 ModuleBuilder dependentModule = findModuleFromBuilders(modules, module, prefix, line);
702 if (dependentModule == null) {
706 return findIdentity(dependentModule.getAddedIdentities(), name);
708 return findIdentity(module.getAddedIdentities(), baseString);
712 public static IdentitySchemaNodeBuilder findIdentity(final Set<IdentitySchemaNodeBuilder> identities,
714 for (IdentitySchemaNodeBuilder identity : identities) {
715 if (identity.getQName().getLocalName().equals(name)) {
723 * Get module in which this node is defined.
726 * @return builder of module where this node is defined
728 public static ModuleBuilder getParentModule(final Builder node) {
729 if (node instanceof ModuleBuilder) {
730 return (ModuleBuilder) node;
732 Builder parent = node.getParent();
733 while (!(parent instanceof ModuleBuilder)) {
734 parent = parent.getParent();
736 Preconditions.checkState(parent instanceof ModuleBuilder);
737 ModuleBuilder parentModule = (ModuleBuilder) parent;
738 if (parentModule.isSubmodule()) {
739 parentModule = parentModule.getParent();
744 public static Set<DataSchemaNodeBuilder> wrapChildNodes(final String moduleName, final int line,
745 final Set<DataSchemaNode> nodes, final SchemaPath parentPath, final URI ns, final Date rev,
747 Set<DataSchemaNodeBuilder> result = new HashSet<>();
749 for (DataSchemaNode node : nodes) {
750 QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
751 DataSchemaNodeBuilder wrapped = wrapChildNode(moduleName, line, node, parentPath, qname);
757 public static DataSchemaNodeBuilder wrapChildNode(final String moduleName, final int line,
758 final DataSchemaNode node, final SchemaPath parentPath, final QName qname) {
760 final SchemaPath schemaPath = parentPath.createChild(qname);
762 if (node instanceof AnyXmlSchemaNode) {
763 return new AnyXmlBuilder(moduleName, line, qname, schemaPath, ((AnyXmlSchemaNode) node));
764 } else if (node instanceof ChoiceNode) {
765 return new ChoiceBuilder(moduleName, line, qname, schemaPath, ((ChoiceNode) node));
766 } else if (node instanceof ContainerSchemaNode) {
767 return new ContainerSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((ContainerSchemaNode) node));
768 } else if (node instanceof LeafSchemaNode) {
769 return new LeafSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((LeafSchemaNode) node));
770 } else if (node instanceof LeafListSchemaNode) {
771 return new LeafListSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((LeafListSchemaNode) node));
772 } else if (node instanceof ListSchemaNode) {
773 return new ListSchemaNodeBuilder(moduleName, line, qname, schemaPath, ((ListSchemaNode) node));
774 } else if (node instanceof ChoiceCaseNode) {
775 return new ChoiceCaseBuilder(moduleName, line, qname, schemaPath, ((ChoiceCaseNode) node));
777 throw new YangParseException(moduleName, line, "Failed to copy node: Unknown type of DataSchemaNode: "
782 public static Set<GroupingBuilder> wrapGroupings(final String moduleName, final int line,
783 final Set<GroupingDefinition> nodes, final SchemaPath parentPath, final URI ns, final Date rev,
785 Set<GroupingBuilder> result = new HashSet<>();
786 for (GroupingDefinition node : nodes) {
787 QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
788 SchemaPath schemaPath = parentPath.createChild(qname);
789 result.add(new GroupingBuilderImpl(moduleName, line, qname, schemaPath, node));
794 public static Set<TypeDefinitionBuilder> wrapTypedefs(final String moduleName, final int line,
795 final DataNodeContainer dataNode, final SchemaPath parentPath, final URI ns, final Date rev,
797 Set<TypeDefinition<?>> nodes = dataNode.getTypeDefinitions();
798 Set<TypeDefinitionBuilder> result = new HashSet<>();
799 for (TypeDefinition<?> node : nodes) {
800 QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
801 SchemaPath schemaPath = parentPath.createChild(qname);
802 result.add(new TypeDefinitionBuilderImpl(moduleName, line, qname, schemaPath, ((ExtendedType) node)));
807 public static List<UnknownSchemaNodeBuilderImpl> wrapUnknownNodes(final String moduleName, final int line,
808 final List<UnknownSchemaNode> nodes, final SchemaPath parentPath, final URI ns, final Date rev,
810 List<UnknownSchemaNodeBuilderImpl> result = new ArrayList<>();
811 for (UnknownSchemaNode node : nodes) {
812 QName qname = new QName(ns, rev, pref, node.getQName().getLocalName());
813 SchemaPath schemaPath = parentPath.createChild(qname);
814 result.add(new UnknownSchemaNodeBuilderImpl(moduleName, line, qname, schemaPath, node));
819 private static final class ByteSourceImpl extends ByteSource {
820 private final String toString;
821 private final ByteArrayOutputStream output = new ByteArrayOutputStream();
823 private ByteSourceImpl(final InputStream input) throws IOException {
824 toString = input.toString();
825 IOUtils.copy(input, output);
829 public InputStream openStream() throws IOException {
830 return new NamedByteArrayInputStream(output.toByteArray(), toString);