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