void put(Scriptable scope, String name, Object javaObject, Object value, boolean isStatic) { Map<String, Object> ht = isStatic ? staticMembers : members; Object member = ht.get(name); if (!isStatic && member == null) { // Try to get static member from instance (LC3) member = staticMembers.get(name); } if (member == null) throw reportMemberNotFound(name); if (member instanceof FieldAndMethods) { FieldAndMethods fam = (FieldAndMethods) ht.get(name); member = fam.field; } // Is this a bean property "set"? if (member instanceof BeanProperty) { BeanProperty bp = (BeanProperty) member; if (bp.setter == null) { throw reportMemberNotFound(name); } // If there's only one setter or if the value is null, use the // main setter. Otherwise, let the NativeJavaMethod decide which // setter to use: if (bp.setters == null || value == null) { Class<?> setType = bp.setter.argTypes[0]; Object[] args = {Context.jsToJava(value, setType)}; try { bp.setter.invoke(javaObject, args); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } } else { Object[] args = {value}; bp.setters.call( Context.getContext(), ScriptableObject.getTopLevelScope(scope), scope, args); } } else { if (!(member instanceof Field)) { String str = (member == null) ? "msg.java.internal.private" : "msg.java.method.assign"; throw Context.reportRuntimeError1(str, name); } Field field = (Field) member; Object javaValue = Context.jsToJava(value, field.getType()); try { field.set(javaObject, javaValue); } catch (IllegalAccessException accessEx) { if ((field.getModifiers() & Modifier.FINAL) != 0) { // treat Java final the same as JavaScript [[READONLY]] return; } throw Context.throwAsScriptRuntimeEx(accessEx); } catch (IllegalArgumentException argEx) { throw Context.reportRuntimeError3( "msg.java.internal.field.type", value.getClass().getName(), field, javaObject.getClass().getName()); } } }
/** * Return new {@link Scriptable} instance using the default constructor for the class of the * underlying Java method. Return null to indicate that the call method should be used to create * new objects. */ public Scriptable createObject(Context cx, Scriptable scope) { if (member.isCtor() || (parmsLength == VARARGS_CTOR)) { return null; } Scriptable result; try { result = (Scriptable) member.getDeclaringClass().newInstance(); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } result.setPrototype(getClassPrototype()); result.setParentScope(getParentScope()); return result; }
static Object js_createAdpter(Context cx, Scriptable scope, Object[] args) { int N = args.length; if (N == 0) { throw ScriptRuntime.typeError0("msg.adapter.zero.args"); } Class superClass = null; Class[] intfs = new Class[N - 1]; int interfaceCount = 0; for (int i = 0; i != N - 1; ++i) { Object arg = args[i]; if (!(arg instanceof NativeJavaClass)) { throw ScriptRuntime.typeError2( "msg.not.java.class.arg", String.valueOf(i), ScriptRuntime.toString(arg)); } Class c = ((NativeJavaClass) arg).getClassObject(); if (!c.isInterface()) { if (superClass != null) { throw ScriptRuntime.typeError2("msg.only.one.super", superClass.getName(), c.getName()); } superClass = c; } else { intfs[interfaceCount++] = c; } } if (superClass == null) superClass = ScriptRuntime.ObjectClass; Class[] interfaces = new Class[interfaceCount]; System.arraycopy(intfs, 0, interfaces, 0, interfaceCount); Scriptable obj = ScriptRuntime.toObject(cx, scope, args[N - 1]); Class adapterClass = getAdapterClass(scope, superClass, interfaces, obj); Class[] ctorParms = {ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass}; Object[] ctorArgs = {cx.getFactory(), obj}; try { Object adapter = adapterClass.getConstructor(ctorParms).newInstance(ctorArgs); return getAdapterSelf(adapterClass, adapter); } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } }
Object get(Scriptable scope, String name, Object javaObject, boolean isStatic) { Map<String, Object> ht = isStatic ? staticMembers : members; Object member = ht.get(name); if (!isStatic && member == null) { // Try to get static member from instance (LC3) member = staticMembers.get(name); } if (member == null) { member = this.getExplicitFunction( scope, name, javaObject, isStatic); if (member == null) return Scriptable.NOT_FOUND; } if (member instanceof Scriptable) { return member; } Context cx = Context.getContext(); Object rval; Class<?> type; try { if (member instanceof BeanProperty) { BeanProperty bp = (BeanProperty) member; if (bp.getter == null) return Scriptable.NOT_FOUND; rval = bp.getter.invoke(javaObject, Context.emptyArgs); type = bp.getter.method().getReturnType(); } else { Field field = (Field) member; rval = field.get(isStatic ? null : javaObject); type = field.getType(); } } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } // Need to wrap the object before we return it. scope = ScriptableObject.getTopLevelScope(scope); return cx.getWrapFactory().wrap(cx, scope, rval, type); }
static Object js_createAdapter(Context cx, Scriptable scope, Object[] args) { int N = args.length; if (N == 0) { throw ScriptRuntime.typeError0("msg.adapter.zero.args"); } // Expected arguments: // Any number of NativeJavaClass objects representing the super-class // and/or interfaces to implement, followed by one NativeObject providing // the implementation, followed by any number of arguments to pass on // to the (super-class) constructor. int classCount; for (classCount = 0; classCount < N - 1; classCount++) { Object arg = args[classCount]; // We explicitly test for NativeObject here since checking for // instanceof ScriptableObject or !(instanceof NativeJavaClass) // would fail for a Java class that isn't found in the class path // as NativeJavaPackage extends ScriptableObject. if (arg instanceof NativeObject) { break; } if (!(arg instanceof NativeJavaClass)) { throw ScriptRuntime.typeError2( "msg.not.java.class.arg", String.valueOf(classCount), ScriptRuntime.toString(arg)); } } Class<?> superClass = null; Class<?>[] intfs = new Class[classCount]; int interfaceCount = 0; for (int i = 0; i < classCount; ++i) { Class<?> c = ((NativeJavaClass) args[i]).getClassObject(); if (!c.isInterface()) { if (superClass != null) { throw ScriptRuntime.typeError2("msg.only.one.super", superClass.getName(), c.getName()); } superClass = c; } else { intfs[interfaceCount++] = c; } } if (superClass == null) { superClass = ScriptRuntime.ObjectClass; } Class<?>[] interfaces = new Class[interfaceCount]; System.arraycopy(intfs, 0, interfaces, 0, interfaceCount); // next argument is implementation, must be scriptable Scriptable obj = ScriptableObject.ensureScriptable(args[classCount]); Class<?> adapterClass = getAdapterClass(scope, superClass, interfaces, obj); Object adapter; int argsCount = N - classCount - 1; try { if (argsCount > 0) { // Arguments contain parameters for super-class constructor. // We use the generic Java method lookup logic to find and // invoke the right constructor. Object[] ctorArgs = new Object[argsCount + 2]; ctorArgs[0] = obj; ctorArgs[1] = cx.getFactory(); System.arraycopy(args, classCount + 1, ctorArgs, 2, argsCount); // TODO: cache class wrapper? NativeJavaClass classWrapper = new NativeJavaClass(scope, adapterClass, true); NativeJavaMethod ctors = classWrapper.members.ctors; int index = ctors.findCachedFunction(cx, ctorArgs); if (index < 0) { String sig = NativeJavaMethod.scriptSignature(args); throw Context.reportRuntimeError2("msg.no.java.ctor", adapterClass.getName(), sig); } // Found the constructor, so try invoking it. adapter = NativeJavaClass.constructInternal(ctorArgs, ctors.methods[index]); } else { Class<?>[] ctorParms = {ScriptRuntime.ScriptableClass, ScriptRuntime.ContextFactoryClass}; Object[] ctorArgs = {obj, cx.getFactory()}; adapter = adapterClass.getConstructor(ctorParms).newInstance(ctorArgs); } Object self = getAdapterSelf(adapterClass, adapter); // Return unwrapped JavaAdapter if it implements Scriptable if (self instanceof Wrapper) { Object unwrapped = ((Wrapper) self).unwrap(); if (unwrapped instanceof Scriptable) { if (unwrapped instanceof ScriptableObject) { ScriptRuntime.setObjectProtoAndParent((ScriptableObject) unwrapped, scope); } return unwrapped; } } return self; } catch (Exception ex) { throw Context.throwAsScriptRuntimeEx(ex); } }