Source Code Cross Referenced for Locale.java in  » 6.0-JDK-Modules » j2me » java » util » 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 » j2me » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * 
0003:         * @(#)Locale.java	1.64 06/10/10
0004:         * 
0005:         * Portions Copyright  2000-2006 Sun Microsystems, Inc. All Rights
0006:         * Reserved.  Use is subject to license terms.
0007:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0008:         * 
0009:         * This program is free software; you can redistribute it and/or
0010:         * modify it under the terms of the GNU General Public License version
0011:         * 2 only, as published by the Free Software Foundation.
0012:         * 
0013:         * This program is distributed in the hope that it will be useful, but
0014:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0015:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0016:         * General Public License version 2 for more details (a copy is
0017:         * included at /legal/license.txt).
0018:         * 
0019:         * You should have received a copy of the GNU General Public License
0020:         * version 2 along with this work; if not, write to the Free Software
0021:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0022:         * 02110-1301 USA
0023:         * 
0024:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0025:         * Clara, CA 95054 or visit www.sun.com if you need additional
0026:         * information or have any questions.
0027:         */
0028:
0029:        /*
0030:         * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
0031:         * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
0032:         *
0033:         * The original version of this source code and documentation
0034:         * is copyrighted and owned by Taligent, Inc., a wholly-owned
0035:         * subsidiary of IBM. These materials are provided under terms
0036:         * of a License Agreement between Taligent and Sun. This technology
0037:         * is protected by multiple US and International patents.
0038:         *
0039:         * This notice and attribution to Taligent may not be removed.
0040:         * Taligent is a registered trademark of Taligent, Inc.
0041:         *
0042:         */
0043:
0044:        package java.util;
0045:
0046:        import java.io.*;
0047:        import java.security.AccessController;
0048:        import java.text.MessageFormat;
0049:        import sun.security.action.GetPropertyAction;
0050:        import sun.text.resources.LocaleData;
0051:
0052:        /**
0053:         *
0054:         * A <code>Locale</code> object represents a specific geographical, political,
0055:         * or cultural region. An operation that requires a <code>Locale</code> to perform
0056:         * its task is called <em>locale-sensitive</em> and uses the <code>Locale</code>
0057:         * to tailor information for the user. For example, displaying a number
0058:         * is a locale-sensitive operation--the number should be formatted
0059:         * according to the customs/conventions of the user's native country,
0060:         * region, or culture.
0061:         *
0062:         * <P>
0063:         * Create a <code>Locale</code> object using the constructors in this class:
0064:         * <blockquote>
0065:         * <pre>
0066:         * Locale(String language)
0067:         * Locale(String language, String country)
0068:         * Locale(String language, String country, String variant)
0069:         * </pre>
0070:         * </blockquote>
0071:         * The language argument is a valid <STRONG>ISO Language Code.</STRONG> 
0072:         * These codes are the lower-case, two-letter codes as defined by ISO-639.
0073:         * You can find a full list of these codes at a number of sites, such as:
0074:         * <BR><a href ="http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt">
0075:         * <code>http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt</code></a>
0076:         *
0077:         * <P>
0078:         * The country argument is a valid <STRONG>ISO Country Code.</STRONG> These 
0079:         * codes are the upper-case, two-letter codes as defined by ISO-3166.
0080:         * You can find a full list of these codes at a number of sites, such as:
0081:         * <BR><a href="http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html">
0082:         * <code>http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html</code></a>
0083:         *
0084:         * <P>
0085:         * The variant argument is a vendor or browser-specific code.
0086:         * For example, use WIN for Windows, MAC for Macintosh, and POSIX for POSIX.
0087:         * Where there are two variants, separate them with an underscore, and
0088:         * put the most important one first. For example, a Traditional Spanish collation 
0089:         * might construct a locale with parameters for language, country and variant as: 
0090:         * "es", "ES", "Traditional_WIN".
0091:         *
0092:         * <P>
0093:         * Because a <code>Locale</code> object is just an identifier for a region,
0094:         * no validity check is performed when you construct a <code>Locale</code>.
0095:         * If you want to see whether particular resources are available for the
0096:         * <code>Locale</code> you construct, you must query those resources. For
0097:         * example, ask the <code>NumberFormat</code> for the locales it supports
0098:         * using its <code>getAvailableLocales</code> method.
0099:         * <BR><STRONG>Note:</STRONG> When you ask for a resource for a particular
0100:         * locale, you get back the best available match, not necessarily
0101:         * precisely what you asked for. For more information, look at
0102:         * {@link ResourceBundle}.
0103:         *
0104:         * <P>
0105:         * The <code>Locale</code> class provides a number of convenient constants
0106:         * that you can use to create <code>Locale</code> objects for commonly used
0107:         * locales. For example, the following creates a <code>Locale</code> object
0108:         * for the United States:
0109:         * <blockquote>
0110:         * <pre>
0111:         * Locale.US
0112:         * </pre>
0113:         * </blockquote>
0114:         *
0115:         * <P>
0116:         * Once you've created a <code>Locale</code> you can query it for information about
0117:         * itself. Use <code>getCountry</code> to get the ISO Country Code and
0118:         * <code>getLanguage</code> to get the ISO Language Code. You can
0119:         * use <code>getDisplayCountry</code> to get the
0120:         * name of the country suitable for displaying to the user. Similarly,
0121:         * you can use <code>getDisplayLanguage</code> to get the name of
0122:         * the language suitable for displaying to the user. Interestingly,
0123:         * the <code>getDisplayXXX</code> methods are themselves locale-sensitive
0124:         * and have two versions: one that uses the default locale and one
0125:         * that uses the locale specified as an argument.
0126:         *
0127:         * <P>
0128:         * The Java 2 platform provides a number of classes that perform locale-sensitive
0129:         * operations. For example, the <code>NumberFormat</code> class formats
0130:         * numbers, currency, or percentages in a locale-sensitive manner. Classes
0131:         * such as <code>NumberFormat</code> have a number of convenience methods
0132:         * for creating a default object of that type. For example, the
0133:         * <code>NumberFormat</code> class provides these three convenience methods
0134:         * for creating a default <code>NumberFormat</code> object:
0135:         * <blockquote>
0136:         * <pre>
0137:         * NumberFormat.getInstance()
0138:         * NumberFormat.getCurrencyInstance()
0139:         * NumberFormat.getPercentInstance()
0140:         * </pre>
0141:         * </blockquote>
0142:         * These methods have two variants; one with an explicit locale
0143:         * and one without; the latter using the default locale.
0144:         * <blockquote>
0145:         * <pre>
0146:         * NumberFormat.getInstance(myLocale)
0147:         * NumberFormat.getCurrencyInstance(myLocale)
0148:         * NumberFormat.getPercentInstance(myLocale)
0149:         * </pre>
0150:         * </blockquote>
0151:         * A <code>Locale</code> is the mechanism for identifying the kind of object
0152:         * (<code>NumberFormat</code>) that you would like to get. The locale is
0153:         * <STRONG>just</STRONG> a mechanism for identifying objects,
0154:         * <STRONG>not</STRONG> a container for the objects themselves.
0155:         *
0156:         * <P>
0157:         * Each class that performs locale-sensitive operations allows you
0158:         * to get all the available objects of that type. You can sift
0159:         * through these objects by language, country, or variant,
0160:         * and use the display names to present a menu to the user.
0161:         * For example, you can create a menu of all the collation objects
0162:         * suitable for a given language. Such classes must implement these
0163:         * three class methods:
0164:         * <blockquote>
0165:         * <pre>
0166:         * public static Locale[] getAvailableLocales()
0167:         * public static String getDisplayName(Locale objectLocale,
0168:         *                                     Locale displayLocale)
0169:         * public static final String getDisplayName(Locale objectLocale)
0170:         *     // getDisplayName will throw MissingResourceException if the locale
0171:         *     // is not one of the available locales.
0172:         * </pre>
0173:         * </blockquote>
0174:         *
0175:         * @see         ResourceBundle
0176:         * @see         java.text.Format
0177:         * @see         java.text.NumberFormat
0178:         * @see         java.text.Collator
0179:         * @version     1.55, 01/19/00
0180:         * @author      Mark Davis
0181:         * @since       1.1
0182:         */
0183:
0184:        public final class Locale implements  Cloneable, Serializable {
0185:
0186:            /** Useful constant for language.
0187:             */
0188:            static public final Locale ENGLISH = new Locale("en", "", "");
0189:
0190:            /** Useful constant for language.
0191:             */
0192:            static public final Locale FRENCH = new Locale("fr", "", "");
0193:
0194:            /** Useful constant for language.
0195:             */
0196:            static public final Locale GERMAN = new Locale("de", "", "");
0197:
0198:            /** Useful constant for language.
0199:             */
0200:            static public final Locale ITALIAN = new Locale("it", "", "");
0201:
0202:            /** Useful constant for language.
0203:             */
0204:            static public final Locale JAPANESE = new Locale("ja", "", "");
0205:
0206:            /** Useful constant for language.
0207:             */
0208:            static public final Locale KOREAN = new Locale("ko", "", "");
0209:
0210:            /** Useful constant for language.
0211:             */
0212:            static public final Locale CHINESE = new Locale("zh", "", "");
0213:
0214:            /** Useful constant for language.
0215:             */
0216:            static public final Locale SIMPLIFIED_CHINESE = new Locale("zh",
0217:                    "CN", "");
0218:
0219:            /** Useful constant for language.
0220:             */
0221:            static public final Locale TRADITIONAL_CHINESE = new Locale("zh",
0222:                    "TW", "");
0223:
0224:            /** Useful constant for country.
0225:             */
0226:            static public final Locale FRANCE = new Locale("fr", "FR", "");
0227:
0228:            /** Useful constant for country.
0229:             */
0230:            static public final Locale GERMANY = new Locale("de", "DE", "");
0231:
0232:            /** Useful constant for country.
0233:             */
0234:            static public final Locale ITALY = new Locale("it", "IT", "");
0235:
0236:            /** Useful constant for country.
0237:             */
0238:            static public final Locale JAPAN = new Locale("ja", "JP", "");
0239:
0240:            /** Useful constant for country.
0241:             */
0242:            static public final Locale KOREA = new Locale("ko", "KR", "");
0243:
0244:            /** Useful constant for country.
0245:             */
0246:            static public final Locale CHINA = new Locale("zh", "CN", "");
0247:
0248:            /** Useful constant for country.
0249:             */
0250:            static public final Locale PRC = new Locale("zh", "CN", "");
0251:
0252:            /** Useful constant for country.
0253:             */
0254:            static public final Locale TAIWAN = new Locale("zh", "TW", "");
0255:
0256:            /** Useful constant for country.
0257:             */
0258:            static public final Locale UK = new Locale("en", "GB", "");
0259:
0260:            /** Useful constant for country.
0261:             */
0262:            static public final Locale US = new Locale("en", "US", "");
0263:
0264:            /** Useful constant for country.
0265:             */
0266:            static public final Locale CANADA = new Locale("en", "CA", "");
0267:
0268:            /** Useful constant for country.
0269:             */
0270:            static public final Locale CANADA_FRENCH = new Locale("fr", "CA",
0271:                    "");
0272:
0273:            /** serialization ID
0274:             */
0275:            static final long serialVersionUID = 9149081749638150636L;
0276:
0277:            /**
0278:             * Construct a locale from language, country, variant.
0279:             * NOTE:  ISO 639 is not a stable standard; some of the language codes it defines
0280:             * (specifically iw, ji, and in) have changed.  This constructor accepts both the
0281:             * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other
0282:             * API on Locale will return only the OLD codes.
0283:             * @param language lowercase two-letter ISO-639 code.
0284:             * @param country uppercase two-letter ISO-3166 code.
0285:             * @param variant vendor and browser specific code. See class description.
0286:             * @exception NullPointerException thrown if any argument is null.
0287:             */
0288:            public Locale(String language, String country, String variant) {
0289:                this .language = convertOldISOCodes(language);
0290:                this .country = toUpperCase(country).intern();
0291:                this .variant = variant.intern();
0292:            }
0293:
0294:            /**
0295:             * Construct a locale from language, country.
0296:             * NOTE:  ISO 639 is not a stable standard; some of the language codes it defines
0297:             * (specifically iw, ji, and in) have changed.  This constructor accepts both the
0298:             * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other
0299:             * API on Locale will return only the OLD codes.
0300:             * @param language lowercase two-letter ISO-639 code.
0301:             * @param country uppercase two-letter ISO-3166 code.
0302:             * @exception NullPointerException thrown if either argument is null.
0303:             */
0304:            public Locale(String language, String country) {
0305:                this (language, country, "");
0306:            }
0307:
0308:            /**
0309:             * Construct a locale from a language code.
0310:             * NOTE:  ISO 639 is not a stable standard; some of the language codes it defines
0311:             * (specifically iw, ji, and in) have changed.  This constructor accepts both the
0312:             * old codes (iw, ji, and in) and the new codes (he, yi, and id), but all other
0313:             * API on Locale will return only the OLD codes.
0314:             * @param language lowercase two-letter ISO-639 code.
0315:             * @exception NullPointerException thrown if argument is null.
0316:             * @since 1.4
0317:             */
0318:            public Locale(String language) {
0319:                this (language, "", "");
0320:            }
0321:
0322:            /**
0323:             * Gets the current value of the default locale for this instance
0324:             * of the Java Virtual Machine.
0325:             * <p>
0326:             * The Java Virtual Machine sets the default locale during startup
0327:             * based on the host environment. It is used by many locale-sensitive
0328:             * methods if no locale is explicitly specified.
0329:             * It can be changed using the
0330:             * {@link #setDefault(java.util.Locale) setDefault} method.
0331:             *
0332:             * @return the default locale for this instance of the Java Virtual Machine
0333:             */
0334:            public static Locale getDefault() {
0335:                // do not synchronize this method - see 4071298
0336:                // it's OK if more than one default locale happens to be created
0337:                if (defaultLocale == null) {
0338:                    String language, region, country, variant;
0339:                    language = (String) AccessController
0340:                            .doPrivileged(new GetPropertyAction(
0341:                                    "user.language", "en"));
0342:                    // for compatibility, check for old user.region property
0343:                    region = (String) AccessController
0344:                            .doPrivileged(new GetPropertyAction("user.region"));
0345:                    if (region != null) {
0346:                        // region can be of form country, country_variant, or _variant
0347:                        int i = region.indexOf('_');
0348:                        if (i >= 0) {
0349:                            country = region.substring(0, i);
0350:                            variant = region.substring(i + 1);
0351:                        } else {
0352:                            country = region;
0353:                            variant = "";
0354:                        }
0355:                    } else {
0356:                        country = (String) AccessController
0357:                                .doPrivileged(new GetPropertyAction(
0358:                                        "user.country", ""));
0359:                        variant = (String) AccessController
0360:                                .doPrivileged(new GetPropertyAction(
0361:                                        "user.variant", ""));
0362:                    }
0363:                    defaultLocale = new Locale(language, country, variant);
0364:                }
0365:                return defaultLocale;
0366:            }
0367:
0368:            /**
0369:             * Sets the default locale for this instance of the Java Virtual Machine.
0370:             * This does not affect the host locale.
0371:             * <p>
0372:             * If there is a security manager, its <code>checkPermission</code>
0373:             * method is called with a <code>PropertyPermission("user.language", "write")</code>
0374:             * permission before the default locale is changed.
0375:             * <p>
0376:             * The Java Virtual Machine sets the default locale during startup
0377:             * based on the host environment. It is used by many locale-sensitive
0378:             * methods if no locale is explicitly specified.
0379:             * <p>
0380:             * Since changing the default locale may affect many different areas
0381:             * of functionality, this method should only be used if the caller
0382:             * is prepared to reinitialize locale-sensitive code running
0383:             * within the same Java Virtual Machine, such as the user interface.
0384:             *
0385:             * @throws SecurityException
0386:             *        if a security manager exists and its
0387:             *        <code>checkPermission</code> method doesn't allow the operation.
0388:             * @throws NullPointerException if <code>newLocale</code> is null
0389:             * @param newLocale the new default locale
0390:             * @see SecurityManager#checkPermission
0391:             * @see java.util.PropertyPermission
0392:             */
0393:            public static synchronized void setDefault(Locale newLocale) {
0394:                if (newLocale == null)
0395:                    throw new NullPointerException(
0396:                            "Can't set default locale to NULL");
0397:
0398:                SecurityManager sm = System.getSecurityManager();
0399:                if (sm != null)
0400:                    sm.checkPermission(new PropertyPermission("user.language",
0401:                            "write"));
0402:                defaultLocale = newLocale;
0403:            }
0404:
0405:            /**
0406:             * Returns a list of all installed locales.
0407:             */
0408:            public static Locale[] getAvailableLocales() {
0409:                return LocaleData.getAvailableLocales("LocaleString");
0410:            }
0411:
0412:            /**
0413:             * Returns a list of all 2-letter country codes defined in ISO 3166.
0414:             * Can be used to create Locales.
0415:             */
0416:            public static String[] getISOCountries() {
0417:                if (isoCountries == null) {
0418:                    isoCountries = new String[compressedIsoCountries.length() / 6];
0419:                    for (int i = 0; i < isoCountries.length; i++)
0420:                        isoCountries[i] = compressedIsoCountries.substring(
0421:                                (i * 6) + 1, (i * 6) + 3);
0422:                }
0423:                String[] result = new String[isoCountries.length];
0424:                System.arraycopy(isoCountries, 0, result, 0,
0425:                        isoCountries.length);
0426:                return result;
0427:            }
0428:
0429:            /**
0430:             * Returns a list of all 2-letter language codes defined in ISO 639.
0431:             * Can be used to create Locales.
0432:             * [NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
0433:             * The list this function returns includes both the new and the old codes for the
0434:             * languages whose codes have changed.]
0435:             */
0436:            public static String[] getISOLanguages() {
0437:                if (isoLanguages == null) {
0438:                    isoLanguages = new String[compressedIsoLanguages.length() / 6];
0439:                    for (int i = 0; i < isoLanguages.length; i++)
0440:                        isoLanguages[i] = compressedIsoLanguages.substring(
0441:                                (i * 6) + 1, (i * 6) + 3);
0442:                }
0443:                String[] result = new String[isoLanguages.length];
0444:                System.arraycopy(isoLanguages, 0, result, 0,
0445:                        isoLanguages.length);
0446:                return result;
0447:            }
0448:
0449:            /**
0450:             * Returns the language code for this locale, which will either be the empty string
0451:             * or a lowercase ISO 639 code.
0452:             * <p>NOTE:  ISO 639 is not a stable standard-- some languages' codes have changed.
0453:             * Locale's constructor recognizes both the new and the old codes for the languages
0454:             * whose codes have changed, but this function always returns the old code.  If you
0455:             * want to check for a specific language whose code has changed, don't do <pre>
0456:             * if (locale.getLanguage().equals("he")
0457:             *    ...
0458:             * </pre>Instead, do<pre>
0459:             * if (locale.getLanguage().equals(new Locale("he", "", "").getLanguage())
0460:             *    ...</pre>
0461:             * @see #getDisplayLanguage
0462:             */
0463:            public String getLanguage() {
0464:                return language;
0465:            }
0466:
0467:            /**
0468:             * Returns the country/region code for this locale, which will either be the empty string
0469:             * or an upercase ISO 3166 2-letter code.
0470:             * @see #getDisplayCountry
0471:             */
0472:            public String getCountry() {
0473:                return country;
0474:            }
0475:
0476:            /**
0477:             * Returns the variant code for this locale.
0478:             * @see #getDisplayVariant
0479:             */
0480:            public String getVariant() {
0481:                return variant;
0482:            }
0483:
0484:            /**
0485:             * Getter for the programmatic name of the entire locale,
0486:             * with the language, country and variant separated by underbars.
0487:             * Language is always lower case, and country is always upper case.
0488:             * If the language is missing, the string will begin with an underbar.
0489:             * If both the language and country fields are missing, this function
0490:             * will return the empty string, even if the variant field is filled in
0491:             * (you can't have a locale with just a variant-- the variant must accompany
0492:             * a valid language or country code).
0493:             * Examples: "en", "de_DE", "_GB", "en_US_WIN", "de__POSIX", "fr__MAC"
0494:             * @see #getDisplayName
0495:             */
0496:            public final String toString() {
0497:                boolean l = language.length() != 0;
0498:                boolean c = country.length() != 0;
0499:                boolean v = variant.length() != 0;
0500:                StringBuffer result = new StringBuffer(language);
0501:                if (c || (l && v)) {
0502:                    result.append('_').append(country); // This may just append '_'
0503:                }
0504:                if (v && (l || c)) {
0505:                    result.append('_').append(variant);
0506:                }
0507:                return result.toString();
0508:            }
0509:
0510:            /**
0511:             * Returns a three-letter abbreviation for this locale's language.  If the locale
0512:             * doesn't specify a language, this will be the empty string.  Otherwise, this will
0513:             * be a lowercase ISO 639-2/T language code.
0514:             * The ISO 639-2 language codes can be found on-line at
0515:             *   <a href="ftp://dkuug.dk/i18n/iso-639-2.txt"><code>ftp://dkuug.dk/i18n/iso-639-2.txt</code></a>
0516:             * @exception MissingResourceException Throws MissingResourceException if the
0517:             * three-letter language abbreviation is not available for this locale.
0518:             */
0519:            public String getISO3Language() throws MissingResourceException {
0520:                int length = language.length();
0521:
0522:                if (length == 0) {
0523:                    return "";
0524:                }
0525:
0526:                int index = compressedIsoLanguages.indexOf("," + language);
0527:                if (index == -1 || length != 2) {
0528:                    throw new MissingResourceException(
0529:                            "Couldn't find 3-letter language code for "
0530:                                    + language, "LocaleElements_" + toString(),
0531:                            "ShortLanguage");
0532:                }
0533:                return compressedIsoLanguages.substring(index + 3, index + 6);
0534:            }
0535:
0536:            /**
0537:             * Returns a three-letter abbreviation for this locale's country.  If the locale
0538:             * doesn't specify a country, this will be tbe the empty string.  Otherwise, this will
0539:             * be an uppercase ISO 3166 3-letter country code.
0540:             * @exception MissingResourceException Throws MissingResourceException if the
0541:             * three-letter country abbreviation is not available for this locale.
0542:             */
0543:            public String getISO3Country() throws MissingResourceException {
0544:                int length = country.length();
0545:
0546:                if (length == 0) {
0547:                    return "";
0548:                }
0549:
0550:                int index = compressedIsoCountries.indexOf("," + country);
0551:                if (index == -1 || length != 2) {
0552:                    throw new MissingResourceException(
0553:                            "Couldn't find 3-letter country code for "
0554:                                    + country, "LocaleElements_" + toString(),
0555:                            "ShortCountry");
0556:                }
0557:                return compressedIsoCountries.substring(index + 3, index + 6);
0558:            }
0559:
0560:            /**
0561:             * Returns a name for the locale's language that is appropriate for display to the
0562:             * user.
0563:             * If possible, the name returned will be localized for the default locale.
0564:             * For example, if the locale is fr_FR and the default locale
0565:             * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
0566:             * the default locale is fr_FR, getDisplayLanguage() will return "anglais".
0567:             * If the name returned cannot be localized for the default locale,
0568:             * (say, we don't have a Japanese name for Croatian),
0569:             * this function falls back on the English name, and uses the ISO code as a last-resort
0570:             * value.  If the locale doesn't specify a language, this function returns the empty string.
0571:             */
0572:            public final String getDisplayLanguage() {
0573:                return getDisplayLanguage(getDefault());
0574:            }
0575:
0576:            /**
0577:             * Returns a name for the locale's language that is appropriate for display to the
0578:             * user.
0579:             * If possible, the name returned will be localized according to inLocale.
0580:             * For example, if the locale is fr_FR and inLocale
0581:             * is en_US, getDisplayLanguage() will return "French"; if the locale is en_US and
0582:             * inLocale is fr_FR, getDisplayLanguage() will return "anglais".
0583:             * If the name returned cannot be localized according to inLocale,
0584:             * (say, we don't have a Japanese name for Croatian),
0585:             * this function falls back on the default locale, on the English name, and finally
0586:             * on the ISO code as a last-resort value.  If the locale doesn't specify a language,
0587:             * this function returns the empty string.
0588:             */
0589:            public String getDisplayLanguage(Locale inLocale) {
0590:                String langCode = language;
0591:                if (langCode.length() == 0)
0592:                    return "";
0593:
0594:                Locale workingLocale = (Locale) inLocale.clone();
0595:                String result = null;
0596:                int phase = 0;
0597:                boolean done = false;
0598:
0599:                if (workingLocale.variant.length() == 0)
0600:                    phase = 1;
0601:                if (workingLocale.country.length() == 0)
0602:                    phase = 2;
0603:
0604:                while (!done) {
0605:                    try {
0606:                        ResourceBundle bundle = LocaleData
0607:                                .getLocaleElements(workingLocale);
0608:                        result = findStringMatch((String[][]) bundle
0609:                                .getObject("Languages"), langCode, langCode);
0610:                        if (result.length() != 0)
0611:                            done = true;
0612:                    } catch (Exception e) {
0613:                        // just fall through
0614:                    }
0615:
0616:                    if (!done) {
0617:                        switch (phase) {
0618:                        case 0:
0619:                            workingLocale.variant = "";
0620:                            break;
0621:
0622:                        case 1:
0623:                            workingLocale.country = "";
0624:                            break;
0625:
0626:                        case 2:
0627:                            workingLocale = getDefault();
0628:                            break;
0629:
0630:                        case 3:
0631:                            workingLocale = new Locale("", "", "");
0632:                            break;
0633:
0634:                        default:
0635:                            return langCode;
0636:                        }
0637:                        phase++;
0638:                    }
0639:                }
0640:                return result;
0641:            }
0642:
0643:            /**
0644:             * Returns a name for the locale's country that is appropriate for display to the
0645:             * user.
0646:             * If possible, the name returned will be localized for the default locale.
0647:             * For example, if the locale is fr_FR and the default locale
0648:             * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
0649:             * the default locale is fr_FR, getDisplayLanguage() will return "Etats-Unis".
0650:             * If the name returned cannot be localized for the default locale,
0651:             * (say, we don't have a Japanese name for Croatia),
0652:             * this function falls back on the English name, and uses the ISO code as a last-resort
0653:             * value.  If the locale doesn't specify a country, this function returns the empty string.
0654:             */
0655:            public final String getDisplayCountry() {
0656:                return getDisplayCountry(getDefault());
0657:            }
0658:
0659:            /**
0660:             * Returns a name for the locale's country that is appropriate for display to the
0661:             * user.
0662:             * If possible, the name returned will be localized according to inLocale.
0663:             * For example, if the locale is fr_FR and inLocale
0664:             * is en_US, getDisplayCountry() will return "France"; if the locale is en_US and
0665:             * inLocale is fr_FR, getDisplayLanguage() will return "Etats-Unis".
0666:             * If the name returned cannot be localized according to inLocale.
0667:             * (say, we don't have a Japanese name for Croatia),
0668:             * this function falls back on the default locale, on the English name, and finally
0669:             * on the ISO code as a last-resort value.  If the locale doesn't specify a country,
0670:             * this function returns the empty string.
0671:             */
0672:            public String getDisplayCountry(Locale inLocale) {
0673:                String ctryCode = country;
0674:                if (ctryCode.length() == 0)
0675:                    return "";
0676:
0677:                Locale workingLocale = (Locale) inLocale.clone();
0678:                String result = null;
0679:                int phase = 0;
0680:                boolean done = false;
0681:
0682:                if (workingLocale.variant.length() == 0)
0683:                    phase = 1;
0684:                if (workingLocale.country.length() == 0)
0685:                    phase = 2;
0686:
0687:                while (!done) {
0688:                    try {
0689:                        ResourceBundle bundle = LocaleData
0690:                                .getLocaleElements(workingLocale);
0691:                        result = findStringMatch((String[][]) bundle
0692:                                .getObject("Countries"), ctryCode, ctryCode);
0693:                        if (result.length() != 0)
0694:                            done = true;
0695:                    } catch (Exception e) {
0696:                        // just fall through
0697:                    }
0698:
0699:                    if (!done) {
0700:                        switch (phase) {
0701:                        case 0:
0702:                            workingLocale.variant = "";
0703:                            break;
0704:
0705:                        case 1:
0706:                            workingLocale.country = "";
0707:                            break;
0708:
0709:                        case 2:
0710:                            workingLocale = getDefault();
0711:                            break;
0712:
0713:                        case 3:
0714:                            workingLocale = new Locale("", "", "");
0715:                            break;
0716:
0717:                        default:
0718:                            return ctryCode;
0719:                        }
0720:                        phase++;
0721:                    }
0722:                }
0723:                return result;
0724:            }
0725:
0726:            /**
0727:             * Returns a name for the locale's variant code that is appropriate for display to the
0728:             * user.  If possible, the name will be localized for the default locale.  If the locale
0729:             * doesn't specify a variant code, this function returns the empty string.
0730:             */
0731:            public final String getDisplayVariant() {
0732:                return getDisplayVariant(getDefault());
0733:            }
0734:
0735:            /**
0736:             * Returns a name for the locale's variant code that is appropriate for display to the
0737:             * user.  If possible, the name will be localized for inLocale.  If the locale
0738:             * doesn't specify a variant code, this function returns the empty string.
0739:             */
0740:            public String getDisplayVariant(Locale inLocale) {
0741:                if (variant.length() == 0)
0742:                    return "";
0743:
0744:                ResourceBundle bundle = LocaleData.getLocaleElements(inLocale);
0745:
0746:                String names[] = getDisplayVariantArray(bundle);
0747:
0748:                // Get the localized patterns for formatting a list, and use
0749:                // them to format the list.
0750:                String[] patterns;
0751:                try {
0752:                    patterns = (String[]) bundle
0753:                            .getObject("LocaleNamePatterns");
0754:                } catch (MissingResourceException e) {
0755:                    patterns = null;
0756:                }
0757:                return formatList(patterns, names);
0758:            }
0759:
0760:            /**
0761:             * Returns a name for the locale that is appropriate for display to the
0762:             * user.  This will be the values returned by getDisplayLanguage(), getDisplayCountry(),
0763:             * and getDisplayVariant() assembled into a single string.  The display name will have
0764:             * one of the following forms:<p><blockquote>
0765:             * language (country, variant)<p>
0766:             * language (country)<p>
0767:             * language (variant)<p>
0768:             * country (variant)<p>
0769:             * language<p>
0770:             * country<p>
0771:             * variant<p></blockquote>
0772:             * depending on which fields are specified in the locale.  If the language, country,
0773:             * and variant fields are all empty, this function returns the empty string.
0774:             */
0775:            public final String getDisplayName() {
0776:                return getDisplayName(getDefault());
0777:            }
0778:
0779:            /**
0780:             * Returns a name for the locale that is appropriate for display to the
0781:             * user.  This will be the values returned by getDisplayLanguage(), getDisplayCountry(),
0782:             * and getDisplayVariant() assembled into a single string.  The display name will have
0783:             * one of the following forms:<p><blockquote>
0784:             * language (country, variant)<p>
0785:             * language (country)<p>
0786:             * language (variant)<p>
0787:             * country (variant)<p>
0788:             * language<p>
0789:             * country<p>
0790:             * variant<p></blockquote>
0791:             * depending on which fields are specified in the locale.  If the language, country,
0792:             * and variant fields are all empty, this function returns the empty string.
0793:             */
0794:            public String getDisplayName(Locale inLocale) {
0795:                ResourceBundle bundle = LocaleData.getLocaleElements(inLocale);
0796:
0797:                String languageName = getDisplayLanguage(inLocale);
0798:                String countryName = getDisplayCountry(inLocale);
0799:                String[] variantNames = getDisplayVariantArray(bundle);
0800:
0801:                // Get the localized patterns for formatting a display name.
0802:                String[] patterns;
0803:                try {
0804:                    patterns = (String[]) bundle
0805:                            .getObject("LocaleNamePatterns");
0806:                } catch (MissingResourceException e) {
0807:                    patterns = null;
0808:                }
0809:
0810:                // The display name consists of a main name, followed by qualifiers.
0811:                // Typically, the format is "MainName (Qualifier, Qualifier)" but this
0812:                // depends on what pattern is stored in the display locale.
0813:                String mainName = null;
0814:                String[] qualifierNames = null;
0815:
0816:                // The main name is the language, or if there is no language, the country.
0817:                // If there is neither language nor country (an anomalous situation) then
0818:                // the display name is simply the variant's display name.
0819:                if (languageName.length() != 0) {
0820:                    mainName = languageName;
0821:                    if (countryName.length() != 0) {
0822:                        qualifierNames = new String[variantNames.length + 1];
0823:                        System.arraycopy(variantNames, 0, qualifierNames, 1,
0824:                                variantNames.length);
0825:                        qualifierNames[0] = countryName;
0826:                    } else
0827:                        qualifierNames = variantNames;
0828:                } else if (countryName.length() != 0) {
0829:                    mainName = countryName;
0830:                    qualifierNames = variantNames;
0831:                } else {
0832:                    return formatList(patterns, variantNames);
0833:                }
0834:
0835:                // Create an array whose first element is the number of remaining
0836:                // elements.  This serves as a selector into a ChoiceFormat pattern from
0837:                // the resource.  The second and third elements are the main name and
0838:                // the qualifier; if there are no qualifiers, the third element is
0839:                // unused by the format pattern.
0840:                Object[] displayNames = {
0841:                        new Integer(qualifierNames.length != 0 ? 2 : 1),
0842:                        mainName,
0843:                        // We could also just call formatList() and have it handle the empty
0844:                        // list case, but this is more efficient, and we want it to be
0845:                        // efficient since all the language-only locales will not have any
0846:                        // qualifiers.
0847:                        qualifierNames.length != 0 ? formatList(patterns,
0848:                                qualifierNames) : null };
0849:
0850:                if (patterns != null) {
0851:                    return new MessageFormat(patterns[0]).format(displayNames);
0852:                } else {
0853:                    // If we cannot get the message format pattern, then we use a simple
0854:                    // hard-coded pattern.  This should not occur in practice unless the
0855:                    // installation is missing some core files (LocaleElements etc.).
0856:                    StringBuffer result = new StringBuffer();
0857:                    result.append((String) displayNames[1]);
0858:                    if (displayNames.length > 2) {
0859:                        result.append(" (");
0860:                        result.append((String) displayNames[2]);
0861:                        result.append(")");
0862:                    }
0863:                    return result.toString();
0864:                }
0865:            }
0866:
0867:            /**
0868:             * Overrides Cloneable
0869:             */
0870:            public Object clone() {
0871:                try {
0872:                    Locale that = (Locale) super .clone();
0873:                    return that;
0874:                } catch (CloneNotSupportedException e) {
0875:                    throw new InternalError();
0876:                }
0877:            }
0878:
0879:            /**
0880:             * Override hashCode.
0881:             * Since Locales are often used in hashtables, caches the value
0882:             * for speed.
0883:             */
0884:            // Depending on performance of synchronized, may want to
0885:            // just compute in constructor.
0886:            public synchronized int hashCode() {
0887:                if (hashcode == -1) {
0888:                    hashcode = language.hashCode() ^ country.hashCode()
0889:                            ^ variant.hashCode();
0890:                }
0891:                return hashcode;
0892:            }
0893:
0894:            // Overrides
0895:
0896:            /**
0897:             * Returns true if this Locale is equal to another object.  A Locale is
0898:             * deemed equal to another Locale with identical language, country,
0899:             * and variant, and unequal to all other objects.
0900:             *
0901:             * @return true if this Locale is equal to the specified object.
0902:             */
0903:
0904:            public boolean equals(Object obj) {
0905:                if (this  == obj) // quick check
0906:                    return true;
0907:                if (!(obj instanceof  Locale)) // (1) same object?
0908:                    return false;
0909:                Locale other = (Locale) obj;
0910:                if (hashCode() != other.hashCode())
0911:                    return false; // quick check
0912:                if (language != other.language)
0913:                    return false;
0914:                if (country != other.country)
0915:                    return false;
0916:                if (variant != other.variant)
0917:                    return false;
0918:                return true; // we made it through the guantlet.
0919:                // (1)  We don't check super.equals since it is Object.
0920:                //      Since Locale is final, we don't have to check both directions.
0921:            }
0922:
0923:            // ================= privates =====================================
0924:
0925:            // instance and class variables. For now keep these separate, since it is
0926:            // faster to match. Later, make into single string.
0927:
0928:            /**
0929:             * @serial
0930:             * @see #getLanguage
0931:             */
0932:            private String language = "";
0933:
0934:            /**
0935:             * @serial
0936:             * @see #getCountry
0937:             */
0938:            private String country = "";
0939:
0940:            /**
0941:             * @serial
0942:             * @see #getVariant
0943:             */
0944:            private String variant = "";
0945:
0946:            /**
0947:             * Placeholder for the object's hash code.  Always -1.
0948:             * @serial
0949:             */
0950:            private int hashcode = -1;
0951:
0952:            private static Locale defaultLocale = null;
0953:
0954:            /**
0955:             * Return an array of the display names of the variant.
0956:             * @param bundle the ResourceBundle to use to get the display names
0957:             * @return an array of display names, possible of zero length.
0958:             */
0959:            private String[] getDisplayVariantArray(ResourceBundle bundle) {
0960:                // Split the variant name into tokens separated by '_'.
0961:                StringTokenizer tokenizer = new StringTokenizer(variant, "_");
0962:                String[] names = new String[tokenizer.countTokens()];
0963:
0964:                // For each variant token, lookup the display name.  If
0965:                // not found, use the variant name itself.
0966:                for (int i = 0; i < names.length; ++i) {
0967:                    String token = tokenizer.nextToken();
0968:                    try {
0969:                        names[i] = (String) bundle.getObject("%%" + token);
0970:                    } catch (MissingResourceException e) {
0971:                        names[i] = token;
0972:                    }
0973:                }
0974:
0975:                return names;
0976:            }
0977:
0978:            /**
0979:             * Format a list with an array of patterns.
0980:             * @param patterns an array of three patterns. The first pattern is not
0981:             * used. The second pattern should create a MessageFormat taking 0-3 arguments
0982:             * and formatting them into a list. The third pattern should take 2 arguments
0983:             * and is used by composeList. If patterns is null, then a the list is
0984:             * formatted by concatenation with the delimiter ','.
0985:             * @param stringList the list of strings to be formatted.
0986:             * @return a string representing the list.
0987:             */
0988:            private static String formatList(String[] patterns,
0989:                    String[] stringList) {
0990:                // If we have no list patterns, compose the list in a simple,
0991:                // non-localized way.
0992:                if (patterns == null) {
0993:                    StringBuffer result = new StringBuffer();
0994:                    for (int i = 0; i < stringList.length; ++i) {
0995:                        if (i > 0)
0996:                            result.append(',');
0997:                        result.append(stringList[i]);
0998:                    }
0999:                    return result.toString();
1000:                }
1001:
1002:                // Compose the list down to three elements if necessary
1003:                if (stringList.length > 3) {
1004:                    MessageFormat format = new MessageFormat(patterns[2]);
1005:                    stringList = composeList(format, stringList);
1006:                }
1007:
1008:                // Rebuild the argument list with the list length as the first element
1009:                Object[] args = new Object[stringList.length + 1];
1010:                System.arraycopy(stringList, 0, args, 1, stringList.length);
1011:                args[0] = new Integer(stringList.length);
1012:
1013:                // Format it using the pattern in the resource
1014:                MessageFormat format = new MessageFormat(patterns[1]);
1015:                return format.format(args);
1016:            }
1017:
1018:            /**
1019:             * Given a list of strings, return a list shortened to three elements.
1020:             * Shorten it by applying the given format to the first two elements
1021:             * recursively.
1022:             * @param format a format which takes two arguments
1023:             * @param list a list of strings
1024:             * @return if the list is three elements or shorter, the same list;
1025:             * otherwise, a new list of three elements.
1026:             */
1027:            private static String[] composeList(MessageFormat format,
1028:                    String[] list) {
1029:                if (list.length <= 3)
1030:                    return list;
1031:
1032:                // Use the given format to compose the first two elements into one
1033:                String[] listItems = { list[0], list[1] };
1034:                String newItem = format.format(listItems);
1035:
1036:                // Form a new list one element shorter
1037:                String[] newList = new String[list.length - 1];
1038:                System.arraycopy(list, 2, newList, 1, newList.length - 1);
1039:                newList[0] = newItem;
1040:
1041:                // Recurse
1042:                return composeList(format, newList);
1043:            }
1044:
1045:            /**
1046:             * @serialData The first three fields are three <code>String</code> objects:
1047:             * the first is a 2-letter ISO 639 code representing the locale's language,
1048:             * the second is a 2-letter ISO 3166 code representing the locale's region or
1049:             * country, and the third is an optional chain of variant codes defined by this
1050:             * library.  Any of the fields may be the empty string.  The fourth field is an
1051:             * <code>int</code> whose value is always -1.  This is a sentinel value indicating
1052:             * the <code>Locale</code>'s hash code must be recomputed.
1053:             */
1054:            private void writeObject(ObjectOutputStream out) throws IOException {
1055:                // hashcode is semantically transient.  We couldn't define it as transient
1056:                // because versions of this class that DIDN'T declare it as transient have
1057:                // already shipped.  What we're doing here is making sure that the written-out
1058:                // version of hashcode is always -1, regardless of what's really stored there
1059:                // (we hold onto the original value just in case someone might want it again).
1060:                // Writing -1 ensures that version 1.1 Locales will always recalculate their
1061:                // hash codes after being streamed back in.  This is necessary because
1062:                // String.hashCode() calculates its hash code differently in 1.2 than it did
1063:                // in 1.1.
1064:                int temp = hashcode;
1065:                hashcode = -1;
1066:                out.defaultWriteObject();
1067:                hashcode = temp;
1068:            }
1069:
1070:            /**
1071:             * @serialData The first three fields are three <code>String</code> objects:
1072:             * the first is a 2-letter ISO 639 code representing the locale's language,
1073:             * the second is a 2-letter ISO 3166 code representing the locale's region or
1074:             * country, and the third is an optional chain of variant codes defined by this
1075:             * library.  Any of the fields may be the empty string.  The fourth field is an
1076:             * <code>int</code>representing the locale's hash code, but is ignored by
1077:             * <code>readObject()</code>.  Whatever this field's value, the hash code is
1078:             * initialized to -1, a sentinel value that indicates the hash code must be
1079:             * recomputed.
1080:             */
1081:            private void readObject(ObjectInputStream in) throws IOException,
1082:                    ClassNotFoundException {
1083:                // hashcode is semantically transient.  We couldn't define it as transient
1084:                // because versions of this class that DIDN'T declare is as transient have
1085:                // already shipped.  This code makes sure that whatever value for hashcode
1086:                // was written on the stream, we ignore it and recalculate it on demand.  This
1087:                // is necessary because String.hashCode() calculates is hash code differently
1088:                // in version 1.2 than it did in 1.1.
1089:                in.defaultReadObject();
1090:                hashcode = -1;
1091:                language = convertOldISOCodes(language);
1092:                country = country.intern();
1093:                variant = variant.intern();
1094:            }
1095:
1096:            /**
1097:             * List of all 2-letter language codes currently defined in ISO 639.
1098:             * (Because the Java VM specification turns an array constant into executable code
1099:             * that generates the array element by element, we keep the array in compressed
1100:             * form in a single string and build the array from it at run time when requested.)
1101:             * [We're now also using this table to store a mapping from 2-letter ISO language codes
1102:             * to 3-letter ISO language codes.  Each group of characters consists of a comma, a
1103:             * 2-letter code, and a 3-letter code.  We look up a 3-letter code by searching for
1104:             * a comma followed by a 2-letter code and then getting the three letters following
1105:             * the 2-letter code.]
1106:             */
1107:            private static String[] isoLanguages = null;
1108:            private static final String compressedIsoLanguages = ",aaaar,ababk,afafr,amamh,arara,asasm,ayaym,azaze,babak,bebel,bgbul,bhbih,bibis,bnben,"
1109:                    + "bobod,brbre,cacat,cocos,csces,cycym,dadan,dedeu,dzdzo,elell,eneng,eoepo,esspa,"
1110:                    + "etest,eueus,fafas,fifin,fjfij,fofao,frfra,fyfry,gagai,gdgdh,glglg,gngrn,guguj,"
1111:                    + "hahau,heheb,hihin,hrhrv,huhun,hyhye,iaina,idind,ieile,ikipk,inind,isisl,itita,"
1112:                    + "iuiku,iwheb,jajpn,jiyid,jwjaw,kakat,kkkaz,klkal,kmkhm,knkan,kokor,kskas,kukur,"
1113:                    + "kykir,lalat,lnlin,lolao,ltlit,lvlav,mgmlg,mimri,mkmkd,mlmal,mnmon,momol,mrmar,"
1114:                    + "msmsa,mtmlt,mymya,nanau,nenep,nlnld,nonor,ococi,omorm,orori,papan,plpol,pspus,"
1115:                    + "ptpor,quque,rmroh,rnrun,roron,rurus,rwkin,sasan,sdsnd,sgsag,shsrp,sisin,skslk,"
1116:                    + "slslv,smsmo,snsna,sosom,sqsqi,srsrp,ssssw,stsot,susun,svswe,swswa,tatam,tetel,"
1117:                    + "tgtgk,ththa,titir,tktuk,tltgl,tntsn,toton,trtur,tstso,tttat,twtwi,uguig,ukukr,"
1118:                    + "ururd,uzuzb,vivie,vovol,wowol,xhxho,yiyid,yoyor,zazha,zhzho,zuzul";
1119:
1120:            /**
1121:             * List of all 2-letter country codes currently defined in ISO 3166.
1122:             * (Because the Java VM specification turns an array constant into executable code
1123:             * that generates the array element by element, we keep the array in compressed
1124:             * form in a single string and build the array from it at run time when requested.)
1125:             * [We're now also using this table to store a mapping from 2-letter ISO country codes
1126:             * to 3-letter ISO country codes.  Each group of characters consists of a comma, a
1127:             * 2-letter code, and a 3-letter code.  We look up a 3-letter code by searching for
1128:             * a comma followed by a 2-letter code and then getting the three letters following
1129:             * the 2-letter code.]
1130:             */
1131:            private static String[] isoCountries = null;
1132:            private static final String compressedIsoCountries = ",ADAND,AEARE,AFAFG,AGATG,AIAIA,ALALB,AMARM,ANANT,AOAGO,AQATA,ARARG,ASASM,ATAUT,"
1133:                    + "AUAUS,AWABW,AZAZE,BABIH,BBBRB,BDBGD,BEBEL,BFBFA,BGBGR,BHBHR,BIBDI,BJBEN,BMBMU,"
1134:                    + "BNBRN,BOBOL,BRBRA,BSBHS,BTBTN,BVBVT,BWBWA,BYBLR,BZBLZ,CACAN,CCCCK,CFCAF,CGCOG,"
1135:                    + "CHCHE,CICIV,CKCOK,CLCHL,CMCMR,CNCHN,COCOL,CRCRI,CUCUB,CVCPV,CXCXR,CYCYP,CZCZE,"
1136:                    + "DEDEU,DJDJI,DKDNK,DMDMA,DODOM,DZDZA,ECECU,EEEST,EGEGY,EHESH,ERERI,ESESP,ETETH,"
1137:                    + "FIFIN,FJFJI,FKFLK,FMFSM,FOFRO,FRFRA,FXFXX,GAGAB,GBGBR,GDGRD,GEGEO,GFGUF,GHGHA,"
1138:                    + "GIGIB,GLGRL,GMGMB,GNGIN,GPGLP,GQGNQ,GRGRC,GSSGS,GTGTM,GUGUM,GWGNB,GYGUY,HKHKG,"
1139:                    + "HMHMD,HNHND,HRHRV,HTHTI,HUHUN,IDIDN,IEIRL,ILISR,ININD,IOIOT,IQIRQ,IRIRN,ISISL,"
1140:                    + "ITITA,JMJAM,JOJOR,JPJPN,KEKEN,KGKGZ,KHKHM,KIKIR,KMCOM,KNKNA,KPPRK,KRKOR,KWKWT,"
1141:                    + "KYCYM,KZKAZ,LALAO,LBLBN,LCLCA,LILIE,LKLKA,LRLBR,LSLSO,LTLTU,LULUX,LVLVA,LYLBY,"
1142:                    + "MAMAR,MCMCO,MDMDA,MGMDG,MHMHL,MKMKD,MLMLI,MMMMR,MNMNG,MOMAC,MPMNP,MQMTQ,MRMRT,"
1143:                    + "MSMSR,MTMLT,MUMUS,MVMDV,MWMWI,MXMEX,MYMYS,MZMOZ,NANAM,NCNCL,NENER,NFNFK,NGNGA,"
1144:                    + "NINIC,NLNLD,NONOR,NPNPL,NRNRU,NUNIU,NZNZL,OMOMN,PAPAN,PEPER,PFPYF,PGPNG,PHPHL,"
1145:                    + "PKPAK,PLPOL,PMSPM,PNPCN,PRPRI,PTPRT,PWPLW,PYPRY,QAQAT,REREU,ROROM,RURUS,RWRWA,"
1146:                    + "SASAU,SBSLB,SCSYC,SDSDN,SESWE,SGSGP,SHSHN,SISVN,SJSJM,SKSVK,SLSLE,SMSMR,SNSEN,"
1147:                    + "SOSOM,SRSUR,STSTP,SVSLV,SYSYR,SZSWZ,TCTCA,TDTCD,TFATF,TGTGO,THTHA,TJTJK,TKTKL,"
1148:                    + "TMTKM,TNTUN,TOTON,TPTMP,TRTUR,TTTTO,TVTUV,TWTWN,TZTZA,UAUKR,UGUGA,UMUMI,USUSA,"
1149:                    + "UYURY,UZUZB,VAVAT,VCVCT,VEVEN,VGVGB,VIVIR,VNVNM,VUVUT,WFWLF,WSWSM,YEYEM,YTMYT,"
1150:                    + "YUYUG,ZAZAF,ZMZMB,ZRZAR,ZWZWE";
1151:
1152:            /*
1153:             * Locale needs its own, locale insenitive version of toLowerCase to
1154:             * avoid circularity problems between Locale and String.
1155:             * The most straightforward algorithm is used. Look at optimizations later.
1156:             */
1157:            private String toLowerCase(String str) {
1158:                char[] buf = str.toCharArray();
1159:                for (int i = 0; i < buf.length; i++) {
1160:                    buf[i] = Character.toLowerCase(buf[i]);
1161:                }
1162:                return new String(buf);
1163:            }
1164:
1165:            /*
1166:             * Locale needs its own, locale insensitive version of toUpperCase to
1167:             * avoid circularity problems between Locale and String.
1168:             * The most straightforward algorithm is used. Look at optimizations later.
1169:             */
1170:            private String toUpperCase(String str) {
1171:                char[] buf = str.toCharArray();
1172:                for (int i = 0; i < buf.length; i++) {
1173:                    buf[i] = Character.toUpperCase(buf[i]);
1174:                }
1175:                return new String(buf);
1176:            }
1177:
1178:            private String findStringMatch(String[][] languages,
1179:                    String desiredLanguage, String fallbackLanguage) {
1180:                for (int i = 0; i < languages.length; ++i)
1181:                    if (desiredLanguage.equals(languages[i][0]))
1182:                        return languages[i][1];
1183:                if (!fallbackLanguage.equals(desiredLanguage))
1184:                    for (int i = 0; i < languages.length; ++i)
1185:                        if (fallbackLanguage.equals(languages[i][0]))
1186:                            return languages[i][1];
1187:                if (!"EN".equals(desiredLanguage)
1188:                        && "EN".equals(fallbackLanguage))
1189:                    for (int i = 0; i < languages.length; ++i)
1190:                        if ("EN".equals(languages[i][0]))
1191:                            return languages[i][1];
1192:                return "";
1193:            }
1194:
1195:            private String convertOldISOCodes(String language) {
1196:                // we accept both the old and the new ISO codes for the languages whose ISO
1197:                // codes have changed, but we always store the OLD code, for backward compatibility
1198:                language = toLowerCase(language).intern();
1199:                if (language == "he") {
1200:                    return "iw";
1201:                } else if (language == "yi") {
1202:                    return "ji";
1203:                } else if (language == "id") {
1204:                    return "in";
1205:                } else {
1206:                    return language;
1207:                }
1208:            }
1209:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.