void Proxy::proxyConstructor(const v8::FunctionCallbackInfo<v8::Value>& args) { LOGD(TAG, "proxy constructor callback!"); Isolate* isolate = args.GetIsolate(); EscapableHandleScope scope(isolate); JNIEnv *env = JNIScope::getEnv(); Local<Object> jsProxy = args.This(); // First things first, we need to wrap the object in case future calls need to unwrap proxy! Proxy* proxy = new Proxy(NULL); proxy->wrap(isolate, jsProxy); // every instance gets a special "_properties" object for us to use internally for get/setProperty jsProxy->DefineOwnProperty(isolate->GetCurrentContext(), propertiesSymbol.Get(isolate), Object::New(isolate), static_cast<PropertyAttribute>(DontEnum)); // Now we hook up a java Object from the JVM... jobject javaProxy = ProxyFactory::unwrapJavaProxy(args); // do we already have one that got passed in? bool deleteRef = false; if (!javaProxy) { // No passed in java object, so let's create an instance // Look up java class from prototype... Local<Object> prototype = jsProxy->GetPrototype()->ToObject(isolate); Local<Function> constructor = prototype->Get(constructorSymbol.Get(isolate)).As<Function>(); Local<External> wrap = constructor->Get(javaClassSymbol.Get(isolate)).As<External>(); jclass javaClass = static_cast<jclass>(wrap->Value()); // Now we create an instance of the class and hook it up JNIUtil::logClassName("Creating java proxy for class %s", javaClass); javaProxy = ProxyFactory::createJavaProxy(javaClass, jsProxy, args); deleteRef = true; } proxy->attach(javaProxy); int length = args.Length(); if (length > 0 && args[0]->IsObject()) { bool extend = true; Local<Object> createProperties = args[0].As<Object>(); Local<String> constructorName = createProperties->GetConstructorName(); if (strcmp(*titanium::Utf8Value(constructorName), "Arguments") == 0) { extend = false; int32_t argsLength = createProperties->Get(STRING_NEW(isolate, "length"))->Int32Value(); if (argsLength > 1) { Local<Value> properties = createProperties->Get(1); if (properties->IsObject()) { extend = true; createProperties = properties.As<Object>(); } } } if (extend) { Local<Array> names = createProperties->GetOwnPropertyNames(); int length = names->Length(); Local<Object> properties = jsProxy->Get(propertiesSymbol.Get(isolate))->ToObject(isolate); for (int i = 0; i < length; ++i) { Local<Value> name = names->Get(i); Local<Value> value = createProperties->Get(name); bool isProperty = true; if (name->IsString()) { Local<String> nameString = name.As<String>(); if (!jsProxy->HasRealNamedCallbackProperty(nameString) && !jsProxy->HasRealNamedProperty(nameString)) { jsProxy->Set(name, value); isProperty = false; } } if (isProperty) { properties->Set(name, value); } } } } if (!args.Data().IsEmpty() && args.Data()->IsFunction()) { Local<Function> proxyFn = args.Data().As<Function>(); Local<Value> *fnArgs = new Local<Value>[length]; for (int i = 0; i < length; ++i) { fnArgs[i] = args[i]; } proxyFn->Call(isolate->GetCurrentContext(), jsProxy, length, fnArgs); } if (deleteRef) { JNIEnv *env = JNIScope::getEnv(); if (env) { env->DeleteLocalRef(javaProxy); } } args.GetReturnValue().Set(scope.Escape(jsProxy)); }