use of org.mozilla.javascript.MemberBox in project scriptographer by scriptographer.
the class ExtendedJavaClass method construct.
public Scriptable construct(Context cx, Scriptable scope, Object[] args) {
// If the normal constructor failed, try to see if the last
// argument is a Callable or a NativeObject object.
// If it is a NativeObject, use it as a hashtable containing
// fields to be added to the object. If it is a Callable,
// call it on the object and again use its return value
// as a hashtable if it is a NativeObject.
Class classObject = getClassObject();
int modifiers = classObject.getModifiers();
NativeObject properties = null;
Callable initialize = null;
if (args.length > 0 && !Modifier.isInterface(modifiers) && !Modifier.isAbstract(modifiers)) {
// Look at the last argument to find out if we need to do something
// special. Possibilities: a object literal that defines fields to
// be set, or a function that is executed on the object and of which
// the result can be fields to be set.
Object last = args[args.length - 1];
// which might be arguments to methods...
if (last instanceof Callable && !(last instanceof NativeJavaClass))
initialize = (Callable) last;
else if (last instanceof NativeObject) {
// Now see if the constructor takes a Map as the last argument.
// If so, the NativeObject will be converted to it thought
// RhinoWrapFactory. Otherwise, the NativeObject is used
// as the properties to be set on the instance after creation.
MemberBox ctor = findConstructor(cx, args);
if (ctor != null) {
Class[] types = ctor.ctor().getParameterTypes();
Class lastType = types[types.length - 1];
// of which NativeObject's can be converted to.
if (!ArgumentReader.class.isAssignableFrom(lastType) && !Map.class.isAssignableFrom(lastType)) {
properties = (NativeObject) last;
if (ScriptableObject.hasProperty(properties, "unwrap"))
properties = null;
}
} else {
// There is no constructor that has to be checked, so it
// can only be a properties list.
properties = (NativeObject) last;
}
if (properties != null) {
// Support initialize in the passed object literal too.
Object obj = ScriptableObject.getProperty(properties, "initialize");
if (obj instanceof Callable)
initialize = (Callable) obj;
}
}
// will be found:
if (initialize != null || properties != null) {
Object[] newArgs = new Object[args.length - 1];
for (int i = 0; i < newArgs.length; i++) newArgs[i] = args[i];
args = newArgs;
}
}
Scriptable obj = super.construct(cx, scope, args);
// properties returned by initialize.
if (properties != null)
setProperties(obj, properties);
// into the object after, if it is a NativeObject.
if (initialize != null) {
Object res = initialize.call(cx, scope, obj, args);
if (res instanceof NativeObject)
setProperties(obj, (NativeObject) res);
}
return obj;
}
Aggregations