• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * Tests {@link XmlStreamWriter}.
33  */
34 public class XmlStreamWriterTest {
35 
36     /** French */
37     private static final String TEXT_LATIN1 = "eacute: \u00E9";
38 
39     /** Greek */
40     private static final String TEXT_LATIN7 = "alpha: \u03B1";
41 
42     /** Euro support */
43     private static final String TEXT_LATIN15 = "euro: \u20AC";
44 
45     /** Japanese */
46     private static final String TEXT_EUC_JP = "hiragana A: \u3042";
47 
48     /** Unicode: support everything */
49     private static final String TEXT_UNICODE = TEXT_LATIN1 + ", " + TEXT_LATIN7
50             + ", " + TEXT_LATIN15 + ", " + TEXT_EUC_JP;
51 
52     @SuppressWarnings("resource")
checkXmlContent(final String xml, final String encodingName, final String defaultEncodingName)53     private static void checkXmlContent(final String xml, final String encodingName, final String defaultEncodingName)
54             throws IOException {
55         final ByteArrayOutputStream out = new ByteArrayOutputStream();
56         final XmlStreamWriter writerCheck;
57         try (final XmlStreamWriter writer = XmlStreamWriter.builder().setOutputStream(out).setCharset(defaultEncodingName).get()) {
58             writerCheck = writer;
59             writer.write(xml);
60         }
61         final byte[] xmlContent = out.toByteArray();
62         final Charset charset = Charset.forName(encodingName);
63         final Charset writerCharset = Charset.forName(writerCheck.getEncoding());
64         assertEquals(charset, writerCharset);
65         assertTrue(writerCharset.contains(charset), writerCharset.name());
66         assertArrayEquals(xml.getBytes(encodingName), xmlContent);
67     }
68 
checkXmlWriter(final String text, final String encoding)69     private static void checkXmlWriter(final String text, final String encoding)
70             throws IOException {
71         checkXmlWriter(text, encoding, null);
72     }
73 
checkXmlWriter(final String text, final String encoding, final String defaultEncoding)74     private static void checkXmlWriter(final String text, final String encoding, final String defaultEncoding)
75             throws IOException {
76         final String xml = createXmlContent(text, encoding);
77         String effectiveEncoding = encoding;
78         if (effectiveEncoding == null) {
79             effectiveEncoding = defaultEncoding == null ? StandardCharsets.UTF_8.name() : defaultEncoding;
80         }
81         checkXmlContent(xml, effectiveEncoding, defaultEncoding);
82     }
83 
createXmlContent(final String text, final String encoding)84     private static String createXmlContent(final String text, final String encoding) {
85         String xmlDecl = "<?xml version=\"1.0\"?>";
86         if (encoding != null) {
87             xmlDecl = "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>";
88         }
89         return xmlDecl + "\n<text>" + text + "</text>";
90     }
91 
92     @Test
testDefaultEncoding()93     public void testDefaultEncoding() throws IOException {
94         checkXmlWriter(TEXT_UNICODE, null, null);
95         checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.UTF_8.name());
96         checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.UTF_16.name());
97         checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.UTF_16BE.name());
98         checkXmlWriter(TEXT_UNICODE, null, StandardCharsets.ISO_8859_1.name());
99     }
100 
101     @Test
testEBCDICEncoding()102     public void testEBCDICEncoding() throws IOException {
103         checkXmlWriter("simple text in EBCDIC", "CP1047");
104     }
105 
106     @Test
testEmpty()107     public void testEmpty() throws IOException {
108         try (final ByteArrayOutputStream out = new ByteArrayOutputStream();
109                 XmlStreamWriter writer = new XmlStreamWriter(out)) {
110             writer.flush();
111             writer.write("");
112             writer.flush();
113             writer.write(".");
114             writer.flush();
115         }
116         try (final ByteArrayOutputStream out = new ByteArrayOutputStream();
117                 XmlStreamWriter writer = XmlStreamWriter.builder().setOutputStream(out).get()) {
118             writer.flush();
119             writer.write("");
120             writer.flush();
121             writer.write(".");
122             writer.flush();
123         }
124     }
125 
126     @Test
testEUC_JPEncoding()127     public void testEUC_JPEncoding() throws IOException {
128         checkXmlWriter(TEXT_EUC_JP, "EUC-JP");
129     }
130 
131     @Test
testLatin15Encoding()132     public void testLatin15Encoding() throws IOException {
133         checkXmlWriter(TEXT_LATIN15, "ISO-8859-15");
134     }
135 
136     @Test
testLatin1Encoding()137     public void testLatin1Encoding() throws IOException {
138         checkXmlWriter(TEXT_LATIN1, StandardCharsets.ISO_8859_1.name());
139     }
140 
141     @Test
testLatin7Encoding()142     public void testLatin7Encoding() throws IOException {
143         checkXmlWriter(TEXT_LATIN7, "ISO-8859-7");
144     }
145 
146     /** Turkish language has specific rules to convert dotted and dotless i character. */
147     @Test
148     @DefaultLocale(language = "tr")
testLowerCaseEncodingWithTurkishLocale_IO_557()149     public void testLowerCaseEncodingWithTurkishLocale_IO_557() throws IOException {
150         checkXmlWriter(TEXT_UNICODE, "utf-8");
151         checkXmlWriter(TEXT_LATIN1, "iso-8859-1");
152         checkXmlWriter(TEXT_LATIN7, "iso-8859-7");
153     }
154 
155     @Test
testNoXmlHeader()156     public void testNoXmlHeader() throws IOException {
157         checkXmlContent("<text>text with no XML header</text>", StandardCharsets.UTF_8.name(), null);
158     }
159 
160     @Test
testUTF16BEEncoding()161     public void testUTF16BEEncoding() throws IOException {
162         checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_16BE.name());
163     }
164 
165     @Test
testUTF16Encoding()166     public void testUTF16Encoding() throws IOException {
167         checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_16.name());
168     }
169 
170     @Test
testUTF16LEEncoding()171     public void testUTF16LEEncoding() throws IOException {
172         checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_16LE.name());
173     }
174 
175     @Test
testUTF8Encoding()176     public void testUTF8Encoding() throws IOException {
177         checkXmlWriter(TEXT_UNICODE, StandardCharsets.UTF_8.name());
178     }
179 }
180