Index: nbproject/project.xml =================================================================== --- nbproject/project.xml (revision 5031) +++ nbproject/project.xml (working copy) @@ -86,7 +86,7 @@ ${src.dir} - lib/bsf.jar:build_lib/junit.jar:build_lib/jline-0.9.91.jar:build_lib/asm-3.0.jar:build_lib/asm-commons-3.0.jar:build_lib/asm-util-3.0.jar:build_lib/jna.jar:build_lib/nailgun-0.7.1.jar + lib/bsf.jar:build_lib/junit.jar:build_lib/jline-0.9.91.jar:build_lib/asm-3.0.jar:build_lib/asm-commons-3.0.jar:build_lib/asm-util-3.0.jar:build_lib/jna.jar:build_lib/nailgun-0.7.1.jar:build_lib/dynalang-0.3.jar ${jruby.classes.dir} ${lib.dir}/jruby.jar ${api.docs.dir} Index: src/org/jruby/RubyClass.java =================================================================== --- src/org/jruby/RubyClass.java (revision 5031) +++ src/org/jruby/RubyClass.java (working copy) @@ -34,10 +34,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; +import java.util.Map; import java.util.Set; +import org.dynalang.mop.CallProtocol; +import org.dynalang.mop.MetaobjectProtocol; import org.jruby.anno.JRubyMethod; import org.jruby.internal.runtime.methods.DynamicMethod; +import org.jruby.javasupport.JavaUtil; import org.jruby.javasupport.util.RuntimeHelpers; import org.jruby.runtime.Arity; import org.jruby.runtime.Block; @@ -56,7 +61,7 @@ * * @author jpetersen */ -public class RubyClass extends RubyModule { +public class RubyClass extends RubyModule implements MetaobjectProtocol { public static void createClassClass(Ruby runtime, RubyClass classClass) { classClass.index = ClassIndex.CLASS; @@ -428,4 +433,96 @@ return result; } }; + + public Object call(Object target, Object id, CallProtocol protocol, Map args) { + Object[] argsArray = args.values().toArray(); + + return call(target, id, protocol, argsArray); + } + + public Object call(Object target, Object id, CallProtocol protocol, Object... args) { + if (!(target instanceof IRubyObject)) return Results.noAuthority; + + IRubyObject receiver = JavaUtil.convertJavaToRuby(getRuntime(), target); + String name = id.toString(); + IRubyObject[] rubyArgs = new IRubyObject[args.length]; + + DynamicMethod method = searchMethod(name); + if (method == null || method.isUndefined()) return Results.doesNotExist; + + for (int i = 0; i < args.length; i++) { + // Do not do auto-conversion of Java types into Ruby types here; if we + // encounter a non-ruby type, return noRepresentation. + if (!(args[i] instanceof IRubyObject)) return Results.noRepresentation; + rubyArgs[i] = JavaUtil.convertJavaToRuby(getRuntime(), args[i]); + } + + IRubyObject result = invoke(getRuntime().getCurrentContext(), receiver, name, rubyArgs, CallType.NORMAL, Block.NULL_BLOCK); + + // TODO: At the moment, no conversion from Java types; we really need to pull the trigger on lightweights + return result; + } + + public Results delete(Object target, long id) { + return Results.notDeleteable; + } + + public Object get(Object target, long id) { + return Results.noRepresentation; + } + + public Boolean has(Object target, long id) { + return null; + } + + public Iterator propertyIds(Object target) { + return null; + } + + public Results put(Object target, long id, Object value, CallProtocol protocol) { + return Results.noRepresentation; + } + + public Results delete(Object target, Object id) { + return Results.notDeleteable; + } + + public Boolean has(Object arg0, Object arg1) { + return null; + } + + public Iterator properties(Object arg0) { + return null; + } + + public Results put(Object target, Object id, Object value, CallProtocol protocol) { + if (!(target instanceof IRubyObject)) return Results.noAuthority; + if (!(value instanceof IRubyObject)) return Results.noRepresentation; + String name = id.toString() + "="; + + Object result = call(target, name, protocol, value); + if (result instanceof Results) return (Results)result; + + return Results.ok; + } + + public Object representAs(Object target, Class type) { + return Results.noAuthority; + } + + public Object get(Object target, Object id) { + if (!(target instanceof IRubyObject)) return Results.noAuthority; + String name = id.toString(); + + // FIXME: passing null here seems wrong; why doesn't get receive protocol too? + return call(target, name, null); + } + + public Object call(Object id, CallProtocol protocol, Map args) { + return call(this, id, protocol, args); + } + + public Object call(Object id, CallProtocol protocol, Object... args) { + return call(this, id, protocol, args); + } }