/*
 * Copyright 2000-2007 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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package sun.nio.ch;

import java.io.*;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;


class Reflect {                                 // package-private

    private Reflect() { }

    private static class ReflectionError extends Error {
        private static final long serialVersionUID = -8659519328078164097L;
        ReflectionError(Throwable x) {
            super(x);
        }
    }

    private static void setAccessible(final AccessibleObject ao) {
        AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    ao.setAccessible(true);
                    return null;
                }});
    }

    static Constructor lookupConstructor(String className,
                                         Class[] paramTypes)
    {
        try {
            Class cl = Class.forName(className);
            Constructor c = cl.getDeclaredConstructor(paramTypes);
            setAccessible(c);
            return c;
        } catch (ClassNotFoundException x) {
            throw new ReflectionError(x);
        } catch (NoSuchMethodException x) {
            throw new ReflectionError(x);
        }
    }

    static Object invoke(Constructor c, Object[] args) {
        try {
            return c.newInstance(args);
        } catch (InstantiationException x) {
            throw new ReflectionError(x);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        } catch (InvocationTargetException x) {
            throw new ReflectionError(x);
        }
    }

    static Method lookupMethod(String className,
                               String methodName,
                               Class[] paramTypes)
    {
        try {
            Class cl = Class.forName(className);
            Method m = cl.getDeclaredMethod(methodName, paramTypes);
            setAccessible(m);
            return m;
        } catch (ClassNotFoundException x) {
            throw new ReflectionError(x);
        } catch (NoSuchMethodException x) {
            throw new ReflectionError(x);
        }
    }

    static Object invoke(Method m, Object ob, Object[] args) {
        try {
            return m.invoke(ob, args);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        } catch (InvocationTargetException x) {
            throw new ReflectionError(x);
        }
    }

    static Object invokeIO(Method m, Object ob, Object[] args)
        throws IOException
    {
        try {
            return m.invoke(ob, args);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        } catch (InvocationTargetException x) {
            if (IOException.class.isInstance(x.getCause()))
                throw (IOException)x.getCause();
            throw new ReflectionError(x);
        }
    }

    static Field lookupField(String className, String fieldName) {
        try {
            Class cl = Class.forName(className);
            Field f = cl.getDeclaredField(fieldName);
            setAccessible(f);
            return f;
        } catch (ClassNotFoundException x) {
            throw new ReflectionError(x);
        } catch (NoSuchFieldException x) {
            throw new ReflectionError(x);
        }
    }

    static Object get(Object ob, Field f) {
        try {
            return f.get(ob);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        }
    }

    static Object get(Field f) {
        return get(null, f);
    }

    static void set(Object ob, Field f, Object val) {
        try {
            f.set(ob, val);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        }
    }

    static void setInt(Object ob, Field f, int val) {
        try {
            f.setInt(ob, val);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        }
    }

    static void setBoolean(Object ob, Field f, boolean val) {
        try {
            f.setBoolean(ob, val);
        } catch (IllegalAccessException x) {
            throw new ReflectionError(x);
        }
    }

}
