1 /* 2 * Copyright (c) 2007, 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 * @test 25 * @bug 5102289 6278334 26 * @summary Test the default Control implementation. The expiration 27 * functionality of newBundle, getTimeToLive, and needsReload is 28 * tested by ExpirationTest.sh. The factory methods are tested 29 * separately. 30 * @build TestResourceRB 31 * @build NonResourceBundle 32 * @run main DefaultControlTest 33 */ 34 35 import java.util.*; 36 import static java.util.ResourceBundle.Control.*; 37 38 public class DefaultControlTest { 39 // The ResourceBundle.Control instance 40 static final ResourceBundle.Control CONTROL 41 = ResourceBundle.Control.getControl(FORMAT_DEFAULT); 42 43 static final ResourceBundle BUNDLE = new ResourceBundle() { 44 public Enumeration<String> getKeys() { return null; } 45 protected Object handleGetObject(String key) { return null; } 46 }; 47 48 static final String CLAZZ = FORMAT_CLASS.get(0); 49 50 static final String PROPERTIES = FORMAT_PROPERTIES.get(0); 51 52 static final ClassLoader LOADER = DefaultControlTest.class.getClassLoader(); 53 54 // Full arguments for NPE testing 55 static final Object[] FULLARGS = { "any", 56 Locale.US, 57 FORMAT_PROPERTIES.get(0), 58 LOADER, 59 BUNDLE }; 60 61 static int errors; 62 main(String[] args)63 public static void main(String[] args) { 64 checkConstants(); 65 66 // Test getFormats(String) 67 testGetFormats(); 68 69 // Test getCandidateLocales(String, Locale) 70 testGetCandidateLocales(); 71 72 // Test getFallbackLocale(String, Locale) 73 testGetFallbackLocale(); 74 75 // Test newBundle(String, Locale, String, ClassLoader, boolean) 76 testNewBundle(); 77 78 // Test toBundleName(String, Locale) 79 testToBundleName(); 80 81 // Test getTimeToLive(String, Locale) 82 testGetTimeToLive(); 83 84 // Test needsReload(String, Locale, String, ClassLoader, 85 // ResourceBundle, long) 86 testNeedsReload(); 87 88 // Test toResourceName(String, String) 89 testToResourceName(); 90 91 if (errors > 0) { 92 throw new RuntimeException("FAILED: " + errors + " error(s)"); 93 } 94 } 95 checkConstants()96 private static void checkConstants() { 97 // Check FORMAT_* 98 if (!CONTROL.FORMAT_DEFAULT.equals(Arrays.asList("java.class", 99 "java.properties"))) { 100 error("Wrong Control.FORMAT_DEFAULT"); 101 } 102 checkImmutableList(CONTROL.FORMAT_DEFAULT); 103 if (!CONTROL.FORMAT_CLASS.equals(Arrays.asList("java.class"))) { 104 error("Wrong Control.FORMAT_CLASS"); 105 } 106 checkImmutableList(CONTROL.FORMAT_CLASS); 107 if (!CONTROL.FORMAT_PROPERTIES.equals(Arrays.asList("java.properties"))) { 108 error("Wrong Control.FORMAT_PROPERTIES"); 109 } 110 checkImmutableList(CONTROL.FORMAT_PROPERTIES); 111 112 // Check TTL_* 113 if (CONTROL.TTL_DONT_CACHE != -1) { 114 error("Wrong Control.TTL_DONT_CACHE: %d%n", CONTROL.TTL_DONT_CACHE); 115 } 116 if (CONTROL.TTL_NO_EXPIRATION_CONTROL != -2) { 117 error("Wrong Control.TTL_NO_EXPIRATION_CONTROL: %d%n", 118 CONTROL.TTL_NO_EXPIRATION_CONTROL); 119 } 120 } 121 checkImmutableList(List<String> list)122 private static void checkImmutableList(List<String> list) { 123 try { 124 list.add("hello"); 125 error("%s is mutable%n", list); 126 } catch (UnsupportedOperationException e) { 127 } 128 } 129 testGetFormats()130 private static void testGetFormats() { 131 List<String> list = CONTROL.getFormats("foo"); 132 if (list != CONTROL.FORMAT_DEFAULT) { 133 error("getFormats returned " + list); 134 } 135 try { 136 list = CONTROL.getFormats(null); 137 error("getFormats doesn't throw NPE."); 138 } catch (NullPointerException e) { 139 } 140 } 141 testGetCandidateLocales()142 private static void testGetCandidateLocales() { 143 Map<Locale, Locale[]> candidateData = new HashMap<Locale, Locale[]>(); 144 candidateData.put(new Locale("ja", "JP", "YOK"), new Locale[] { 145 new Locale("ja", "JP", "YOK"), 146 new Locale("ja", "JP"), 147 new Locale("ja"), 148 new Locale("") }); 149 candidateData.put(new Locale("ja", "JP"), new Locale[] { 150 new Locale("ja", "JP"), 151 new Locale("ja"), 152 new Locale("") }); 153 candidateData.put(new Locale("ja"), new Locale[] { 154 new Locale("ja"), 155 new Locale("") }); 156 157 candidateData.put(new Locale("ja", "", "YOK"), new Locale[] { 158 new Locale("ja", "", "YOK"), 159 new Locale("ja"), 160 new Locale("") }); 161 candidateData.put(new Locale("", "JP", "YOK"), new Locale[] { 162 new Locale("", "JP", "YOK"), 163 new Locale("", "JP"), 164 new Locale("") }); 165 candidateData.put(new Locale("", "", "YOK"), new Locale[] { 166 new Locale("", "", "YOK"), 167 new Locale("") }); 168 candidateData.put(new Locale("", "JP"), new Locale[] { 169 new Locale("", "JP"), 170 new Locale("") }); 171 candidateData.put(new Locale(""), new Locale[] { 172 new Locale("") }); 173 174 for (Locale locale : candidateData.keySet()) { 175 List<Locale> candidates = CONTROL.getCandidateLocales("any", locale); 176 List<Locale> expected = Arrays.asList(candidateData.get(locale)); 177 if (!candidates.equals(expected)) { 178 error("Wrong candidates for %s: got %s, expected %s%n", 179 toString(locale), candidates, expected); 180 } 181 } 182 final int NARGS = 2; 183 for (int mask = 0; mask < (1 << NARGS)-1; mask++) { 184 Object[] data = getNpeArgs(NARGS, mask); 185 try { 186 List<Locale> candidates = CONTROL.getCandidateLocales((String) data[0], 187 (Locale) data[1]); 188 error("getCandidateLocales(%s, %s) doesn't throw NPE.%n", 189 data[0], toString((Locale)data[1])); 190 } catch (NullPointerException e) { 191 } 192 } 193 } 194 testGetFallbackLocale()195 private static void testGetFallbackLocale() { 196 Locale current = Locale.getDefault(); 197 Locale.setDefault(Locale.ITALY); 198 try { 199 Locale loc = CONTROL.getFallbackLocale("any", Locale.FRANCE); 200 if (loc != Locale.ITALY) { 201 error("getFallbackLocale: got %s, expected %s%n", 202 toString(loc), toString(Locale.ITALY)); 203 } 204 loc = CONTROL.getFallbackLocale("any", Locale.ITALY); 205 if (loc != null) { 206 error("getFallbackLocale: got %s, expected null%n", toString(loc)); 207 } 208 } finally { 209 Locale.setDefault(current); 210 } 211 212 final int NARGS = 2; 213 for (int mask = 0; mask < (1 << NARGS)-1; mask++) { 214 Object[] data = getNpeArgs(NARGS, mask); 215 try { 216 Locale loc = CONTROL.getFallbackLocale((String) data[0], (Locale) data[1]); 217 error("getFallbackLocale(%s, %s) doesn't throw NPE.%n", data[0], data[1]); 218 } catch (NullPointerException e) { 219 } 220 } 221 } 222 testNewBundle()223 private static void testNewBundle() { 224 int testNo = 0; 225 ResourceBundle rb = null; 226 try { 227 testNo = 1; 228 rb = CONTROL.newBundle("StressOut", Locale.JAPANESE, 229 PROPERTIES, LOADER, false); 230 String s = rb.getString("data"); 231 if (!s.equals("Japan")) { 232 error("newBundle: #%d got %s, expected Japan%n", testNo, s); 233 } 234 235 testNo = 2; 236 rb = CONTROL.newBundle("TestResourceRB", new Locale(""), 237 CLAZZ, LOADER, false); 238 s = rb.getString("type"); 239 if (!s.equals(CLAZZ)) { 240 error("newBundle: #%d got %s, expected %s%n", testNo, s, CLAZZ); 241 } 242 } catch (Throwable e) { 243 error("newBundle: #%d threw %s%n", testNo, e); 244 e.printStackTrace(); 245 } 246 247 // Test exceptions 248 249 try { 250 // MalformedDataRB contains an invalid Unicode notation which 251 // causes to throw an IllegalArgumentException. 252 rb = CONTROL.newBundle("MalformedDataRB", Locale.ENGLISH, 253 PROPERTIES, LOADER, false); 254 error("newBundle: doesn't throw IllegalArgumentException with malformed data."); 255 } catch (IllegalArgumentException iae) { 256 } catch (Exception e) { 257 error("newBundle: threw %s%n", e); 258 } 259 260 try { 261 rb = CONTROL.newBundle("StressOut", Locale.JAPANESE, 262 "foo.bar", LOADER, false); 263 error("newBundle: doesn't throw IllegalArgumentException with invalid format."); 264 } catch (IllegalArgumentException iae) { 265 } catch (Exception e) { 266 error("newBundle: threw %s%n", e); 267 } 268 269 try { 270 rb = CONTROL.newBundle("NonResourceBundle", new Locale(""), 271 "java.class", LOADER, false); 272 error("newBundle: doesn't throw ClassCastException with a non-ResourceBundle subclass."); 273 } catch (ClassCastException cce) { 274 } catch (Exception e) { 275 error("newBundle: threw %s%n", e); 276 } 277 278 // NPE test 279 final int NARGS = 4; 280 for (int mask = 0; mask < (1 << NARGS)-1; mask++) { 281 Object[] data = getNpeArgs(NARGS, mask); 282 Locale loc = (Locale) data[1]; 283 try { 284 rb = CONTROL.newBundle((String) data[0], loc, 285 (String) data[2], (ClassLoader) data[3], 286 false); 287 error("newBundle(%s, %s, %s, %s, false) doesn't throw NPE.%n", 288 data[0], toString(loc), data[2], data[3]); 289 } catch (NullPointerException npe) { 290 } catch (Exception e) { 291 error("newBundle(%s, %s, %s, %s, false) threw %s.%n", 292 data[0], toString(loc), data[2], data[3], e); 293 } 294 } 295 } 296 testGetTimeToLive()297 private static void testGetTimeToLive() { 298 long ttl = CONTROL.getTimeToLive("any", Locale.US); 299 if (ttl != CONTROL.TTL_NO_EXPIRATION_CONTROL) { 300 error("getTimeToLive: got %d, expected %d%n", ttl, 301 CONTROL.TTL_NO_EXPIRATION_CONTROL); 302 } 303 final int NARGS = 2; 304 for (int mask = 0; mask < (1 << NARGS)-1; mask++) { 305 Object[] data = getNpeArgs(NARGS, mask); 306 try { 307 ttl = CONTROL.getTimeToLive((String) data[0], (Locale) data[1]); 308 error("getTimeToLive(%s, %s) doesn't throw NPE.%n", data[0], data[1]); 309 } catch (NullPointerException e) { 310 } 311 } 312 } 313 314 // The functionality of needsReload is tested by 315 // ExpirationTest.sh. Only parameter checking is tested here. testNeedsReload()316 private static void testNeedsReload() { 317 long loadTime = System.currentTimeMillis(); 318 319 // NPE test 320 final int NARGS = 5; 321 for (int mask = 0; mask < (1 << NARGS)-1; mask++) { 322 Object[] data = getNpeArgs(NARGS, mask); 323 Locale loc = (Locale) data[1]; 324 try { 325 boolean b = CONTROL.needsReload((String) data[0], loc, 326 (String) data[2], (ClassLoader) data[3], 327 (ResourceBundle) data[4], loadTime); 328 error("needsReload(%s, %s, %s, %s, %s, loadTime) doesn't throw NPE.%n", 329 data[0], toString(loc), data[2], data[3], data[4]); 330 } catch (NullPointerException e) { 331 } 332 } 333 } 334 testToBundleName()335 private static void testToBundleName() { 336 final String name = "J2SE"; 337 Map<Locale, String> bundleNames = new HashMap<Locale, String>(); 338 bundleNames.put(new Locale("ja", "JP", "YOK"), 339 name + "_" + "ja" + "_" + "JP" + "_" + "YOK"); 340 bundleNames.put(new Locale("ja", "JP"), 341 name + "_" + "ja" + "_" + "JP"); 342 bundleNames.put(new Locale("ja"), 343 name + "_" + "ja"); 344 bundleNames.put(new Locale("ja", "", "YOK"), 345 name + "_" + "ja" + "_" + "" + "_" + "YOK"); 346 bundleNames.put(new Locale("", "JP", "YOK"), 347 name + "_" + "" + "_" + "JP" + "_" + "YOK"); 348 bundleNames.put(new Locale("", "", "YOK"), 349 name + "_" + "" + "_" + "" + "_" + "YOK"); 350 bundleNames.put(new Locale("", "JP"), 351 name + "_" + "" + "_" + "JP"); 352 bundleNames.put(new Locale(""), 353 name); 354 355 for (Locale locale : bundleNames.keySet()) { 356 String bn = CONTROL.toBundleName(name, locale); 357 String expected = bundleNames.get(locale); 358 if (!bn.equals(expected)) { 359 error("toBundleName: got %s, expected %s%n", bn, expected); 360 } 361 } 362 363 final int NARGS = 2; 364 for (int mask = 0; mask < (1 << NARGS)-1; mask++) { 365 Object[] data = getNpeArgs(NARGS, mask); 366 try { 367 String s = CONTROL.toBundleName((String) data[0], (Locale) data[1]); 368 error("toBundleName(%s, %s) doesn't throw NPE.%n", data[0], data[1]); 369 } catch (NullPointerException e) { 370 } 371 } 372 } 373 testToResourceName()374 private static void testToResourceName() { 375 String[][] names = { 376 // bundleName, suffix, expected result 377 { "com.sun.J2SE", "xml", "com/sun/J2SE.xml" }, 378 { ".J2SE", "xml", "/J2SE.xml" }, 379 { "J2SE", "xml", "J2SE.xml" }, 380 { "com/sun/J2SE", "xml", "com/sun/J2SE.xml" }, 381 { "com.sun.J2SE", "", "com/sun/J2SE." }, 382 { ".", "", "/." }, 383 { "", "", "." }, 384 385 // data for NPE tests 386 { null, "any", null }, 387 { "any", null, null }, 388 { null, null, null }, 389 }; 390 391 for (String[] data : names) { 392 String result = null; 393 boolean npeThrown = false; 394 try { 395 result = CONTROL.toResourceName(data[0], data[1]); 396 } catch (NullPointerException npe) { 397 npeThrown = true; 398 } 399 String expected = data[2]; 400 if (expected != null) { 401 if (!result.equals(expected)) { 402 error("toResourceName: got %s, expected %s%n", result, data[2]); 403 } 404 } else { 405 if (!npeThrown) { 406 error("toResourceName(%s, %s) doesn't throw NPE.%n", data[0], data[1]); 407 } 408 } 409 } 410 } 411 412 /** 413 * Produces permutations argument data that contains at least one 414 * null. 415 */ getNpeArgs(int length, int mask)416 private static Object[] getNpeArgs(int length, int mask) { 417 Object[] data = new Object[length]; 418 for (int i = 0; i < length; i++) { 419 if ((mask & (1 << i)) == 0) { 420 data[i] = null; 421 } else { 422 data[i] = FULLARGS[i]; 423 } 424 } 425 return data; 426 } 427 toString(Locale loc)428 private static String toString(Locale loc) { 429 if (loc == null) 430 return "null"; 431 return "\"" + loc.getLanguage() + "_" + loc.getCountry() + "_" + loc.getVariant() + "\""; 432 } 433 error(String msg)434 private static void error(String msg) { 435 System.out.println(msg); 436 errors++; 437 } 438 error(String fmt, Object... args)439 private static void error(String fmt, Object... args) { 440 System.out.printf(fmt, args); 441 errors++; 442 } 443 } 444