// Needed by NativeJavaObject de-serializer public static Object readAdapterObject(Scriptable self, ObjectInputStream in) throws IOException, ClassNotFoundException { ContextFactory factory; Context cx = Context.getCurrentContext(); if (cx != null) { factory = cx.getFactory(); } else { factory = null; } Class<?> superClass = Class.forName((String) in.readObject()); String[] interfaceNames = (String[]) in.readObject(); Class<?>[] interfaces = new Class[interfaceNames.length]; for (int i = 0; i < interfaceNames.length; i++) interfaces[i] = Class.forName(interfaceNames[i]); Scriptable delegee = (Scriptable) in.readObject(); Class<?> adapterClass = getAdapterClass(self, superClass, interfaces, delegee); Class<?>[] ctorParms = { ScriptRuntime.ContextFactoryClass, ScriptRuntime.ScriptableClass, ScriptRuntime.ScriptableClass }; Object[] ctorArgs = {factory, delegee, self}; try { return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } catch (NoSuchMethodException e) { } throw new ClassNotFoundException("adapter"); }
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); } }