2
* The Apache Software License, Version 1.1
5
* Copyright (c) 2000-2002 The Apache Software Foundation. All rights
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in
17
* the documentation and/or other materials provided with the
20
* 3. The end-user documentation included with the redistribution,
21
* if any, must include the following acknowledgment:
22
* "This product includes software developed by the
23
* Apache Software Foundation (http://www.apache.org/)."
24
* Alternately, this acknowledgment may appear in the software itself,
25
* if and wherever such third-party acknowledgments normally appear.
27
* 4. The names "Xerces" and "Apache Software Foundation" must
28
* not be used to endorse or promote products derived from this
29
* software without prior written permission. For written
30
* permission, please contact apache@apache.org.
32
* 5. Products derived from this software may not be called "Apache",
33
* nor may "Apache" appear in their name, without prior written
34
* permission of the Apache Software Foundation.
36
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48
* ====================================================================
50
* This software consists of voluntary contributions made by many
51
* individuals on behalf of the Apache Software Foundation and was
52
* originally based on software copyright (c) 1999, International
53
* Business Machines, Inc., http://www.apache.org. For more
54
* information on the Apache Software Foundation, please see
55
* <http://www.apache.org/>.
2
* Copyright 2000-2002,2004,2005 The Apache Software Foundation.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
59
17
package org.apache.xml.serialize;
61
19
import java.io.OutputStream;
68
26
* This class represents an encoding.
70
* @version $Id: EncodingInfo.java,v 1.5 2003/11/04 19:24:54 mrglavas Exp $
28
* @version $Id: EncodingInfo.java 320382 2005-05-22 19:11:07Z mrglavas $
72
30
public class EncodingInfo {
74
// Method: sun.io.CharToByteConverter.getConverter(java.lang.String)
75
private static java.lang.reflect.Method fgGetConverterMethod = null;
77
// Method: sun.io.CharToByteConverter.canConvert(char)
78
private static java.lang.reflect.Method fgCanConvertMethod = null;
80
// Flag indicating whether or not sun.io.CharToByteConverter is available.
81
private static boolean fgConvertersAvailable = false;
83
// An array to hold the argument for a method of CharToByteConverter.
32
// An array to hold the argument for a method of Charset, CharsetEncoder or CharToByteConverter.
84
33
private Object [] fArgsForMethod = null;
86
35
// name of encoding as registered with IANA;
92
// The charToByteConverter with which we test unusual characters.
41
// The CharsetEncoder with which we test unusual characters.
42
Object fCharsetEncoder = null;
44
// The CharToByteConverter with which we test unusual characters.
93
45
Object fCharToByteConverter = null;
95
47
// Is the converter null because it can't be instantiated
96
48
// for some reason (perhaps we're running with insufficient authority as
98
50
boolean fHaveTriedCToB = false;
52
// Is the charset encoder usable or available.
53
boolean fHaveTriedCharsetEncoder = false;
101
56
* Creates new <code>EncodingInfo</code> instance.
132
87
return new OutputStreamWriter(output, "UTF8");
133
88
return new OutputStreamWriter(output, javaName);
136
* Checks whether the specified character is printable or not
92
* Checks whether the specified character is printable or not in this encoding.
139
94
* @param ch a code point (0-0x10ffff)
141
96
public boolean isPrintable(char ch) {
142
if(ch <= this.lastPrintable)
97
if (ch <= this.lastPrintable) {
145
if(fCharToByteConverter == null) {
146
if(fHaveTriedCToB || !fgConvertersAvailable) {
100
return isPrintable0(ch);
104
* Checks whether the specified character is printable or not in this encoding.
105
* This method accomplishes this using a java.nio.CharsetEncoder. If NIO isn't
106
* available it will attempt use a sun.io.CharToByteConverter.
108
* @param ch a code point (0-0x10ffff)
110
private boolean isPrintable0(char ch) {
112
// Attempt to get a CharsetEncoder for this encoding.
113
if (fCharsetEncoder == null && CharsetMethods.fgNIOCharsetAvailable && !fHaveTriedCharsetEncoder) {
114
if (fArgsForMethod == null) {
115
fArgsForMethod = new Object [1];
117
// try and create the CharsetEncoder
119
fArgsForMethod[0] = javaName;
120
Object charset = CharsetMethods.fgCharsetForNameMethod.invoke(null, fArgsForMethod);
121
if (((Boolean) CharsetMethods.fgCharsetCanEncodeMethod.invoke(charset, (Object[]) null)).booleanValue()) {
122
fCharsetEncoder = CharsetMethods.fgCharsetNewEncoderMethod.invoke(charset, (Object[]) null);
124
// This charset cannot be used for encoding, don't try it again...
126
fHaveTriedCharsetEncoder = true;
129
catch (Exception e) {
130
// don't try it again...
131
fHaveTriedCharsetEncoder = true;
134
// Attempt to use the CharsetEncoder to determine whether the character is printable.
135
if (fCharsetEncoder != null) {
137
fArgsForMethod[0] = new Character(ch);
138
return ((Boolean) CharsetMethods.fgCharsetEncoderCanEncodeMethod.invoke(fCharsetEncoder, fArgsForMethod)).booleanValue();
140
catch (Exception e) {
141
// obviously can't use this charset encoder; possibly a JDK bug
142
fCharsetEncoder = null;
143
fHaveTriedCharsetEncoder = false;
147
// As a last resort try to use a sun.io.CharToByteConverter to
148
// determine whether this character is printable. We will always
149
// reach here on JDK 1.3 or below.
150
if (fCharToByteConverter == null) {
151
if (fHaveTriedCToB || !CharToByteConverterMethods.fgConvertersAvailable) {
147
152
// forget it; nothing we can do...
150
155
if (fArgsForMethod == null) {
151
156
fArgsForMethod = new Object [1];
153
// try and create it:
158
// try and create the CharToByteConverter
155
160
fArgsForMethod[0] = javaName;
156
fCharToByteConverter = fgGetConverterMethod.invoke(null, fArgsForMethod);
157
} catch(Exception e) {
161
fCharToByteConverter = CharToByteConverterMethods.fgGetConverterMethod.invoke(null, fArgsForMethod);
163
catch (Exception e) {
158
164
// don't try it again...
159
165
fHaveTriedCToB = true;
179
186
String s = new String(bTest, name);
182
// Attempt to get methods for char to byte
183
// converter on class initialization.
186
Class clazz = Class.forName("sun.io.CharToByteConverter");
187
fgGetConverterMethod = clazz.getMethod("getConverter", new Class [] {String.class});
188
fgCanConvertMethod = clazz.getMethod("canConvert", new Class [] {Character.TYPE});
189
fgConvertersAvailable = true;
190
* Holder of methods from java.nio.charset.Charset and java.nio.charset.CharsetEncoder.
192
static class CharsetMethods {
194
// Method: java.nio.charset.Charset.forName(java.lang.String)
195
private static java.lang.reflect.Method fgCharsetForNameMethod = null;
197
// Method: java.nio.charset.Charset.canEncode()
198
private static java.lang.reflect.Method fgCharsetCanEncodeMethod = null;
200
// Method: java.nio.charset.Charset.newEncoder()
201
private static java.lang.reflect.Method fgCharsetNewEncoderMethod = null;
203
// Method: java.nio.charset.CharsetEncoder.canEncode(char)
204
private static java.lang.reflect.Method fgCharsetEncoderCanEncodeMethod = null;
206
// Flag indicating whether or not java.nio.charset.* is available.
207
private static boolean fgNIOCharsetAvailable = false;
209
private CharsetMethods() {}
211
// Attempt to get methods for Charset and CharsetEncoder on class initialization.
214
Class charsetClass = Class.forName("java.nio.charset.Charset");
215
Class charsetEncoderClass = Class.forName("java.nio.charset.CharsetEncoder");
216
fgCharsetForNameMethod = charsetClass.getMethod("forName", new Class [] {String.class});
217
fgCharsetCanEncodeMethod = charsetClass.getMethod("canEncode", new Class [] {});
218
fgCharsetNewEncoderMethod = charsetClass.getMethod("newEncoder", new Class [] {});
219
fgCharsetEncoderCanEncodeMethod = charsetEncoderClass.getMethod("canEncode", new Class [] {Character.TYPE});
220
fgNIOCharsetAvailable = true;
222
// ClassNotFoundException, NoSuchMethodException or SecurityException
223
// Whatever the case, we cannot use java.nio.charset.*.
224
catch (Exception exc) {
225
fgCharsetForNameMethod = null;
226
fgCharsetCanEncodeMethod = null;
227
fgCharsetEncoderCanEncodeMethod = null;
228
fgCharsetNewEncoderMethod = null;
229
fgNIOCharsetAvailable = false;
191
// ClassNotFoundException, NoSuchMethodException or SecurityException
192
// Whatever the case, we cannot use sun.io.CharToByteConverter.
193
catch (Exception exc) {
194
fgGetConverterMethod = null;
195
fgCanConvertMethod = null;
196
fgConvertersAvailable = false;
235
* Holder of methods from sun.io.CharToByteConverter.
237
static class CharToByteConverterMethods {
239
// Method: sun.io.CharToByteConverter.getConverter(java.lang.String)
240
private static java.lang.reflect.Method fgGetConverterMethod = null;
242
// Method: sun.io.CharToByteConverter.canConvert(char)
243
private static java.lang.reflect.Method fgCanConvertMethod = null;
245
// Flag indicating whether or not sun.io.CharToByteConverter is available.
246
private static boolean fgConvertersAvailable = false;
248
private CharToByteConverterMethods() {}
250
// Attempt to get methods for char to byte converter on class initialization.
253
Class clazz = Class.forName("sun.io.CharToByteConverter");
254
fgGetConverterMethod = clazz.getMethod("getConverter", new Class [] {String.class});
255
fgCanConvertMethod = clazz.getMethod("canConvert", new Class [] {Character.TYPE});
256
fgConvertersAvailable = true;
258
// ClassNotFoundException, NoSuchMethodException or SecurityException
259
// Whatever the case, we cannot use sun.io.CharToByteConverter.
260
catch (Exception exc) {
261
fgGetConverterMethod = null;
262
fgCanConvertMethod = null;
263
fgConvertersAvailable = false;