001: /*
002: ******************************************************************************
003: * Copyright (C) 1996-2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: ******************************************************************************
006: *
007: ******************************************************************************
008: */
009:
010: package com.ibm.icu.impl;
011:
012: import java.util.Locale;
013:
014: /**
015: * A class to hold utility functions missing from java.util.Locale.
016: */
017: public class LocaleUtility {
018:
019: /**
020: * A helper function to convert a string of the form
021: * aa_BB_CC to a locale object. Why isn't this in Locale?
022: */
023: public static Locale getLocaleFromName(String name) {
024: String language = "";
025: String country = "";
026: String variant = "";
027:
028: int i1 = name.indexOf('_');
029: if (i1 < 0) {
030: language = name;
031: } else {
032: language = name.substring(0, i1);
033: ++i1;
034: int i2 = name.indexOf('_', i1);
035: if (i2 < 0) {
036: country = name.substring(i1);
037: } else {
038: country = name.substring(i1, i2);
039: variant = name.substring(i2 + 1);
040: }
041: }
042:
043: return new Locale(language, country, variant);
044: }
045:
046: /**
047: * Compare two locale strings of the form aa_BB_CC, and
048: * return true if parent is a 'strict' fallback of child, that is,
049: * if child =~ "^parent(_.+)*" (roughly).
050: */
051: public static boolean isFallbackOf(String parent, String child) {
052: if (!child.startsWith(parent)) {
053: return false;
054: }
055: int i = parent.length();
056: return (i == child.length() || child.charAt(i) == '_');
057: }
058:
059: /**
060: * Compare two locales, and return true if the parent is a
061: * 'strict' fallback of the child (parent string is a fallback
062: * of child string).
063: */
064: public static boolean isFallbackOf(Locale parent, Locale child) {
065: return isFallbackOf(parent.toString(), child.toString());
066: }
067:
068: /**
069: * Convenience method that calls canonicalLocaleString(String) with
070: * locale.toString();
071: */
072: public static String canonicalLocaleString(Locale locale) {
073: return canonicalLocaleString(locale.toString());
074: }
075:
076: /**
077: * You'd think that Locale canonicalizes, since it munges the
078: * renamed languages, but it doesn't quite. It forces the region
079: * to be upper case but doesn't do anything about the language or
080: * variant. Our canonical form is 'lower_UPPER_UPPER'.
081: */
082: public static String canonicalLocaleString(String id) {
083: if (id != null) {
084: int x = id.indexOf("_");
085: if (x == -1) {
086: id = id.toLowerCase(Locale.ENGLISH);
087: } else {
088: StringBuffer buf = new StringBuffer();
089: buf.append(id.substring(0, x).toLowerCase(
090: Locale.ENGLISH));
091: buf.append(id.substring(x).toUpperCase(Locale.ENGLISH));
092:
093: int len = buf.length();
094: int n = len;
095: while (--n >= 0 && buf.charAt(n) == '_') {
096: }
097: if (++n != len) {
098: buf.delete(n, len);
099: }
100: id = buf.toString();
101: }
102: }
103: return id;
104: }
105:
106: /**
107: * Fallback from the given locale name by removing the rightmost _-delimited
108: * element. If there is none, return the root locale ("", "", ""). If this
109: * is the root locale, return null. NOTE: The string "root" is not
110: * recognized; do not use it.
111: *
112: * @return a new Locale that is a fallback from the given locale, or null.
113: */
114: public static Locale fallback(Locale loc) {
115:
116: // Split the locale into parts and remove the rightmost part
117: String[] parts = new String[] { loc.getLanguage(),
118: loc.getCountry(), loc.getVariant() };
119: int i;
120: for (i = 2; i >= 0; --i) {
121: if (parts[i].length() != 0) {
122: parts[i] = "";
123: break;
124: }
125: }
126: if (i < 0) {
127: return null; // All parts were empty
128: }
129: return new Locale(parts[0], parts[1], parts[2]);
130: }
131: }
|