/*
 * Copyright (c) 2007, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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);
            }
        }
    }
}
