/*
* 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;
}
}