/**
* 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.cxf.staxutils.transform;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.stream.StreamSource;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.staxutils.StaxUtils;
import org.junit.Assert;
/**
*
*/
public final class TransformTestUtils {
private static final Logger LOG = LogUtils.getLogger(TransformTestUtils.class);
private TransformTestUtils() {
}
// test utilities methods
static void transformInStreamAndCompare(String inname, String outname,
Map<String, String> transformElements,
Map<String, String> appendElements,
List<String> dropElements,
Map<String, String> transformAttributes,
Map<String, String> appendAttributes)
throws XMLStreamException {
XMLStreamReader reader = createInTransformedStreamReader(inname,
transformElements,
appendElements,
dropElements,
transformAttributes);
XMLStreamReader teacher =
StaxUtils.createXMLStreamReader(
TransformTestUtils.class.getResourceAsStream(outname));
verifyReaders(teacher, reader, false, true);
}
static void transformOutStreamAndCompare(String inname, String outname,
Map<String, String> transformElements,
Map<String, String> appendElements,
List<String> dropElements,
Map<String, String> transformAttributes,
Map<String, String> appendAttributes)
throws XMLStreamException {
XMLStreamReader reader = createOutTransformedStreamReader(inname,
transformElements, appendElements,
dropElements, transformAttributes,
false, null);
XMLStreamReader teacher =
StaxUtils.createXMLStreamReader(
TransformTestUtils.class.getResourceAsStream(outname));
verifyReaders(teacher, reader, false, true);
}
static XMLStreamReader createInTransformedStreamReader(
String file,
Map<String, String> emap,
Map<String, String> eappend,
List<String> dropEls,
Map<String, String> amap) throws XMLStreamException {
return new InTransformReader(StaxUtils.createXMLStreamReader(
TransformTestUtils.class.getResourceAsStream(file)),
emap, eappend, dropEls, amap, false);
}
static XMLStreamReader createOutTransformedStreamReader(
String file,
Map<String, String> emap,
Map<String, String> append,
List<String> dropEls,
Map<String, String> amap,
boolean attributesToElements,
String defaultNamespace) throws XMLStreamException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
XMLStreamWriter writer =
new OutTransformWriter(StaxUtils.createXMLStreamWriter(os, StandardCharsets.UTF_8.name()),
emap, append, dropEls, amap, attributesToElements, defaultNamespace);
StaxUtils.copy(new StreamSource(TransformTestUtils.class.getResourceAsStream(file)), writer);
writer.flush();
return StaxUtils.createXMLStreamReader(new ByteArrayInputStream(os.toByteArray()));
}
/**
* Verifies the two stream events are equivalent and throws an assertion
* exception at the first mismatch.
* @param teacher
* @param reader
* @param eec
* @throws XMLStreamException
*/
static void verifyReaders(XMLStreamReader teacher, XMLStreamReader reader,
boolean eec, boolean pfx) throws XMLStreamException {
// compare the elements and attributes while ignoring comments, line breaks, etc
for (;;) {
int revent = getNextEvent(reader);
int tevent = getNextEvent(teacher);
if (revent == -1 && tevent == -1) {
break;
}
LOG.fine("Event: " + tevent + " ? " + revent);
Assert.assertEquals("parsing event", tevent, revent);
switch (revent) {
case XMLStreamConstants.START_ELEMENT:
LOG.fine("Start Element " + teacher.getName() + " ? " + reader.getName());
Assert.assertEquals("wrong start element.", teacher.getName(), reader.getName());
if (pfx) {
// verify if the namespace prefix are preserved
Assert.assertEquals("wrong start element prefix.", teacher.getPrefix(), reader.getPrefix());
verifyNamespaceDeclarations(teacher, reader);
}
verifyAttributes(teacher, reader);
break;
case XMLStreamConstants.END_ELEMENT:
LOG.fine("End Element " + teacher.getName() + " ? " + reader.getName());
if (eec) {
// perform end-element-check
Assert.assertEquals("wrong end element qname.", teacher.getName(), reader.getName());
}
break;
case XMLStreamConstants.CHARACTERS:
LOG.fine("Characters " + teacher.getText() + " ? " + reader.getText());
Assert.assertEquals("wrong characteres.", teacher.getText(), reader.getText());
break;
default:
}
}
}
private static void verifyAttributes(XMLStreamReader teacher, XMLStreamReader reader) {
int acount = teacher.getAttributeCount();
Assert.assertEquals(acount, reader.getAttributeCount());
Map<QName, String> attributesMap = new HashMap<>();
// temporarily store all the attributes
for (int i = 0; i < acount; i++) {
attributesMap.put(reader.getAttributeName(i), reader.getAttributeValue(i));
}
// compares each attribute
for (int i = 0; i < acount; i++) {
String avalue = attributesMap.remove(teacher.getAttributeName(i));
Assert.assertEquals("attribute " + teacher.getAttributeName(i) + " has wrong value.",
teacher.getAttributeValue(i), avalue);
}
// attributes must be exhausted
Assert.assertTrue("attributes must be exhausted.", attributesMap.isEmpty());
}
private static void verifyNamespaceDeclarations(XMLStreamReader teacher, XMLStreamReader reader) {
int dcount = teacher.getNamespaceCount();
for (int i = 0; i < dcount; i++) {
String p = teacher.getNamespacePrefix(i);
Assert.assertEquals("nsdecl prefix " + p + " is incorrectly bound.",
teacher.getNamespaceURI(i), reader.getNamespaceURI(p));
}
}
/**
* Returns the next relevant reader event.
*
* @param reader
* @return
* @throws XMLStreamException
*/
private static int getNextEvent(XMLStreamReader reader) throws XMLStreamException {
while (reader.hasNext()) {
int e = reader.next();
if (e == XMLStreamConstants.END_DOCUMENT) {
return e;
}
if (e == XMLStreamConstants.START_ELEMENT || e == XMLStreamConstants.END_ELEMENT) {
return e;
} else if (e == XMLStreamConstants.CHARACTERS) {
String text = reader.getText();
if (text.trim().length() == 0) {
continue;
}
return e;
}
}
return -1;
}
}