/** * 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.camel.converter.jaxp; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.StringReader; import java.nio.charset.Charset; import java.util.Arrays; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import org.apache.camel.ContextTestSupport; import org.apache.camel.Exchange; import org.apache.camel.impl.DefaultExchange; public class StaxConverterTest extends ContextTestSupport { private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); private static final Charset UTF_8 = Charset.forName("UTF-8"); private static final String TEST_XML = "<test>Test Message with umlaut \u00E4\u00F6\u00FC</test>"; // umlauts have different encoding in UTF-8 and ISO-8859-1 (Latin1) private static final String TEST_XML_WITH_XML_HEADER_ISO_8859_1 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + TEST_XML; private static final ByteArrayInputStream TEST_XML_WITH_XML_HEADER_ISO_8859_1_AS_BYTE_ARRAY_STREAM = new ByteArrayInputStream( TEST_XML_WITH_XML_HEADER_ISO_8859_1.getBytes(ISO_8859_1)); private static final String TEST_XML_WITH_XML_HEADER = "<?xml version=\"1.0\"?>" + TEST_XML; private static final String TEST_XML_7000; static { StringBuilder sb = new StringBuilder(7000); // using quote character to make the plain characters comparison work with the generated xml sb.append("<?xml version='1.0' encoding='utf-8'?>").append("<list>"); int n = 6963 - TEST_XML.length(); while (n > 0) { sb.append(TEST_XML); n -= TEST_XML.length(); } sb.append("</list>"); TEST_XML_7000 = sb.toString(); } public void testEncodingXmlEventReader() throws Exception { TEST_XML_WITH_XML_HEADER_ISO_8859_1_AS_BYTE_ARRAY_STREAM.reset(); XMLEventReader reader = null; XMLEventWriter writer = null; ByteArrayOutputStream output = null; try { // enter text encoded with Latin1 reader = context.getTypeConverter().mandatoryConvertTo(XMLEventReader.class, TEST_XML_WITH_XML_HEADER_ISO_8859_1_AS_BYTE_ARRAY_STREAM); output = new ByteArrayOutputStream(); // ensure UTF-8 encoding Exchange exchange = new DefaultExchange(context); exchange.setProperty(Exchange.CHARSET_NAME, UTF_8.toString()); writer = context.getTypeConverter().mandatoryConvertTo(XMLEventWriter.class, exchange, output); while (reader.hasNext()) { writer.add(reader.nextEvent()); } } finally { if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } } assertNotNull(output); String result = new String(output.toByteArray(), UTF_8.name()); // normalize the auotation mark if (result.indexOf('\'') > 0) { result = result.replace('\'', '"'); } boolean equals = TEST_XML_WITH_XML_HEADER.equals(result) || TEST_XML_WITH_XML_HEADER_ISO_8859_1.equals(result); assertTrue("Should match header", equals); } public void testEncodingXmlStreamReader() throws Exception { TEST_XML_WITH_XML_HEADER_ISO_8859_1_AS_BYTE_ARRAY_STREAM.reset(); XMLStreamReader reader = null; XMLStreamWriter writer = null; ByteArrayOutputStream output = null; try { // enter text encoded with Latin1 reader = context.getTypeConverter().mandatoryConvertTo(XMLStreamReader.class, TEST_XML_WITH_XML_HEADER_ISO_8859_1_AS_BYTE_ARRAY_STREAM); output = new ByteArrayOutputStream(); // ensure UTF-8 encoding Exchange exchange = new DefaultExchange(context); exchange.setProperty(Exchange.CHARSET_NAME, UTF_8.name()); writer = context.getTypeConverter().mandatoryConvertTo(XMLStreamWriter.class, exchange, output); // copy to writer while (reader.hasNext()) { reader.next(); switch (reader.getEventType()) { case XMLStreamConstants.START_DOCUMENT: writer.writeStartDocument(); break; case XMLStreamConstants.END_DOCUMENT: writer.writeEndDocument(); break; case XMLStreamConstants.START_ELEMENT: writer.writeStartElement(reader.getName().getLocalPart()); break; case XMLStreamConstants.CHARACTERS: writer.writeCharacters(reader.getText()); break; case XMLStreamConstants.END_ELEMENT: writer.writeEndElement(); break; default: break; } } } finally { if (reader != null) { reader.close(); } if (writer != null) { writer.close(); } } assertNotNull(output); String result = new String(output.toByteArray(), UTF_8.name()); assertEquals(TEST_XML, result); } public void testToReaderByXmlStreamReader() throws Exception { StringReader src = new StringReader(TEST_XML_7000); XMLStreamReader xreader = null; Reader reader = null; try { xreader = context.getTypeConverter().mandatoryConvertTo(XMLStreamReader.class, src); reader = context.getTypeConverter().mandatoryConvertTo(Reader.class, xreader); // verify StringReader expected = new StringReader(TEST_XML_7000); char[] tmp1 = new char[512]; char[] tmp2 = new char[512]; for (;;) { int n1 = 0; int n2 = 0; try { n1 = expected.read(tmp1, 0, tmp1.length); n2 = reader.read(tmp2, 0, tmp2.length); } catch (IOException e) { fail("unable to read data"); } assertEquals(n1, n2); if (n2 < 0) { break; } assertTrue(Arrays.equals(tmp1, tmp2)); } } finally { if (xreader != null) { xreader.close(); } if (reader != null) { reader.close(); } } } public void testToInputSreamByXmlStreamReader() throws Exception { StringReader src = new StringReader(TEST_XML_7000); XMLStreamReader xreader = null; InputStream in = null; try { xreader = context.getTypeConverter().mandatoryConvertTo(XMLStreamReader.class, src); in = context.getTypeConverter().mandatoryConvertTo(InputStream.class, xreader); // verify InputStream expected = new ByteArrayInputStream(TEST_XML_7000.getBytes("utf-8")); byte[] tmp1 = new byte[512]; byte[] tmp2 = new byte[512]; for (;;) { int n1 = 0; int n2 = 0; try { n1 = expected.read(tmp1, 0, tmp1.length); n2 = in.read(tmp2, 0, tmp2.length); } catch (IOException e) { fail("unable to read data"); } assertEquals(n1, n2); if (n2 < 0) { break; } assertTrue(Arrays.equals(tmp1, tmp2)); } } finally { if (xreader != null) { xreader.close(); } if (in != null) { in.close(); } } } }