/*
 * 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  1.3 99/02/15
    @summary test Resource Bundle for bug 4179766
    @build Bug4179766Class Bug4179766Resource Bug4179766Getter
    @run main TestBug4179766
    @bug 4179766
*/
/*
 *
 *
 * (C) Copyright IBM Corp. 1996 - 1999 - 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.util.Hashtable;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.util.Hashtable;
import java.io.File;
import java.io.FileInputStream;

/**
 * This class tests the behavior of the ResourceBundle cache with
 * respect to ClassLoaders.  The same resource loaded by different
 * loaders should be cached as separate objects, one for each loader.
 * In order to test this behavior, this test constructs a custom
 * class loader to load its resources.  It does not delegate resource
 * loading to the system loader to load the class files, but loads
 * them from the current directory instead.  This is so that the
 * defining class loader for the resources is different.  If it
 * delegated to the system loader to load the resources, the
 * defining ClassLoader would be the same even though the initiating
 * loader differered, and the resource would only be cached once.
 */
public class TestBug4179766 extends RBTestFmwk {
    //hash code used by class loaders when sameHash is true
    private static final int SAME_HASH_CODE = 0;
    //the next unique hash code
    private static int nextHashCode = SAME_HASH_CODE + 1;
    //suffix on class files
    private static final String CLASS_SUFFIX = ".class";

    //generate a unique hashcode for a class loader
    private static synchronized int getNextHashCode() {
        return nextHashCode++;
    }

    public static void main(String[] args) throws Exception {
        //static links so all needed classes get compiled
        Object o1 = new Bug4179766Class();
        Object o2 = new Bug4179766Resource();
        new TestBug4179766().run(args);
    }

    /**
    * Ensure the resource cache is working correctly for a single
    * resource from a single loader.  If we get the same resource
    * from the same loader twice, we should get the same resource.
    */
    public void testCache() throws Exception {
        Loader loader = new Loader(false);
        ResourceBundle b1 = getResourceBundle(loader, "Bug4179766Resource");
        if (b1 == null) {
            errln("Resource not found: Bug4179766Resource");
        }
        ResourceBundle b2 = getResourceBundle(loader, "Bug4179766Resource");
        if (b2 == null) {
            errln("Resource not found: Bug4179766Resource");
        }
        printIDInfo("[bundle1]",b1);
        printIDInfo("[bundle2]",b2);
        if (b1 != b2) {
            errln("Different objects returned by same ClassLoader");
        }
    }

    /**
    * Test that loaders with the same hash key still
    * cache resources seperately
    */
    public void testSameHash() throws Exception {
        doTest(true);
    }

    /**
    * Test that loaders with different hash keys
    * cache resources seperately
    */
    public void testDifferentHash() throws Exception {
        doTest(false);
    }

    /**
     * Ensure that cached resources for different ClassLoaders
     * are cached seperately
     */
    private void doTest(boolean sameHash) throws Exception {
        ResourceBundle b1 = getResourceBundle(new Loader(sameHash), "Bug4179766Resource");
        if (b1 == null) {
           errln("Resource not found: Bug4179766Resource");
        }
        ResourceBundle b2 = getResourceBundle(new Loader(sameHash), "Bug4179766Resource");
        if (b2 == null) {
           errln("Resource not found: Bug4179766Resource");
        }
        printIDInfo("[bundle1]",b1);
        printIDInfo("[bundle2]",b2);
        if (b1 == b2) {
           errln("Same object returned by different ClassLoaders");
        }
    }

    /**
     * Get a resource using a specified class loader to load the resource
     */
    private ResourceBundle getResourceBundle(Loader loader, String name) throws Exception {
        try {
            Class c = loader.loadClass("Bug4179766Class");
            Bug4179766Getter test = (Bug4179766Getter)c.newInstance();
            return test.getResourceBundle(name);
        } catch (ClassNotFoundException e) {
            errln("Class not found by custom class loader: "+name);
            throw e;
        } catch (InstantiationException e) {
            errln("Error instantiating: "+name);
            throw e;
        } catch (IllegalAccessException e) {
            errln("IllegalAccessException instantiating: "+name);
            throw e;
        }
    }

    /**
     * Print information about an object
     * [message][object's identity][object's class][object's loader][loaders hash][loaders identity]
     */
    private void printIDInfo(String message, Object o) {
        if (o == null) {
            return;
        }
        Class c = o.getClass();
        ClassLoader l = c.getClassLoader();
        int hash = -1;
        if (l != null) {
            hash = l.hashCode();
        }
        logln(message + System.identityHashCode(o) + "  Class: " + c
                + "  ClassLoader: " + l + "  loaderHash: " + hash
                + "  loaderPrimHash: " + System.identityHashCode(l));
    }

    /**
     * A simple class loader that loads classes from the current
     * working directory.  The hash code of the loader can be
     * set to be either the loaders identity or 0, allowing several
     * loaders to have the same hashCode value.
     */
    public class Loader extends ClassLoader {
        private int thisHashCode;

        /**
         * Create a new loader
         */
        public Loader(boolean sameHash) {
            if (sameHash) {
                thisHashCode = SAME_HASH_CODE;
            } else {
                thisHashCode = getNextHashCode();
            }
        }

        /**
         * Return the hash code for this loader.
         */
        public int hashCode() {
            return thisHashCode;
        }

        /**
         * Get the data from the class file for the specified class.  If
         * the file can't be found, or the class is not one of the
         * special ones listed below, return null.
         *    Bug4179766Class
         *    Bug4179766Resource
         */
        private byte[] getClassData(String className) {
            boolean shouldLoad = className.equals("Bug4179766Class");
            shouldLoad = shouldLoad || className.equals("Bug4179766Resource");

            if (shouldLoad) {
                try {
                    File file = new File(System.getProperty("test.classes", "."), className+CLASS_SUFFIX);
                    FileInputStream fi = new FileInputStream(file);
                    byte[] result = new byte[fi.available()];
                    fi.read(result);
                    return result;
                } catch (Exception e) {
                    return null;
                }
            } else {
                return null;
            }
        }

        /**
         * Load a class.  Files we can load take preference over ones the system
         * can load.
         */
        public synchronized Class loadClass(String className, boolean resolveIt)
                throws ClassNotFoundException {

            Class result = findLoadedClass(className);
            if (result != null) {
                printInfo("        ***Returning cached class: "+className, result);
                return result;
            }

            byte[] classData = getClassData(className);
            if (classData == null) {
                //we don't have a local copy of this one
                return loadFromSystem(className);
            }

            result = defineClass(classData, 0, classData.length);
            if (result == null) {
                //there was an error defining the class
                return loadFromSystem(className);
            }

            if (resolveIt) {
                resolveClass(result);
            }

            printInfo("        ***Loaded local class: "+className, result);
            return result;
        }

        /**
         * Delegate loading to the system loader
         */
        private Class loadFromSystem(String className) throws ClassNotFoundException {
            try {
                Class result = super.findSystemClass(className);
                printInfo("        ***Returning system class: "+className, result);
                return result;
            } catch (ClassNotFoundException e) {
                printInfo("        ***Class not found: "+className, null);
                throw e;
            }
        }

        /**
         * Print information about a class that was loaded
         * [loader identity][message][class identity]
         */
        private void printInfo(String message, Class c) {
            if (c != null) {
                logln(""+System.identityHashCode(this)+"  "+message+"  "+System.identityHashCode(c));
            } else {
                logln(""+System.identityHashCode(this)+"  "+message);
            }
        }
    }
}
