~ubuntu-branches/ubuntu/karmic/libxerces2-java/karmic

« back to all changes in this revision

Viewing changes to src/org/apache/xml/serialize/EncodingInfo.java

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-12-04 17:37:55 UTC
  • mfrom: (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20061204173755-hb6ybrrrk097zhx7
Tags: 2.8.1-1ubuntu1
* Merge with Debian unstable; remaining changes:
  - Build -gcj package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * The Apache Software License, Version 1.1
3
 
 *
4
 
 *
5
 
 * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights 
6
 
 * reserved.
7
 
 *
8
 
 * Redistribution and use in source and binary forms, with or without
9
 
 * modification, are permitted provided that the following conditions
10
 
 * are met:
11
 
 *
12
 
 * 1. Redistributions of source code must retain the above copyright
13
 
 *    notice, this list of conditions and the following disclaimer. 
14
 
 *
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
18
 
 *    distribution.
19
 
 *
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.
26
 
 *
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.
31
 
 *
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.
35
 
 *
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
47
 
 * SUCH DAMAGE.
48
 
 * ====================================================================
49
 
 *
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.
 
3
 * 
 
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
 
7
 * 
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
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.
56
15
 */
57
16
 
58
 
 
59
17
package org.apache.xml.serialize;
60
18
 
61
19
import java.io.OutputStream;
67
25
/**
68
26
 * This class represents an encoding.
69
27
 *
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 $
71
29
 */
72
30
public class EncodingInfo {
73
 
 
74
 
    // Method: sun.io.CharToByteConverter.getConverter(java.lang.String)
75
 
    private static java.lang.reflect.Method fgGetConverterMethod = null; 
76
 
    
77
 
    // Method: sun.io.CharToByteConverter.canConvert(char)
78
 
    private static java.lang.reflect.Method fgCanConvertMethod = null;
79
 
    
80
 
    // Flag indicating whether or not sun.io.CharToByteConverter is available.
81
 
    private static boolean fgConvertersAvailable = false;
82
 
    
83
 
    // An array to hold the argument for a method of CharToByteConverter.
 
31
    
 
32
    // An array to hold the argument for a method of Charset, CharsetEncoder or CharToByteConverter.
84
33
    private Object [] fArgsForMethod = null;
85
34
    
86
35
    // name of encoding as registered with IANA;
89
38
    String javaName;
90
39
    int lastPrintable;
91
40
    
92
 
    // The charToByteConverter with which we test unusual characters.
 
41
    // The CharsetEncoder with which we test unusual characters.
 
42
    Object fCharsetEncoder = null;
 
43
    
 
44
    // The CharToByteConverter with which we test unusual characters.
93
45
    Object fCharToByteConverter = null;
94
46
    
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 
97
49
    // an applet?
98
50
    boolean fHaveTriedCToB = false;
 
51
    
 
52
    // Is the charset encoder usable or available.
 
53
    boolean fHaveTriedCharsetEncoder = false;
99
54
 
100
55
    /**
101
56
     * Creates new <code>EncodingInfo</code> instance.
132
87
            return new OutputStreamWriter(output, "UTF8");
133
88
        return new OutputStreamWriter(output, javaName);
134
89
    }
 
90
    
135
91
    /**
136
 
     * Checks whether the specified character is printable or not
137
 
     * in this encoding.
 
92
     * Checks whether the specified character is printable or not in this encoding.
138
93
     *
139
94
     * @param ch a code point (0-0x10ffff)
140
95
     */
141
96
    public boolean isPrintable(char ch) {
142
 
        if(ch <= this.lastPrintable) 
 
97
        if (ch <= this.lastPrintable) {
143
98
            return true;
144
 
        
145
 
        if(fCharToByteConverter == null) {
146
 
            if(fHaveTriedCToB || !fgConvertersAvailable) {
 
99
        }
 
100
        return isPrintable0(ch);
 
101
    }
 
102
    
 
103
    /**
 
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.
 
107
     *
 
108
     * @param ch a code point (0-0x10ffff)
 
109
     */
 
110
    private boolean isPrintable0(char ch) {
 
111
        
 
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];
 
116
            }
 
117
            // try and create the CharsetEncoder
 
118
            try {
 
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);
 
123
                }
 
124
                // This charset cannot be used for encoding, don't try it again...
 
125
                else {
 
126
                    fHaveTriedCharsetEncoder = true;
 
127
                } 
 
128
            } 
 
129
            catch (Exception e) {   
 
130
                // don't try it again...
 
131
                fHaveTriedCharsetEncoder = true;
 
132
            }
 
133
        }
 
134
        // Attempt to use the CharsetEncoder to determine whether the character is printable.
 
135
        if (fCharsetEncoder != null) {
 
136
            try {
 
137
                fArgsForMethod[0] = new Character(ch);
 
138
                return ((Boolean) CharsetMethods.fgCharsetEncoderCanEncodeMethod.invoke(fCharsetEncoder, fArgsForMethod)).booleanValue();
 
139
            } 
 
140
            catch (Exception e) {
 
141
                // obviously can't use this charset encoder; possibly a JDK bug
 
142
                fCharsetEncoder = null;
 
143
                fHaveTriedCharsetEncoder = false;
 
144
            }
 
145
        }
 
146
        
 
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...
148
153
                return false;
149
154
            }
150
155
            if (fArgsForMethod == null) {
151
156
                fArgsForMethod = new Object [1];
152
157
            }
153
 
            // try and create it:
 
158
            // try and create the CharToByteConverter
154
159
            try {
155
160
                fArgsForMethod[0] = javaName;
156
 
                fCharToByteConverter = fgGetConverterMethod.invoke(null, fArgsForMethod);
157
 
            } catch(Exception e) {   
 
161
                fCharToByteConverter = CharToByteConverterMethods.fgGetConverterMethod.invoke(null, fArgsForMethod);
 
162
            } 
 
163
            catch (Exception e) {   
158
164
                // don't try it again...
159
165
                fHaveTriedCToB = true;
160
166
                return false;
162
168
        }
163
169
        try {
164
170
            fArgsForMethod[0] = new Character(ch);
165
 
            return ((Boolean) fgCanConvertMethod.invoke(fCharToByteConverter, fArgsForMethod)).booleanValue();
166
 
        } catch (Exception e) {
 
171
            return ((Boolean) CharToByteConverterMethods.fgCanConvertMethod.invoke(fCharToByteConverter, fArgsForMethod)).booleanValue();
 
172
        } 
 
173
        catch (Exception e) {
167
174
            // obviously can't use this converter; probably some kind of
168
175
            // security restriction
169
176
            fCharToByteConverter = null;
179
186
        String s = new String(bTest, name);
180
187
    }
181
188
    
182
 
    // Attempt to get methods for char to byte 
183
 
    // converter on class initialization.
184
 
    static {
185
 
        try {
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;
 
189
    /**
 
190
     * Holder of methods from java.nio.charset.Charset and java.nio.charset.CharsetEncoder.
 
191
     */
 
192
    static class CharsetMethods {
 
193
        
 
194
        // Method: java.nio.charset.Charset.forName(java.lang.String)
 
195
        private static java.lang.reflect.Method fgCharsetForNameMethod = null; 
 
196
        
 
197
        // Method: java.nio.charset.Charset.canEncode()
 
198
        private static java.lang.reflect.Method fgCharsetCanEncodeMethod = null;
 
199
        
 
200
        // Method: java.nio.charset.Charset.newEncoder()
 
201
        private static java.lang.reflect.Method fgCharsetNewEncoderMethod = null;
 
202
        
 
203
        // Method: java.nio.charset.CharsetEncoder.canEncode(char)
 
204
        private static java.lang.reflect.Method fgCharsetEncoderCanEncodeMethod = null;
 
205
        
 
206
        // Flag indicating whether or not java.nio.charset.* is available.
 
207
        private static boolean fgNIOCharsetAvailable = false;
 
208
        
 
209
        private CharsetMethods() {}
 
210
        
 
211
        // Attempt to get methods for Charset and CharsetEncoder on class initialization.
 
212
        static {
 
213
            try {
 
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;
 
221
            }
 
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;
 
230
            }
190
231
        }
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;
 
232
    }
 
233
    
 
234
    /**
 
235
     * Holder of methods from sun.io.CharToByteConverter.
 
236
     */
 
237
    static class CharToByteConverterMethods {
 
238
        
 
239
        // Method: sun.io.CharToByteConverter.getConverter(java.lang.String)
 
240
        private static java.lang.reflect.Method fgGetConverterMethod = null; 
 
241
        
 
242
        // Method: sun.io.CharToByteConverter.canConvert(char)
 
243
        private static java.lang.reflect.Method fgCanConvertMethod = null;
 
244
        
 
245
        // Flag indicating whether or not sun.io.CharToByteConverter is available.
 
246
        private static boolean fgConvertersAvailable = false;
 
247
        
 
248
        private CharToByteConverterMethods() {}
 
249
        
 
250
        // Attempt to get methods for char to byte converter on class initialization.
 
251
        static {
 
252
            try {
 
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;
 
257
            }
 
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;
 
264
            }
197
265
        }
198
266
    }
199
267
}