001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package org.apache.geronimo.testsupport; 021 022 import java.io.StringReader; 023 024 import javax.xml.parsers.DocumentBuilder; 025 import javax.xml.parsers.DocumentBuilderFactory; 026 import javax.xml.parsers.ParserConfigurationException; 027 028 import org.w3c.dom.Attr; 029 import org.w3c.dom.Document; 030 import org.w3c.dom.Element; 031 import org.w3c.dom.NamedNodeMap; 032 import org.w3c.dom.Node; 033 import org.w3c.dom.NodeList; 034 import org.w3c.dom.Text; 035 import org.xml.sax.InputSource; 036 037 /** 038 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 039 */ 040 public class DOMUtils { 041 042 public static Document load(String xml) throws Exception { 043 DocumentBuilder builder = getDocumentBuilder(); 044 Document document = builder.parse(new InputSource(new StringReader(xml))); 045 return document; 046 } 047 048 public static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException { 049 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 050 builderFactory.setNamespaceAware(true); 051 DocumentBuilder builder = builderFactory.newDocumentBuilder(); 052 return builder; 053 } 054 055 public static void compareNodes(Node expected, Node actual) throws Exception { 056 if (expected.getNodeType() != actual.getNodeType()) { 057 throw new Exception("Different types of nodes: " + expected + " " + actual); 058 } 059 if (expected instanceof Document) { 060 Document expectedDoc = (Document)expected; 061 Document actualDoc = (Document)actual; 062 compareNodes(expectedDoc.getDocumentElement(), actualDoc.getDocumentElement()); 063 } else if (expected instanceof Element) { 064 Element expectedElement = (Element)expected; 065 Element actualElement = (Element)actual; 066 067 // compare element names 068 if (!expectedElement.getLocalName().equals(actualElement.getLocalName())) { 069 throw new Exception("Element names do not match: " + expectedElement.getLocalName() + " " + actualElement.getLocalName()); 070 } 071 // compare element ns 072 String expectedNS = expectedElement.getNamespaceURI(); 073 String actualNS = actualElement.getNamespaceURI(); 074 if ((expectedNS == null && actualNS != null) || (expectedNS != null && !expectedNS.equals(actualNS))) { 075 throw new Exception("Element namespaces names do not match: " + expectedNS + " " + actualNS); 076 } 077 078 String elementName = "{" + expectedElement.getNamespaceURI() + "}" + actualElement.getLocalName(); 079 080 // compare attributes 081 NamedNodeMap expectedAttrs = expectedElement.getAttributes(); 082 NamedNodeMap actualAttrs = actualElement.getAttributes(); 083 if (countNonNamespaceAttribures(expectedAttrs) != countNonNamespaceAttribures(actualAttrs)) { 084 throw new Exception(elementName + ": Number of attributes do not match up: " + countNonNamespaceAttribures(expectedAttrs) + " " + countNonNamespaceAttribures(actualAttrs)); 085 } 086 for (int i = 0; i < expectedAttrs.getLength(); i++) { 087 Attr expectedAttr = (Attr)expectedAttrs.item(i); 088 if (expectedAttr.getName().startsWith("xmlns")) { 089 continue; 090 } 091 Attr actualAttr = null; 092 if (expectedAttr.getNamespaceURI() == null) { 093 actualAttr = (Attr)actualAttrs.getNamedItem(expectedAttr.getName()); 094 } else { 095 actualAttr = (Attr)actualAttrs.getNamedItemNS(expectedAttr.getNamespaceURI(), expectedAttr.getLocalName()); 096 } 097 if (actualAttr == null) { 098 throw new Exception(elementName + ": No attribute found:" + expectedAttr); 099 } 100 if (!expectedAttr.getValue().equals(actualAttr.getValue())) { 101 throw new Exception(elementName + ": Attribute values do not match: " + expectedAttr.getValue() + " " + actualAttr.getValue()); 102 } 103 } 104 105 // compare children 106 NodeList expectedChildren = expectedElement.getChildNodes(); 107 NodeList actualChildren = actualElement.getChildNodes(); 108 if (expectedChildren.getLength() != actualChildren.getLength()) { 109 throw new Exception(elementName + ": Number of children do not match up: " + expectedChildren.getLength() + " " + actualChildren.getLength()); 110 } 111 for (int i = 0; i < expectedChildren.getLength(); i++) { 112 Node expectedChild = expectedChildren.item(i); 113 Node actualChild = actualChildren.item(i); 114 compareNodes(expectedChild, actualChild); 115 } 116 } else if (expected instanceof Text) { 117 String expectedData = ((Text)expected).getData(); 118 String actualData = ((Text)actual).getData(); 119 120 if (!expectedData.equals(actualData)) { 121 throw new Exception("Text does not match: " + expectedData + " " + actualData); 122 } 123 } 124 } 125 126 private static int countNonNamespaceAttribures(NamedNodeMap attrs) { 127 int n = 0; 128 for (int i = 0; i< attrs.getLength(); i++ ) { 129 Attr attr = (Attr) attrs.item(i); 130 if (!attr.getName().startsWith("xmlns")) { 131 n++; 132 } 133 } 134 return n; 135 } 136 137 }