blob: d661f976d777854f3ffa7515b0e2bb7854366cdc [file] [log] [blame]
/*
* Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.persistence.testing.jaxb.beanvalidation;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* Compares contents of two xml files. Ignores whitespaces.
*
* @author jungi
*/
public final class ContentComparator {
private static final Logger LOGGER = Logger.getLogger(ContentComparator.class.getName());
/** Creates a new instance of ContentComparator */
private ContentComparator() {
}
/**
* Compares content of two xml files. Ignores whitespaces.
*
* @param f1 usually golden file
* @param f2 other file which we want to compare against golden file (or any other file)
* @return true if both files have the same content except of whitespaces
*/
public static boolean equalsXML(File f1, File f2) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document d1 = db.parse(f1);
Document d2 = db.parse(f2);
return compare(d1.getDocumentElement(), d2.getDocumentElement());
} catch (ParserConfigurationException e) {
LOGGER.log(Level.WARNING, "Exception from test - comparing XML files", e); //NOI18N
} catch (SAXException e) {
LOGGER.log(Level.WARNING, "Exception from test - comparing XML files", e); //NOI18N
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Exception from test - comparing XML files", e); //NOI18N
}
return false;
}
private static boolean compare(Node n1, Node n2) {
List<Node> l1 = new LinkedList<Node>();
List<Node> l2 = new LinkedList<Node>();
l1.add(n1);
l2.add(n2);
while (!l1.isEmpty() && !l2.isEmpty()) {
Node m1 = l1.remove(0);
Node m2 = l2.remove(0);
//check basic things - node name, value, attributes - if they're OK, we can continue
if (sameNode(m1, m2)) {
//now compare children
NodeList nl = m1.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node e = nl.item(i);
if (e.getNodeType() == Node.TEXT_NODE) {
//ignore empty places
if (e.getNodeValue().trim().equals("")) {
continue;
}
}
l1.add(nl.item(i));
}
nl = m2.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node e = nl.item(i);
if (e.getNodeType() == Node.TEXT_NODE) {
//ignore empty places
if (e.getNodeValue().trim().equals("")) {
continue;
}
}
l2.add(nl.item(i));
}
} else {
//nodes are not equals - print some info
LOGGER.warning("================================================"); //NOI18N
LOGGER.warning("m1: " + m1.getNodeName() + "; \'" + m1.getNodeValue() + "\'"); //NOI18N
LOGGER.warning("m2: " + m2.getNodeName() + "; \'" + m2.getNodeValue() + "\'"); //NOI18N
LOGGER.warning("================================================"); //NOI18N
return false;
}
}
// check remains
if (!l1.isEmpty()) {
// missing nodes
LOGGER.warning("================================================"); //NOI18N
LOGGER.warning("Expected " + l1.size() + " more node(s):"); //NOI18N
logNodes(l1);
LOGGER.warning("================================================"); //NOI18N
return false;
} else if (!l2.isEmpty()) {
// extra nodes
LOGGER.warning("================================================"); //NOI18N
LOGGER.warning("Got " + l2.size() + " more node(s) than expected:"); //NOI18N
logNodes(l2);
LOGGER.warning("================================================"); //NOI18N
return false;
} else {
return true;
}
}
//attrs, name, value
private static boolean sameNode(Node n1, Node n2) {
//check node name
if (!n1.getNodeName().equals(n2.getNodeName())) {
LOGGER.warning("================================================"); //NOI18N
LOGGER.warning("Expected node: " + n1.getNodeName() + ", got: " + n2.getNodeName()); //NOI18N
LOGGER.warning("================================================"); //NOI18N
return false;
}
//check node value
if (!((n1.getNodeValue() != null)
? n1.getNodeValue().equals(n2.getNodeValue())
: (n2.getNodeValue() == null))) {
LOGGER.warning("================================================"); //NOI18N
LOGGER.warning("Expected node value: " + n1.getNodeValue() + ", got: " + n2.getNodeValue()); //NOI18N
LOGGER.warning("================================================"); //NOI18N
return false;
}
//check node attributes
NamedNodeMap nnm1 = n1.getAttributes();
NamedNodeMap nnm2 = n2.getAttributes();
if ((nnm1 == null && nnm2 != null)
|| (nnm1 != null && nnm2 == null)) {
return false;
}
if (nnm1 == null) {
return true;
}
for (int i = 0; i < nnm1.getLength(); i++) {
Node x = nnm1.item(i);
Node y = nnm2.item(i);
if (!(x.getNodeName().equals(y.getNodeName())
&& x.getNodeValue().equals(y.getNodeValue()))) {
//nodes are not equals - print some info
LOGGER.warning("================================================"); //NOI18N
LOGGER.warning("Expected attribute: " + x.getNodeName() + "=\'" + x.getNodeValue() + "\'," //NOI18N
+ " got: " + y.getNodeName() + "=\'" + y.getNodeValue() + "\'"); //NOI18N
LOGGER.warning("================================================"); //NOI18N
return false;
}
}
return true;
}
private static void logNodes(List<Node> nodes) {
if (LOGGER.isLoggable(Level.WARNING)) {
for(Node n : nodes) {
LOGGER.warning("Node name: " + n.getNodeName()); //NOI18N
}
}
}
}