/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

/**
 * Class loader test.
 */
public class Main {
    /**
     * Thrown when an unexpected Exception is caught internally.
     */
    static class TestFailed extends Exception {
        public TestFailed(Throwable cause) {
            super(cause);
        }
    }

    /**
     * A class loader which loads classes from the dex file
     * "test.jar". However, it will return null when asked to load the
     * class InaccessibleSuper.
     *
     * When testing code calls BrokenDexLoader's findBrokenClass(),
     * a BrokenDexLoader will be the defining loader for the class
     * Inaccessible.  The VM will call the defining loader for
     * "InaccessibleSuper", which will return null, which the VM
     * should be able to deal with gracefully.
     *
     * Note that this depends heavily on the Dalvik test harness.
     */
    static class BrokenDexLoader extends ClassLoader {

        /** We return null when asked to load InaccessibleSuper. */
        private static class InaccessibleSuper {}
        private static class Inaccessible extends InaccessibleSuper {}

        private static final String SUPERCLASS_NAME =
                "Main$BrokenDexLoader$InaccessibleSuper";
        private static final String CLASS_NAME =
                "Main$BrokenDexLoader$Inaccessible";

        private static final String DEX_FILE = System.getenv("DEX_LOCATION") + "/086-null-super.jar";

        public BrokenDexLoader(ClassLoader parent) {
            super(parent);
        }

        /**
         * Finds the class with the specified binary name, from DEX_FILE.
         *
         * If we don't find a match, we throw an exception.
         */
        private Class<?> findDexClass(String name)
                throws TestFailed, InvocationTargetException
        {

            try {
                /*
                 * Find the DexFile class, and construct a DexFile object
                 * through reflection, then call loadCLass on it.
                 */
                Class<?> mDexClass = ClassLoader.getSystemClassLoader().
                        loadClass("dalvik.system.DexFile");
                Constructor<?> ctor = mDexClass.getConstructor(String.class);
                Object mDexFile = ctor.newInstance(DEX_FILE);
                Method meth = mDexClass.
                        getMethod("loadClass", String.class, ClassLoader.class);
                /*
                 * Invoking loadClass on CLASS_NAME is expected to
                 * throw an InvocationTargetException. Anything else
                 * is an error we can't recover from.
                 */
                meth.invoke(mDexFile, name, this);
            } catch (NoSuchMethodException nsme) {
                throw new TestFailed(nsme);
            } catch (InstantiationException ie) {
                throw new TestFailed(ie);
            } catch (IllegalAccessException iae) {
                throw new TestFailed(iae);
            } catch (ClassNotFoundException cnfe) {
                throw new TestFailed(cnfe);
            }

            return null;
        }

        /**
         * Load a class.
         *
         * Return null if the class's name is SUPERCLASS_NAME;
         * otherwise invoke the super's loadClass method.
         */
        public Class<?> loadClass(String name, boolean resolve)
                throws ClassNotFoundException
        {
            if (SUPERCLASS_NAME.equals(name)) {
                return null;
            }

            return super.loadClass(name, resolve);
        }

        /**
         * Attempt to find the class with the superclass we refuse to
         * load.  This is expected to throw an
         * InvocationTargetException, with a NullPointerException as
         * its cause.
         */
        public void findBrokenClass()
                throws TestFailed, InvocationTargetException
        {
            findDexClass(CLASS_NAME);
        }
    }

    /**
     * Main entry point.
     */
    public static void main(String[] args)
            throws TestFailed, ClassNotFoundException {
        /*
         * Run test.
         */
        testFailLoadAndGc();
    }

    /**
     * See if we can GC after a failed load.
     */
    static void testFailLoadAndGc() throws TestFailed {
        try {
            BrokenDexLoader loader;

            loader = new BrokenDexLoader(ClassLoader.getSystemClassLoader());
            loader.findBrokenClass();
            System.out.println("ERROR: Inaccessible was accessible");
        } catch (InvocationTargetException ite) {
            Throwable cause = ite.getCause();
            if (cause instanceof NullPointerException) {
                System.out.println("Got expected ITE/NPE");
            } else {
                System.out.println("Got unexpected ITE");
                ite.printStackTrace(System.out);
            }
        }
    }
}
