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 4049325 4073127 4083270 4106034 4108126
  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 
  64 import java.text.*;
  65 import java.util.*;
  66 import java.io.*;
  67 
  68 public class ResourceBundleTest extends RBTestFmwk {
  69     public static void main(String[] args) throws Exception {
  70         new ResourceBundleTest().run(args);
  71     }
  72 
  73     public ResourceBundleTest() {
  74         makePropertiesFile();
  75     }
  76 
  77     public void TestResourceBundle() {
  78         Locale  saveDefault = Locale.getDefault();
  79         Locale.setDefault(new Locale("fr", "FR"));
  80 
  81         // load up the resource bundle, and make sure we got the right one
  82         ResourceBundle  bundle = ResourceBundle.getBundle("TestResource");
  83         if (!bundle.getClass().getName().equals("TestResource_fr"))
  84             errln("Expected TestResource_fr, got " + bundle.getClass().getName());
  85 
  86         // these resources are defines in ResourceBundle_fr
  87         String  test1 = bundle.getString("Time");
  88         if (!test1.equals("Time keeps on slipping..."))
  89             errln("TestResource_fr returned wrong value for \"Time\":  got " + test1);
  90 
  91         test1 = bundle.getString("For");
  92         if (!test1.equals("Four score and seven years ago..."))
  93             errln("TestResource_fr returned wrong value for \"For\":  got " + test1);
  94 
  95         String[] test2 = bundle.getStringArray("All");
  96         if (test2.length != 4)
  97             errln("TestResource_fr returned wrong number of elements for \"All\": got " + test2.length);
  98         else if (!test2[0].equals("'Twas brillig, and the slithy toves") ||
  99                  !test2[1].equals("Did gyre and gimble in the wabe.") ||
 100                  !test2[2].equals("All mimsy were the borogoves,") ||
 101                  !test2[3].equals("And the mome raths outgrabe."))
 102             errln("TestResource_fr returned the wrong value for one of the elements in \"All\"");
 103 
 104         Object  test3 = bundle.getObject("Good");
 105         if (test3 == null || test3.getClass() != Integer.class)
 106             errln("TestResource_fr returned an object of the wrong class for \"Good\"");
 107         else if (((Integer)test3).intValue() != 3)
 108             errln("TestResource_fr returned the wrong value for \"Good\": got " + test3);
 109 
 110         // This resource is defined in TestResource and inherited by TestResource_fr
 111         test2 = bundle.getStringArray("Men");
 112         if (test2.length != 3)
 113             errln("TestResource_fr returned wrong number of elements for \"Men\": got " + test2.length);
 114         else if (!test2[0].equals("1") ||
 115                  !test2[1].equals("2") ||
 116                  !test2[2].equals("C"))
 117             errln("TestResource_fr returned the wrong value for one of the elements in \"All\"");
 118 
 119         // This resource is defined in neither TestResource not TestResource_fr
 120         try {
 121             test3 = bundle.getObject("Is");
 122             errln("TestResource_fr returned a value for \"Is\" when it shouldn't: got " + test3);
 123         }
 124         catch (MissingResourceException e) {
 125         }
 126 
 127         String[] keys = { "Now", "Time", "For", "All", "Good", "Men", "Come" };
 128         checkKeys(bundle.getKeys(),  keys);
 129 
 130         Locale.setDefault(saveDefault);
 131     }
 132 
 133     public void TestListResourceBundle() {
 134         // load up the resource and check to make sure we got the right class
 135         // (we don't define be_BY or be, so we fall back on the root default)
 136         ResourceBundle  bundle = ResourceBundle.getBundle("TestResource",
 137                             new Locale("be", "BY"));
 138         if (!bundle.getClass().getName().equals("TestResource"))
 139             errln("Expected TestResource, got " + bundle.getClass().getName());
 140 
 141         doListResourceBundleTest(bundle);
 142     }
 143 
 144     /**
 145      * @bug 4073127
 146      * Repeat TestListResourceBundle on TestResource_it, which is a ListResourceBundle
 147      * with NO contents.  It should gracefully inherit everything from the root
 148      * TestResource.
 149      */
 150     public void TestEmptyListResourceBundle() {
 151         ResourceBundle bundle = ResourceBundle.getBundle("TestResource",
 152                             new Locale("it", "IT"));
 153         doListResourceBundleTest(bundle);
 154     }
 155 
 156     private void doListResourceBundleTest(ResourceBundle bundle) {
 157         // load up the resource and check to make sure we got the right class
 158         // all of these resources are defined in TestResource; it doesn' inherit from anybody
 159         String  test1 = bundle.getString("Now");
 160         if (!test1.equals("Now is the time for all..."))
 161             errln("TestResource returned wrong value for \"Now\":  got " + test1);
 162 
 163         test1 = bundle.getString("Time");
 164         if (!test1.equals("Howdy Doody Time!"))
 165             errln("TestResource returned wrong value for \"Time\":  got " + test1);
 166 
 167         test1 = bundle.getString("Come");
 168         if (!test1.equals("Come into my parlor..."))
 169             errln("TestResource returned wrong value for \"Come\":  got " + test1);
 170 
 171         Object  test3 = bundle.getObject("Good");
 172         if (test3 == null || test3.getClass() != Integer.class)
 173             errln("TestResource returned an object of the wrong class for \"Good\"");
 174         else if (((Integer)test3).intValue() != 27)
 175             errln("TestResource returned the wrong value for \"Good\": got " + test3);
 176 
 177         String[] test2 = bundle.getStringArray("Men");
 178         if (test2.length != 3)
 179             errln("TestResource returned wrong number of elements for \"Men\": got " + test2.length);
 180         else if (!test2[0].equals("1") ||
 181                  !test2[1].equals("2") ||
 182                  !test2[2].equals("C"))
 183             errln("TestResource returned the wrong value for one of the elements in \"All\"");
 184 
 185         // this item isn't defined in TestResource
 186         try {
 187             test3 = bundle.getObject("All");
 188             errln("TestResource_en returned a value for \"All\" when it shouldn't: got " + test3);
 189         }
 190         catch (MissingResourceException e) {
 191         }
 192 
 193         String[] keys = { "Now", "Time", "Good", "Men", "Come" };
 194         checkKeys(bundle.getKeys(), keys);
 195     }
 196 
 197     /**
 198      * @bug 4049325
 199      * @ summary Bug 4049325 says ResourceBundle.findBundle() uses a hard-coded '/' as
 200      * the directory separator when searching for properties files.  Interestingly, it
 201      * still works on my NT installation.  I can't tell whether this is a required
 202      * property of all Java implementations (the magic appears to happen ClassLoader.
 203      * getResourceAsStream(), which is a native function) or a lucky property of my
 204      * particular implementation.  If this bug regresses, this test may still pass
 205      * because a lower-level facility translates the / to the platform-specific separator
 206      * for us.
 207      */
 208     public void TestPropertyResourceBundle() {
 209         ResourceBundle  bundle = ResourceBundle.getBundle("TestResource",
 210                             new Locale("es", "ES"));
 211 
 212         // these resources are defined in TestResource_es.properties
 213         String  test = bundle.getString("Now");
 214         if (!test.equals("How now brown cow"))
 215             errln("TestResource_es returned wrong value for \"Now\":  got " + test);
 216 
 217         test = bundle.getString("Is");
 218         if (!test.equals("Is there a dog?"))
 219             errln("TestResource_es returned wrong value for \"Is\":  got " + test);
 220 
 221         test = bundle.getString("The");
 222         if (!test.equals("The rain in Spain"))
 223             errln("TestResource_es returned wrong value for \"The\":  got " + test);
 224 
 225         test = bundle.getString("Time");
 226         if (!test.equals("Time marches on..."))
 227             errln("TestResource_es returned wrong value for \"Time\":  got " + test);
 228 
 229         // this resource is defined in TestResource and inherited by TestResource_es
 230         String[] test2 = bundle.getStringArray("Men");
 231         if (test2.length != 3)
 232             errln("TestResource returned wrong number of elements for \"Men\": got " + test2.length);
 233         else if (!test2[0].equals("1") ||
 234                  !test2[1].equals("2") ||
 235                  !test2[2].equals("C"))
 236             errln("TestResource returned the wrong value for one of the elements in \"All\"");
 237 
 238         // this resource is defined in neither TestResource nor TestResource_es
 239         try {
 240             test = bundle.getString("All");
 241             errln("TestResource_es returned a value for \"All\" when it shouldn't: got " + test);
 242         }
 243         catch (MissingResourceException e) {
 244         }
 245 
 246         String[] keys = { "Now", "Is", "The", "Time", "Good", "Men", "Come" };
 247         checkKeys(bundle.getKeys(), keys);
 248     }
 249 
 250     /**
 251      * @bug 4108126
 252      */
 253     public void TestGetLocale() {
 254         // try to find TestResource_fr_CH.  Should get fr_CH as its locale
 255         ResourceBundle test = ResourceBundle.getBundle("TestResource",
 256                         new Locale("fr", "CH", ""));
 257         Locale locale = test.getLocale();
 258         if (!(locale.getLanguage().equals("fr")) || !(locale.getCountry().equals("CH")))
 259             errln("Actual locale for TestResource_fr_CH should have been fr_CH, got " + locale);
 260 
 261         // try to find TestResource_fr_BE, which doesn't exist.  Should get fr as its locale
 262         test = ResourceBundle.getBundle("TestResource",
 263                         new Locale("fr", "BE", ""));
 264         locale = test.getLocale();
 265         if (!(locale.getLanguage().equals("fr")) || !(locale.getCountry().equals("")))
 266             errln("Actual locale for TestResource_fr_BE should have been fr, got " + locale);
 267 
 268         // try to find TestResource_iw_IL, which doesn't exist.  Should get root locale
 269         // as its locale
 270         test = ResourceBundle.getBundle("TestResource",
 271                         new Locale("iw", "IL", ""));
 272         locale = test.getLocale();
 273         if (!(locale.getLanguage().equals("")) || !(locale.getCountry().equals("")))
 274             errln("Actual locale for TestResource_iw_IL should have been the root locale, got "
 275                             + locale);
 276     }
 277 
 278     /*
 279      * @bug 4083270
 280      */
 281     public void TestNonSubclass() {
 282         // ResourceBundle.getBundle should never return an object that isn't an instance
 283         // of ResourceBundle or one of its subclasses.  We have a class called FakeTestResource
 284         // in this package that isn't a ResourceBundle.  If we get that back, we barf.
 285         // (Actually, at the time I fixed this bug, getResource() would throw a
 286         // ClassCastException in that case.)
 287         // There's also a properties file called FakeTestResource; we should get back a
 288         // PropertyResourceBundle pointing to that file.
 289         Object test1 = ResourceBundle.getBundle("FakeTestResource",
 290                 Locale.US);
 291 
 292         if (!(test1 instanceof ResourceBundle))
 293             errln("Got back a " + test1.getClass().getName() + " instead of a PropertyResourceBundle when looking for FakeTestResource.");
 294 
 295         ResourceBundle test = (ResourceBundle)test1;
 296 
 297         // there's also a properties file called FakeTestResource.  getBundle() should
 298         // find it, and it should have the following contents
 299         String message = test.getString("message");
 300         if (!message.equals("Hello!"))
 301             errln("Supposedly found FakeTestResource.properties, but it had the wrong contents.");
 302     }
 303 
 304     /*
 305      * @bug 4106034
 306      */
 307     public void TestErrorMessage() {
 308         // Ensure that the message produced by the exception thrown
 309         // by ResourceBundle.getObject contains both the class name and
 310         // the key name.
 311         final String className = "TestResource";
 312         final String keyName = "DontGetThis";
 313         ResourceBundle bundle = ResourceBundle.getBundle(className,
 314                             new Locale("it", "IT"));
 315         try {
 316             Object o = bundle.getObject(keyName);
 317             errln(bundle.getClass().getName()+" returned a value for tag \""+keyName+"\" when it should have thrown an exception.  It returned "+o);
 318         } catch (MissingResourceException e) {
 319             String message = e.getMessage();
 320             boolean found = false;
 321             if (message.indexOf(className) < 0) {
 322                     errln("MissingResourceException error message did not contain class name.");
 323             }
 324             if (message.indexOf(keyName) < 0) {
 325                     errln("MissingResourceException error message did not contain resource key name.");
 326             }
 327         }
 328     }
 329 
 330 
 331     private void makePropertiesFile() {
 332         try {
 333             //
 334             // The getProperty call is to ensure that this test will work with
 335             // the JTREG test harness.  When running in the harness, the current
 336             // directory is often set to someplace that isn't on the CLASSPATH,
 337             // so we can't just create the properties files in the current
 338             // directory.  But the harness uses the "test.classes" property to
 339             // tell us where the classes directory is.
 340             //
 341             String classesDir = System.getProperty("test.classes", ".");
 342             File    file = new File(classesDir, "TestResource_es.properties");
 343             if (!file.exists()) {
 344                 FileOutputStream stream = new FileOutputStream(file);
 345                 Properties  props = new Properties();
 346 
 347                 props.put("Now", "How now brown cow");
 348                 props.put("Is", "Is there a dog?");
 349                 props.put("The", "The rain in Spain");
 350                 props.put("Time", "Time marches on...");
 351 
 352                 props.save(stream, "Test property list");
 353 
 354                 stream.close();
 355             }
 356 
 357             file = new File(classesDir, "FakeTestResource.properties");
 358             if (!file.exists()) {
 359                 FileOutputStream stream = new FileOutputStream(file);
 360                 Properties props = new Properties();
 361 
 362                 props.put("message", "Hello!");
 363 
 364                 props.save(stream, "Test property list");
 365 
 366                 stream.close();
 367             }
 368         }
 369         catch (java.io.IOException e) {
 370             errln("Got exception: " + e);
 371         }
 372     }
 373 
 374     private void checkKeys(Enumeration testKeys, String[] expectedKeys) {
 375         Hashtable   hash = new Hashtable();
 376         String      element;
 377         int         elementCount = 0;
 378 
 379         for (int i=0; i < expectedKeys.length; i++)
 380             hash.put(expectedKeys[i], expectedKeys[i]);
 381 
 382         while (testKeys.hasMoreElements()) {
 383             element = (String)testKeys.nextElement();
 384             elementCount++;
 385             if (!hash.containsKey(element))
 386                 errln(element + " missing from key list.");
 387         }
 388 
 389         if (elementCount != expectedKeys.length)
 390             errln("Wrong number of elements in key list: expected " + expectedKeys.length +
 391                 " got " + elementCount);
 392     }
 393 }