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.data.impl;
10 import java.util.AbstractMap.SimpleEntry;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
15 import java.util.Stack;
17 import javax.xml.parsers.DocumentBuilder;
18 import javax.xml.parsers.DocumentBuilderFactory;
19 import javax.xml.parsers.ParserConfigurationException;
20 import javax.xml.xpath.XPath;
21 import javax.xml.xpath.XPathConstants;
22 import javax.xml.xpath.XPathExpression;
23 import javax.xml.xpath.XPathExpressionException;
24 import javax.xml.xpath.XPathFactory;
26 import com.google.common.collect.Maps;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
29 import org.opendaylight.yangtools.yang.data.api.ModifyAction;
30 import org.opendaylight.yangtools.yang.data.api.Node;
31 import org.opendaylight.yangtools.yang.data.api.NodeModification;
32 import org.opendaylight.yangtools.yang.data.api.SimpleNode;
33 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
34 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
36 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.w3c.dom.Element;
41 import com.google.common.base.Joiner;
42 import com.google.common.collect.Lists;
45 * @author michal.rehak
48 public abstract class NodeUtils {
50 private static final Logger LOG = LoggerFactory.getLogger(NodeUtils.class);
55 private static final String USER_KEY_NODE = "node";
59 * @return node path up till root node
61 public static String buildPath(Node<?> node) {
62 List<String> breadCrumbs = new ArrayList<>();
63 Node<?> tmpNode = node;
64 while (tmpNode != null) {
65 breadCrumbs.add(0, tmpNode.getNodeType().getLocalName());
66 tmpNode = tmpNode.getParent();
69 return Joiner.on(".").join(breadCrumbs);
74 * @return dom tree, containing same node structure, yang nodes are
75 * associated to dom nodes as user data
77 public static org.w3c.dom.Document buildShadowDomTree(CompositeNode treeRootNode) {
78 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
79 org.w3c.dom.Document doc = null;
81 DocumentBuilder bob = dbf.newDocumentBuilder();
82 doc = bob.newDocument();
83 } catch (ParserConfigurationException e) {
84 LOG.error("documentBuilder problem", e);
88 Stack<SimpleEntry<org.w3c.dom.Node, Node<?>>> jobQueue = new Stack<>();
89 jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(doc, treeRootNode));
91 while (!jobQueue.isEmpty()) {
92 SimpleEntry<org.w3c.dom.Node, Node<?>> job = jobQueue.pop();
93 org.w3c.dom.Node jointPlace = job.getKey();
94 Node<?> item = job.getValue();
95 QName nodeType = item.getNodeType();
96 Element itemEl = doc.createElementNS(nodeType.getNamespace().toString(), item.getNodeType().getLocalName());
97 itemEl.setUserData(USER_KEY_NODE, item, null);
98 if (item instanceof SimpleNode<?>) {
99 Object value = ((SimpleNode<?>) item).getValue();
101 itemEl.setTextContent(String.valueOf(value));
104 if (item instanceof NodeModification) {
105 ModifyAction modificationAction = ((NodeModification) item).getModificationAction();
106 if (modificationAction != null) {
107 itemEl.setAttribute("modifyAction", modificationAction.toString());
111 jointPlace.appendChild(itemEl);
113 if (item instanceof CompositeNode) {
114 for (Node<?> child : ((CompositeNode) item).getChildren()) {
115 jobQueue.push(new SimpleEntry<org.w3c.dom.Node, Node<?>>(itemEl, child));
126 * @return user data value on found node
127 * @throws XPathExpressionException
129 @SuppressWarnings("unchecked")
130 public static <T> T findNodeByXpath(org.w3c.dom.Document doc, String xpathEx) throws XPathExpressionException {
132 XPathFactory xPathfactory = XPathFactory.newInstance();
133 XPath xpath = xPathfactory.newXPath();
134 XPathExpression expr = xpath.compile(xpathEx);
136 org.w3c.dom.Node result = (org.w3c.dom.Node) expr.evaluate(doc, XPathConstants.NODE);
137 if (result != null) {
138 userNode = (T) result.getUserData(USER_KEY_NODE);
145 * build NodeMap, where key = qName; value = node
148 * @return map of children, where key = qName and value is list of children
151 public static Map<QName, List<Node<?>>> buildNodeMap(List<Node<?>> value) {
152 Map<QName, List<Node<?>>> nodeMapTmp = Maps.newLinkedHashMap();
154 throw new IllegalStateException("nodeList should not be null or empty");
156 for (Node<?> node : value) {
157 List<Node<?>> qList = nodeMapTmp.get(node.getNodeType());
159 qList = new ArrayList<>();
160 nodeMapTmp.put(node.getNodeType(), qList);
169 * @return map of lists, where key = path; value = {@link DataSchemaNode}
171 public static Map<String, ListSchemaNode> buildMapOfListNodes(SchemaContext context) {
172 Map<String, ListSchemaNode> mapOfLists = new HashMap<>();
174 Stack<DataSchemaNode> jobQueue = new Stack<>();
175 jobQueue.addAll(context.getDataDefinitions());
177 while (!jobQueue.isEmpty()) {
178 DataSchemaNode dataSchema = jobQueue.pop();
179 if (dataSchema instanceof ListSchemaNode) {
180 mapOfLists.put(schemaPathToPath(dataSchema.getPath().getPath()), (ListSchemaNode) dataSchema);
183 if (dataSchema instanceof DataNodeContainer) {
184 jobQueue.addAll(((DataNodeContainer) dataSchema).getChildNodes());
195 private static String schemaPathToPath(List<QName> qNamesPath) {
196 List<String> pathSeed = new ArrayList<>();
197 for (QName qNameItem : qNamesPath) {
198 pathSeed.add(qNameItem.getLocalName());
200 return Joiner.on(".").join(pathSeed);
204 * add given node to it's parent's list of children
208 public static void fixParentRelation(Node<?> newNode) {
209 if (newNode.getParent() != null) {
210 List<Node<?>> siblings = newNode.getParent().getChildren();
211 if (!siblings.contains(newNode)) {
212 siblings.add(newNode);
218 * crawl all children of given node and assign it as their parent
222 public static void fixChildrenRelation(CompositeNode parentNode) {
223 if (parentNode.getChildren() != null) {
224 for (Node<?> child : parentNode.getChildren()) {
225 if (child instanceof AbstractNodeTO<?>) {
226 ((AbstractNodeTO<?>) child).setParent(parentNode);
235 * @return list of values of map, found by given keys
237 public static <T, K> List<K> collectMapValues(List<T> keys, Map<T, K> dataMap) {
238 List<K> valueSubList = new ArrayList<>();
240 valueSubList.add(dataMap.get(key));
248 * @return list of children in list of appropriate type
250 public static List<Node<?>> buildChildrenList(Node<?>... nodes) {
251 return Lists.newArrayList(nodes);