1/* 2 * Copyright (c) 2007, 2017, 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 4049325 4073127 4083270 4106034 4108126 8027930 8171139 26 @summary test Resource Bundle 27 @build TestResource TestResource_de TestResource_fr TestResource_fr_CH 28 @build TestResource_it FakeTestResource 29 @run main ResourceBundleTest 30*/ 31/* 32 * 33 * 34 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved 35 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved 36 * 37 * Portions copyright (c) 2007 Sun Microsystems, Inc. 38 * All Rights Reserved. 39 * 40 * The original version of this source code and documentation 41 * is copyrighted and owned by Taligent, Inc., a wholly-owned 42 * subsidiary of IBM. These materials are provided under terms 43 * of a License Agreement between Taligent and Sun. This technology 44 * is protected by multiple US and International patents. 45 * 46 * This notice and attribution to Taligent may not be removed. 47 * Taligent is a registered trademark of Taligent, Inc. 48 * 49 * Permission to use, copy, modify, and distribute this software 50 * and its documentation for NON-COMMERCIAL purposes and without 51 * fee is hereby granted provided that this copyright notice 52 * appears in all copies. Please refer to the file "copyright.html" 53 * for further important copyright and licensing information. 54 * 55 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF 56 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 57 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 58 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR 59 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR 60 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. 61 * 62 */ 63 64import java.text.*; 65import java.util.*; 66import java.util.ResourceBundle.Control; 67import java.io.*; 68import java.net.URL; 69 70public class ResourceBundleTest extends RBTestFmwk { 71 public static void main(String[] args) throws Exception { 72 new ResourceBundleTest().run(args); 73 } 74 75 public ResourceBundleTest() { 76 makePropertiesFile(); 77 } 78 79 public void TestResourceBundle() { 80 Locale saveDefault = Locale.getDefault(); 81 Locale.setDefault(new Locale("fr", "FR")); 82 83 // load up the resource bundle, and make sure we got the right one 84 ResourceBundle bundle = ResourceBundle.getBundle("TestResource"); 85 if (!bundle.getClass().getName().equals("TestResource_fr")) 86 errln("Expected TestResource_fr, got " + bundle.getClass().getName()); 87 88 // these resources are defines in ResourceBundle_fr 89 String test1 = bundle.getString("Time"); 90 if (!test1.equals("Time keeps on slipping...")) 91 errln("TestResource_fr returned wrong value for \"Time\": got " + test1); 92 93 test1 = bundle.getString("For"); 94 if (!test1.equals("Four score and seven years ago...")) 95 errln("TestResource_fr returned wrong value for \"For\": got " + test1); 96 97 String[] test2 = bundle.getStringArray("All"); 98 if (test2.length != 4) 99 errln("TestResource_fr returned wrong number of elements for \"All\": got " + test2.length); 100 else if (!test2[0].equals("'Twas brillig, and the slithy toves") || 101 !test2[1].equals("Did gyre and gimble in the wabe.") || 102 !test2[2].equals("All mimsy were the borogoves,") || 103 !test2[3].equals("And the mome raths outgrabe.")) 104 errln("TestResource_fr returned the wrong value for one of the elements in \"All\""); 105 106 Object test3 = bundle.getObject("Good"); 107 if (test3 == null || test3.getClass() != Integer.class) 108 errln("TestResource_fr returned an object of the wrong class for \"Good\""); 109 else if (((Integer)test3).intValue() != 3) 110 errln("TestResource_fr returned the wrong value for \"Good\": got " + test3); 111 112 // This resource is defined in TestResource and inherited by TestResource_fr 113 test2 = bundle.getStringArray("Men"); 114 if (test2.length != 3) 115 errln("TestResource_fr returned wrong number of elements for \"Men\": got " + test2.length); 116 else if (!test2[0].equals("1") || 117 !test2[1].equals("2") || 118 !test2[2].equals("C")) 119 errln("TestResource_fr returned the wrong value for one of the elements in \"All\""); 120 121 // This resource is defined in neither TestResource not TestResource_fr 122 try { 123 test3 = bundle.getObject("Is"); 124 errln("TestResource_fr returned a value for \"Is\" when it shouldn't: got " + test3); 125 } 126 catch (MissingResourceException e) { 127 } 128 129 String[] keys = { "Now", "Time", "For", "All", "Good", "Men", "Come" }; 130 checkKeys(bundle.getKeys(), keys); 131 132 Locale.setDefault(saveDefault); 133 } 134 135 public void TestListResourceBundle() { 136 // load up the resource and check to make sure we got the right class 137 // (we don't define be_BY or be, so we fall back on the root default) 138 ResourceBundle bundle = ResourceBundle.getBundle("TestResource", 139 new Locale("be", "BY"), 140 Control.getNoFallbackControl(Control.FORMAT_DEFAULT)); 141 if (!bundle.getClass().getName().equals("TestResource")) 142 errln("Expected TestResource, got " + bundle.getClass().getName()); 143 144 doListResourceBundleTest(bundle); 145 } 146 147 /** 148 * @bug 4073127 149 * Repeat TestListResourceBundle on TestResource_it, which is a ListResourceBundle 150 * with NO contents. It should gracefully inherit everything from the root 151 * TestResource. 152 */ 153 public void TestEmptyListResourceBundle() { 154 ResourceBundle bundle = ResourceBundle.getBundle("TestResource", 155 new Locale("it", "IT")); 156 doListResourceBundleTest(bundle); 157 } 158 159 private void doListResourceBundleTest(ResourceBundle bundle) { 160 // load up the resource and check to make sure we got the right class 161 // all of these resources are defined in TestResource; it doesn' inherit from anybody 162 String test1 = bundle.getString("Now"); 163 if (!test1.equals("Now is the time for all...")) 164 errln("TestResource returned wrong value for \"Now\": got " + test1); 165 166 test1 = bundle.getString("Time"); 167 if (!test1.equals("Howdy Doody Time!")) 168 errln("TestResource returned wrong value for \"Time\": got " + test1); 169 170 test1 = bundle.getString("Come"); 171 if (!test1.equals("Come into my parlor...")) 172 errln("TestResource returned wrong value for \"Come\": got " + test1); 173 174 Object test3 = bundle.getObject("Good"); 175 if (test3 == null || test3.getClass() != Integer.class) 176 errln("TestResource returned an object of the wrong class for \"Good\""); 177 else if (((Integer)test3).intValue() != 27) 178 errln("TestResource returned the wrong value for \"Good\": got " + test3); 179 180 String[] test2 = bundle.getStringArray("Men"); 181 if (test2.length != 3) 182 errln("TestResource returned wrong number of elements for \"Men\": got " + test2.length); 183 else if (!test2[0].equals("1") || 184 !test2[1].equals("2") || 185 !test2[2].equals("C")) 186 errln("TestResource returned the wrong value for one of the elements in \"All\""); 187 188 // this item isn't defined in TestResource 189 try { 190 test3 = bundle.getObject("All"); 191 errln("TestResource_en returned a value for \"All\" when it shouldn't: got " + test3); 192 } 193 catch (MissingResourceException e) { 194 } 195 196 String[] keys = { "Now", "Time", "Good", "Men", "Come" }; 197 checkKeys(bundle.getKeys(), keys); 198 } 199 200 /** 201 * @bug 4049325 202 * @ summary Bug 4049325 says ResourceBundle.findBundle() uses a hard-coded '/' as 203 * the directory separator when searching for properties files. Interestingly, it 204 * still works on my NT installation. I can't tell whether this is a required 205 * property of all Java implementations (the magic appears to happen ClassLoader. 206 * getResourceAsStream(), which is a native function) or a lucky property of my 207 * particular implementation. If this bug regresses, this test may still pass 208 * because a lower-level facility translates the / to the platform-specific separator 209 * for us. 210 */ 211 public void TestPropertyResourceBundle() { 212 ResourceBundle bundle = ResourceBundle.getBundle("TestResource", 213 new Locale("es", "ES")); 214 215 // these resources are defined in TestResource_es.properties 216 String test = bundle.getString("Now"); 217 if (!test.equals("How now brown cow")) 218 errln("TestResource_es returned wrong value for \"Now\": got " + test); 219 220 test = bundle.getString("Is"); 221 if (!test.equals("Is there a dog?")) 222 errln("TestResource_es returned wrong value for \"Is\": got " + test); 223 224 test = bundle.getString("The"); 225 if (!test.equals("The rain in Spain")) 226 errln("TestResource_es returned wrong value for \"The\": got " + test); 227 228 test = bundle.getString("Time"); 229 if (!test.equals("Time marches on...")) 230 errln("TestResource_es returned wrong value for \"Time\": got " + test); 231 232 // this resource is defined in TestResource and inherited by TestResource_es 233 String[] test2 = bundle.getStringArray("Men"); 234 if (test2.length != 3) 235 errln("TestResource returned wrong number of elements for \"Men\": got " + test2.length); 236 else if (!test2[0].equals("1") || 237 !test2[1].equals("2") || 238 !test2[2].equals("C")) 239 errln("TestResource returned the wrong value for one of the elements in \"All\""); 240 241 // this resource is defined in neither TestResource nor TestResource_es 242 try { 243 test = bundle.getString("All"); 244 errln("TestResource_es returned a value for \"All\" when it shouldn't: got " + test); 245 } 246 catch (MissingResourceException e) { 247 } 248 249 String[] keys = { "Now", "Is", "The", "Time", "Good", "Men", "Come" }; 250 checkKeys(bundle.getKeys(), keys); 251 } 252 253 /** 254 * @bug 4108126 255 */ 256 public void TestGetLocale() { 257 // try to find TestResource_fr_CH. Should get fr_CH as its locale 258 ResourceBundle test = ResourceBundle.getBundle("TestResource", 259 new Locale("fr", "CH", "")); 260 Locale locale = test.getLocale(); 261 if (!(locale.getLanguage().equals("fr")) || !(locale.getCountry().equals("CH"))) 262 errln("Actual locale for TestResource_fr_CH should have been fr_CH, got " + locale); 263 264 // try to find TestResource_fr_BE, which doesn't exist. Should get fr as its locale 265 test = ResourceBundle.getBundle("TestResource", 266 new Locale("fr", "BE", "")); 267 locale = test.getLocale(); 268 if (!(locale.getLanguage().equals("fr")) || !(locale.getCountry().equals(""))) 269 errln("Actual locale for TestResource_fr_BE should have been fr, got " + locale); 270 271 // try to find TestResource_iw_IL, which doesn't exist. Should get root locale 272 // as its locale 273 test = ResourceBundle.getBundle("TestResource", 274 new Locale("iw", "IL", ""), 275 Control.getNoFallbackControl(Control.FORMAT_DEFAULT)); 276 locale = test.getLocale(); 277 if (!(locale.getLanguage().equals("")) || !(locale.getCountry().equals(""))) 278 errln("Actual locale for TestResource_iw_IL should have been the root locale, got " 279 + locale); 280 } 281 282 /* 283 * @bug 4083270 284 */ 285 public void TestNonSubclass() { 286 // ResourceBundle.getBundle should never return an object that isn't an instance 287 // of ResourceBundle or one of its subclasses. We have a class called FakeTestResource 288 // in this package that isn't a ResourceBundle. If we get that back, we barf. 289 // (Actually, at the time I fixed this bug, getResource() would throw a 290 // ClassCastException in that case.) 291 // There's also a properties file called FakeTestResource; we should get back a 292 // PropertyResourceBundle pointing to that file. 293 Object test1 = ResourceBundle.getBundle("FakeTestResource", 294 Locale.US); 295 296 if (!(test1 instanceof ResourceBundle)) 297 errln("Got back a " + test1.getClass().getName() + " instead of a PropertyResourceBundle when looking for FakeTestResource."); 298 299 ResourceBundle test = (ResourceBundle)test1; 300 301 // there's also a properties file called FakeTestResource. getBundle() should 302 // find it, and it should have the following contents 303 String message = test.getString("message"); 304 if (!message.equals("Hello!")) 305 errln("Supposedly found FakeTestResource.properties, but it had the wrong contents."); 306 } 307 308 /* 309 * @bug 4106034 310 */ 311 public void TestErrorMessage() { 312 // Ensure that the message produced by the exception thrown 313 // by ResourceBundle.getObject contains both the class name and 314 // the key name. 315 final String className = "TestResource"; 316 final String keyName = "DontGetThis"; 317 ResourceBundle bundle = ResourceBundle.getBundle(className, 318 new Locale("it", "IT")); 319 try { 320 Object o = bundle.getObject(keyName); 321 errln(bundle.getClass().getName()+" returned a value for tag \""+keyName+"\" when it should have thrown an exception. It returned "+o); 322 } catch (MissingResourceException e) { 323 String message = e.getMessage(); 324 boolean found = false; 325 if (message.indexOf(className) < 0) { 326 errln("MissingResourceException error message did not contain class name."); 327 } 328 if (message.indexOf(keyName) < 0) { 329 errln("MissingResourceException error message did not contain resource key name."); 330 } 331 } 332 } 333 334 /* 335 * @bug 8171139 336 * @summary Make sure clearCache() clears cached ResourceBundle instances 337 */ 338 public void TestClearCache() { 339 final String className = "TestResource"; 340 Locale loc = Locale.getDefault(); 341 342 // testing no-arg clearCache() 343 ResourceBundle rb1 = ResourceBundle.getBundle(className, loc); 344 ResourceBundle.clearCache(); 345 ResourceBundle rb2 = ResourceBundle.getBundle(className, loc); 346 if (rb1 == rb2) { 347 errln("clearCache(no-arg) did not clear cache"); 348 } 349 350 // clearCache() with a custom classloader 351 ClassLoader cl1 = new DummyClassLoader(); 352 rb1 = ResourceBundle.getBundle(className, loc, cl1); 353 if (rb1 == rb2) { 354 errln("Same bundle was returned for different class loaders"); 355 } 356 ResourceBundle.clearCache(cl1); 357 rb2= ResourceBundle.getBundle(className, loc, cl1); 358 if (rb1 == rb2) { 359 errln("clearCache(classLoader) did not clear cache"); 360 } 361 ClassLoader cl2 = new DummyClassLoader(); 362 rb1 = ResourceBundle.getBundle(className, loc, cl2); 363 if (rb1 == rb2) { 364 errln("Same bundle was returned for different class loaders"); 365 } 366 ResourceBundle.clearCache(cl1); 367 rb2 = ResourceBundle.getBundle(className, loc, cl2); 368 if (rb1 != rb2) { 369 errln("clearCache(classLoader) incorrectly cleared cache"); 370 } 371 } 372 373 private void makePropertiesFile() { 374 try { 375 // 376 // The getProperty call is to ensure that this test will work with 377 // the JTREG test harness. When running in the harness, the current 378 // directory is often set to someplace that isn't on the CLASSPATH, 379 // so we can't just create the properties files in the current 380 // directory. But the harness uses the "test.classes" property to 381 // tell us where the classes directory is. 382 // 383 String classesDir = System.getProperty("test.classes", "."); 384 File file = new File(classesDir, "TestResource_es.properties"); 385 if (!file.exists()) { 386 FileOutputStream stream = new FileOutputStream(file); 387 Properties props = new Properties(); 388 389 props.put("Now", "How now brown cow"); 390 props.put("Is", "Is there a dog?"); 391 props.put("The", "The rain in Spain"); 392 props.put("Time", "Time marches on..."); 393 394 props.save(stream, "Test property list"); 395 396 stream.close(); 397 } 398 399 file = new File(classesDir, "FakeTestResource.properties"); 400 if (!file.exists()) { 401 FileOutputStream stream = new FileOutputStream(file); 402 Properties props = new Properties(); 403 404 props.put("message", "Hello!"); 405 406 props.save(stream, "Test property list"); 407 408 stream.close(); 409 } 410 } 411 catch (java.io.IOException e) { 412 errln("Got exception: " + e); 413 } 414 } 415 416 private void checkKeys(Enumeration testKeys, String[] expectedKeys) { 417 Hashtable hash = new Hashtable(); 418 String element; 419 int elementCount = 0; 420 421 for (int i=0; i < expectedKeys.length; i++) 422 hash.put(expectedKeys[i], expectedKeys[i]); 423 424 while (testKeys.hasMoreElements()) { 425 element = (String)testKeys.nextElement(); 426 elementCount++; 427 if (!hash.containsKey(element)) 428 errln(element + " missing from key list."); 429 } 430 431 if (elementCount != expectedKeys.length) 432 errln("Wrong number of elements in key list: expected " + expectedKeys.length + 433 " got " + elementCount); 434 } 435 436 private static class DummyClassLoader extends ClassLoader { 437 public DummyClassLoader() { 438 super(DummyClassLoader.class.getClassLoader()); 439 } 440 441 public Class<?> loadClass(String name) throws ClassNotFoundException { 442 return DummyClassLoader.class.getClassLoader().loadClass(name); 443 } 444 445 public URL getResource(String name) { 446 return DummyClassLoader.class.getClassLoader().getResource(name); 447 } 448 449 public InputStream getResourceAsStream(String name) { 450 return DummyClassLoader.class.getClassLoader().getResourceAsStream(name); 451 } 452 } 453} 454