1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.io.output; 18 19 import static org.junit.jupiter.api.Assertions.assertArrayEquals; 20 import static org.junit.jupiter.api.Assertions.assertEquals; 21 import static org.junit.jupiter.api.Assertions.assertTrue; 22 23 import java.io.ByteArrayOutputStream; 24 import java.io.IOException; 25 import java.nio.charset.Charset; 26 import java.nio.charset.StandardCharsets; 27 28 import org.junit.jupiter.api.Test; 29 import org.junitpioneer.jupiter.DefaultLocale; 30 31 /** 32 */ 33 public class XmlStreamWriterTest { 34 35 /** French */ 36 private static final String TEXT_LATIN1 = "eacute: \u00E9"; 37 38 /** Greek */ 39 private static final String TEXT_LATIN7 = "alpha: \u03B1"; 40 41 /** Euro support */ 42 private static final String TEXT_LATIN15 = "euro: \u20AC"; 43 44 /** Japanese */ 45 private static final String TEXT_EUC_JP = "hiragana A: \u3042"; 46 47 /** Unicode: support everything */ 48 private static final String TEXT_UNICODE = TEXT_LATIN1 + ", " + TEXT_LATIN7 49 + ", " + TEXT_LATIN15 + ", " + TEXT_EUC_JP; 50 checkXmlContent(final String xml, final String encodingName, final String defaultEncodingName)51 private static void checkXmlContent(final String xml, final String encodingName, final String defaultEncodingName) 52 throws IOException { 53 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 54 final XmlStreamWriter writer = new XmlStreamWriter(out, defaultEncodingName); 55 writer.write(xml); 56 writer.close(); 57 final byte[] xmlContent = out.toByteArray(); 58 final Charset charset = Charset.forName(encodingName); 59 final Charset writerCharset = Charset.forName(writer.getEncoding()); 60 assertEquals(charset, writerCharset); 61 assertTrue(writerCharset.contains(charset), writerCharset.name()); 62 assertArrayEquals(xml.getBytes(encodingName), xmlContent); 63 } 64 checkXmlWriter(final String text, final String encoding)65 private static void checkXmlWriter(final String text, final String encoding) 66 throws IOException { 67 checkXmlWriter(text, encoding, null); 68 } 69 checkXmlWriter(final String text, final String encoding, final String defaultEncoding)70 private static void checkXmlWriter(final String text, final String encoding, final String defaultEncoding) 71 throws IOException { 72 final String xml = createXmlContent(text, encoding); 73 String effectiveEncoding = encoding; 74 if (effectiveEncoding == null) { 75 effectiveEncoding = defaultEncoding == null ? StandardCharsets.UTF_8.name() : defaultEncoding; 76 } 77 checkXmlContent(xml, effectiveEncoding, defaultEncoding); 78 } 79 createXmlContent(final String text, final String encoding)80 private static String createXmlContent(final String text, final String encoding) { 81 String xmlDecl = "<?xml version=\"1.0\"?>"; 82 if (encoding != null) { 83 xmlDecl = "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>"; 84 } 85 return xmlDecl + "\n<text>" + text + "</text>"; 86 } 87 88 @Test testDefaultEncoding()89 public void testDefaultEncoding() throws IOException { 90 checkXmlWriter(TEXT_UNICODE, null, null); 91 checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.UTF_8.name()); 92 checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.UTF_16.name()); 93 checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.UTF_16BE.name()); 94 checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.ISO_8859_1.name()); 95 } 96 97 @Test testEBCDICEncoding()98 public void testEBCDICEncoding() throws IOException { 99 checkXmlWriter("simple text in EBCDIC", "CP1047"); 100 } 101 102 @Test testEmpty()103 public void testEmpty() throws IOException { 104 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 105 try (XmlStreamWriter writer = new XmlStreamWriter(out)) { 106 writer.flush(); 107 writer.write(""); 108 writer.flush(); 109 writer.write("."); 110 writer.flush(); 111 } 112 } 113 114 @Test testEUC_JPEncoding()115 public void testEUC_JPEncoding() throws IOException { 116 checkXmlWriter(TEXT_EUC_JP, "EUC-JP"); 117 } 118 119 @Test testLatin15Encoding()120 public void testLatin15Encoding() throws IOException { 121 checkXmlWriter(TEXT_LATIN15, "ISO-8859-15"); 122 } 123 124 @Test testLatin1Encoding()125 public void testLatin1Encoding() throws IOException { 126 checkXmlWriter(TEXT_LATIN1, StandardCharsets.ISO_8859_1.name()); 127 } 128 129 @Test testLatin7Encoding()130 public void testLatin7Encoding() throws IOException { 131 checkXmlWriter(TEXT_LATIN7, "ISO-8859-7"); 132 } 133 134 /** Turkish language has specific rules to convert dotted and dotless i character. */ 135 @Test 136 @DefaultLocale(language = "tr") testLowerCaseEncodingWithTurkishLocale_IO_557()137 public void testLowerCaseEncodingWithTurkishLocale_IO_557() throws IOException { 138 checkXmlWriter(TEXT_UNICODE, "utf-8"); 139 checkXmlWriter(TEXT_LATIN1, "iso-8859-1"); 140 checkXmlWriter(TEXT_LATIN7, "iso-8859-7"); 141 } 142 143 @Test testNoXmlHeader()144 public void testNoXmlHeader() throws IOException { 145 checkXmlContent("<text>text with no XML header</text>", StandardCharsets.UTF_8.name(), null); 146 } 147 148 @Test testUTF16BEEncoding()149 public void testUTF16BEEncoding() throws IOException { 150 checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_16BE.name()); 151 } 152 153 @Test testUTF16Encoding()154 public void testUTF16Encoding() throws IOException { 155 checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_16.name()); 156 } 157 158 @Test testUTF16LEEncoding()159 public void testUTF16LEEncoding() throws IOException { 160 checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_16LE.name()); 161 } 162 163 @Test testUTF8Encoding()164 public void testUTF8Encoding() throws IOException { 165 checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_8.name()); 166 } 167 } 168