blob: 67261b48b8b54fc76de2f24b38bbc0d6047d8f8b [file] [log] [blame]
package org.unicode.cldr.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import com.ibm.icu.util.ICUUncheckedIOException;
/**
* List of locale IDs which are somehow 'special'. Parses SpecialLocales.txt
*
* @author srl
*
*/
public class SpecialLocales {
private static final String INCLUDE_SUBLOCALES = "*";
public enum Type {
/**
* Locale may not be modified by user.
*/
readonly,
/**
* Locale may be modified by user. Contents aren't part of CLDR release and may change.
*/
scratch
};
/**
* Get the type of this locale
*
* @param l
* @return a Type or null
*/
public static Type getType(CLDRLocale l) {
return getInstance().getTypeInternal(l);
}
/**
* Get all CLDRLocales matching this type. Does not include wildcard (*) sublocales.
*
* @param t
* @return a set, or null if none found
*/
public static Set<CLDRLocale> getByType(Type t) {
return getInstance().getByTypeInternal(t);
}
/**
* Get the comment on this locale. Strip out @ text.
*
* @param l
* @return string or null
*/
public static String getComment(CLDRLocale l) {
return getCommentRaw(l).replaceAll("@", "");
}
/**
* Get the comment on this locale. Include "@locale" markers.
*
* @param l
* @return string or null
*/
public static String getCommentRaw(CLDRLocale l) {
return getInstance().getCommentInternal(l).replaceAll("@@", "@" + l.getBaseName());
}
/**
* Singleton object
*/
private static SpecialLocales singleton = null;
/**
* Internal accessor. All access is via the static functions.
* @return
*/
private static synchronized SpecialLocales getInstance() {
if (singleton == null) {
singleton = new SpecialLocales();
}
return singleton;
}
private Map<CLDRLocale, Type> specials = new HashMap<CLDRLocale, Type>();
private Map<Type, Set<CLDRLocale>> types = new HashMap<Type, Set<CLDRLocale>>();
private Map<CLDRLocale, String> comments = new HashMap<CLDRLocale, String>();
private Set<CLDRLocale> specialsWildcards = new HashSet<CLDRLocale>();
public Set<CLDRLocale> getByTypeInternal(Type t) {
return types.get(t);
}
public Type getTypeInternal(CLDRLocale l) {
l = findLocale(l, l);
return specials.get(l);
}
public String getCommentInternal(CLDRLocale l) {
l = findLocale(l, l);
return comments.get(l);
}
public CLDRLocale findLocale(CLDRLocale fromLocale, CLDRLocale origLocale) {
if (origLocale == fromLocale && specials.containsKey(origLocale)) {
return origLocale; // explicit locale - no search.
}
if (fromLocale == null) {
return origLocale;
}
if (specialsWildcards.contains(fromLocale)) {
return fromLocale;
}
return findLocale(fromLocale.getParent(), origLocale);
}
/**
* Internal constructor
*/
private SpecialLocales() {
// from StandardCodes.java
String line;
int ln = 0;
try {
BufferedReader lstreg = CldrUtility.getUTF8Data("SpecialLocales.txt");
while (true) {
line = lstreg.readLine();
ln++;
if (line == null)
break;
int commentPos = line.indexOf('#');
if (commentPos >= 0) {
line = line.substring(0, commentPos);
}
line = line.trim();
if (line.length() == 0)
continue;
List<String> stuff = CldrUtility.splitList(line, ';', true);
String id = (String) stuff.get(0);
boolean includeSublocs = (id.endsWith(INCLUDE_SUBLOCALES));
if (includeSublocs) {
id = id.substring(0, id.length() - INCLUDE_SUBLOCALES.length());
}
String type = (String) stuff.get(1);
String comment = (String) stuff.get(2);
Type t = null;
// verify that the locale is valid
CLDRLocale l = null;
try {
l = CLDRLocale.getInstance(id);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid CLDRLocale in SpecialLocales.txt:" + ln + ": " + line);
}
// verify that the type is valid
try {
t = Type.valueOf(type.toLowerCase(Locale.ENGLISH));
} catch (Exception e) {
throw new IllegalArgumentException("Invalid SpecialLocales.Type in SpecialLocales.txt:" + ln + ": "
+ line);
}
Set<CLDRLocale> s = types.get(t);
if (s == null) {
s = new TreeSet<CLDRLocale>();
types.put(t, s);
}
s.add(l);
specials.put(l, t);
if (includeSublocs) {
specialsWildcards.add(l);
}
if (!comment.isEmpty()) {
comments.put(l, comment);
}
if (false) {
System.out.println(SpecialLocales.class.getSimpleName() + ": locale " + l + ", includejSublocs=" + includeSublocs + ", type=" + t
+ ", comment: " + comment);
}
}
} catch (IOException e) {
throw new ICUUncheckedIOException("Internal Error", e);
}
specials = Collections.unmodifiableMap(specials);
specialsWildcards = Collections.unmodifiableSet(specialsWildcards);
comments = Collections.unmodifiableMap(comments);
types = Collections.unmodifiableMap(types);
}
}