/*
 * Copyright (c) 2009 JSCAPE
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with JSCAPE.
 *
 */

package com.jscape.util.reflection;

import com.jscape.util.functor.UnaryFunction;

import java.lang.reflect.Constructor;

/**
 * @author Alex Usun
 */
public class ObjectCreator<T>
        extends UnaryFunction<Class, T> {

    private final Class[] argTypes;
    private final Object[] args;

    @SuppressWarnings("unchecked")
    public static <T> T create(Class aClass, Class[] argTypes, Object... args)
            throws ReflectionException {
        try {
            Constructor constructor = aClass.getDeclaredConstructor(argTypes);
            constructor.setAccessible(true);
            return (T) constructor.newInstance(args);
        } catch (Exception e) {
            throw new ReflectionException(e);
        }
    }

    public static <T> T create(Class aClass)
            throws ReflectionException {
        return ObjectCreator.<T>create(aClass, new Class[0]);
    }

    public static <T> T create(String aClass)
            throws ReflectionException {
        try {
            return ObjectCreator.<T>create(Class.forName(aClass));
        } catch (ClassNotFoundException e) {
            throw new ReflectionException(e);
        }
    }

    public ObjectCreator(Class[] argTypes, Object[] args) {
        this.argTypes = argTypes;
        this.args = args;
    }

    public ObjectCreator() {
        this(new Class[0], new Object[0]);
    }

    public T evaluate(Class value) {
        try {
            return ObjectCreator.<T>create(value, this.argTypes, this.args);
        } catch (Exception e) {
            throw new IllegalArgumentException(e);
        }
    }
}
