1 /* 2 ******************************************************************************* 3 * Copyright (C) 2009-2014, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ******************************************************************************* 6 */ 7 package com.ibm.icu.impl.locale; 8 9 import java.util.Collections; 10 import java.util.Map.Entry; 11 import java.util.Set; 12 import java.util.SortedMap; 13 import java.util.SortedSet; 14 import java.util.TreeMap; 15 import java.util.TreeSet; 16 17 public class UnicodeLocaleExtension extends Extension { 18 public static final char SINGLETON = 'u'; 19 20 private static final SortedSet<String> EMPTY_SORTED_SET = new TreeSet<String>(); 21 private static final SortedMap<String, String> EMPTY_SORTED_MAP = new TreeMap<String, String>(); 22 23 private SortedSet<String> _attributes = EMPTY_SORTED_SET; 24 private SortedMap<String, String> _keywords = EMPTY_SORTED_MAP; 25 26 public static final UnicodeLocaleExtension CA_JAPANESE; 27 public static final UnicodeLocaleExtension NU_THAI; 28 29 static { 30 CA_JAPANESE = new UnicodeLocaleExtension(); 31 CA_JAPANESE._keywords = new TreeMap<String, String>(); 32 CA_JAPANESE._keywords.put("ca", "japanese"); 33 CA_JAPANESE._value = "ca-japanese"; 34 35 NU_THAI = new UnicodeLocaleExtension(); 36 NU_THAI._keywords = new TreeMap<String, String>(); 37 NU_THAI._keywords.put("nu", "thai"); 38 NU_THAI._value = "nu-thai"; 39 } 40 UnicodeLocaleExtension()41 private UnicodeLocaleExtension() { 42 super(SINGLETON); 43 } 44 UnicodeLocaleExtension(SortedSet<String> attributes, SortedMap<String, String> keywords)45 UnicodeLocaleExtension(SortedSet<String> attributes, SortedMap<String, String> keywords) { 46 this(); 47 if (attributes != null && attributes.size() > 0) { 48 _attributes = attributes; 49 } 50 if (keywords != null && keywords.size() > 0) { 51 _keywords = keywords; 52 } 53 54 if (_attributes.size() > 0 || _keywords.size() > 0) { 55 StringBuilder sb = new StringBuilder(); 56 for (String attribute : _attributes) { 57 sb.append(LanguageTag.SEP).append(attribute); 58 } 59 for (Entry<String, String> keyword : _keywords.entrySet()) { 60 String key = keyword.getKey(); 61 String value = keyword.getValue(); 62 63 sb.append(LanguageTag.SEP).append(key); 64 if (value.length() > 0) { 65 sb.append(LanguageTag.SEP).append(value); 66 } 67 } 68 _value = sb.substring(1); // skip leading '-' 69 } 70 } 71 getUnicodeLocaleAttributes()72 public Set<String> getUnicodeLocaleAttributes() { 73 return Collections.unmodifiableSet(_attributes); 74 } 75 getUnicodeLocaleKeys()76 public Set<String> getUnicodeLocaleKeys() { 77 return Collections.unmodifiableSet(_keywords.keySet()); 78 } 79 getUnicodeLocaleType(String unicodeLocaleKey)80 public String getUnicodeLocaleType(String unicodeLocaleKey) { 81 return _keywords.get(unicodeLocaleKey); 82 } 83 isSingletonChar(char c)84 public static boolean isSingletonChar(char c) { 85 return (SINGLETON == AsciiUtil.toLower(c)); 86 } 87 isAttribute(String s)88 public static boolean isAttribute(String s) { 89 // 3*8alphanum 90 return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s); 91 } 92 isKey(String s)93 public static boolean isKey(String s) { 94 // 2alphanum 95 return (s.length() == 2) && AsciiUtil.isAlphaNumericString(s); 96 } 97 isTypeSubtag(String s)98 public static boolean isTypeSubtag(String s) { 99 // 3*8alphanum 100 return (s.length() >= 3) && (s.length() <= 8) && AsciiUtil.isAlphaNumericString(s); 101 } 102 isType(String s)103 public static boolean isType(String s) { 104 // sequence of type subtags delimited by '-' 105 int startIdx = 0; 106 boolean sawSubtag = false; 107 while (true) { 108 int idx = s.indexOf(LanguageTag.SEP, startIdx); 109 String subtag = idx < 0 ? s.substring(startIdx) : s.substring(startIdx, idx); 110 if (!isTypeSubtag(subtag)) { 111 return false; 112 } 113 sawSubtag = true; 114 if (idx < 0) { 115 break; 116 } 117 startIdx = idx + 1; 118 } 119 return sawSubtag && startIdx < s.length(); 120 } 121 } 122