2 * Copyright (c) 2015 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
9 package org.opendaylight.netconf.util.test;
11 import org.custommonkey.xmlunit.ElementNameAndTextQualifier;
12 import org.custommonkey.xmlunit.ElementQualifier;
13 import org.w3c.dom.Element;
14 import org.w3c.dom.Node;
15 import org.w3c.dom.NodeList;
18 * Custom xmlunit qualifier that doesn't care about order when deeper in the recursion
19 * defaults to comparing element name and text content.
21 public class NetconfXmlUnitRecursiveQualifier implements ElementQualifier {
23 private final ElementQualifier qualifier;
25 public NetconfXmlUnitRecursiveQualifier() {
26 this.qualifier = new ElementNameAndTextQualifier();
29 public NetconfXmlUnitRecursiveQualifier(final ElementQualifier qualifier) {
30 this.qualifier = qualifier;
34 public boolean qualifyForComparison(Element currentControl,
35 Element currentTest) {
36 return compareNodes(currentControl, currentTest);
39 @SuppressWarnings("checkstyle:IllegalCatch")
40 private boolean compareNodes(Node currentControl, Node currentTest) {
43 if (!qualifier.qualifyForComparison((Element) currentControl,
44 (Element) currentTest)) {
48 NodeList controlNodes;
51 if (currentControl.hasChildNodes() && currentTest.hasChildNodes()) {
52 controlNodes = currentControl.getChildNodes();
53 testNodes = currentTest.getChildNodes();
55 return !(currentControl.hasChildNodes() || currentTest.hasChildNodes());
58 return (countNodesWithoutConsecutiveTextNodes(controlNodes)
59 == countNodesWithoutConsecutiveTextNodes(testNodes)) && checkChildren(controlNodes, testNodes);
61 } catch (Exception e) {
66 private boolean checkChildren(NodeList controlNodes, NodeList testNodes) {
67 for (int i = 0; i < controlNodes.getLength(); i++) {
68 boolean matchFound = false;
69 for (int j = 0; j < testNodes.getLength(); j++) {
70 Node controlNode = controlNodes.item(i);
71 Node testNode = testNodes.item(j);
73 if (controlNode.getNodeType() != testNode.getNodeType()) {
77 if (controlNode.getNodeType() == Node.TEXT_NODE) {
78 if (concatenateText(controlNode).equals(concatenateText(testNode))) {
83 } else if (compareNodes(controlNode, testNode)) {
96 private static String concatenateText(Node textNode) {
97 StringBuilder builder = new StringBuilder();
101 if (next.getNodeValue() != null) {
102 builder.append(next.getNodeValue().trim());
103 next = next.getNextSibling();
105 } while (next != null && next.getNodeType() == Node.TEXT_NODE);
107 return builder.toString();
110 private static int countNodesWithoutConsecutiveTextNodes(NodeList nodeList) {
112 boolean lastNodeWasText = false;
113 final int length = nodeList.getLength();
114 for (int i = 0; i < length; i++) {
115 Node node = nodeList.item(i);
116 if (!lastNodeWasText || node.getNodeType() != Node.TEXT_NODE) {
119 lastNodeWasText = node.getNodeType() == Node.TEXT_NODE;