@JRubyMethod public IRubyObject java_send(ThreadContext context, IRubyObject rubyName, IRubyObject argTypes) { String name = rubyName.asJavaString(); RubyArray argTypesAry = argTypes.convertToArray(); Ruby runtime = context.runtime; checkArgSizeMismatch(runtime, 0, argTypesAry); JavaMethod method = new JavaMethod(runtime, getMethod(context, name)); return method.invokeDirect(context, getObject()); }
private RubyMethod getRubyMethod(ThreadContext context, String name, Class... argTypes) { Method jmethod = getMethod(context, name, argTypes); if (Modifier.isStatic(jmethod.getModifiers())) { return RubyMethod.newMethod(metaClass.getSingletonClass(), CodegenUtils.prettyParams(argTypes).toString(), metaClass.getSingletonClass(), name, getMethodInvoker(jmethod), getMetaClass()); } else { return RubyMethod.newMethod(metaClass, CodegenUtils.prettyParams(argTypes).toString(), metaClass, name, getMethodInvoker(jmethod), this); } }
@JRubyMethod public static IRubyObject dup(final ThreadContext context, final IRubyObject self) { java.util.Collection coll = unwrapIfJavaObject(self); final JavaProxy dup = (JavaProxy) ((RubyBasicObject) self).dup(); if ( coll == dup.getObject() && ! (coll instanceof Cloneable) ) { dup.setObject( tryNewEqualInstance(coll) ); } return dup; }
@Override public IRubyObject initialize_copy(IRubyObject original) { super.initialize_copy(original); // because we lazily init JavaObject in the data-wrapped slot, explicitly copy over the object setObject( ((JavaProxy) original).cloneObject() ); return this; }
@Override @SuppressWarnings("unchecked") public <T> T toJava(Class<T> type) { final Object object = getObject(); final Class<?> clazz = object.getClass(); if ( type.isAssignableFrom(clazz) ) return type.cast(object); if ( type.isAssignableFrom(getClass()) ) return type.cast(this); // e.g. IRubyObject.class throw getRuntime().newTypeError("failed to coerce " + clazz.getName() + " to " + type.getName()); }
@JRubyMethod public IRubyObject marshal_dump() { if ( ! Serializable.class.isAssignableFrom(object.getClass()) ) { throw getRuntime().newTypeError("Java type is not serializable, cannot be marshaled " + getJavaClass()); } try { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); new ObjectOutputStream(bytes).writeObject(object); return getRuntime().newString(new ByteList(bytes.toByteArray(), false)); } catch (IOException ex) { throw getRuntime().newTypeError("Java type is not serializable: " + ex.getMessage()); } }
private static String unwrapJavaString(IRubyObject arg) { if (arg instanceof JavaProxy) { Object str = ((JavaProxy) arg).getObject(); return str instanceof String ? (String) str : null; } return null; }
@Override public IRubyObject initialize_copy(IRubyObject original) { super.initialize_copy(original); // because we lazily init JavaObject in the data-wrapped slot, explicitly copy over the object setObject(((JavaProxy)original).object); return this; }
private static void findFields(ThreadContext context, RubyModule topModule, IRubyObject args[], boolean asReader, boolean asWriter) { Map<String, String> fieldMap = getFieldListFromArgs(args); for (RubyModule module = topModule; module != null; module = module.getSuperClass()) { Class<?> javaClass = getJavaClass(context, module); // Hit a non-java proxy class (included Modules can be a cause of this...skip) if (javaClass == null) continue; Field[] fields = JavaClass.getDeclaredFields(javaClass); for (int j = 0; j < fields.length; j++) { installField(context, fieldMap, fields[j], module, asReader, asWriter); } } // We could not find all of them print out first one (we could print them all?) if (!fieldMap.isEmpty()) { throw JavaClass.undefinedFieldError(context.runtime, topModule.getName(), fieldMap.keySet().iterator().next()); } }
@Override public void setVariable(int index, Object value) { confirmCachedProxy(NONPERSISTENT_IVAR_MESSAGE); super.setVariable(index, value); }
@JRubyMethod(meta = true, rest = true) public static IRubyObject field_writer(ThreadContext context, IRubyObject self, IRubyObject[] args) { findFields(context, (RubyModule) self, args, false, true); return context.nil; }
public Object getObject() { // FIXME: Added this because marshal_spec seemed to reconstitute objects without calling dataWrapStruct // this resulted in object being null after unmarshalling... if (object == null) { if (javaObject == null) { throw getRuntime().newRuntimeError("Java wrapper with no contents: " + this.getMetaClass().getName()); } else { object = javaObject.getValue(); } } return object; }
private static void findFields(final ThreadContext context, final RubyModule topModule, final IRubyObject[] args, final boolean asReader, final boolean asWriter) { final Map<String, String> fieldMap = getFieldListFromArgs(context, args); for (RubyModule module = topModule; module != null; module = module.getSuperClass()) { final Class<?> javaClass = JavaClass.getJavaClassIfProxy(context, module); // Hit a non-java proxy class (included Modules can be a cause of this...skip) if ( javaClass == null ) continue; Field[] fields = JavaClass.getDeclaredFields(javaClass); for (int j = 0; j < fields.length; j++) { installField(context, fieldMap, fields[j], module, asReader, asWriter); } } // We could not find all of them print out first one (we could print them all?) if ( ! fieldMap.isEmpty() ) { throw JavaClass.undefinedFieldError(context.runtime, topModule.getName(), fieldMap.keySet().iterator().next()); } }
public IRubyObject allocate(Ruby runtime, RubyClass klazz) { return new JavaProxy(runtime, klazz); } };
/** * Given {@link JavaProxy} instance, which represents an instance of a Ruby class that * extends from a Java type, return {@link JavaProxyClass}, which encapsulates a generated * Java subtype that JRuby uses to represent this Ruby object. */ private JavaProxyClass getProxyClass(JavaProxy original) { // taken from org.jruby.javasupport.Java. needs to be factored out from there IRubyObject proxyClass = original.getMetaClass().getInstanceVariables().fastGetInstanceVariable("@java_proxy_class"); if (proxyClass == null || proxyClass.isNil()) { proxyClass = JavaProxyClass.get_with_class(original, original.getMetaClass()); original.getMetaClass().getInstanceVariables().fastSetInstanceVariable("@java_proxy_class", proxyClass); } return (JavaProxyClass)proxyClass; }
JavaProxy.createJavaProxy(context); ArrayJavaProxyCreator.createArrayJavaProxyCreator(context); ConcreteJavaProxy.createConcreteJavaProxy(context);
@Override public IRubyObject initialize_copy(IRubyObject original) { super.initialize_copy(original); // because we lazily init JavaObject in the data-wrapped slot, explicitly copy over the object setObject(((JavaProxy)original).object); return this; }