KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > io > Encodings


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: Encodings.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
22  */

23 package org.enhydra.xml.io;
24
25 import java.io.BufferedReader JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.InputStreamReader JavaDoc;
29 import java.lang.reflect.Constructor JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.util.StringTokenizer JavaDoc;
33
34 // FIXME: The information here is limited, need to find a canonical
35
// source of names and encoding sizes, etc. Create an XML file describing
36
// it.
37

38 /**
39  * Class that manages information about encodings.
40  */

41 public final class Encodings {
42     /**
43      * Some standard character set constants. Using the standard names.
44      */

45     public static final String JavaDoc ISO_8859_1 = "ISO_8859-1";
46     public static final String JavaDoc US_ASCII = "US-ASCII";
47     public static final String JavaDoc SHIFT_JIS = "Shift_JIS";
48
49     /**
50      * Resource name of file containing character set information.
51      */

52     private final String JavaDoc CHAR_SET_TABLE
53         = "org/enhydra/xml/io/character-sets.tbl";
54
55     /**
56      * String use for null encoding in file.
57      */

58     private final String JavaDoc NULL_STR = "null";
59
60     /**
61      * Singleton instance.
62      */

63     private static Encodings fSingleton;
64
65     /**
66      * Singleton empty list of aliases.
67      */

68     private static final String JavaDoc[] fEmptyAliases = new String JavaDoc[0];
69
70     /**
71      * Table of character sets. The table is keyed by upper-cased encoding
72      * names and aliases, containing references to CharacterSet objects.
73      */

74     private final HashMap JavaDoc fCharSets = new HashMap JavaDoc();
75     
76     private static final Class JavaDoc CHARSET_CONSTRUCTOR_TYPES[] = {
77         String JavaDoc.class, Integer.TYPE, String JavaDoc.class, String JavaDoc[].class
78     };
79
80     /**
81      * Generate an error about parsing an entry
82      */

83     private void parseError(String JavaDoc msg,
84                             String JavaDoc line) {
85         throw new XMLIOError(msg + "; parsing line in " + CHAR_SET_TABLE
86                              + "\"" + line + "\"");
87     }
88
89     /**
90      * Parse the next entry from the file
91      */

92     private CharacterSet parseCharSetEntry(String JavaDoc line) {
93         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(line);
94         int numTokens = tokens.countTokens();
95         if (numTokens < 4) {
96             parseError("must have at least 4 entries", line);
97         }
98
99         String JavaDoc className = tokens.nextToken();
100         String JavaDoc name = tokens.nextToken();
101         Integer JavaDoc charSetSize = null;
102         try {
103             charSetSize = new Integer JavaDoc(tokens.nextToken());
104         } catch (NumberFormatException JavaDoc nfe) {
105             parseError("invalid character set size", line);
106         }
107         String JavaDoc mimePreferred = tokens.nextToken();;
108         if (mimePreferred.equals(NULL_STR)) {
109             mimePreferred = null;
110         }
111         String JavaDoc[] aliases = fEmptyAliases;
112
113         if (numTokens > 4) {
114             aliases = new String JavaDoc[numTokens - 4];
115             int idx = 0;
116             while (tokens.hasMoreTokens()) {
117                 aliases[idx++] = tokens.nextToken();
118             }
119         }
120         
121         // Instantiate the appropriate charset class.
122
try {
123             Class JavaDoc clazz = Class.forName(className);
124             Constructor JavaDoc ctr = clazz.getConstructor(CHARSET_CONSTRUCTOR_TYPES);
125             Object JavaDoc params[] = { name, charSetSize, mimePreferred, aliases };
126             return (CharacterSet)ctr.newInstance(params);
127         } catch (Exception JavaDoc e) {
128             parseError("Exception loading character set class '" + className + "': " +
129             e.toString(), line);
130         }
131         // Should never be reached, but must be here to make the compiler happy
132
throw new IllegalStateException JavaDoc("Ooops. This should never happen. Please debug");
133     }
134
135     /**
136      * Add an entry to the mapping table.
137      */

138     private void addEntry(CharacterSet charSet) {
139         fCharSets.put(charSet.getName().toUpperCase().intern(), charSet);
140         
141         String JavaDoc[] aliases = charSet.getAliases();
142         int len = (aliases == null) ? 0 : aliases.length;
143         for (int idx = 0; idx < len; idx++) {
144             fCharSets.put(aliases[idx].toUpperCase().intern(), charSet);
145         }
146     }
147
148     /**
149      * Parse the character set file.
150      */

151     private void parseCharacterSetTable(BufferedReader JavaDoc in) throws IOException JavaDoc {
152         String JavaDoc line;
153         while ((line = in.readLine()) != null) {
154             addEntry(parseCharSetEntry(line));
155         }
156     }
157
158     /**
159      * Parse the character set file.
160      */

161     private void parseCharacterSetTable() {
162         ClassLoader JavaDoc loader = Encodings.class.getClassLoader();
163         if (loader == null) {
164             // Works around a JDeveloper JVM bug.
165
loader = ClassLoader.getSystemClassLoader();
166         }
167         InputStream JavaDoc inStream = loader.getResourceAsStream(CHAR_SET_TABLE);
168         if (inStream == null) {
169             throw new XMLIOError("can't find \"" + CHAR_SET_TABLE + "\" on class path");
170         }
171         try {
172             try {
173                 BufferedReader JavaDoc in = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(inStream));
174                 parseCharacterSetTable(in);
175             } finally {
176                 inStream.close();
177             }
178         } catch (IOException JavaDoc except) {
179             throw new XMLIOError("error reading " + CHAR_SET_TABLE);
180         }
181     }
182
183     /**
184      * Disallow external instantiation.
185      */

186     private Encodings() {
187         parseCharacterSetTable();
188     }
189
190     /**
191      * Get the entry for an encoding name or null.
192      */

193     public CharacterSet getCharacterSet(String JavaDoc encoding) {
194         return (CharacterSet)fCharSets.get(encoding.toUpperCase());
195     }
196
197     /**
198      * Determine if an encoding is a valid encoding.
199      */

200     public boolean isValid(String JavaDoc encoding) {
201         return getCharacterSet(encoding) != null;
202     }
203     
204     /**
205      * Get the encoding name, given any encoding or alias, or null
206      * if unknown encoding.
207      */

208     public String JavaDoc getName(String JavaDoc encoding) {
209         CharacterSet charSet = getCharacterSet(encoding);
210         if (charSet == null) {
211             return null;
212         } else {
213             return charSet.getName();
214         }
215     }
216
217     /**
218      * Get the preferred MIME encoding, or null if unknown encoding.
219      */

220     public String JavaDoc getMIMEPreferred(String JavaDoc encoding) {
221         CharacterSet charSet = getCharacterSet(encoding);
222         if (charSet == null) {
223             return null;
224         } else {
225             return charSet.getMIMEPreferred();
226         }
227     }
228
229     /**
230      * Get the encoding aliases, given any encoding or alias,
231      * or null if unknown encoding.
232      */

233     public String JavaDoc[] getAliases(String JavaDoc encoding) {
234         CharacterSet charSet = getCharacterSet(encoding);
235         if (charSet == null) {
236             return null;
237         } else {
238             return charSet.getAliases();
239         }
240     }
241
242     /**
243      * Get the maximum value of an unicode character in an encoding.
244      * This checks for 7 and 8 bit encodings; everything else is considered
245      * to require 16 bits.
246      */

247     public int getMaxCharacterValue(String JavaDoc encoding) {
248         CharacterSet charSet = getCharacterSet(encoding);
249         if (charSet == null) {
250             return 0xFFFF; // assume the best
251
} else {
252             return charSet.getMaxCharValue();
253         }
254     }
255
256     /**
257      * Determine if two encoding names represent the same encoding.
258      * Handles nulls, with two nulls being considered the same encoding.
259      */

260     public boolean sameEncodings(String JavaDoc encoding1,
261                                  String JavaDoc encoding2) {
262         if ((encoding1 == null) && (encoding2 == null)) {
263             return true;
264         } else if ((encoding1 == null) || (encoding2 == null)) {
265             return false;
266         } else {
267             return (getCharacterSet(encoding1) == getCharacterSet(encoding2));
268         }
269     }
270
271     /**
272      * Return string representation for debugging.
273      */

274     public String JavaDoc toString() {
275         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(4096); // larger than default
276
Iterator JavaDoc values = fCharSets.values().iterator();
277         while (values.hasNext()) {
278             buf.append(values.next().toString());
279             buf.append('\n');
280         }
281         return buf.toString();
282     }
283
284     /**
285      * Get the singleton instance of this class.
286      */

287     public static Encodings getEncodings() {
288         if (fSingleton == null) {
289             fSingleton = new Encodings();
290         }
291         return fSingleton;
292     }
293 }
294
Popular Tags