1 /* 2 * Copyright (c) 2016, 2020, 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 8241082 8242010 27 * @summary Checks the IANA language subtag registry data update 28 * (LSR Revision: 2020-04-01) 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, bpp, cey, cnp, cqu, csp, dif, dmw, ema," 47 + " en-gb-oed, gti, kdz, koj, kru, kwq, kxe, kzk, lii, lmm, lsn, lsv, lvi, mtm," 48 + " ngv, nns, oyb, phr, pnd, pub, scv, 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("bpp", 1.0), 62 new LanguageRange("nxu", 1.0), 63 new LanguageRange("cey", 1.0), 64 new LanguageRange("cnp", 1.0), 65 new LanguageRange("zh-cnp", 1.0), 66 new LanguageRange("cqu", 1.0), 67 new LanguageRange("quh", 1.0), 68 new LanguageRange("csp", 1.0), 69 new LanguageRange("zh-csp", 1.0), 70 new LanguageRange("dif", 1.0), 71 new LanguageRange("dit", 1.0), 72 new LanguageRange("dmw", 1.0), 73 new LanguageRange("xrq", 1.0), 74 new LanguageRange("ema", 1.0), 75 new LanguageRange("uok", 1.0), 76 new LanguageRange("en-gb-oed", 1.0), 77 new LanguageRange("en-gb-oxendict", 1.0), 78 new LanguageRange("gti", 1.0), 79 new LanguageRange("nyc", 1.0), 80 new LanguageRange("kdz", 1.0), 81 new LanguageRange("ncp", 1.0), 82 new LanguageRange("koj", 1.0), 83 new LanguageRange("kwv", 1.0), 84 new LanguageRange("kru", 1.0), 85 new LanguageRange("kxl", 1.0), 86 new LanguageRange("kwq", 1.0), 87 new LanguageRange("yam", 1.0), 88 new LanguageRange("kxe", 1.0), 89 new LanguageRange("tvd", 1.0), 90 new LanguageRange("kzk", 1.0), 91 new LanguageRange("gli", 1.0), 92 new LanguageRange("drr", 1.0), 93 new LanguageRange("lii", 1.0), 94 new LanguageRange("raq", 1.0), 95 new LanguageRange("lmm", 1.0), 96 new LanguageRange("rmx", 1.0), 97 new LanguageRange("lsn", 1.0), 98 new LanguageRange("sgn-lsn", 1.0), 99 new LanguageRange("lsv", 1.0), 100 new LanguageRange("sgn-lsv", 1.0), 101 new LanguageRange("lvi", 1.0), 102 new LanguageRange("mtm", 1.0), 103 new LanguageRange("ymt", 1.0), 104 new LanguageRange("ngv", 1.0), 105 new LanguageRange("nnx", 1.0), 106 new LanguageRange("nns", 1.0), 107 new LanguageRange("nbr", 1.0), 108 new LanguageRange("oyb", 1.0), 109 new LanguageRange("thx", 1.0), 110 new LanguageRange("skk", 1.0), 111 new LanguageRange("jeg", 1.0), 112 new LanguageRange("phr", 1.0), 113 new LanguageRange("pmu", 1.0), 114 new LanguageRange("pnd", 1.0), 115 new LanguageRange("pub", 1.0), 116 new LanguageRange("puz", 1.0), 117 new LanguageRange("scv", 1.0), 118 new LanguageRange("zir", 1.0), 119 new LanguageRange("snz", 1.0), 120 new LanguageRange("asd", 1.0), 121 new LanguageRange("suj", 1.0), 122 new LanguageRange("szy", 1.0), 123 new LanguageRange("taj", 1.0), 124 new LanguageRange("tsf", 1.0), 125 new LanguageRange("tjj", 1.0), 126 new LanguageRange("tjp", 1.0), 127 new LanguageRange("tvx", 1.0), 128 new LanguageRange("uss", 1.0), 129 new LanguageRange("uth", 1.0), 130 new LanguageRange("wkr", 0.9), 131 new LanguageRange("ar-hyw", 0.8), 132 new LanguageRange("yug", 0.5), 133 new LanguageRange("yuu", 0.5), 134 new LanguageRange("gfx", 0.4), 135 new LanguageRange("oun", 0.4), 136 new LanguageRange("mwj", 0.4), 137 new LanguageRange("vaj", 0.4) 138 ); 139 140 public static void main(String[] args) { 141 testLanguageRange(); 142 testLocale(); 143 144 if (err) { 145 throw new RuntimeException("Failed."); 146 } 147 } 148 149 private static void testLanguageRange() { 150 System.out.println("Test LanguageRange class parse method..."); 151 test_parse(); 152 } 153 154 private static void testLocale() { 155 System.out.println("Test Locale class methods..."); 156 test_filter(); 157 test_filterTags(); 158 test_lookup(); 159 test_lookupTag(); 160 } 161 162 private static void test_parse() { 163 boolean error = false; 164 List<LanguageRange> got = LanguageRange.parse(ACCEPT_LANGUAGE); 165 if (!areEqual(EXPECTED_RANGE_LIST, got)) { 166 error = true; 167 System.err.println(" language parse() test failed."); 168 } 169 170 if (error) { 171 err = true; 172 System.out.println(" test_parse() failed."); 173 } else { 174 System.out.println(" test_parse() passed."); 175 } 176 177 } 178 179 private static boolean areEqual(List<LanguageRange> expected, 180 List<LanguageRange> got) { 181 boolean error = false; 182 183 int expectedSize = expected.size(); 184 int actualSize = got.size(); 185 186 if (expectedSize != actualSize) { 187 error = true; 188 189 System.err.println(" Expected size=" + expectedSize); 190 for (LanguageRange lr : expected) { 191 System.err.println(" range=" + lr.getRange() 192 + ", weight=" + lr.getWeight()); 193 } 194 195 System.err.println(" Actual size=" + actualSize); 196 for (LanguageRange lr : got) { 197 System.err.println(" range=" + lr.getRange() 198 + ", weight=" + lr.getWeight()); 199 } 200 } else { 201 for (int i = 0; i < expectedSize; i++) { 202 LanguageRange lr1 = expected.get(i); 203 LanguageRange lr2 = got.get(i); 204 205 if (!lr1.getRange().equals(lr2.getRange()) 206 || lr1.getWeight() != lr2.getWeight()) { 207 error = true; 208 System.err.println(" " + i + ": Expected: range=" + lr1.getRange() 209 + ", weight=" + lr1.getWeight()); 210 System.err.println(" " + i + ": Actual: range=" + lr2.getRange() 211 + ", weight=" + lr2.getWeight()); 212 } 213 } 214 } 215 216 return !error; 217 } 218 219 private static void test_filter() { 220 boolean error = false; 221 222 String ranges = "mtm-RU, en-gb-oed, coy, ar-HY"; 223 String tags = "de-DE, en, mtm-RU, ymt-RU, en-gb-oxendict, ja-JP, pij, nts, ar-arevela"; 224 FilteringMode mode = EXTENDED_FILTERING; 225 226 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 227 List<Locale> tagList = generateLocales(tags); 228 String actualLocales 229 = showLocales(Locale.filter(priorityList, tagList, mode)); 230 String expectedLocales = "mtm-RU, ymt-RU, en-GB-oxendict, nts, pij"; 231 232 if (!expectedLocales.equals(actualLocales)) { 233 error = true; 234 showErrorMessage("#1 filter(" + mode + ")", 235 ranges, tags, expectedLocales, actualLocales); 236 } 237 238 ranges = "phr-*-IN, ja-JP"; 239 tags = "en, pmu-Guru-IN, ja-Latn-JP, iw"; 240 mode = EXTENDED_FILTERING; 241 242 priorityList = LanguageRange.parse(ranges); 243 tagList = generateLocales(tags); 244 actualLocales = showLocales(Locale.filter(priorityList, tagList, mode)); 245 expectedLocales = "pmu-Guru-IN, ja-Latn-JP"; 246 247 if (!expectedLocales.equals(actualLocales)) { 248 error = true; 249 showErrorMessage("#2 filter(" + mode + ")", 250 ranges, tags, expectedLocales, actualLocales); 251 } 252 253 if (error) { 254 err = true; 255 System.out.println(" test_filter() failed."); 256 } else { 257 System.out.println(" test_filter() passed."); 258 } 259 } 260 261 private static void test_filterTags() { 262 boolean error = false; 263 264 String ranges = "gti;q=0.2, gfx, kzj"; 265 String tags = "de-DE, gti, he, nyc, mwj, vaj, ktr, dtp"; 266 267 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 268 List<String> tagList = generateLanguageTags(tags); 269 String actualTags 270 = showLanguageTags(Locale.filterTags(priorityList, tagList)); 271 String expectedTags = "mwj, vaj, ktr, dtp, gti, nyc"; 272 273 if (!expectedTags.equals(actualTags)) { 274 error = true; 275 showErrorMessage("filterTags()", 276 ranges, tags, expectedTags, actualTags); 277 } 278 279 if (error) { 280 err = true; 281 System.out.println(" test_filterTags() failed."); 282 } else { 283 System.out.println(" test_filterTags() passed."); 284 } 285 } 286 287 private static void test_lookup() { 288 boolean error = false; 289 290 String ranges = "en;q=0.2, yam, rmx;q=0.9"; 291 String tags = "de-DE, en, kwq, lmm"; 292 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 293 List<Locale> localeList = generateLocales(tags); 294 String actualLocale 295 = Locale.lookup(priorityList, localeList).toLanguageTag(); 296 String expectedLocale = "kwq"; 297 298 if (!expectedLocale.equals(actualLocale)) { 299 error = true; 300 showErrorMessage("lookup()", ranges, tags, expectedLocale, actualLocale); 301 } 302 303 if (error) { 304 err = true; 305 System.out.println(" test_lookup() failed."); 306 } else { 307 System.out.println(" test_lookup() passed."); 308 } 309 } 310 311 private static void test_lookupTag() { 312 boolean error = false; 313 314 String ranges = "en, tsf;q=0.2"; 315 String tags = "es, ja-JP, taj"; 316 List<LanguageRange> priorityList = LanguageRange.parse(ranges); 317 List<String> tagList = generateLanguageTags(tags); 318 String actualTag = Locale.lookupTag(priorityList, tagList); 319 String expectedTag = "taj"; 320 321 if (!expectedTag.equals(actualTag)) { 322 error = true; 323 showErrorMessage("lookupTag()", ranges, tags, expectedTag, actualTag); 324 } 325 326 if (error) { 327 err = true; 328 System.out.println(" test_lookupTag() failed."); 329 } else { 330 System.out.println(" test_lookupTag() passed."); 331 } 332 } 333 334 private static List<Locale> generateLocales(String tags) { 335 if (tags == null) { 336 return null; 337 } 338 339 List<Locale> localeList = new ArrayList<>(); 340 if (tags.equals("")) { 341 return localeList; 342 } 343 String[] t = tags.split(", "); 344 for (String tag : t) { 345 localeList.add(Locale.forLanguageTag(tag)); 346 } 347 return localeList; 348 } 349 350 private static List<String> generateLanguageTags(String tags) { 351 List<String> tagList = new ArrayList<>(); 352 String[] t = tags.split(", "); 353 for (String tag : t) { 354 tagList.add(tag); 355 } 356 return tagList; 357 } 358 359 private static String showLanguageTags(List<String> tags) { 360 StringBuilder sb = new StringBuilder(); 361 362 Iterator<String> itr = tags.iterator(); 363 if (itr.hasNext()) { 364 sb.append(itr.next()); 365 } 366 while (itr.hasNext()) { 367 sb.append(", "); 368 sb.append(itr.next()); 369 } 370 371 return sb.toString().trim(); 372 } 373 374 private static String showLocales(List<Locale> locales) { 375 StringBuilder sb = new StringBuilder(); 376 377 java.util.Iterator<Locale> itr = locales.iterator(); 378 if (itr.hasNext()) { 379 sb.append(itr.next().toLanguageTag()); 380 } 381 while (itr.hasNext()) { 382 sb.append(", "); 383 sb.append(itr.next().toLanguageTag()); 384 } 385 386 return sb.toString().trim(); 387 } 388 389 private static void showErrorMessage(String methodName, 390 String priorityList, 391 String tags, 392 String expectedTags, 393 String actualTags) { 394 System.err.println("\nIncorrect " + methodName + " result."); 395 System.err.println(" Priority list : " + priorityList); 396 System.err.println(" Language tags : " + tags); 397 System.err.println(" Expected value : " + expectedTags); 398 System.err.println(" Actual value : " + actualTags); 399 } 400 401 } 402