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