/*
 * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
/*
    @test
    @bug 4049325 4073127 4083270 4106034 4108126
    @summary test Resource Bundle
    @build TestResource TestResource_de TestResource_fr TestResource_fr_CH
    @build TestResource_it FakeTestResource
    @run main ResourceBundleTest
*/
/*
 *
 *
 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
 *
 * Portions copyright (c) 2007 Sun Microsystems, Inc.
 * All Rights Reserved.
 *
 * The original version of this source code and documentation
 * is copyrighted and owned by Taligent, Inc., a wholly-owned
 * subsidiary of IBM. These materials are provided under terms
 * of a License Agreement between Taligent and Sun. This technology
 * is protected by multiple US and International patents.
 *
 * This notice and attribution to Taligent may not be removed.
 * Taligent is a registered trademark of Taligent, Inc.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 */

import java.text.*;
import java.util.*;
import java.io.*;

public class ResourceBundleTest extends RBTestFmwk {
    public static void main(String[] args) throws Exception {
        new ResourceBundleTest().run(args);
    }

    public ResourceBundleTest() {
        makePropertiesFile();
    }

    public void TestResourceBundle() {
        Locale  saveDefault = Locale.getDefault();
        Locale.setDefault(new Locale("fr", "FR"));

        // load up the resource bundle, and make sure we got the right one
        ResourceBundle  bundle = ResourceBundle.getBundle("TestResource");
        if (!bundle.getClass().getName().equals("TestResource_fr"))
            errln("Expected TestResource_fr, got " + bundle.getClass().getName());

        // these resources are defines in ResourceBundle_fr
        String  test1 = bundle.getString("Time");
        if (!test1.equals("Time keeps on slipping..."))
            errln("TestResource_fr returned wrong value for \"Time\":  got " + test1);

        test1 = bundle.getString("For");
        if (!test1.equals("Four score and seven years ago..."))
            errln("TestResource_fr returned wrong value for \"For\":  got " + test1);

        String[] test2 = bundle.getStringArray("All");
        if (test2.length != 4)
            errln("TestResource_fr returned wrong number of elements for \"All\": got " + test2.length);
        else if (!test2[0].equals("'Twas brillig, and the slithy toves") ||
                 !test2[1].equals("Did gyre and gimble in the wabe.") ||
                 !test2[2].equals("All mimsy were the borogoves,") ||
                 !test2[3].equals("And the mome raths outgrabe."))
            errln("TestResource_fr returned the wrong value for one of the elements in \"All\"");

        Object  test3 = bundle.getObject("Good");
        if (test3 == null || test3.getClass() != Integer.class)
            errln("TestResource_fr returned an object of the wrong class for \"Good\"");
        else if (((Integer)test3).intValue() != 3)
            errln("TestResource_fr returned the wrong value for \"Good\": got " + test3);

        // This resource is defined in TestResource and inherited by TestResource_fr
        test2 = bundle.getStringArray("Men");
        if (test2.length != 3)
            errln("TestResource_fr returned wrong number of elements for \"Men\": got " + test2.length);
        else if (!test2[0].equals("1") ||
                 !test2[1].equals("2") ||
                 !test2[2].equals("C"))
            errln("TestResource_fr returned the wrong value for one of the elements in \"All\"");

        // This resource is defined in neither TestResource not TestResource_fr
        try {
            test3 = bundle.getObject("Is");
            errln("TestResource_fr returned a value for \"Is\" when it shouldn't: got " + test3);
        }
        catch (MissingResourceException e) {
        }

        String[] keys = { "Now", "Time", "For", "All", "Good", "Men", "Come" };
        checkKeys(bundle.getKeys(),  keys);

        Locale.setDefault(saveDefault);
    }

    public void TestListResourceBundle() {
        // load up the resource and check to make sure we got the right class
        // (we don't define be_BY or be, so we fall back on the root default)
        ResourceBundle  bundle = ResourceBundle.getBundle("TestResource",
                            new Locale("be", "BY"));
        if (!bundle.getClass().getName().equals("TestResource"))
            errln("Expected TestResource, got " + bundle.getClass().getName());

        doListResourceBundleTest(bundle);
    }

    /**
     * @bug 4073127
     * Repeat TestListResourceBundle on TestResource_it, which is a ListResourceBundle
     * with NO contents.  It should gracefully inherit everything from the root
     * TestResource.
     */
    public void TestEmptyListResourceBundle() {
        ResourceBundle bundle = ResourceBundle.getBundle("TestResource",
                            new Locale("it", "IT"));
        doListResourceBundleTest(bundle);
    }

    private void doListResourceBundleTest(ResourceBundle bundle) {
        // load up the resource and check to make sure we got the right class
        // all of these resources are defined in TestResource; it doesn' inherit from anybody
        String  test1 = bundle.getString("Now");
        if (!test1.equals("Now is the time for all..."))
            errln("TestResource returned wrong value for \"Now\":  got " + test1);

        test1 = bundle.getString("Time");
        if (!test1.equals("Howdy Doody Time!"))
            errln("TestResource returned wrong value for \"Time\":  got " + test1);

        test1 = bundle.getString("Come");
        if (!test1.equals("Come into my parlor..."))
            errln("TestResource returned wrong value for \"Come\":  got " + test1);

        Object  test3 = bundle.getObject("Good");
        if (test3 == null || test3.getClass() != Integer.class)
            errln("TestResource returned an object of the wrong class for \"Good\"");
        else if (((Integer)test3).intValue() != 27)
            errln("TestResource returned the wrong value for \"Good\": got " + test3);

        String[] test2 = bundle.getStringArray("Men");
        if (test2.length != 3)
            errln("TestResource returned wrong number of elements for \"Men\": got " + test2.length);
        else if (!test2[0].equals("1") ||
                 !test2[1].equals("2") ||
                 !test2[2].equals("C"))
            errln("TestResource returned the wrong value for one of the elements in \"All\"");

        // this item isn't defined in TestResource
        try {
            test3 = bundle.getObject("All");
            errln("TestResource_en returned a value for \"All\" when it shouldn't: got " + test3);
        }
        catch (MissingResourceException e) {
        }

        String[] keys = { "Now", "Time", "Good", "Men", "Come" };
        checkKeys(bundle.getKeys(), keys);
    }

    /**
     * @bug 4049325
     * @ summary Bug 4049325 says ResourceBundle.findBundle() uses a hard-coded '/' as
     * the directory separator when searching for properties files.  Interestingly, it
     * still works on my NT installation.  I can't tell whether this is a required
     * property of all Java implementations (the magic appears to happen ClassLoader.
     * getResourceAsStream(), which is a native function) or a lucky property of my
     * particular implementation.  If this bug regresses, this test may still pass
     * because a lower-level facility translates the / to the platform-specific separator
     * for us.
     */
    public void TestPropertyResourceBundle() {
        ResourceBundle  bundle = ResourceBundle.getBundle("TestResource",
                            new Locale("es", "ES"));

        // these resources are defined in TestResource_es.properties
        String  test = bundle.getString("Now");
        if (!test.equals("How now brown cow"))
            errln("TestResource_es returned wrong value for \"Now\":  got " + test);

        test = bundle.getString("Is");
        if (!test.equals("Is there a dog?"))
            errln("TestResource_es returned wrong value for \"Is\":  got " + test);

        test = bundle.getString("The");
        if (!test.equals("The rain in Spain"))
            errln("TestResource_es returned wrong value for \"The\":  got " + test);

        test = bundle.getString("Time");
        if (!test.equals("Time marches on..."))
            errln("TestResource_es returned wrong value for \"Time\":  got " + test);

        // this resource is defined in TestResource and inherited by TestResource_es
        String[] test2 = bundle.getStringArray("Men");
        if (test2.length != 3)
            errln("TestResource returned wrong number of elements for \"Men\": got " + test2.length);
        else if (!test2[0].equals("1") ||
                 !test2[1].equals("2") ||
                 !test2[2].equals("C"))
            errln("TestResource returned the wrong value for one of the elements in \"All\"");

        // this resource is defined in neither TestResource nor TestResource_es
        try {
            test = bundle.getString("All");
            errln("TestResource_es returned a value for \"All\" when it shouldn't: got " + test);
        }
        catch (MissingResourceException e) {
        }

        String[] keys = { "Now", "Is", "The", "Time", "Good", "Men", "Come" };
        checkKeys(bundle.getKeys(), keys);
    }

    /**
     * @bug 4108126
     */
    public void TestGetLocale() {
        // try to find TestResource_fr_CH.  Should get fr_CH as its locale
        ResourceBundle test = ResourceBundle.getBundle("TestResource",
                        new Locale("fr", "CH", ""));
        Locale locale = test.getLocale();
        if (!(locale.getLanguage().equals("fr")) || !(locale.getCountry().equals("CH")))
            errln("Actual locale for TestResource_fr_CH should have been fr_CH, got " + locale);

        // try to find TestResource_fr_BE, which doesn't exist.  Should get fr as its locale
        test = ResourceBundle.getBundle("TestResource",
                        new Locale("fr", "BE", ""));
        locale = test.getLocale();
        if (!(locale.getLanguage().equals("fr")) || !(locale.getCountry().equals("")))
            errln("Actual locale for TestResource_fr_BE should have been fr, got " + locale);

        // try to find TestResource_iw_IL, which doesn't exist.  Should get root locale
        // as its locale
        test = ResourceBundle.getBundle("TestResource",
                        new Locale("iw", "IL", ""));
        locale = test.getLocale();
        if (!(locale.getLanguage().equals("")) || !(locale.getCountry().equals("")))
            errln("Actual locale for TestResource_iw_IL should have been the root locale, got "
                            + locale);
    }

    /*
     * @bug 4083270
     */
    public void TestNonSubclass() {
        // ResourceBundle.getBundle should never return an object that isn't an instance
        // of ResourceBundle or one of its subclasses.  We have a class called FakeTestResource
        // in this package that isn't a ResourceBundle.  If we get that back, we barf.
        // (Actually, at the time I fixed this bug, getResource() would throw a
        // ClassCastException in that case.)
        // There's also a properties file called FakeTestResource; we should get back a
        // PropertyResourceBundle pointing to that file.
        Object test1 = ResourceBundle.getBundle("FakeTestResource",
                Locale.US);

        if (!(test1 instanceof ResourceBundle))
            errln("Got back a " + test1.getClass().getName() + " instead of a PropertyResourceBundle when looking for FakeTestResource.");

        ResourceBundle test = (ResourceBundle)test1;

        // there's also a properties file called FakeTestResource.  getBundle() should
        // find it, and it should have the following contents
        String message = test.getString("message");
        if (!message.equals("Hello!"))
            errln("Supposedly found FakeTestResource.properties, but it had the wrong contents.");
    }

    /*
     * @bug 4106034
     */
    public void TestErrorMessage() {
        // Ensure that the message produced by the exception thrown
        // by ResourceBundle.getObject contains both the class name and
        // the key name.
        final String className = "TestResource";
        final String keyName = "DontGetThis";
        ResourceBundle bundle = ResourceBundle.getBundle(className,
                            new Locale("it", "IT"));
        try {
            Object o = bundle.getObject(keyName);
            errln(bundle.getClass().getName()+" returned a value for tag \""+keyName+"\" when it should have thrown an exception.  It returned "+o);
        } catch (MissingResourceException e) {
            String message = e.getMessage();
            boolean found = false;
            if (message.indexOf(className) < 0) {
                    errln("MissingResourceException error message did not contain class name.");
            }
            if (message.indexOf(keyName) < 0) {
                    errln("MissingResourceException error message did not contain resource key name.");
            }
        }
    }


    private void makePropertiesFile() {
        try {
            //
            // The getProperty call is to ensure that this test will work with
            // the JTREG test harness.  When running in the harness, the current
            // directory is often set to someplace that isn't on the CLASSPATH,
            // so we can't just create the properties files in the current
            // directory.  But the harness uses the "test.classes" property to
            // tell us where the classes directory is.
            //
            String classesDir = System.getProperty("test.classes", ".");
            File    file = new File(classesDir, "TestResource_es.properties");
            if (!file.exists()) {
                FileOutputStream stream = new FileOutputStream(file);
                Properties  props = new Properties();

                props.put("Now", "How now brown cow");
                props.put("Is", "Is there a dog?");
                props.put("The", "The rain in Spain");
                props.put("Time", "Time marches on...");

                props.save(stream, "Test property list");

                stream.close();
            }

            file = new File(classesDir, "FakeTestResource.properties");
            if (!file.exists()) {
                FileOutputStream stream = new FileOutputStream(file);
                Properties props = new Properties();

                props.put("message", "Hello!");

                props.save(stream, "Test property list");

                stream.close();
            }
        }
        catch (java.io.IOException e) {
            errln("Got exception: " + e);
        }
    }

    private void checkKeys(Enumeration testKeys, String[] expectedKeys) {
        Hashtable   hash = new Hashtable();
        String      element;
        int         elementCount = 0;

        for (int i=0; i < expectedKeys.length; i++)
            hash.put(expectedKeys[i], expectedKeys[i]);

        while (testKeys.hasMoreElements()) {
            element = (String)testKeys.nextElement();
            elementCount++;
            if (!hash.containsKey(element))
                errln(element + " missing from key list.");
        }

        if (elementCount != expectedKeys.length)
            errln("Wrong number of elements in key list: expected " + expectedKeys.length +
                " got " + elementCount);
    }
}
