1 33 package org.jruby.javasupport; 34 35 import java.lang.reflect.InvocationHandler ; 36 import java.lang.reflect.Method ; 37 import java.lang.reflect.Proxy ; 38 import org.jruby.Ruby; 39 import org.jruby.RubyBignum; 40 import org.jruby.RubyFixnum; 41 import org.jruby.RubyFloat; 42 import org.jruby.RubyModule; 43 import org.jruby.RubyProc; 44 import org.jruby.RubyString; 45 import org.jruby.RubyTime; 46 import org.jruby.javasupport.proxy.JavaProxyClass; 47 import org.jruby.runtime.Block; 48 import org.jruby.runtime.CallbackFactory; 49 import org.jruby.runtime.ClassIndex; 50 import org.jruby.runtime.builtin.IRubyObject; 51 52 public class Java { 53 public static RubyModule createJavaModule(Ruby runtime) { 54 RubyModule javaModule = runtime.defineModule("Java"); 55 CallbackFactory callbackFactory = runtime.callbackFactory(Java.class); 56 javaModule.defineModuleFunction("define_exception_handler", callbackFactory.getOptSingletonMethod("define_exception_handler")); 57 javaModule.defineModuleFunction("primitive_to_java", callbackFactory.getSingletonMethod("primitive_to_java", IRubyObject.class)); 58 javaModule.defineModuleFunction("java_to_primitive", callbackFactory.getSingletonMethod("java_to_primitive", IRubyObject.class)); 59 javaModule.defineModuleFunction("java_to_ruby", callbackFactory.getSingletonMethod("java_to_ruby", IRubyObject.class)); 60 javaModule.defineModuleFunction("ruby_to_java", callbackFactory.getSingletonMethod("ruby_to_java", IRubyObject.class)); 61 javaModule.defineModuleFunction("new_proxy_instance", callbackFactory.getOptSingletonMethod("new_proxy_instance")); 62 63 JavaObject.createJavaObjectClass(runtime, javaModule); 64 JavaArray.createJavaArrayClass(runtime, javaModule); 65 JavaClass.createJavaClassClass(runtime, javaModule); 66 JavaMethod.createJavaMethodClass(runtime, javaModule); 67 JavaConstructor.createJavaConstructorClass(runtime, javaModule); 68 JavaField.createJavaFieldClass(runtime, javaModule); 69 70 JavaProxyClass.createJavaProxyModule(runtime); 72 73 return javaModule; 74 } 75 76 public static IRubyObject define_exception_handler(IRubyObject recv, IRubyObject[] args, Block block) { 78 String name = args[0].toString(); 79 RubyProc handler = null; 80 if (args.length > 1) { 81 handler = (RubyProc)args[1]; 82 } else { 83 handler = recv.getRuntime().newProc(false, block); 84 } 85 recv.getRuntime().getJavaSupport().defineExceptionHandler(name, handler); 86 87 return recv; 88 } 89 90 public static IRubyObject primitive_to_java(IRubyObject recv, IRubyObject object, Block unusedBlock) { 91 if (object instanceof JavaObject) { 92 return object; 93 } 94 Ruby runtime = recv.getRuntime(); 95 Object javaObject; 96 switch (object.getMetaClass().index) { 97 case ClassIndex.NIL: 98 javaObject = null; 99 break; 100 case ClassIndex.FIXNUM: 101 javaObject = new Long (((RubyFixnum) object).getLongValue()); 102 break; 103 case ClassIndex.BIGNUM: 104 javaObject = ((RubyBignum) object).getValue(); 105 break; 106 case ClassIndex.FLOAT: 107 javaObject = new Double (((RubyFloat) object).getValue()); 108 break; 109 case ClassIndex.STRING: 110 javaObject = ((RubyString) object).toString(); 111 break; 112 case ClassIndex.TRUE: 113 javaObject = Boolean.TRUE; 114 break; 115 case ClassIndex.FALSE: 116 javaObject = Boolean.FALSE; 117 break; 118 default: 119 if (object instanceof RubyTime) { 120 javaObject = ((RubyTime)object).getJavaDate(); 121 } else { 122 javaObject = object; 123 } 124 } 125 return JavaObject.wrap(runtime, javaObject); 126 } 127 128 131 public static IRubyObject java_to_ruby(IRubyObject recv, IRubyObject object, Block unusedBlock) { 132 if (object instanceof JavaObject) { 133 object = JavaUtil.convertJavaToRuby(recv.getRuntime(), ((JavaObject) object).getValue()); 134 } 135 136 if (object instanceof JavaObject) { 138 return recv.getRuntime().getModule("JavaUtilities").callMethod(recv.getRuntime().getCurrentContext(), "wrap", object); 139 } 140 141 return object; 142 } 143 144 148 public static IRubyObject ruby_to_java(final IRubyObject recv, IRubyObject object, Block unusedBlock) { 149 if (object.respondsTo("to_java_object")) { 150 IRubyObject result = object.getInstanceVariable("@java_object"); 151 if (result == null) { 152 result = object.callMethod(recv.getRuntime().getCurrentContext(), "to_java_object"); 153 } 154 return result; 155 } 156 157 return primitive_to_java(recv, object, unusedBlock); 158 } 159 160 public static IRubyObject java_to_primitive(IRubyObject recv, IRubyObject object, Block unusedBlock) { 161 if (object instanceof JavaObject) { 162 return JavaUtil.convertJavaToRuby(recv.getRuntime(), ((JavaObject) object).getValue()); 163 } 164 165 return object; 166 } 167 168 public static IRubyObject new_proxy_instance(final IRubyObject recv, IRubyObject[] args, Block block) { 169 int size = recv.checkArgumentCount(args, 1, -1) - 1; 170 final RubyProc proc; 171 172 if (args[size] instanceof RubyProc) { 174 proc = (RubyProc) args[size]; 175 } else { 176 proc = recv.getRuntime().newProc(false, block); 177 size++; 178 } 179 180 Class [] interfaces = new Class [size]; 182 for (int i = 0; i < size; i++) { 183 if (!(args[i] instanceof JavaClass) || !((JavaClass)args[i]).interface_p().isTrue()) { 184 throw recv.getRuntime().newArgumentError("Java interface expected."); 185 } 186 interfaces[i] = ((JavaClass) args[i]).javaClass(); 187 } 188 189 return JavaObject.wrap(recv.getRuntime(), Proxy.newProxyInstance(recv.getRuntime().getJavaSupport().getJavaClassLoader(), interfaces, new InvocationHandler () { 190 public Object invoke(Object proxy, Method method, Object [] nargs) throws Throwable { 191 int methodArgsLength = method.getParameterTypes().length; 192 String methodName = method.getName(); 193 194 if (methodName.equals("toString") && methodArgsLength == 0) { 195 return proxy.getClass().getName(); 196 } else if (methodName.equals("hashCode") && methodArgsLength == 0) { 197 return new Integer (proxy.getClass().hashCode()); 198 } else if (methodName.equals("equals") && methodArgsLength == 1 && method.getParameterTypes()[0].equals(Object .class)) { 199 return Boolean.valueOf(proxy == nargs[0]); 200 } 201 int length = nargs == null ? 0 : nargs.length; 202 IRubyObject[] rubyArgs = new IRubyObject[length + 2]; 203 rubyArgs[0] = JavaObject.wrap(recv.getRuntime(), proxy); 204 rubyArgs[1] = new JavaMethod(recv.getRuntime(), method); 205 for (int i = 0; i < length; i++) { 206 rubyArgs[i + 2] = JavaObject.wrap(recv.getRuntime(), nargs[i]); 207 } 208 return JavaUtil.convertArgument(proc.call(rubyArgs), method.getReturnType()); 209 } 210 })); 211 } 212 } 213 | Popular Tags |