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