Java tutorial
/******************************************************************************* * Copyright (c) 2000, 2005 Jiva Medical and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Jiva Medical - initial API and implementation *******************************************************************************/ package org.eclipse.uomo.xml.test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.lang.StringUtils; import org.eclipse.uomo.core.UOMoException; import org.eclipse.uomo.xml.impl.XMLReader; import org.eclipse.uomo.xml.impl.XMLWriter; import org.eclipse.uomo.xml.impl.XMLWriterParser; import org.junit.Before; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.Text; import org.xml.sax.SAXException; public abstract class XMLTestCase implements XMLTestConfiguration { @Before public void setUp() throws Exception { // super.setUp(); checkOsxXmlHandlers(); } public static void checkOsxXmlHandlers() { // this is a workaround for a weird OSX related issue - something to do // with the way Apple register Crimson. // feel free to disable it if it's not a problem for you if (isOsx()) { System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl"); System.setProperty("javax.xml.parsers.SAXParserFactory", "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl"); System.setProperty("org.w3c.dom.DOMImplementationSourceList", "com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl"); } } private void prettyXML(String source, String dest) throws SAXException, IOException { XMLWriter dst = new XMLWriter(new FileOutputStream(new File(dest)), "UTF-8"); dst.setPretty(true); dst.setSortAttributes(true); XMLReader src = new XMLReader(new XMLWriterParser(dst)); src.parse(new FileInputStream(new File(source))); } private final static int CR = 13; private final static int LF = 10; protected void compareDOMs(String filename1, String filename2, String name1, String name2) throws FileNotFoundException, ParserConfigurationException, SAXException, IOException, InterruptedException, UOMoException { Document one = loadDom(filename1); Document two = loadDom(filename2); String diff = compareElements(one.getDocumentElement(), two.getDocumentElement(), "/"); if (diff != null) { showDiff(filename1, filename2, name1, name2, true, diff); } } private String compareElements(Element e1, Element e2, String p) { if (!e1.getNamespaceURI().equals(e2.getNamespaceURI())) return "element namespaces differ at " + p; if (!e1.getLocalName().equals(e2.getLocalName())) return "element names differ at " + p; String msg = compareAttributes(e1, e2, p); if (msg != null) return msg; p = p + "/" + e1.getNodeName(); int i = 0; Node c1 = getNextRelevantNode(e1.getFirstChild()); Node c2 = getNextRelevantNode(e2.getFirstChild()); while (c1 != null && c2 != null) { if (c1.getNodeType() != c2.getNodeType()) return "Different node types (" + Integer.toString(c1.getNodeType()) + "/" + c2.getNodeType() + ") @ " + p; msg = null; if (c1.getNodeType() == Node.TEXT_NODE) { msg = compareTexts((Text) c1, (Text) c2, p + "[" + Integer.toString(i) + "]"); } else if (c1.getNodeType() == Node.ELEMENT_NODE) { msg = compareElements((Element) c1, (Element) c2, p + "[" + Integer.toString(i) + "]"); } else msg = "unknown node type " + Integer.toString(c1.getNodeType()); if (msg != null) return msg; c1 = getNextRelevantNode(c1.getNextSibling()); c2 = getNextRelevantNode(c2.getNextSibling()); i++; } if (c1 != null && c2 == null) return "node present in one and not in two @ " + p; if (c2 != null && c1 == null) return "node present in two and not in one @ " + p; return null; } private String compareAttributes(Element e1, Element e2, String p) { NamedNodeMap n1 = e1.getAttributes(); NamedNodeMap n2 = e2.getAttributes(); for (int i = 0; i < n1.getLength(); i++) { Node a1 = n1.item(0); Node a2 = n2.getNamedItemNS(a1.getNamespaceURI(), a1.getLocalName()); if (a2 == null) return "Unable to find attribute " + a1.getNodeName() + " @ " + p; if (a1.getNodeValue() != null || a2.getNodeValue() != null) { if (a1.getNodeValue() == null || a2.getNodeValue() == null || !a1.getNodeValue().equals(a2.getNodeValue())) return "Attribute text differs @ " + p + "/@" + a1.getNodeName() + ": '" + a1.getNodeValue() + "' / '" + a2.getNodeValue() + "'"; } } for (int i = 0; i < n2.getLength(); i++) { Node a2 = n2.item(0); Node a1 = n1.getNamedItemNS(a2.getNamespaceURI(), a2.getLocalName()); if (a1 == null) return "Unable to find attribute " + a2.getNodeName() + " @ " + p; if (a1.getNodeValue() != null || a2.getNodeValue() != null) { if (a1.getNodeValue() == null || a2.getNodeValue() == null || !a1.getNodeValue().equals(a2.getNodeValue())) return "Attribute text differs @ " + p + "/@" + a1.getNodeName() + ": '" + a1.getNodeValue() + "' / '" + a2.getNodeValue() + "'"; } } return null; } private String compareTexts(Text c1, Text c2, String p) { String s1 = normaliseWhitespace(c1.getNodeValue()); String s2 = normaliseWhitespace(c2.getNodeValue()); if (s1 == null && s2 == null) return null; else if (s1 == null || s2 == null || !s1.equals(s2)) return "Text differs @ " + p + ": '" + s1 + "' / '" + s2 + "'"; else return null; } private String normaliseWhitespace(String s) { StringBuilder bldr = new StringBuilder(); boolean w = false; for (Character ch : s.toCharArray()) { if (!Character.isWhitespace(ch)) { bldr.append(ch); w = false; } else if (!w) { bldr.append(' '); w = true; } else { // nothing } } return bldr.toString(); } private Node getNextRelevantNode(Node node) { while (node != null && node.getNodeType() != Node.ELEMENT_NODE && !(node.getNodeType() == Node.TEXT_NODE && !StringUtils.isWhitespace(node.getNodeValue()))) node = node.getNextSibling(); return node; } private Document loadDom(String filename) throws ParserConfigurationException, FileNotFoundException, SAXException, IOException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); File file = new File(filename); return builder.parse(new FileInputStream(file)); } protected void compareXMLs(String filename1, String filename2, String name1, String name2, boolean makePretty) throws IOException, UOMoException, InterruptedException, SAXException { FileInputStream one = new FileInputStream(new File(filename1)); FileInputStream two = new FileInputStream(new File(filename2)); int size1 = one.available(); int size2 = two.available(); boolean same = true; int count = 0; int ia1 = -1; int ia2 = -1; while (same && one.available() > 0 && two.available() > 0) { int i1 = ia1 != -1 ? ia1 : one.read(); ia1 = -1; int i2 = ia2 != -1 ? ia2 : two.read(); ia2 = -1; if (i1 == CR) { i1 = LF; ia1 = one.read(); if (ia1 == LF) ia1 = -1; } if (i2 == CR) { i2 = LF; ia2 = two.read(); if (ia2 == LF) ia2 = -1; } same = i1 == i2; count++; } int left1 = one.available(); int left2 = two.available(); one.close(); two.close(); if (!same || left1 > 0 || left2 > 0) { if (!same) showDiff(filename1, filename2, name1, name2, makePretty, "Content is not as expected @ " + Integer.toString(count) + " of " + Integer.toString(size1) + "/" + Integer.toString(size2)); else showDiff(filename1, filename2, name1, name2, makePretty, "Content is same until end of file @ " + Integer.toString(size1) + "/" + Integer.toString(size2)); } } private void showDiff(String filename1, String filename2, String name1, String name2, boolean makePretty, String msg) throws SAXException, IOException, InterruptedException, UOMoException { if (makePretty) { prettyXML(filename1, TEMP_PATH + name1 + ".xml"); prettyXML(filename2, TEMP_PATH + name2 + ".xml"); } else { copyFile(filename1, TEMP_PATH + name1 + ".xml"); copyFile(filename2, TEMP_PATH + name2 + ".xml"); } if (!SKIP_THIRD_PARTY) { if (isOsx()) Runtime.getRuntime() .exec(COMPARE_PATH + " " + TEMP_PATH + name1 + ".xml" + " " + TEMP_PATH + name2 + ".xml"); else Runtime.getRuntime().exec(COMPARE_PATH + " \"" + TEMP_PATH + name1 + ".xml" + "\" \"" + TEMP_PATH + name2 + ".xml" + "\""); } Thread.sleep(1000); throw new UOMoException(msg); } private void copyFile(String source, String dest) throws SAXException, IOException { InputStream in = new FileInputStream(new File(source)); OutputStream out = new FileOutputStream(new File(dest)); // Transfer bytes from in to out byte[] buf = new byte[1024]; int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } in.close(); out.close(); } protected void compareFiles(String filename1, String filename2) throws IOException, UOMoException, InterruptedException { FileInputStream one = new FileInputStream(new File(filename1)); FileInputStream two = new FileInputStream(new File(filename2)); boolean same = one.available() == two.available(); while (same && one.available() > 0) { same = one.read() == two.read(); } if (!same) { if (!SKIP_THIRD_PARTY) Runtime.getRuntime().exec(COMPARE_PATH + " \"" + filename1 + "\" \"" + filename2 + "\""); Thread.sleep(1000); throw new UOMoException("Content is not as expected @ " + Integer.toString(one.available())); } } protected void compareStrings(String content1, String content2) throws IOException, UOMoException, InterruptedException { String filename1 = TEMP_FILENAME + "1"; String filename2 = TEMP_FILENAME + "2"; stringToFile(content1, filename1); stringToFile(content2, filename2); compareFiles(filename1, filename2); } private void stringToFile(String content, String filename) throws IOException { FileWriter file = new FileWriter(new File(filename)); file.write(content); file.flush(); file.close(); } protected static boolean isOsx() { String lcOSName = System.getProperty("os.name").toLowerCase(); boolean MAC_OS_X = lcOSName.startsWith("mac os x"); return MAC_OS_X; } }