/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.openejb.jee; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Characters; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; import java.io.StringReader; /** * @version $Rev$ $Date$ */ public class StaxCompare { public static void compare(final String a, final String b) throws Exception { final StringBuilder message = new StringBuilder(); final XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.SUPPORT_DTD, false); final XMLEventReader rA = factory.createXMLEventReader(new StringReader(a)); final XMLEventReader rB = factory.createXMLEventReader(new StringReader(b)); if (!compare(rA, rB, message)) { throw new Exception(message.toString()); } } public static boolean compare(final XMLEventReader a, final XMLEventReader b, final StringBuilder message) { XMLEvent eventA; XMLEvent eventB; int eventType; try { while ((eventA = nextInterestingEvent(a)) != null & (eventB = nextInterestingEvent(b)) != null) { if ((eventType = eventA.getEventType()) != eventB.getEventType()) { message.append("events of different types: ").append(eventA).append(", ").append(eventB); return false; } if (eventType == XMLStreamConstants.START_ELEMENT) { final StartElement startA = eventA.asStartElement(); final StartElement startB = eventB.asStartElement(); if (!startA.getName().getLocalPart().equals(startB.getName().getLocalPart())) { message.append("Different elements ").append(startA.getName()).append(", ").append(startB.getName()).append(" at location ").append(eventA.getLocation()); return false; } } else if (eventType == XMLStreamConstants.END_ELEMENT) { final EndElement endA = eventA.asEndElement(); final EndElement endB = eventB.asEndElement(); if (!endA.getName().getLocalPart().equals(endB.getName().getLocalPart())) { message.append("Different elements ").append(endA.getName()).append(", ").append(endB.getName()).append(" at location ").append(eventA.getLocation()); return false; } } else if (eventType == XMLStreamConstants.CHARACTERS) { final Characters endA = eventA.asCharacters(); final Characters endB = eventB.asCharacters(); if (!endA.getData().equals(endB.getData())) { message.append("Different content ").append(endA.getData()).append(", ").append(endB.getData()).append(" at location ").append(eventA.getLocation()); return false; } } } if (eventA != null) { message.append("A is longer: ").append(eventA.getLocation()); return false; } if (eventB != null) { message.append("B is longer: ").append(eventB.getLocation()); return false; } } catch (final XMLStreamException e) { message.append("Exception processing ").append(e.getMessage()); return false; } return true; } private static XMLEvent nextInterestingEvent(final XMLEventReader r) throws XMLStreamException { do { final XMLEvent e = r.nextEvent(); final int t = e.getEventType(); if (t == XMLStreamConstants.START_ELEMENT || t == XMLStreamConstants.END_ELEMENT || t == XMLStreamConstants.ATTRIBUTE) { return e; } } while (r.hasNext()); return null; } }