/*
 * Copyright (c) 2006, 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 5021246
 * @summary Check that class downloading is supported by RMI connector
 * @author Eamonn McManus
 * @run main RMIDownloadTest receive without
 * @run main RMIDownloadTest send without
 * @run main RMIDownloadTest receive with
 * @run main RMIDownloadTest send with
 */

/*
 * This test checks that class downloading is supported by the RMI connector.
 * We copy a precompiled class file into the temporary directory (which we
 * assume is not in the classpath).  We also create an instance of that
 * class using a hardcoded ClassLoader.  Then we try to get a remote attribute
 * that returns that instance, and we try to set the remote attribute to the
 * instance.  In both cases, this will only work if the class can be downloaded
 * based on the codebase that we have set to the temporary directory.  We also
 * test that it does *not* work when the codebase is not set, in case the test
 * is succeeding for some other reason.
 *
 * We run the test four times, for each combination of (send, receive) x
 * (with-codebase, without-codebase).  Doing all four tests within the same
 * run doesn't work, probably because RMI remembers the codebase property
 * setting at some point.
 */

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.security.Permission;
import java.util.Arrays;
import javax.management.Attribute;
import javax.management.MBeanServer;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

public class RMIDownloadTest {
    /* Following byte array was produced from this class:
     *
     * public class Zooby implements java.io.Serializable {}
     *
     * by this program:
     *
     * public class MakeZooby {
     *     public static void main(String[] args) throws Exception {
     *         int b;
     *         for (int offset = 0; (b = System.in.read()) >= 0; offset++) {
     *             System.out.print((byte) b + "," +
     *                              ((offset % 16) == 15 ? '\n' : ' '));
     *         }
     *         System.out.println();
     *     }
     * }
     */
    private static final byte[] zoobyClassBytes = {
        -54, -2, -70, -66, 0, 0, 0, 49, 0, 12, 10, 0, 3, 0, 8, 7,
        0, 9, 7, 0, 10, 7, 0, 11, 1, 0, 6, 60, 105, 110, 105, 116,
        62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 12, 0,
        5, 0, 6, 1, 0, 5, 90, 111, 111, 98, 121, 1, 0, 16, 106, 97,
        118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0,
        20, 106, 97, 118, 97, 47, 105, 111, 47, 83, 101, 114, 105, 97, 108, 105,
        122, 97, 98, 108, 101, 0, 33, 0, 2, 0, 3, 0, 1, 0, 4, 0,
        0, 0, 1, 0, 1, 0, 5, 0, 6, 0, 1, 0, 7, 0, 0, 0,
        17, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0,
        0, 0, 0, 0,
    };

    private static class ZoobyClassLoader extends ClassLoader {
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            if (name.equals("Zooby")) {
                return super.defineClass(name, zoobyClassBytes,
                        0, zoobyClassBytes.length);
            } else
                throw new ClassNotFoundException(name);
        }
    }


    private static MBeanServer pmbs;
    private static ObjectName getSetName;
    private static GetSet getSetInstance;

    public static void main(String[] args) throws Exception {
        int sendIndex = -1;
        int withIndex = -1;
        if (args.length == 2) {
            sendIndex =
                    Arrays.asList("send", "receive").indexOf(args[0]);
            withIndex =
                    Arrays.asList("with", "without").indexOf(args[1]);
        }
        if (sendIndex < 0 || withIndex < 0)
            throw new Exception("Usage: RMIDownloadTest (send|receive) (with|without)");
        final boolean send = (sendIndex == 0);
        final boolean with = (withIndex == 0);

        pmbs = ManagementFactory.getPlatformMBeanServer();
        getSetName = new ObjectName(":type=GetSet");
        getSetInstance = new GetSet();
        pmbs.registerMBean(getSetInstance, getSetName);

        System.setSecurityManager(new LaidBackSecurityManager());

//        System.setProperty("sun.rmi.loader.logLevel", "VERBOSE");

        String tmpdir = System.getProperty("java.io.tmpdir");
        String classfile = tmpdir + File.separator + "Zooby.class";
        File zoobyFile = new File(classfile);
        zoobyFile.deleteOnExit();
        OutputStream os = new FileOutputStream(zoobyFile);
        for (byte b : zoobyClassBytes)
            os.write(b);
        os.close();

        // Check that we can't load the Zooby class from the classpath
        try {
            Class.forName("Zooby");
            throw new Exception("Class \"Zooby\" is in the classpath!");
        } catch (ClassNotFoundException e) {
            // OK: expected
        }

        if (send)
            System.out.println("Testing we can send an object from client to server");
        else
            System.out.println("Testing we can receive an object from server to client");

        if (with) {
            // Test with the codebase property.  Downloading should work.
            URL zoobyURL = zoobyFile.getParentFile().toURI().toURL();
            System.setProperty("java.rmi.server.codebase", zoobyURL.toString());
            System.out.println("Testing with codebase, should work");
            System.out.println("Codebase is " +
                    System.getProperty("java.rmi.server.codebase"));
            test(send, true);
        } else {
            // Test without setting the codebase property.
            // This should not work; if it does it probably means java.io.tmpdir
            // is in the classpath.
            System.out.println("Testing without codebase, should fail");
            test(send, false);
        }

    }

    private static void test(boolean send, boolean shouldWork) throws Exception {
        try {
            testWithException(send);
        } catch (Exception e) {
            if (shouldWork)
                throw e;
            System.out.println("Got exception as expected: " + e);
            return;
        }
        if (!shouldWork)
            throw new Exception("Test passed without codebase but should not");
    }

    private static void testWithException(boolean send)
    throws Exception {
        ClassLoader zoobyCL = new ZoobyClassLoader();
        Class<?> zoobyClass = Class.forName("Zooby", false, zoobyCL);
        Object zooby = zoobyClass.newInstance();

        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///");
        JMXConnectorServer cs =
                JMXConnectorServerFactory.newJMXConnectorServer(url, null, pmbs);
        cs.start();
        JMXServiceURL addr = cs.getAddress();
        JMXConnector cc = JMXConnectorFactory.connect(addr);
        MBeanServerConnection mbsc = cc.getMBeanServerConnection();

        Object rzooby;
        if (send) {
            System.out.println("Sending object...");
            mbsc.setAttribute(getSetName, new Attribute("It", zooby));
            rzooby = getSetInstance.getIt();
        } else {
            System.out.println("Receiving object...");
            getSetInstance.setIt(zooby);
            rzooby = mbsc.getAttribute(getSetName, "It");
        }

        if (!rzooby.getClass().getName().equals("Zooby")) {
            throw new Exception("FAILED: remote object is not a Zooby");
        }
        if (rzooby.getClass().getClassLoader() ==
                zooby.getClass().getClassLoader()) {
            throw new Exception("FAILED: same class loader: " +
                    zooby.getClass().getClassLoader());
        }

        cc.close();
        cs.stop();
    }

    public static interface GetSetMBean {
        public Object getIt();
        public void setIt(Object x);
    }

    public static class GetSet implements GetSetMBean {
        public GetSet() {
        }

        public Object getIt() {
            return what;
        }

        public void setIt(Object x) {
            this.what = x;
        }

        private Object what;
    }

    public static class LaidBackSecurityManager extends SecurityManager {
        public void checkPermission(Permission perm) {
            // OK, dude
        }
    }
}
