/*
 * Copyright 1999-2003 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 4227192
 * @summary This is a test of the restrictions on the parameters that may
 * be passed to the Proxy.getProxyClass method.
 * @author Peter Jones
 *
 * @build ClassRestrictions
 * @run main ClassRestrictions
 */

import java.lang.reflect.Proxy;
import java.net.URLClassLoader;

public class ClassRestrictions {

    public interface Bar {
        int foo();
    }

    public interface Baz {
        long foo();
    }

    interface Bashful {
        void foo();
    }

    public static void main(String[] args) {

        System.err.println(
            "\nTest of restrictions on parameters to Proxy.getProxyClass\n");

        try {
            ClassLoader loader = ClassLoader.getSystemClassLoader();
            Class[] interfaces;
            Class proxyClass;

            /*
             * All of the Class objects in the interfaces array must represent
             * interfaces, not classes or primitive types.
             */
            try {
                interfaces = new Class[] { Object.class };
                proxyClass = Proxy.getProxyClass(loader, interfaces);
                throw new RuntimeException(
                    "proxy class created with java.lang.Object as interface");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                System.err.println();
                // assume exception is for intended failure
            }
            try {
                interfaces = new Class[] { Integer.TYPE };
                proxyClass = Proxy.getProxyClass(loader, interfaces);
                throw new RuntimeException(
                    "proxy class created with int.class as interface");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                System.err.println();
                // assume exception is for intended failure
            }

            /*
             * No two elements in the interfaces array may refer to identical
             * Class objects.
             */
            try {
                interfaces = new Class[] { Bar.class, Bar.class };
                proxyClass = Proxy.getProxyClass(loader, interfaces);
                throw new RuntimeException(
                    "proxy class created with repeated interfaces");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                System.err.println();
                // assume exception is for intended failure
            }

            /*
             * All of the interfaces types must be visible by name though the
             * specified class loader.
             */
            ClassLoader altLoader = new URLClassLoader(
                ((URLClassLoader) loader).getURLs(), null);
            Class altBarClass;
            altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
            try {
                interfaces = new Class[] { altBarClass };
                proxyClass = Proxy.getProxyClass(loader, interfaces);
                throw new RuntimeException(
                    "proxy class created with interface " +
                    "not visible to class loader");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                System.err.println();
                // assume exception is for intended failure
            }

            /*
             * All non-public interfaces must be in the same package.
             */
            Class nonPublic1 = Bashful.class;
            Class nonPublic2 = null;
            String[] nonPublicInterfaces = new String[] {
                "java.awt.Conditional",
                "java.util.zip.ZipConstants",
                "javax.swing.GraphicsWrapper",
                "javax.swing.JPopupMenu$Popup",
                "javax.swing.JTable$Resizable2",
                "javax.swing.JTable$Resizable3",
                "javax.swing.ToolTipManager$Popup",
                "sun.audio.Format",
                "sun.audio.HaePlayable",
                "sun.tools.agent.StepConstants",
            };
            for (int i = 0; i < nonPublicInterfaces.length; i++) {
                try {
                    nonPublic2 = Class.forName(nonPublicInterfaces[i]);
                    break;
                } catch (ClassNotFoundException e) {
                }
            }
            if (nonPublic2 == null) {
                throw new RuntimeException(
                    "no second non-public interface found for test");
            }
            try {
                interfaces = new Class[] { nonPublic1, nonPublic2 };
                proxyClass = Proxy.getProxyClass(loader, interfaces);
                throw new RuntimeException(
                    "proxy class created with two non-public interfaces " +
                    "in different packages");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                System.err.println();
                // assume exception is for intended failure
            }

            /*
             * No two interfaces may each have a method with the same name and
             * parameter signature but different return type.
             */
            try {
                interfaces = new Class[] { Bar.class, Baz.class };
                proxyClass = Proxy.getProxyClass(loader, interfaces);
                throw new RuntimeException(
                    "proxy class created with conflicting methods");
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                System.err.println();
                // assume exception is for intended failure
            }

            /*
             * All components of this test have passed.
             */
            System.err.println("\nTEST PASSED");

        } catch (Exception e) {
            System.err.println("\nTEST FAILED:");
            e.printStackTrace();
            throw new RuntimeException("TEST FAILED: " + e.toString());
        }
    }
}
