blob: 4f9ed47fce094a7b4a8d0eac9f581cae29d31640 [file] [log] [blame]
/*
* 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.commons.io.input;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.junit.Test;
/**
* Test the Encoding Utilities part of {@link XmlStreamReader}.
*/
public class XmlStreamReaderUtilitiesTest {
private static String RAWMGS1 = "encoding mismatch";
private static String RAWMGS2 = "unknown BOM";
private static String HTTPMGS1 = "BOM must be NULL";
private static String HTTPMGS2 = "encoding mismatch";
private static String HTTPMGS3 = "Invalid MIME";
private static String APPXML = "application/xml";
private static String APPXML_UTF8 = "application/xml;charset=UTF-8";
private static String APPXML_UTF16 = "application/xml;charset=UTF-16";
private static String APPXML_UTF32 = "application/xml;charset=UTF-32";
private static String APPXML_UTF16BE = "application/xml;charset=UTF-16BE";
private static String APPXML_UTF16LE = "application/xml;charset=UTF-16LE";
private static String APPXML_UTF32BE = "application/xml;charset=UTF-32BE";
private static String APPXML_UTF32LE = "application/xml;charset=UTF-32LE";
private static String TXTXML = "text/xml";
@Test
public void testContentTypeEncoding() {
checkContentTypeEncoding(null, null);
checkContentTypeEncoding(null, "");
checkContentTypeEncoding(null, "application/xml");
checkContentTypeEncoding(null, "application/xml;");
checkContentTypeEncoding(null, "multipart/mixed;boundary=frontier");
checkContentTypeEncoding(null, "multipart/mixed;boundary='frontier'");
checkContentTypeEncoding(null, "multipart/mixed;boundary=\"frontier\"");
checkContentTypeEncoding("UTF-16", "application/xml;charset=utf-16");
checkContentTypeEncoding("UTF-16", "application/xml;charset=UTF-16");
checkContentTypeEncoding("UTF-16", "application/xml;charset='UTF-16'");
checkContentTypeEncoding("UTF-16", "application/xml;charset=\"UTF-16\"");
checkContentTypeEncoding("UTF-32", "application/xml;charset=utf-32");
checkContentTypeEncoding("UTF-32", "application/xml;charset=UTF-32");
checkContentTypeEncoding("UTF-32", "application/xml;charset='UTF-32'");
checkContentTypeEncoding("UTF-32", "application/xml;charset=\"UTF-32\"");
}
private void checkContentTypeEncoding(final String expected, final String httpContentType) {
assertEquals("ContentTypeEncoding=[" + httpContentType + "]", expected, XmlStreamReader.getContentTypeEncoding(httpContentType));
}
@Test
public void testContentTypeMime() {
checkContentTypeMime(null, null);
checkContentTypeMime("", "");
checkContentTypeMime("application/xml", "application/xml");
checkContentTypeMime("application/xml", "application/xml;");
checkContentTypeMime("application/xml", "application/xml;charset=utf-16");
checkContentTypeMime("application/xml", "application/xml;charset=utf-32");
}
private void checkContentTypeMime(final String expected, final String httpContentType) {
assertEquals("ContentTypeMime=[" + httpContentType + "]", expected, XmlStreamReader.getContentTypeMime(httpContentType));
}
@Test
public void testAppXml() {
checkAppXml(false, null);
checkAppXml(false, "");
checkAppXml(true, "application/xml");
checkAppXml(true, "application/xml-dtd");
checkAppXml(true, "application/xml-external-parsed-entity");
checkAppXml(true, "application/soap+xml");
checkAppXml(true, "application/atom+xml");
checkAppXml(false, "application/atomxml");
checkAppXml(false, "text/xml");
checkAppXml(false, "text/atom+xml");
checkAppXml(true, "application/xml-dtd");
checkAppXml(true, "application/xml-external-parsed-entity");
}
@SuppressWarnings("boxing")
private void checkAppXml(final boolean expected, final String mime) {
assertEquals("Mime=[" + mime + "]", expected, XmlStreamReader.isAppXml(mime));
}
@Test
public void testTextXml() {
checkTextXml(false, null);
checkTextXml(false, "");
checkTextXml(true, "text/xml");
checkTextXml(true, "text/xml-external-parsed-entity");
checkTextXml(true, "text/soap+xml");
checkTextXml(true, "text/atom+xml");
checkTextXml(false, "text/atomxml");
checkTextXml(false, "application/xml");
checkTextXml(false, "application/atom+xml");
}
@SuppressWarnings("boxing")
private void checkTextXml(final boolean expected, final String mime) {
assertEquals("Mime=[" + mime + "]", expected, XmlStreamReader.isTextXml(mime));
}
@Test
public void testCalculateRawEncodingNoBOM() throws IOException {
// No BOM Expected BOM Guess XML Default
checkRawError(RAWMGS2, "UTF-32", null, null, null);
//
checkRawEncoding("UTF-8", null, null, null, null);
checkRawEncoding("UTF-8", null, "UTF-16BE", null, null); /* why default & not Guess? */
checkRawEncoding("UTF-8", null, null, "UTF-16BE", null); /* why default & not XMLEnc? */
checkRawEncoding("UTF-8", null, "UTF-8", "UTF-8", "UTF-16BE");
//
checkRawEncoding("UTF-16BE", null, "UTF-16BE", "UTF-16BE", null);
checkRawEncoding("UTF-16BE", null, null, null, "UTF-16BE");
checkRawEncoding("UTF-16BE", null, "UTF-8", null, "UTF-16BE"); /* why default & not Guess? */
checkRawEncoding("UTF-16BE", null, null, "UTF-8", "UTF-16BE"); /* why default & not Guess? */
checkRawEncoding("UTF-16BE", null, "UTF-16BE", "UTF-16", null);
checkRawEncoding("UTF-16LE", null, "UTF-16LE", "UTF-16", null);
}
@Test
public void testCalculateRawEncodingStandard() throws IOException {
// Standard BOM Checks BOM Other Default
testCalculateRawEncodingStandard("UTF-8", "UTF-16BE", "UTF-16LE");
testCalculateRawEncodingStandard("UTF-16BE", "UTF-8", "UTF-16LE");
testCalculateRawEncodingStandard("UTF-16LE", "UTF-8", "UTF-16BE");
}
@Test
//@Ignore
public void testCalculateRawEncodingStandardUtf32() throws IOException {
// Standard BOM Checks BOM Other Default
testCalculateRawEncodingStandard("UTF-8", "UTF-32BE", "UTF-32LE");
testCalculateRawEncodingStandard("UTF-32BE", "UTF-8", "UTF-32LE");
testCalculateRawEncodingStandard("UTF-32LE", "UTF-8", "UTF-32BE");
}
private void testCalculateRawEncodingStandard(final String bomEnc, final String otherEnc, final String defaultEnc) throws IOException {
// Expected BOM Guess XMLEnc Default
checkRawEncoding(bomEnc, bomEnc, null, null, defaultEnc);
checkRawEncoding(bomEnc, bomEnc, bomEnc, null, defaultEnc);
checkRawError(RAWMGS1, bomEnc, otherEnc, null, defaultEnc);
checkRawEncoding(bomEnc, bomEnc, null, bomEnc, defaultEnc);
checkRawError(RAWMGS1, bomEnc, null, otherEnc, defaultEnc);
checkRawEncoding(bomEnc, bomEnc, bomEnc, bomEnc, defaultEnc);
checkRawError(RAWMGS1, bomEnc, bomEnc, otherEnc, defaultEnc);
checkRawError(RAWMGS1, bomEnc, otherEnc, bomEnc, defaultEnc);
}
@Test
public void testCalculateRawEncodingAdditonalUTF16() throws IOException {
// BOM Guess XML Default
checkRawError(RAWMGS1, "UTF-16BE", "UTF-16", null, null);
checkRawEncoding("UTF-16BE", "UTF-16BE", null, "UTF-16", null);
checkRawEncoding("UTF-16BE", "UTF-16BE", "UTF-16BE", "UTF-16", null);
checkRawError(RAWMGS1, "UTF-16BE", null, "UTF-16LE", null);
checkRawError(RAWMGS1, "UTF-16BE", "UTF-16BE", "UTF-16LE", null);
checkRawError(RAWMGS1, "UTF-16LE", "UTF-16", null, null);
checkRawEncoding("UTF-16LE", "UTF-16LE", null, "UTF-16", null);
checkRawEncoding("UTF-16LE", "UTF-16LE", "UTF-16LE", "UTF-16", null);
checkRawError(RAWMGS1, "UTF-16LE", null, "UTF-16BE", null);
checkRawError(RAWMGS1, "UTF-16LE", "UTF-16LE", "UTF-16BE", null);
}
@Test
public void testCalculateRawEncodingAdditonalUTF32() throws IOException {
// BOM Guess XML Default
checkRawError(RAWMGS1, "UTF-32BE", "UTF-32", null, null);
checkRawEncoding("UTF-32BE", "UTF-32BE", null, "UTF-32", null);
checkRawEncoding("UTF-32BE", "UTF-32BE", "UTF-32BE", "UTF-32", null);
checkRawError(RAWMGS1, "UTF-32BE", null, "UTF-32LE", null);
checkRawError(RAWMGS1, "UTF-32BE", "UTF-32BE", "UTF-32LE", null);
checkRawError(RAWMGS1, "UTF-32LE", "UTF-32", null, null);
checkRawEncoding("UTF-32LE", "UTF-32LE", null, "UTF-32", null);
checkRawEncoding("UTF-32LE", "UTF-32LE", "UTF-32LE", "UTF-32", null);
checkRawError(RAWMGS1, "UTF-32LE", null, "UTF-32BE", null);
checkRawError(RAWMGS1, "UTF-32LE", "UTF-32LE", "UTF-32BE", null);
}
private void checkRawEncoding(final String expected,
final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final String defaultEncoding) throws IOException {
final StringBuilder builder = new StringBuilder();
builder.append("RawEncoding: ").append(bomEnc).append("], ");
builder.append("bomEnc=[").append(bomEnc).append("], ");
builder.append("xmlGuessEnc=[").append(xmlGuessEnc).append("], ");
builder.append("xmlEnc=[").append(xmlEnc).append("], ");
builder.append("defaultEncoding=[").append(defaultEncoding).append("],");
final String encoding = calculateRawEncoding(bomEnc,xmlGuessEnc,xmlEnc, defaultEncoding);
assertEquals(builder.toString(), expected, encoding);
}
protected String calculateRawEncoding(final String bomEnc, final String xmlGuessEnc, final String xmlEnc,
final String defaultEncoding) throws IOException {
final MockXmlStreamReader mock = new MockXmlStreamReader(defaultEncoding);
final String enc = mock.calculateRawEncoding(bomEnc, xmlGuessEnc, xmlEnc);
mock.close();
return enc;
}
private void checkRawError(final String msgSuffix,
final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final String defaultEncoding) {
try {
checkRawEncoding("XmlStreamReaderException", bomEnc, xmlGuessEnc, xmlEnc, defaultEncoding);
fail("Expected XmlStreamReaderException");
} catch (final XmlStreamReaderException e) {
assertTrue("Msg Start: " + e.getMessage(), e.getMessage().startsWith("Invalid encoding"));
assertTrue("Msg End: " + e.getMessage(), e.getMessage().endsWith(msgSuffix));
assertEquals("bomEnc", bomEnc, e.getBomEncoding());
assertEquals("xmlGuessEnc", xmlGuessEnc, e.getXmlGuessEncoding());
assertEquals("xmlEnc", xmlEnc, e.getXmlEncoding());
assertNull("ContentTypeEncoding", e.getContentTypeEncoding());
assertNull("ContentTypeMime", e.getContentTypeMime());
} catch (final Exception e) {
fail("Expected XmlStreamReaderException, but threw " + e);
}
}
@Test
public void testCalculateHttpEncoding() throws IOException {
// No BOM Expected Lenient cType BOM Guess XML Default
checkHttpError(HTTPMGS3, true, null, null, null, null, null);
checkHttpError(HTTPMGS3, false, null, null, null, "UTF-8", null);
checkHttpEncoding("UTF-8", true, null, null, null, "UTF-8", null);
checkHttpEncoding("UTF-16LE", true, null, null, null, "UTF-16LE", null);
checkHttpError(HTTPMGS3, false, "text/css", null, null, null, null);
checkHttpEncoding("US-ASCII", false, TXTXML, null, null, null, null);
checkHttpEncoding("UTF-16BE", false, TXTXML, null, null, null, "UTF-16BE");
checkHttpEncoding("UTF-8", false, APPXML, null, null, null, null);
checkHttpEncoding("UTF-16BE", false, APPXML, null, null, null, "UTF-16BE");
checkHttpEncoding("UTF-8", false, APPXML, "UTF-8", null, null, "UTF-16BE");
checkHttpEncoding("UTF-16LE", false, APPXML_UTF16LE, null, null, null, null);
checkHttpEncoding("UTF-16BE", false, APPXML_UTF16BE, null, null, null, null);
checkHttpError(HTTPMGS1, false, APPXML_UTF16LE, "UTF-16LE", null, null, null);
checkHttpError(HTTPMGS1, false, APPXML_UTF16BE, "UTF-16BE", null, null, null);
checkHttpError(HTTPMGS2, false, APPXML_UTF16, null, null, null, null);
checkHttpError(HTTPMGS2, false, APPXML_UTF16, "UTF-8", null, null, null);
checkHttpEncoding("UTF-16LE", false, APPXML_UTF16, "UTF-16LE", null, null, null);
checkHttpEncoding("UTF-16BE", false, APPXML_UTF16, "UTF-16BE", null, null, null);
checkHttpEncoding("UTF-8", false, APPXML_UTF8, null, null, null, null);
checkHttpEncoding("UTF-8", false, APPXML_UTF8, "UTF-16BE", "UTF-16BE", "UTF-16BE", "UTF-16BE");
}
@Test
public void testCalculateHttpEncodingUtf32() throws IOException {
// No BOM Expected Lenient cType BOM Guess XML Default
checkHttpEncoding("UTF-32LE", true, null, null, null, "UTF-32LE", null);
checkHttpEncoding("UTF-32BE", false, TXTXML, null, null, null, "UTF-32BE");
checkHttpEncoding("UTF-32BE", false, APPXML, null, null, null, "UTF-32BE");
checkHttpEncoding("UTF-32LE", false, APPXML_UTF32LE, null, null, null, null);
checkHttpEncoding("UTF-32BE", false, APPXML_UTF32BE, null, null, null, null);
checkHttpError(HTTPMGS1, false, APPXML_UTF32LE, "UTF-32LE", null, null, null);
checkHttpError(HTTPMGS1, false, APPXML_UTF32BE, "UTF-32BE", null, null, null);
checkHttpError(HTTPMGS2, false, APPXML_UTF32, null, null, null, null);
checkHttpError(HTTPMGS2, false, APPXML_UTF32, "UTF-8", null, null, null);
checkHttpEncoding("UTF-32LE", false, APPXML_UTF32, "UTF-32LE", null, null, null);
checkHttpEncoding("UTF-32BE", false, APPXML_UTF32, "UTF-32BE", null, null, null);
checkHttpEncoding("UTF-8", false, APPXML_UTF8, "UTF-32BE", "UTF-32BE", "UTF-32BE", "UTF-32BE");
}
private void checkHttpEncoding(final String expected, final boolean lenient, final String httpContentType,
final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final String defaultEncoding) throws IOException {
final StringBuilder builder = new StringBuilder();
builder.append("HttpEncoding=[").append(bomEnc).append("], ");
builder.append("lenient=[").append(lenient).append("], ");
builder.append("httpContentType=[").append(httpContentType).append("], ");
builder.append("bomEnc=[").append(bomEnc).append("], ");
builder.append("xmlGuessEnc=[").append(xmlGuessEnc).append("], ");
builder.append("xmlEnc=[").append(xmlEnc).append("], ");
builder.append("defaultEncoding=[").append(defaultEncoding).append("],");
final String encoding = calculateHttpEncoding(httpContentType, bomEnc, xmlGuessEnc, xmlEnc, lenient, defaultEncoding);
assertEquals(builder.toString(), expected, encoding);
}
protected String calculateHttpEncoding(final String httpContentType, final String bomEnc, final String xmlGuessEnc,
final String xmlEnc, final boolean lenient, final String defaultEncoding) throws IOException {
final MockXmlStreamReader mock = new MockXmlStreamReader(defaultEncoding);
final String enc = mock.calculateHttpEncoding(httpContentType, bomEnc, xmlGuessEnc, xmlEnc, lenient);
mock.close();
return enc;
}
private void checkHttpError(final String msgSuffix, final boolean lenient, final String httpContentType,
final String bomEnc, final String xmlGuessEnc, final String xmlEnc, final String defaultEncoding) {
try {
checkHttpEncoding("XmlStreamReaderException", lenient, httpContentType, bomEnc, xmlGuessEnc, xmlEnc, defaultEncoding);
fail("Expected XmlStreamReaderException");
} catch (final XmlStreamReaderException e) {
assertTrue("Msg Start: " + e.getMessage(), e.getMessage().startsWith("Invalid encoding"));
assertTrue("Msg End: " + e.getMessage(), e.getMessage().endsWith(msgSuffix));
assertEquals("bomEnc", bomEnc, e.getBomEncoding());
assertEquals("xmlGuessEnc", xmlGuessEnc, e.getXmlGuessEncoding());
assertEquals("xmlEnc", xmlEnc, e.getXmlEncoding());
assertEquals("ContentTypeEncoding", XmlStreamReader.getContentTypeEncoding(httpContentType),
e.getContentTypeEncoding());
assertEquals("ContentTypeMime", XmlStreamReader.getContentTypeMime(httpContentType),
e.getContentTypeMime());
} catch (final Exception e) {
fail("Expected XmlStreamReaderException, but threw " + e);
}
}
/** Mock {@link XmlStreamReader} implementation */
private static class MockXmlStreamReader extends XmlStreamReader {
MockXmlStreamReader(final String defaultEncoding) throws IOException {
super(new ByteArrayInputStream("".getBytes()), null, true, defaultEncoding);
}
}
}