/** 
 * Copyright 2006-2007 Yu Su, Ye Zheng
 * Distributed under the GNU General Public License 2.0
 */

package com.xruby.runtime.javasupport;

import com.xruby.runtime.lang.RubyBlock;
import com.xruby.runtime.lang.RubyException;
import com.xruby.runtime.lang.RubyValue;
import com.xruby.runtime.lang.RubyVarArgMethod;
import com.xruby.runtime.value.RubyArray;
import com.xruby.runtime.value.RubyData;

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

/**
 * Java Method Wrapper for both public method and constructor
 *
 * @author yu su (beanworms@gmail.com)
 */
public class JavaMethod extends RubyVarArgMethod {
    private Method method;
    private Constructor constructor;
    private boolean isConstructor;

    /**
     * Public method
     *
     *  @param method method instance
     */
    public JavaMethod(Method method) {
        this.method = method;
    }

    /**
     *  Public constructor
     *  @param constructor Constructor instance
     */
    public JavaMethod(Constructor constructor) {
        this.constructor = constructor;
        this.isConstructor = true;
    }

    @SuppressWarnings("unchecked")
	protected RubyValue run(RubyValue receiver, RubyArray args, RubyBlock block) {
        Object[] arguments = JavaUtil.convertToJavaValues(args);

        try {
            if(!isConstructor) {
                Object object = null;
                if(!(receiver instanceof JavaClass)){
                    object = ((RubyData<Object>)receiver).getData();
                }
                //If the underlying method is static,object will be null!
                Object retValue = method.invoke(object, arguments);

                return JavaUtil.convertToRubyValue(retValue);
            }
            else {
                Object instance = constructor.newInstance(arguments);
                RubyData<Object> value = new RubyJavaObject<Object>((JavaClass) receiver, instance);
                return value;
            }
        } catch (Exception e) {          // IllegalAccessException and InvocationTargetException
            throw new RubyException(e.getMessage());
        }
    }
}

@@ -36,16 +36,26 @@
 Ye Zheng
+, Yu Zhang
 %0A * Dist
@@ -159,40 +159,240 @@
 ort 
-com.xruby.runtime.lang.RubyBlock
+java.lang.reflect.Constructor;%0Aimport java.lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0Aimport java.lang.reflect.Modifier;%0A%0Aimport com.xruby.runtime.lang.RubyBlock;%0Aimport com.xruby.runtime.lang.RubyClass
 ;%0Aim
@@ -430,24 +430,67 @@
 yException;%0A
+import com.xruby.runtime.lang.RubyRuntime;%0A
 import com.x
@@ -654,80 +654,8 @@
 a;%0A%0A
-import java.lang.reflect.Constructor;%0Aimport java.lang.reflect.Method;%0A%0A
 /**%0A
@@ -1682,16 +1682,296 @@
 Data();%0A
+                %7D                %0A                if(!(Modifier.isStatic(method.getModifiers())) && object == null)%7B%0A                    throw new RubyException(RubyRuntime.NoMethodErrorClass, %22undefined method '%22 + method.getName() + %22' for %22 + ((RubyClass)receiver).getName());%0A
         
@@ -1972,32 +1972,49 @@
               %7D%0A
+                %0A
                 
@@ -2463,16 +2463,128 @@
    %7D
- 
 catch (
+IllegalArgumentException e) %7B%0A            throw new RubyException(e.getMessage());%0A        %7D catch (Instantiation
 Exce
@@ -2593,16 +2593,17 @@
 ion e) %7B
+%0A
         
@@ -2608,38 +2608,166 @@
     
-// IllegalAccessException and 
+  throw new RubyException(e.getMessage());%0A        %7D catch (IllegalAccessException e) %7B%0A            throw new RubyException(e.getMessage());%0A        %7D catch (
 Invo
@@ -2787,16 +2787,21 @@
 xception
+ e) %7B
 %0A       
@@ -2852,20 +2852,21 @@
 ;%0A        %7D%0A
+%0A
     %7D%0A%7D%0A

fix a bug about static method