1 /* 2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8040211 8191404 8203872 8222980 8225435 27 * @summary Checks the IANA language subtag registry data update 28 * (LSR Revision: 2019-09-16) with Locale and Locale.LanguageRange 29 * class methods. 30 * @run main Bug8040211 31 */ 32 33 import java.util.ArrayList; 34 import java.util.Iterator; 35 import java.util.Locale; 36 import java.util.List; 37 import java.util.Locale.LanguageRange; 38 import java.util.Locale.FilteringMode; 39 import static java.util.Locale.FilteringMode.EXTENDED_FILTERING; 40 41 public class Bug8040211 { 42 43 static boolean err = false; 44 45 private static final String ACCEPT_LANGUAGE = 46 "Accept-Language: aam, adp, aog, aue, bcg, cey, cqu, dif, ema," 47 + " en-gb-oed, gti, kdz, koj, kwq, kxe, lii, lmm, lsn, lsv, lvi, mtm," 48 + " ngv, nns, oyb, phr, pnd, pub, snz, suj, szy,taj, tjj, tjp, tvx," 49 + " uss, uth, wkr;q=0.9, ar-hyw;q=0.8, yug;q=0.5, gfx;q=0.4"; 50 private static final List<LanguageRange> EXPECTED_RANGE_LIST = List.of( 51 new LanguageRange("aam", 1.0), 52 new LanguageRange("aas", 1.0), 53 new LanguageRange("adp", 1.0), 54 new LanguageRange("dz", 1.0), 55 new LanguageRange("aog", 1.0), 56 new LanguageRange("myd", 1.0), 57 new LanguageRange("aue", 1.0), 58 new LanguageRange("ktz", 1.0), 59 new LanguageRange("bcg", 1.0), 60 new LanguageRange("bgm", 1.0), 61 new LanguageRange("cey", 1.0), 62 new LanguageRange("cqu", 1.0), 63 new LanguageRange("quh", 1.0), 64 new LanguageRange("dif", 1.0), 65 new LanguageRange("dit", 1.0), 66 new LanguageRange("ema", 1.0), 67 new LanguageRange("uok", 1.0), 68 new LanguageRange("en-gb-oed", 1.0), 69 new LanguageRange("en-gb-oxendict", 1.0), 70 new LanguageRange("gti", 1.0), 71 new LanguageRange("nyc", 1.0), 72 new LanguageRange("kdz", 1.0), 73 new LanguageRange("ncp", 1.0), 74 new LanguageRange("koj", 1.0), 75 new LanguageRange("kwv", 1.0), 76 new LanguageRange("kwq", 1.0), 77 new LanguageRange("yam", 1.0), 78 new LanguageRange("kxe", 1.0), 79 new LanguageRange("tvd", 1.0), 80 new LanguageRange("lii", 1.0), 81 new LanguageRange("raq", 1.0), 82 new LanguageRange("lmm", 1.0), 83 new LanguageRange("rmx", 1.0), 84 new LanguageRange("lsn", 1.0), 85 new LanguageRange("lsv", 1.0), 86 new LanguageRange("lvi", 1.0), 87 new LanguageRange("mtm", 1.0), 88 new LanguageRange("ymt", 1.0), 89 new LanguageRange("ngv", 1.0), 90 new LanguageRange("nnx", 1.0), 91 new LanguageRange("nns", 1.0), 92 new LanguageRange("nbr", 1.0), 93 new LanguageRange("oyb", 1.0), 94 new LanguageRange("thx", 1.0), 95 new LanguageRange("skk", 1.0), 96 new LanguageRange("jeg", 1.0), 97 new LanguageRange("phr", 1.0), 98 new LanguageRange("pmu", 1.0), 99 new LanguageRange("pnd", 1.0), 100 new LanguageRange("pub", 1.0), 101 new LanguageRange("puz", 1.0), 102 new LanguageRange("snz", 1.0), 103 new LanguageRange("asd", 1.0), 104 new LanguageRange("suj", 1.0), 105 new LanguageRange("szy", 1.0), 106 new LanguageRange("taj", 1.0), 107 new LanguageRange("tsf", 1.0), 108 new LanguageRange("tjj", 1.0), 109 new LanguageRange("tjp", 1.0), 110 new LanguageRange("tvx", 1.0), 111 new LanguageRange("uss", 1.0), 112 new LanguageRange("uth", 1.0), 113 new LanguageRange("wkr", 0.9), 114 new LanguageRange("ar-hyw", 0.8), 115 new LanguageRange("yug", 0.5), 116 new LanguageRange("yuu", 0.5), 117 new LanguageRange("gfx", 0.4), 118 new LanguageRange("oun", 0.4), 119 new LanguageRange("mwj", 0.4), 120 new LanguageRange("vaj", 0.4) 121 ); 122 123 public static void main(String[] args) { 124 testLanguageRange(); 125 testLocale(); 126 127 if (err) { 128 throw new RuntimeException("Failed."); 129 } 130 } 131 132 private static void testLanguageRange() { 133 System.out.println("Test LanguageRange class parse method..."); 134 test_parse(); 135 } 136 137 private static void testLocale() { 138 System.out.println("Test Locale class methods..."); 139 test_filter(); 140 test_filterTags(); 141 test_lookup(); 142 test_lookupTag(); 143 } 144 145 private static void test_parse() { 146 boolean error = false; 147 List<LanguageRange> got = LanguageRange.parse(ACCEPT_LANGUAGE); 148 if (!areEqual(EXPECTED_RANGE_LIST, got)) { 149 error = true; 150 System.err.println(" language parse() test failed."); 151 } 152 153 if (error) { 154 err = true; 155 System.out.println(" test_parse() failed."); 156 } else { 157 System.out.println(" test_parse() passed."); 158 } 159 160 } 161 162 private static boolean areEqual(List<LanguageRange> expected, 163 List<LanguageRange> got) { 164 boolean error = false; 165 166 int expectedSize = expected.size(); 167 int actualSize = got.size(); 168 169 if (expectedSize != actualSize) { 170 error = true; 171 172 System.err.println(" Expected size=" + expectedSize); 173 for (LanguageRange lr : expected) { 174 System.err.println(" range=" + lr.getRange() 175 + ", weight=" + lr.getWeight()); 176 } 177 178 System.err.println(" Actual size=" + actualSize); 179 for (LanguageRange lr : got) { 180 System.err.println(" range=" + lr.getRange() 181 + ", weight=" + lr.getWeight()); 182 } 183 } else { 184 for (int i = 0; i < expectedSize; i++) { 185 LanguageRange lr1 = expected.get(i); 186 LanguageRange lr2 = got.get(i); 187 188 if (!lr1.getRange().equals(lr2.getRange()) 189 || lr1.getWeight() != lr2.getWeight()) { 190 error = true; 191 System.err.println(" " + i + ": Expected: range=" + lr1.getRange() 192 + ", weight=" + lr1.getWeight()); 193 System.err.println(" " + i + ": Actual: range=" + lr2.getRange() 194 + ", weight=" + lr2.getWeight()); 195 } 196 } 197 } 198 199 return !error; 200 } 201 202 private static void test_filter() { 203 boolean error = false; 204 205 String ranges = "mtm-RU, en-gb-oed, coy, ar-HY"; 206 String tags = "de-DE, en, mtm-RU, ymt-RU, en-gb-oxendict, ja-JP, pij, nts, ar-arevela"; 207 FilteringMode mode = EXTENDED_FILTERING; 208 209 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 210 List<Locale> tagList = generateLocales(tags); 211 String actualLocales 212 = showLocales(Locale.filter(priorityList, tagList, mode)); 213 String expectedLocales = "mtm-RU, ymt-RU, en-GB-oxendict, nts, pij"; 214 215 if (!expectedLocales.equals(actualLocales)) { 216 error = true; 217 showErrorMessage("#1 filter(" + mode + ")", 218 ranges, tags, expectedLocales, actualLocales); 219 } 220 221 ranges = "phr-*-IN, ja-JP"; 222 tags = "en, pmu-Guru-IN, ja-Latn-JP, iw"; 223 mode = EXTENDED_FILTERING; 224 225 priorityList = LanguageRange.parse(ranges); 226 tagList = generateLocales(tags); 227 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 228 expectedLocales = "pmu-Guru-IN, ja-Latn-JP"; 229 230 if (!expectedLocales.equals(actualLocales)) { 231 error = true; 232 showErrorMessage("#2 filter(" + mode + ")", 233 ranges, tags, expectedLocales, actualLocales); 234 } 235 236 if (error) { 237 err = true; 238 System.out.println(" test_filter() failed."); 239 } else { 240 System.out.println(" test_filter() passed."); 241 } 242 } 243 244 private static void test_filterTags() { 245 boolean error = false; 246 247 String ranges = "gti;q=0.2, gfx, kzj"; 248 String tags = "de-DE, gti, he, nyc, mwj, vaj, ktr, dtp"; 249 250 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 251 List<String> tagList = generateLanguageTags(tags); 252 String actualTags 253 = showLanguageTags(Locale.filterTags(priorityList, tagList)); 254 String expectedTags = "mwj, vaj, ktr, dtp, gti, nyc"; 255 256 if (!expectedTags.equals(actualTags)) { 257 error = true; 258 showErrorMessage("filterTags()", 259 ranges, tags, expectedTags, actualTags); 260 } 261 262 if (error) { 263 err = true; 264 System.out.println(" test_filterTags() failed."); 265 } else { 266 System.out.println(" test_filterTags() passed."); 267 } 268 } 269 270 private static void test_lookup() { 271 boolean error = false; 272 273 String ranges = "en;q=0.2, yam, rmx;q=0.9"; 274 String tags = "de-DE, en, kwq, lmm"; 275 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 276 List<Locale> localeList = generateLocales(tags); 277 String actualLocale 278 = Locale.lookup(priorityList, localeList).toLanguageTag(); 279 String expectedLocale = "kwq"; 280 281 if (!expectedLocale.equals(actualLocale)) { 282 error = true; 283 showErrorMessage("lookup()", ranges, tags, expectedLocale, actualLocale); 284 } 285 286 if (error) { 287 err = true; 288 System.out.println(" test_lookup() failed."); 289 } else { 290 System.out.println(" test_lookup() passed."); 291 } 292 } 293 294 private static void test_lookupTag() { 295 boolean error = false; 296 297 String ranges = "en, tsf;q=0.2"; 298 String tags = "es, ja-JP, taj"; 299 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 300 List<String> tagList = generateLanguageTags(tags); 301 String actualTag = Locale.lookupTag(priorityList, tagList); 302 String expectedTag = "taj"; 303 304 if (!expectedTag.equals(actualTag)) { 305 error = true; 306 showErrorMessage("lookupTag()", ranges, tags, expectedTag, actualTag); 307 } 308 309 if (error) { 310 err = true; 311 System.out.println(" test_lookupTag() failed."); 312 } else { 313 System.out.println(" test_lookupTag() passed."); 314 } 315 } 316 317 private static List<Locale> generateLocales(String tags) { 318 if (tags == null) { 319 return null; 320 } 321 322 List<Locale> localeList = new ArrayList<>(); 323 if (tags.equals("")) { 324 return localeList; 325 } 326 String[] t = tags.split(", "); 327 for (String tag : t) { 328 localeList.add(Locale.forLanguageTag(tag)); 329 } 330 return localeList; 331 } 332 333 private static List<String> generateLanguageTags(String tags) { 334 List<String> tagList = new ArrayList<>(); 335 String[] t = tags.split(", "); 336 for (String tag : t) { 337 tagList.add(tag); 338 } 339 return tagList; 340 } 341 342 private static String showLanguageTags(List<String> tags) { 343 StringBuilder sb = new StringBuilder(); 344 345 Iterator<String> itr = tags.iterator(); 346 if (itr.hasNext()) { 347 sb.append(itr.next()); 348 } 349 while (itr.hasNext()) { 350 sb.append(", "); 351 sb.append(itr.next()); 352 } 353 354 return sb.toString().trim(); 355 } 356 357 private static String showLocales(List<Locale> locales) { 358 StringBuilder sb = new StringBuilder(); 359 360 java.util.Iterator<Locale> itr = locales.iterator(); 361 if (itr.hasNext()) { 362 sb.append(itr.next().toLanguageTag()); 363 } 364 while (itr.hasNext()) { 365 sb.append(", "); 366 sb.append(itr.next().toLanguageTag()); 367 } 368 369 return sb.toString().trim(); 370 } 371 372 private static void showErrorMessage(String methodName, 373 String priorityList, 374 String tags, 375 String expectedTags, 376 String actualTags) { 377 System.err.println("\nIncorrect " + methodName + " result."); 378 System.err.println(" Priority list : " + priorityList); 379 System.err.println(" Language tags : " + tags); 380 System.err.println(" Expected value : " + expectedTags); 381 System.err.println(" Actual value : " + actualTags); 382 } 383 384 } 385