1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ****************************************************************************** 5 * Copyright (C) 1996-2007, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ****************************************************************************** 8 * 9 ****************************************************************************** 10 */ 11 12 package com.ibm.icu.impl; 13 14 import java.util.Locale; 15 16 /** 17 * A class to hold utility functions missing from java.util.Locale. 18 */ 19 public class LocaleUtility { 20 21 /** 22 * A helper function to convert a string of the form 23 * aa_BB_CC to a locale object. Why isn't this in Locale? 24 */ getLocaleFromName(String name)25 public static Locale getLocaleFromName(String name) { 26 String language = ""; 27 String country = ""; 28 String variant = ""; 29 30 int i1 = name.indexOf('_'); 31 if (i1 < 0) { 32 language = name; 33 } else { 34 language = name.substring(0, i1); 35 ++i1; 36 int i2 = name.indexOf('_', i1); 37 if (i2 < 0) { 38 country = name.substring(i1); 39 } else { 40 country = name.substring(i1, i2); 41 variant = name.substring(i2+1); 42 } 43 } 44 45 return new Locale(language, country, variant); 46 } 47 48 /** 49 * Compare two locale strings of the form aa_BB_CC, and 50 * return true if parent is a 'strict' fallback of child, that is, 51 * if child =~ "^parent(_.+)*" (roughly). 52 */ isFallbackOf(String parent, String child)53 public static boolean isFallbackOf(String parent, String child) { 54 if (!child.startsWith(parent)) { 55 return false; 56 } 57 int i = parent.length(); 58 return (i == child.length() || 59 child.charAt(i) == '_'); 60 } 61 62 /** 63 * Compare two locales, and return true if the parent is a 64 * 'strict' fallback of the child (parent string is a fallback 65 * of child string). 66 */ isFallbackOf(Locale parent, Locale child)67 public static boolean isFallbackOf(Locale parent, Locale child) { 68 return isFallbackOf(parent.toString(), child.toString()); 69 } 70 71 72 /* 73 * Convenience method that calls canonicalLocaleString(String) with 74 * locale.toString(); 75 */ 76 /*public static String canonicalLocaleString(Locale locale) { 77 return canonicalLocaleString(locale.toString()); 78 }*/ 79 80 /* 81 * You'd think that Locale canonicalizes, since it munges the 82 * renamed languages, but it doesn't quite. It forces the region 83 * to be upper case but doesn't do anything about the language or 84 * variant. Our canonical form is 'lower_UPPER_UPPER'. 85 */ 86 /*public static String canonicalLocaleString(String id) { 87 if (id != null) { 88 int x = id.indexOf("_"); 89 if (x == -1) { 90 id = id.toLowerCase(Locale.ENGLISH); 91 } else { 92 StringBuffer buf = new StringBuffer(); 93 buf.append(id.substring(0, x).toLowerCase(Locale.ENGLISH)); 94 buf.append(id.substring(x).toUpperCase(Locale.ENGLISH)); 95 96 int len = buf.length(); 97 int n = len; 98 while (--n >= 0 && buf.charAt(n) == '_') { 99 } 100 if (++n != len) { 101 buf.delete(n, len); 102 } 103 id = buf.toString(); 104 } 105 } 106 return id; 107 }*/ 108 109 /** 110 * Fallback from the given locale name by removing the rightmost _-delimited 111 * element. If there is none, return the root locale ("", "", ""). If this 112 * is the root locale, return null. NOTE: The string "root" is not 113 * recognized; do not use it. 114 * 115 * @return a new Locale that is a fallback from the given locale, or null. 116 */ fallback(Locale loc)117 public static Locale fallback(Locale loc) { 118 119 // Split the locale into parts and remove the rightmost part 120 String[] parts = new String[] 121 { loc.getLanguage(), loc.getCountry(), loc.getVariant() }; 122 int i; 123 for (i=2; i>=0; --i) { 124 if (parts[i].length() != 0) { 125 parts[i] = ""; 126 break; 127 } 128 } 129 if (i<0) { 130 return null; // All parts were empty 131 } 132 return new Locale(parts[0], parts[1], parts[2]); 133 } 134 } 135