• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2016 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 /*
5  *******************************************************************************
6  * Copyright (C) 2015-2016, International Business Machines Corporation and
7  * others. All Rights Reserved.
8  *******************************************************************************
9  */
10 package ohos.global.icu.impl;
11 
12 import java.util.Collections;
13 import java.util.EnumMap;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Set;
19 
20 import ohos.global.icu.impl.locale.AsciiUtil;
21 import ohos.global.icu.util.UResourceBundle;
22 import ohos.global.icu.util.UResourceBundleIterator;
23 
24 /**
25  * @author markdavis
26  * @hide exposed on OHOS
27  *
28  */
29 public class ValidIdentifiers {
30 
31     /**
32      * @hide exposed on OHOS
33      */
34     public enum Datatype {
35         currency,
36         language,
37         region,
38         script,
39         subdivision,
40         unit,
41         variant,
42         u,
43         t,
44         x,
45         illegal
46     }
47 
48     /**
49      * @hide exposed on OHOS
50      */
51     public enum Datasubtype {
52         deprecated,
53         private_use,
54         regular,
55         special,
56         unknown,
57         macroregion,
58         reserved,
59     }
60 
61     /**
62      * @hide exposed on OHOS
63      */
64     public static class ValiditySet {
65         public final Set<String> regularData;
66         public final Map<String,Set<String>> subdivisionData;
ValiditySet(Set<String> plainData, boolean makeMap)67         public ValiditySet(Set<String> plainData, boolean makeMap) {
68             if (makeMap) {
69                 HashMap<String,Set<String>> _subdivisionData = new HashMap<String,Set<String>>();
70                 for (String s : plainData) {
71                     int pos = s.indexOf('-'); // read v28 data also
72                     int pos2 = pos+1;
73                     if (pos < 0) {
74                         pos2 = pos = s.charAt(0) < 'A' ? 3 : 2;
75                     }
76                     final String key = s.substring(0, pos);
77                     final String subdivision = s.substring(pos2);
78 
79                     Set<String> oldSet = _subdivisionData.get(key);
80                     if (oldSet == null) {
81                         _subdivisionData.put(key, oldSet = new HashSet<String>());
82                     }
83                     oldSet.add(subdivision);
84                 }
85                 this.regularData = null;
86                 HashMap<String,Set<String>> _subdivisionData2 = new HashMap<String,Set<String>>();
87                 // protect the sets
88                 for (Entry<String, Set<String>> e : _subdivisionData.entrySet()) {
89                     Set<String> value = e.getValue();
90                     // optimize a bit by using singleton
91                     Set<String> set = value.size() == 1 ? Collections.singleton(value.iterator().next())
92                             : Collections.unmodifiableSet(value);
93                     _subdivisionData2.put(e.getKey(), set);
94                 }
95 
96                 this.subdivisionData = Collections.unmodifiableMap(_subdivisionData2);
97             } else {
98                 this.regularData = Collections.unmodifiableSet(plainData);
99                 this.subdivisionData = null;
100             }
101         }
102 
103         public boolean contains(String code) {
104             if (regularData != null) {
105                 return regularData.contains(code);
106             } else {
107                 int pos = code.indexOf('-');
108                 String key = code.substring(0,pos);
109                 final String value = code.substring(pos+1);
110                 return contains(key, value);
111             }
112         }
113 
114         public boolean contains(String key, String value) {
115             Set<String> oldSet = subdivisionData.get(key);
116             return oldSet != null && oldSet.contains(value);
117         }
118 
119         @Override
120         public String toString() {
121             if (regularData != null) {
122                 return regularData.toString();
123             } else {
124                 return subdivisionData.toString();
125             }
126         }
127     }
128 
129     private static class ValidityData {
130         static final Map<Datatype,Map<Datasubtype,ValiditySet>> data;
131         static {
132             Map<Datatype, Map<Datasubtype, ValiditySet>> _data = new EnumMap<Datatype,Map<Datasubtype,ValiditySet>>(Datatype.class);
133             UResourceBundle suppData = UResourceBundle.getBundleInstance(
134                     ICUData.ICU_BASE_NAME,
135                     "supplementalData",
136                     ICUResourceBundle.ICU_DATA_CLASS_LOADER);
137             UResourceBundle validityInfo = suppData.get("idValidity");
138             for(UResourceBundleIterator datatypeIterator = validityInfo.getIterator();
139                     datatypeIterator.hasNext();) {
140                 UResourceBundle datatype = datatypeIterator.next();
141                 String rawKey = datatype.getKey();
142                 Datatype key = Datatype.valueOf(rawKey);
143                 Map<Datasubtype,ValiditySet> values = new EnumMap<Datasubtype,ValiditySet>(Datasubtype.class);
144                 for(UResourceBundleIterator datasubtypeIterator = datatype.getIterator();
145                         datasubtypeIterator.hasNext();) {
146                     UResourceBundle datasubtype = datasubtypeIterator.next();
147                     String rawsubkey = datasubtype.getKey();
148                     Datasubtype subkey = Datasubtype.valueOf(rawsubkey);
149                     // handle single value specially
150                     Set<String> subvalues = new HashSet<String>();
151                     if (datasubtype.getType() == UResourceBundle.STRING) {
152                         addRange(datasubtype.getString(), subvalues);
153                     } else {
154                         for (String string : datasubtype.getStringArray()) {
155                             addRange(string, subvalues);
156                         }
157                     }
158                     values.put(subkey, new ValiditySet(subvalues, key == Datatype.subdivision));
159                 }
160                 _data.put(key, Collections.unmodifiableMap(values));
161             }
162             data = Collections.unmodifiableMap(_data);
163         }
164         private static void addRange(String string, Set<String> subvalues) {
165             string = AsciiUtil.toLowerString(string);
166             int pos = string.indexOf('~');
167             if (pos < 0) {
168                 subvalues.add(string);
169             } else {
170                 StringRange.expand(string.substring(0,pos), string.substring(pos+1), false, subvalues);
171             }
172         }
173     }
174 
175     public static Map<Datatype, Map<Datasubtype, ValiditySet>> getData() {
176         return ValidityData.data;
177     }
178 
179     /**
180      * Returns the Datasubtype containing the code, or null if there is none.
181      */
182     public static Datasubtype isValid(Datatype datatype, Set<Datasubtype> datasubtypes, String code) {
183         Map<Datasubtype, ValiditySet> subtable = ValidityData.data.get(datatype);
184         if (subtable != null) {
185             for (Datasubtype datasubtype : datasubtypes) {
186                 ValiditySet validitySet = subtable.get(datasubtype);
187                 if (validitySet != null) {
188                     if (validitySet.contains(AsciiUtil.toLowerString(code))) {
189                         return datasubtype;
190                     }
191                 }
192             }
193         }
194         return null;
195     }
196 
197     public static Datasubtype isValid(Datatype datatype, Set<Datasubtype> datasubtypes, String code, String value) {
198         Map<Datasubtype, ValiditySet> subtable = ValidityData.data.get(datatype);
199         if (subtable != null) {
200             code = AsciiUtil.toLowerString(code);
201             value = AsciiUtil.toLowerString(value);
202             for (Datasubtype datasubtype : datasubtypes) {
203                 ValiditySet validitySet = subtable.get(datasubtype);
204                 if (validitySet != null) {
205                     if (validitySet.contains(code, value)) {
206                         return datasubtype;
207                     }
208                 }
209             }
210         }
211         return null;
212     }
213 }
214