ICU-6673 Changed ULocale.ROOT definition from 'root' to empty. Also fixed ULocale#getFallback issues.

X-SVN-Rev: 26998
This commit is contained in:
Yoshito Umaoka 2009-12-01 05:12:27 +00:00
parent d5ce146cc8
commit c77ddd796e
7 changed files with 101 additions and 42 deletions

View file

@ -180,9 +180,6 @@ public class ICULocaleService extends ICUService {
if (primaryID == null) {
return null;
}
if (primaryID.length() == 0) {
primaryID = "root";
}
String canonicalPrimaryID = ULocale.getName(primaryID);
return new LocaleKey(primaryID, canonicalPrimaryID, canonicalFallbackID, kind);
}
@ -206,21 +203,26 @@ public class ICULocaleService extends ICUService {
*/
protected LocaleKey(String primaryID, String canonicalPrimaryID, String canonicalFallbackID, int kind) {
super(primaryID);
this.kind = kind;
if (canonicalPrimaryID == null) {
if (canonicalPrimaryID == null || canonicalPrimaryID.equalsIgnoreCase("root")) {
this.primaryID = "";
} else {
this.primaryID = canonicalPrimaryID;
this.varstart = this.primaryID.indexOf('@');
}
if (this.primaryID == "") {
this.fallbackID = null;
} else {
if (canonicalFallbackID == null || this.primaryID.equals(canonicalFallbackID)) {
this.fallbackID = "";
int idx = canonicalPrimaryID.indexOf('@');
if (idx == 4 && canonicalPrimaryID.regionMatches(true, 0, "root", 0, 4)) {
this.primaryID = canonicalPrimaryID.substring(4);
this.varstart = 0;
this.fallbackID = null;
} else {
this.fallbackID = canonicalFallbackID;
this.primaryID = canonicalPrimaryID;
this.varstart = idx;
if (canonicalFallbackID == null || this.primaryID.equals(canonicalFallbackID)) {
this.fallbackID = "";
} else {
this.fallbackID = canonicalFallbackID;
}
}
}
@ -299,8 +301,8 @@ public class ICULocaleService extends ICUService {
* otherwise return false.</p>
*
* <p>First falls back through the primary ID, then through
* the fallbackID. The final fallback is "root"
* unless the primary id was "root", in which case
* the fallbackID. The final fallback is "" (root)
* unless the primary id was "" (root), in which case
* there is no fallback.
*/
public boolean fallback() {
@ -312,11 +314,10 @@ public class ICULocaleService extends ICUService {
return true;
}
if (fallbackID != null) {
currentID = fallbackID;
if (fallbackID.length() == 0) {
currentID = "root";
fallbackID = null;
} else {
currentID = fallbackID;
fallbackID = "";
}
return true;
@ -548,7 +549,6 @@ public class ICULocaleService extends ICUService {
* Return the supported IDs. This is the set of all locale names for the bundleName.
*/
protected Set<String> getSupportedIDs() {
// note: "root" is one of the ids, but "" is not. Must convert ULocale.ROOT.
return ICUResourceBundle.getFullLocaleNameSet(bundleName, loader());
}

View file

@ -485,7 +485,12 @@ public class ICUResourceBundle extends UResourceBundle {
UResourceBundleIterator iter = bundle.getIterator();
iter.reset();
while (iter.hasNext()) {
locales[i++] = new ULocale(iter.next().getKey());
String locstr = iter.next().getKey();
if (locstr.equals("root")) {
locales[i++] = ULocale.ROOT;
} else {
locales[i++] = new ULocale(locstr);
}
}
bundle = null;
return locales;
@ -506,7 +511,12 @@ public class ICUResourceBundle extends UResourceBundle {
UResourceBundleIterator iter = bundle.getIterator();
iter.reset();
while (iter.hasNext()) {
locales[i++] = iter.next().getKey();
String locstr = iter.next(). getKey();
if (locstr.equals("root")) {
locales[i++] = ULocale.ROOT.toString();
} else {
locales[i++] = locstr;
}
}
bundle = null;
return locales;
@ -533,7 +543,11 @@ public class ICUResourceBundle extends UResourceBundle {
String line;
while ((line = br.readLine()) != null) {
if (line.length() != 0 && !line.startsWith("#")) {
lst.add(line);
if (line.equalsIgnoreCase("root")) {
lst.add(ULocale.ROOT.toString());
} else {
lst.add(line);
}
}
}
return lst;
@ -552,7 +566,12 @@ public class ICUResourceBundle extends UResourceBundle {
URLVisitor v = new URLVisitor() {
public void visit(String s) {
if (s.endsWith(".res") && !"res_index.res".equals(s)) {
lst.add(s.substring(0, s.length() - 4)); // strip '.res'
String locstr = s.substring(0, s.length() - 4);
if (locstr.equalsIgnoreCase("root")) {
lst.add(ULocale.ROOT.toString());
} else {
lst.add(locstr);
}
}
}
};

View file

@ -1287,7 +1287,6 @@ public final class UCaseProps {
/* case mapping properties API ---------------------------------------------- */
private static final ULocale rootLocale = new ULocale("");
private static final int[] rootLocCache = { LOC_ROOT };
/*
* We need a StringBuffer for multi-code point output from the
@ -1328,20 +1327,20 @@ public final class UCaseProps {
*/
case UProperty.CHANGES_WHEN_LOWERCASED:
dummyStringBuffer.setLength(0);
return toFullLower(c, null, dummyStringBuffer, rootLocale, rootLocCache)>=0;
return toFullLower(c, null, dummyStringBuffer, ULocale.ROOT, rootLocCache)>=0;
case UProperty.CHANGES_WHEN_UPPERCASED:
dummyStringBuffer.setLength(0);
return toFullUpper(c, null, dummyStringBuffer, rootLocale, rootLocCache)>=0;
return toFullUpper(c, null, dummyStringBuffer, ULocale.ROOT, rootLocCache)>=0;
case UProperty.CHANGES_WHEN_TITLECASED:
dummyStringBuffer.setLength(0);
return toFullTitle(c, null, dummyStringBuffer, rootLocale, rootLocCache)>=0;
return toFullTitle(c, null, dummyStringBuffer, ULocale.ROOT, rootLocCache)>=0;
/* case UProperty.CHANGES_WHEN_CASEFOLDED: -- in UCharacterProperty.java */
case UProperty.CHANGES_WHEN_CASEMAPPED:
dummyStringBuffer.setLength(0);
return
toFullLower(c, null, dummyStringBuffer, rootLocale, rootLocCache)>=0 ||
toFullUpper(c, null, dummyStringBuffer, rootLocale, rootLocCache)>=0 ||
toFullTitle(c, null, dummyStringBuffer, rootLocale, rootLocCache)>=0;
toFullLower(c, null, dummyStringBuffer, ULocale.ROOT, rootLocCache)>=0 ||
toFullUpper(c, null, dummyStringBuffer, ULocale.ROOT, rootLocCache)>=0 ||
toFullTitle(c, null, dummyStringBuffer, ULocale.ROOT, rootLocCache)>=0;
default:
return false;
}

View file

@ -84,9 +84,6 @@ class NumberFormatServiceShim extends NumberFormat.NumberFormatShim {
// }
ULocale[] actualLoc = new ULocale[1];
if (desiredLocale.equals(ULocale.ROOT)) {
desiredLocale = ULocale.ROOT;
}
NumberFormat fmt = (NumberFormat)service.get(desiredLocale, choice,
actualLoc);
if (fmt == null) {

View file

@ -241,7 +241,7 @@ public final class ULocale implements Serializable {
* The root ULocale.
* @stable ICU 2.8
*/
public static final ULocale ROOT = new ULocale("root", EMPTY_LOCALE);
public static final ULocale ROOT = new ULocale("", EMPTY_LOCALE);
private static final SimpleCache<Locale, ULocale> CACHE = new SimpleCache<Locale, ULocale>();
@ -761,15 +761,23 @@ public final class ULocale implements Serializable {
* Return the given (canonical) locale id minus the last part before the tags.
*/
private static String getFallbackString(String fallback) {
int limit = fallback.indexOf('@');
if (limit == -1) {
limit = fallback.length();
int extStart = fallback.indexOf('@');
if (extStart == -1) {
extStart = fallback.length();
}
int start = fallback.lastIndexOf('_', limit);
if (start == -1) {
start = 0;
int last = fallback.lastIndexOf('_', extStart);
if (last == -1) {
last = 0;
} else {
// truncate empty segment
while (last > 0) {
if (fallback.charAt(last - 1) != '_') {
break;
}
last--;
}
}
return fallback.substring(0, start) + fallback.substring(limit);
return fallback.substring(0, last) + fallback.substring(extStart);
}
/**

View file

@ -792,8 +792,8 @@ public class GlobalizationPreferencesTest extends TestFmwk {
gp.setLocale(new ULocale("zun"));
coll = gp.getCollator();
locStr = coll.getLocale(ULocale.VALID_LOCALE).toString();
if (!locStr.equals("root")) {
errln("FAIL: Collator locale is " + locStr + " Expected: root");
if (!locStr.equals("")) {
errln("FAIL: Collator locale is \"" + locStr + "\" Expected: \"\"(empty)");
}
// Set locales - en_JP, fr, en_US, fr_FR

View file

@ -3875,4 +3875,40 @@ public class ULocaleTest extends TestFmwk {
}
}
public void TestGetFallback() {
// Testing static String getFallback(String)
final String[][] TESTIDS =
{
{"en_US", "en", "", ""}, // ULocale.getFallback("") should return ""
{"EN_us_Var", "en_US", "en", ""}, // Case is always normalized
{"de_DE@collation=phonebook", "de@collation=phonebook", "@collation=phonebook", "@collation=phonebook"}, // Keyword is preserved
{"en__POSIX", "en", ""}, // Trailing empty segment should be truncated
{"_US_POSIX", "_US", ""}, // Same as above
{"root", ""}, // No canonicalization
};
for (String[] chain : TESTIDS) {
for (int i = 1; i < chain.length; i++) {
String fallback = ULocale.getFallback(chain[i-1]);
assertEquals("getFallback(\"" + chain[i-1] + "\")", chain[i], fallback);
}
}
// Testing ULocale getFallback()
final ULocale[][] TESTLOCALES =
{
{new ULocale("en_US"), new ULocale("en"), ULocale.ROOT, null},
{new ULocale("en__POSIX"), new ULocale("en"), ULocale.ROOT, null},
{new ULocale("de_DE@collation=phonebook"), new ULocale("de@collation=phonebook"), new ULocale("@collation=phonebook"), null},
{new ULocale("_US_POSIX"), new ULocale("_US"), ULocale.ROOT, null},
{new ULocale("root"), ULocale.ROOT, null},
};
for(ULocale[] chain : TESTLOCALES) {
for (int i = 1; i < chain.length; i++) {
ULocale fallback = chain[i-1].getFallback();
assertEquals("ULocale(" + chain[i-1] + ").getFallback()", chain[i], fallback);
}
}
}
}