/*
 * Copyright (c) 2003, 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
 * @bug 4950756
 * @summary Test that RequiredModelMBean.invoke will not invoke methods
 * from the RequiredModelMBean class itself if they are not in the
 * ModelMBeanInfo
 * @author Eamonn McManus
 * @run clean RequiredModelMBeanMethodTest
 * @run build RequiredModelMBeanMethodTest
 * @run main RequiredModelMBeanMethodTest
 */

import java.lang.reflect.*;
import javax.management.*;
import javax.management.modelmbean.*;

/*
 * We do the same test with a number of different operations:
 *
 * - A plain operation that is directed to the managed resource in the
 * usual way.  We give it some parameters so we can test that the
 * class loading logic for signature parameters is reasonable.
 *
 * - An operation (removeNotificationListener) that is directed to the
 * RequiredModelMBean itself.  We use this particular operation because
 * it will throw an exception, which allows us to check that it did in
 * fact execute.
 *
 * - An operation (load()) that has the same signature as a
 * RequiredModelMBean operation but is directed to the resource
 * because of a "class" field in the descriptor.
 *
 * - An operation (store()) that has the same signature as a
 * RequiredModelMBean operation but is directed to the resource
 * because of a "targetObject" field in the descriptor.
 *
 * In each case we check that the operation does not work if it is not
 * in the ModelMBeanInfo, and does work if it is.
 */
public class RequiredModelMBeanMethodTest {
    public static void main(String[] args) throws Exception {
        boolean ok = true;
        MBeanServer mbs = MBeanServerFactory.createMBeanServer();

        Descriptor tralalaDescriptor =
            new DescriptorSupport(new String[] {
                "name=tralala",
                "descriptorType=operation",
                "role=operation",
                "targetType=ObjectReference",
            });
        Method tralalaMethod =
            Resource.class.getMethod("tralala",
                                     new Class[] {int.class, Resource.class});
        ModelMBeanOperationInfo tralalaInfo =
            new ModelMBeanOperationInfo("tralala descr", tralalaMethod,
                                        tralalaDescriptor);

        Method remACNLMethod =
            RequiredModelMBean.class.getMethod("removeAttributeChangeNotificationListener",
                                               new Class[] {
                                                   NotificationListener.class,
                                                   String.class
                                               });
        ModelMBeanOperationInfo remACNLInfo =
            new ModelMBeanOperationInfo("remACNL descr", remACNLMethod);

        Descriptor loadDescriptor =
            new DescriptorSupport(new String[] {
                "name=load",
                "descriptorType=operation",
                "role=operation",
                "targetType=ObjectReference",
                "class=" + Resource.class.getName(),
            });
        ModelMBeanOperationInfo loadInfo =
            new ModelMBeanOperationInfo("load", "load descr",
                                        new MBeanParameterInfo[0],
                                        "void", ModelMBeanOperationInfo.ACTION,
                                        loadDescriptor);

        Descriptor storeDescriptor =
            new DescriptorSupport(new String[] {
                "name=store",
                "descriptorType=operation",
                "role=operation",
                "targetType=ObjectReference",
            });
        storeDescriptor.setField("targetObject", resource);
        ModelMBeanOperationInfo storeInfo =
            new ModelMBeanOperationInfo("store", "store descr",
                                        new MBeanParameterInfo[0],
                                        "void", ModelMBeanOperationInfo.ACTION,
                                        storeDescriptor);

        ModelMBeanInfo emptyMMBI =
            new ModelMBeanInfoSupport(Resource.class.getName(),
                                      "empty descr",
                                      null, null, null, null);
        ModelMBean emptyMMB = new RequiredModelMBean(emptyMMBI);
        emptyMMB.setManagedResource(resource, "ObjectReference");
        ObjectName emptyMMBName = new ObjectName("test:type=Empty");
        mbs.registerMBean(emptyMMB, emptyMMBName);

        System.out.println("Testing that we cannot call methods not in the " +
                           "ModelMBeanInfo");
        try {
            boolean thisok = test(mbs, emptyMMBName, false);
            if (thisok)
                System.out.println("...OK");
            else
                ok = false;
        } catch (Exception e) {
            System.out.println("TEST FAILED: Caught exception:");
            e.printStackTrace(System.out);
            ok = false;
        }

        ModelMBeanOperationInfo[] opInfos = {
            tralalaInfo, remACNLInfo, loadInfo, storeInfo,
        };
        ModelMBeanInfo fullMMBI =
            new ModelMBeanInfoSupport(Resource.class.getName(),
                                      "full descr",
                                      null, null, opInfos, null);
        ModelMBean fullMMB = new RequiredModelMBean(fullMMBI);
        fullMMB.setManagedResource(resource, "ObjectReference");
        ObjectName fullMMBName = new ObjectName("test:type=Full");
        mbs.registerMBean(fullMMB, fullMMBName);


        System.out.println();
        System.out.println("Testing that we can call methods in the " +
                           "ModelMBeanInfo");
        System.out.println("  and that \"class\" or \"targetObject\" in " +
                           "descriptor directs methods to resource");
        try {
            boolean thisok = test(mbs, fullMMBName, true);
            if (thisok)
                System.out.println("...OK");
            else
                ok = false;
        } catch (Exception e) {
            System.out.println("TEST FAILED: Caught exception:");
            e.printStackTrace(System.out);
            ok = false;
        }

        if (ok) {
            if (!resource.loadCalled || !resource.storeCalled) {
                System.out.println("TEST FAILED: not called:" +
                                   (resource.loadCalled ? "" : " load") +
                                   (resource.storeCalled ? "" : " store"));
                ok = false;
            }
        }

        // Test the invoke("class.method") form
        if (ok) {
            System.out.println("Testing invoke(\"class.method\")");
            resource.loadCalled = false;
            mbs.invoke(fullMMBName, Resource.class.getName() + ".load",
                       null, null);
            if (!resource.loadCalled) {
                System.out.println("TEST FAILED: load not called");
                ok = false;
            }
            try {
                mbs.invoke(fullMMBName,
                           RequiredModelMBean.class.getName() +
                           ".removeAttributeChangeNotificationListener",
                           new Object[] {boringListener, null},
                           new String[] {
                                   NotificationListener.class.getName(),
                                   String.class.getName(),
                           });
                System.out.println("TEST FAILED: removeNotificationListener" +
                                   " returned successfully but " +
                                   "should not have");
                        ok = false;
            } catch (MBeanException e) {
                final Exception target = e.getTargetException();
                if (target instanceof ListenerNotFoundException) {
                    // OK: there is no such listener
                } else
                    throw e;
            }
        }

        if (ok)
            System.out.println("Test passed");
        else {
            System.out.println("TEST FAILED");
            System.exit(1);
        }
    }

    private static boolean test(MBeanServer mbs, ObjectName name,
                                boolean shouldWork)
            throws Exception {

        boolean ok = true;

        final String[] names = {
            "tralala",
            "removeAttributeChangeNotificationListener",
            "load",
            "store",
        };

        for (int i = 0; i < 4; i++) {
            boolean thisok = true;
            try {
                switch (i) {
                case 0:
                    String tralala = (String)
                        mbs.invoke(name, names[i],
                                   new Object[] {new Integer(5), resource},
                                   new String[] {"int",
                                                 Resource.class.getName()});
                    if (!"tralala".equals(tralala)) {
                        System.out.println("TEST FAILED: tralala returned: " +
                                           tralala);
                        thisok = false;
                    }
                    break;
                case 1:
                    try {
                        mbs.invoke(name,
                                   names[i],
                                   new Object[] {boringListener, null},
                                   new String[] {
                                       NotificationListener.class.getName(),
                                       String.class.getName(),
                                   });
                        System.out.println("TEST FAILED: " + names[i] +
                                           " returned successfully but " +
                                           "should not have");
                        thisok = false;
                    } catch (MBeanException e) {
                        final Exception target = e.getTargetException();
                        if (target instanceof ListenerNotFoundException) {
                            // OK: there is no such listener
                        } else
                            throw e;
                    }
                    break;
                case 2:
                case 3:
                    mbs.invoke(name,
                               names[i],
                               new Object[0],
                               new String[0]);
                    break;
                default:
                    throw new AssertionError();
                }

                thisok = shouldWork;
                if (!shouldWork) {
                    System.out.println("TEST FAILED: " + names[i] +
                                       " worked but should not");
                }
            } catch (MBeanException e) {
                if (shouldWork) {
                    System.out.println("TEST FAILED: " + names[i] + ": " + e);
                    e.printStackTrace(System.out);
                    thisok = false;
                } else {
                    Exception target = e.getTargetException();
                    if (!(target instanceof ServiceNotFoundException)) {
                        System.out.println("TEST FAILED: " + names[i] +
                                           ": wrong exception: " + target);
                        thisok = false;
                    }
                }
            } catch (Exception e) {
                System.out.println("TEST FAILED: " + names[i] + ": " + e);
                e.printStackTrace(System.out);
                thisok = false;
            }

            if (thisok)
                System.out.println("OK: " + names[i]);
            else
                ok = false;
        }

        return ok;
    }

    public static class Resource {
        public String tralala(int x, Resource y) {
            if (x != 5 || y != this)
                return "wrong params: " + x + " " + y;
            return "tralala";
        }

        public void load() {
            loadCalled = true;
        }

        public void store() {
            storeCalled = true;
        }

        boolean loadCalled, storeCalled;
    }

    private static Resource resource = new Resource();

    private static NotificationListener boringListener =
        new NotificationListener() {
            public void handleNotification(Notification n, Object h) {
            }
        };
}
