Source Code Cross Referenced for MessageCatalog.java in  » 6.0-JDK-Modules » jaxb-xjc » com » sun » xml » dtdparser » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » jaxb xjc » com.sun.xml.dtdparser 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
003:         */
004:
005:        package com.sun.xml.dtdparser;
006:
007:        import java.io.InputStream;
008:        import java.text.FieldPosition;
009:        import java.text.MessageFormat;
010:        import java.util.Hashtable;
011:        import java.util.Locale;
012:        import java.util.MissingResourceException;
013:        import java.util.ResourceBundle;
014:
015:        /**
016:         * This class provides support for multi-language string lookup, as needed
017:         * to localize messages from applications supporting multiple languages
018:         * at the same time.  One class of such applications is network services,
019:         * such as HTTP servers, which talk to clients who may not be from the
020:         * same locale as the server.  This class supports a form of negotiation
021:         * for the language used in presenting a message from some package, where
022:         * both user (client) preferences and application (server) support are
023:         * accounted for when choosing locales and formatting messages.
024:         * <p/>
025:         * <P> Each package should have a singleton package-private message catalog
026:         * class.  This ensures that the correct class loader will always be used to
027:         * access message resources, and minimizes use of memory: <PRE>
028:         * package <em>some.package</em>;
029:         * <p/>
030:         * // "foo" might be public
031:         * class foo {
032:         * ...
033:         * // package private
034:         * static final Catalog messages = new Catalog ();
035:         * static final class Catalog extends MessageCatalog {
036:         * Catalog () { super (Catalog.class); }
037:         * }
038:         * ...
039:         * }
040:         * </PRE>
041:         * <p/>
042:         * <P> Messages for a known client could be generated using code
043:         * something like this:  <PRE>
044:         * String clientLanguages [];
045:         * Locale clientLocale;
046:         * String clientMessage;
047:         * <p/>
048:         * // client languages will probably be provided by client,
049:         * // e.g. by an HTTP/1.1 "Accept-Language" header.
050:         * clientLanguages = new String [] { "en-ca", "fr-ca", "ja", "zh" };
051:         * clientLocale = foo.messages.chooseLocale (clientLanguages);
052:         * clientMessage = foo.messages.getMessage (clientLocale,
053:         * "fileCount",
054:         * new Object [] { new Integer (numberOfFiles) }
055:         * );
056:         * </PRE>
057:         * <p/>
058:         * <P> At this time, this class does not include functionality permitting
059:         * messages to be passed around and localized after-the-fact.  The consequence
060:         * of this is that the locale for messages must be passed down through layers
061:         * which have no normal reason to support such passdown, or else the system
062:         * default locale must be used instead of the one the client needs.
063:         * <p/>
064:         * <P> <hr> The following guidelines should be used when constructiong
065:         * multi-language applications:  <OL>
066:         * <p/>
067:         * <LI> Always use <a href=#chooseLocale>chooseLocale</a> to select the
068:         * locale you pass to your <code>getMessage</code> call.  This lets your
069:         * applications use IETF standard locale names, and avoids needless
070:         * use of system defaults.
071:         * <p/>
072:         * <LI> The localized messages for a given package should always go in
073:         * a separate <em>resources</em> sub-package.  There are security
074:         * implications; see below.
075:         * <p/>
076:         * <LI> Make sure that a language name is included in each bundle name,
077:         * so that the developer's locale will not be inadvertently used. That
078:         * is, don't create defaults like <em>resources/Messages.properties</em>
079:         * or <em>resources/Messages.class</em>, since ResourceBundle will choose
080:         * such defaults rather than giving software a chance to choose a more
081:         * appropriate language for its messages.  Your message bundles should
082:         * have names like <em>Messages_en.properties</em> (for the "en", or
083:         * English, language) or <em>Messages_ja.class</em> ("ja" indicates the
084:         * Japanese language).
085:         * <p/>
086:         * <LI> Only use property files for messages in languages which can
087:         * be limited to the ISO Latin/1 (8859-1) characters supported by the
088:         * property file format.  (This is mostly Western European languages.)
089:         * Otherwise, subclass ResourceBundle to provide your messages; it is
090:         * simplest to subclass <code>java.util.ListResourceBundle</code>.
091:         * <p/>
092:         * <LI> Never use another package's message catalog or resource bundles.
093:         * It should not be possible for a change internal to one package (such
094:         * as eliminating or improving messages) to break another package.
095:         * <p/>
096:         * </OL>
097:         * <p/>
098:         * <P> The "resources" sub-package can be treated separately from the
099:         * package with which it is associated.  That main package may be sealed
100:         * and possibly signed, preventing other software from adding classes to
101:         * the package which would be able to access methods and data which are
102:         * not designed to be publicly accessible.  On the other hand, resources
103:         * such as localized messages are often provided after initial product
104:         * shipment, without a full release cycle for the product.  Such files
105:         * (text and class files) need to be added to some package.  Since they
106:         * should not be added to the main package, the "resources" subpackage is
107:         * used without risking the security or integrity of that main package
108:         * as distributed in its JAR file.
109:         *
110:         * @author David Brownell
111:         * @version 1.1, 00/08/05
112:         * @see java.util.Locale
113:         * @see java.util.ListResourceBundle
114:         * @see java.text.MessageFormat
115:         */
116:        // leave this as "abstract" -- each package needs its own subclass,
117:        // else it's not always going to be using the right class loader.
118:        abstract public class MessageCatalog {
119:            private String bundleName;
120:
121:            /**
122:             * Create a message catalog for use by classes in the same package
123:             * as the specified class.  This uses <em>Messages</em> resource
124:             * bundles in the <em>resources</em> sub-package of class passed as
125:             * a parameter.
126:             *
127:             * @param packageMember Class whose package has localized messages
128:             */
129:            protected MessageCatalog(Class packageMember) {
130:                this (packageMember, "Messages");
131:            }
132:
133:            /**
134:             * Create a message catalog for use by classes in the same package
135:             * as the specified class.  This uses the specified resource
136:             * bundle name in the <em>resources</em> sub-package of class passed
137:             * as a parameter; for example, <em>resources.Messages</em>.
138:             *
139:             * @param packageMember Class whose package has localized messages
140:             * @param bundle        Name of a group of resource bundles
141:             */
142:            private MessageCatalog(Class packageMember, String bundle) {
143:                int index;
144:
145:                bundleName = packageMember.getName();
146:                index = bundleName.lastIndexOf('.');
147:                if (index == -1) // "ClassName"
148:                    bundleName = "";
149:                else
150:                    // "some.package.ClassName"
151:                    bundleName = bundleName.substring(0, index) + ".";
152:                bundleName = bundleName + "resources." + bundle;
153:            }
154:
155:            /**
156:             * Get a message localized to the specified locale, using the message ID
157:             * and package name if no message is available.  The locale is normally
158:             * that of the client of a service, chosen with knowledge that both the
159:             * client and this server support that locale.  There are two error
160:             * cases:  first, when the specified locale is unsupported or null, the
161:             * default locale is used if possible; second, when no bundle supports
162:             * that locale, the message ID and package name are used.
163:             *
164:             * @param locale    The locale of the message to use.  If this is null,
165:             *                  the default locale will be used.
166:             * @param messageId The ID of the message to use.
167:             * @return The message, localized as described above.
168:             */
169:            public String getMessage(Locale locale, String messageId) {
170:                ResourceBundle bundle;
171:
172:                // cope with unsupported locale...
173:                if (locale == null)
174:                    locale = Locale.getDefault();
175:
176:                try {
177:                    bundle = ResourceBundle.getBundle(bundleName, locale);
178:                } catch (MissingResourceException e) {
179:                    bundle = ResourceBundle.getBundle(bundleName,
180:                            Locale.ENGLISH);
181:                }
182:                return bundle.getString(messageId);
183:            }
184:
185:            /**
186:             * Format a message localized to the specified locale, using the message
187:             * ID with its package name if none is available.  The locale is normally
188:             * the client of a service, chosen with knowledge that both the client
189:             * server support that locale.  There are two error cases:  first, if the
190:             * specified locale is unsupported or null, the default locale is used if
191:             * possible; second, when no bundle supports that locale, the message ID
192:             * and package name are used.
193:             *
194:             * @param locale     The locale of the message to use.  If this is null,
195:             *                   the default locale will be used.
196:             * @param messageId  The ID of the message format to use.
197:             * @param parameters Used when formatting the message.  Objects in
198:             *                   this list are turned to strings if they are not Strings, Numbers,
199:             *                   or Dates (that is, if MessageFormat would treat them as errors).
200:             * @return The message, localized as described above.
201:             * @see java.text.MessageFormat
202:             */
203:            public String getMessage(Locale locale, String messageId,
204:                    Object parameters[]) {
205:                if (parameters == null)
206:                    return getMessage(locale, messageId);
207:
208:                // since most messages won't be tested (sigh), be friendly to
209:                // the inevitable developer errors of passing random data types
210:                // to the message formatting code.
211:                for (int i = 0; i < parameters.length; i++) {
212:                    if (!(parameters[i] instanceof  String)
213:                            && !(parameters[i] instanceof  Number)
214:                            && !(parameters[i] instanceof  java.util.Date)) {
215:                        if (parameters[i] == null)
216:                            parameters[i] = "(null)";
217:                        else
218:                            parameters[i] = parameters[i].toString();
219:                    }
220:                }
221:
222:                // similarly, cope with unsupported locale...
223:                if (locale == null)
224:                    locale = Locale.getDefault();
225:
226:                // get the appropriately localized MessageFormat object
227:                ResourceBundle bundle;
228:                MessageFormat format;
229:
230:                try {
231:                    bundle = ResourceBundle.getBundle(bundleName, locale);
232:                } catch (MissingResourceException e) {
233:                    bundle = ResourceBundle.getBundle(bundleName,
234:                            Locale.ENGLISH);
235:                    /*String retval;
236:
237:                    retval = packagePrefix (messageId);
238:                    for (int i = 0; i < parameters.length; i++) {
239:                    retval += ' ';
240:                    retval += parameters [i];
241:                    }
242:                    return retval;*/
243:                }
244:                format = new MessageFormat(bundle.getString(messageId));
245:                format.setLocale(locale);
246:
247:                // return the formatted message
248:                StringBuffer result = new StringBuffer();
249:
250:                result = format
251:                        .format(parameters, result, new FieldPosition(0));
252:                return result.toString();
253:            }
254:
255:            /**
256:             * Chooses a client locale to use, using the first language specified in
257:             * the list that is supported by this catalog.  If none of the specified
258:             * languages is supported, a null value is returned.  Such a list of
259:             * languages might be provided in an HTTP/1.1 "Accept-Language" header
260:             * field, or through some other content negotiation mechanism.
261:             * <p/>
262:             * <P> The language specifiers recognized are RFC 1766 style ("fr" for
263:             * all French, "fr-ca" for Canadian French), although only the strict
264:             * ISO subset (two letter language and country specifiers) is currently
265:             * supported.  Java-style locale strings ("fr_CA") are also supported.
266:             *
267:             * @param languages Array of language specifiers, ordered with the most
268:             *                  preferable one at the front.  For example, "en-ca" then "fr-ca",
269:             *                  followed by "zh_CN".
270:             * @return The most preferable supported locale, or null.
271:             * @see java.util.Locale
272:             */
273:            public Locale chooseLocale(String languages[]) {
274:                if ((languages = canonicalize(languages)) != null) {
275:                    for (int i = 0; i < languages.length; i++)
276:                        if (isLocaleSupported(languages[i]))
277:                            return getLocale(languages[i]);
278:                }
279:                return null;
280:            }
281:
282:            //
283:            // Canonicalizes the RFC 1766 style language strings ("en-in") to
284:            // match standard Java usage ("en_IN"), removing strings that don't
285:            // use two character ISO language and country codes.   Avoids all
286:            // memory allocations possible, so that if the strings passed in are
287:            // just lowercase ISO codes (a common case) the input is returned.
288:            //
289:            private String[] canonicalize(String languages[]) {
290:                boolean didClone = false;
291:                int trimCount = 0;
292:
293:                if (languages == null)
294:                    return languages;
295:
296:                for (int i = 0; i < languages.length; i++) {
297:                    String lang = languages[i];
298:                    int len = lang.length();
299:
300:                    // no RFC1766 extensions allowed; "zh" and "zh-tw" (etc) are OK
301:                    // as are regular locale names with no variant ("de_CH").
302:                    if (!(len == 2 || len == 5)) {
303:                        if (!didClone) {
304:                            languages = (String[]) languages.clone();
305:                            didClone = true;
306:                        }
307:                        languages[i] = null;
308:                        trimCount++;
309:                        continue;
310:                    }
311:
312:                    // language code ... if already lowercase, we change nothing
313:                    if (len == 2) {
314:                        lang = lang.toLowerCase();
315:                        if (lang != languages[i]) {
316:                            if (!didClone) {
317:                                languages = (String[]) languages.clone();
318:                                didClone = true;
319:                            }
320:                            languages[i] = lang;
321:                        }
322:                        continue;
323:                    }
324:
325:                    // language_country ... fixup case, force "_"
326:                    char buf[] = new char[5];
327:
328:                    buf[0] = Character.toLowerCase(lang.charAt(0));
329:                    buf[1] = Character.toLowerCase(lang.charAt(1));
330:                    buf[2] = '_';
331:                    buf[3] = Character.toUpperCase(lang.charAt(3));
332:                    buf[4] = Character.toUpperCase(lang.charAt(4));
333:                    if (!didClone) {
334:                        languages = (String[]) languages.clone();
335:                        didClone = true;
336:                    }
337:                    languages[i] = new String(buf);
338:                }
339:
340:                // purge any shadows of deleted RFC1766 extended language codes
341:                if (trimCount != 0) {
342:                    String temp[] = new String[languages.length - trimCount];
343:                    int i;
344:
345:                    for (i = 0, trimCount = 0; i < temp.length; i++) {
346:                        while (languages[i + trimCount] == null)
347:                            trimCount++;
348:                        temp[i] = languages[i + trimCount];
349:                    }
350:                    languages = temp;
351:                }
352:                return languages;
353:            }
354:
355:            //
356:            // Returns a locale object supporting the specified locale, using
357:            // a small cache to speed up some common languages and reduce the
358:            // needless allocation of memory.
359:            //
360:            private Locale getLocale(String localeName) {
361:                String language, country;
362:                int index;
363:
364:                index = localeName.indexOf('_');
365:                if (index == -1) {
366:                    //
367:                    // Special case the builtin JDK languages
368:                    //
369:                    if (localeName.equals("de"))
370:                        return Locale.GERMAN;
371:                    if (localeName.equals("en"))
372:                        return Locale.ENGLISH;
373:                    if (localeName.equals("fr"))
374:                        return Locale.FRENCH;
375:                    if (localeName.equals("it"))
376:                        return Locale.ITALIAN;
377:                    if (localeName.equals("ja"))
378:                        return Locale.JAPANESE;
379:                    if (localeName.equals("ko"))
380:                        return Locale.KOREAN;
381:                    if (localeName.equals("zh"))
382:                        return Locale.CHINESE;
383:
384:                    language = localeName;
385:                    country = "";
386:                } else {
387:                    if (localeName.equals("zh_CN"))
388:                        return Locale.SIMPLIFIED_CHINESE;
389:                    if (localeName.equals("zh_TW"))
390:                        return Locale.TRADITIONAL_CHINESE;
391:
392:                    //
393:                    // JDK also has constants for countries:  en_GB, en_US, en_CA,
394:                    // fr_FR, fr_CA, de_DE, ja_JP, ko_KR.  We don't use those.
395:                    //
396:                    language = localeName.substring(0, index);
397:                    country = localeName.substring(index + 1);
398:                }
399:
400:                return new Locale(language, country);
401:            }
402:
403:            //
404:            // cache for isLanguageSupported(), below ... key is a language
405:            // or locale name, value is a Boolean
406:            //
407:            private Hashtable cache = new Hashtable(5);
408:
409:            /**
410:             * Returns true iff the specified locale has explicit language support.
411:             * For example, the traditional Chinese locale "zh_TW" has such support
412:             * if there are message bundles suffixed with either "zh_TW" or "zh".
413:             * <p/>
414:             * <P> This method is used to bypass part of the search path mechanism
415:             * of the <code>ResourceBundle</code> class, specifically the parts which
416:             * force use of default locales and bundles.  Such bypassing is required
417:             * in order to enable use of a client's preferred languages.  Following
418:             * the above example, if a client prefers "zh_TW" but can also accept
419:             * "ja", this method would be used to detect that there are no "zh_TW"
420:             * resource bundles and hence that "ja" messages should be used.  This
421:             * bypasses the ResourceBundle mechanism which will return messages in
422:             * some other locale (picking some hard-to-anticipate default) instead
423:             * of reporting an error and letting the client choose another locale.
424:             *
425:             * @param localeName A standard Java locale name, using two character
426:             *                   language codes optionally suffixed by country codes.
427:             * @return True iff the language of that locale is supported.
428:             * @see java.util.Locale
429:             */
430:            public boolean isLocaleSupported(String localeName) {
431:                //
432:                // Use previous results if possible.  We expect that the codebase
433:                // is immutable, so we never worry about changing the cache.
434:                //
435:                Boolean value = (Boolean) cache.get(localeName);
436:
437:                if (value != null)
438:                    return value.booleanValue();
439:
440:                //
441:                // Try "language_country_variant", then "language_country",
442:                // then finally "language" ... assuming the longest locale name
443:                // is passed.  If not, we'll try fewer options.
444:                //
445:                ClassLoader loader = null;
446:
447:                for (;;) {
448:                    String name = bundleName + "_" + localeName;
449:
450:                    // look up classes ...
451:                    try {
452:                        Class.forName(name);
453:                        cache.put(localeName, Boolean.TRUE);
454:                        return true;
455:                    } catch (Exception e) {
456:                    }
457:
458:                    // ... then property files (only for ISO Latin/1 messages)
459:                    InputStream in;
460:
461:                    if (loader == null)
462:                        loader = getClass().getClassLoader();
463:
464:                    name = name.replace('.', '/');
465:                    name = name + ".properties";
466:                    if (loader == null)
467:                        in = ClassLoader.getSystemResourceAsStream(name);
468:                    else
469:                        in = loader.getResourceAsStream(name);
470:                    if (in != null) {
471:                        cache.put(localeName, Boolean.TRUE);
472:                        return true;
473:                    }
474:
475:                    int index = localeName.indexOf('_');
476:
477:                    if (index > 0)
478:                        localeName = localeName.substring(0, index);
479:                    else
480:                        break;
481:                }
482:
483:                //
484:                // If we got this far, we failed.  Remember for later.
485:                //
486:                cache.put(localeName, Boolean.FALSE);
487:                return false;
488:            }
489:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.