Handle<FunctionTemplate> PushbotsModule::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("com/pushbots/android/PushbotsModule"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("Pushbots"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::KrollModule::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<PushbotsModule>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "setPushEnabled", PushbotsModule::setPushEnabled); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "tag", PushbotsModule::tag); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "example", PushbotsModule::example); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- instanceTemplate->SetAccessor(String::NewSymbol("alias"), titanium::Proxy::getProperty , PushbotsModule::setter_alias , Handle<Value>(), DEFAULT); instanceTemplate->SetAccessor(String::NewSymbol("enabled"), PushbotsModule::getter_enabled , PushbotsModule::setter_enabled , Handle<Value>(), DEFAULT); instanceTemplate->SetAccessor(String::NewSymbol("exampleProp"), PushbotsModule::getter_exampleProp , PushbotsModule::setter_exampleProp , Handle<Value>(), DEFAULT); // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> ExampleProxy::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("ro/mihaiblaga/imei/ExampleProxy"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("Example"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::TiViewProxy::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<ExampleProxy>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "setMessage", ExampleProxy::setMessage); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "getMessage", ExampleProxy::getMessage); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "printMessage", ExampleProxy::printMessage); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "getImei", ExampleProxy::getImei); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- instanceTemplate->SetAccessor(String::NewSymbol("message"), ExampleProxy::getter_message , ExampleProxy::setter_message , Handle<Value>(), DEFAULT); instanceTemplate->SetAccessor(String::NewSymbol("imei"), ExampleProxy::getter_imei , titanium::Proxy::onPropertyChanged , Handle<Value>(), DEFAULT); // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> NfcTagProxy::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("ta/nfc/NfcTagProxy"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("NfcTag"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::KrollProxy::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<NfcTagProxy>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "getId", NfcTagProxy::getId); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "getTechList", NfcTagProxy::getTechList); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- instanceTemplate->SetAccessor(String::NewSymbol("id"), NfcTagProxy::getter_id , titanium::Proxy::onPropertyChanged , Handle<Value>(), DEFAULT); instanceTemplate->SetAccessor(String::NewSymbol("techList"), NfcTagProxy::getter_techList , titanium::Proxy::onPropertyChanged , Handle<Value>(), DEFAULT); // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> LocalyticsModule::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("pw/localytics/LocalyticsModule"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("Localytics"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::KrollModule::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<LocalyticsModule>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "logEvent", LocalyticsModule::logEvent); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "registerForPush", LocalyticsModule::registerForPush); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "logScreen", LocalyticsModule::logScreen); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "pauseSession", LocalyticsModule::pauseSession); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "resumeSession", LocalyticsModule::resumeSession); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "initSession", LocalyticsModule::initSession); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> ViewProxy::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("ti/osmdroid/ViewProxy"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("View"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::TiViewProxy::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<ViewProxy>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "addAnnotations", ViewProxy::addAnnotations); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "zoom", ViewProxy::zoom); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "setMapType", ViewProxy::setMapType); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "setLocation", ViewProxy::setLocation); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> TitestModule::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("teunozz/test/module/TitestModule"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("Titest"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::KrollModule::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<TitestModule>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "start", TitestModule::start); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "sendData", TitestModule::sendData); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "stop", TitestModule::stop); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> TiAndroidRequeststoragepermissionModule::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("com/boxoutthinkers/reqstorageperm/TiAndroidRequeststoragepermissionModule"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("TiAndroidRequeststoragepermission"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::KrollModule::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<TiAndroidRequeststoragepermissionModule>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- DEFINE_PROTOTYPE_METHOD(proxyTemplate, "requestStoragePermissions", TiAndroidRequeststoragepermissionModule::requestStoragePermissions); DEFINE_PROTOTYPE_METHOD(proxyTemplate, "hasStoragePermission", TiAndroidRequeststoragepermissionModule::hasStoragePermission); Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- // Accessors -------------------------------------------------------------- return proxyTemplate; }
Handle<FunctionTemplate> ApplifecycleModule::getProxyTemplate() { if (!proxyTemplate.IsEmpty()) { return proxyTemplate; } LOGD(TAG, "GetProxyTemplate"); javaClass = titanium::JNIUtil::findClass("de/appwerft/applifecycle/ApplifecycleModule"); HandleScope scope; // use symbol over string for efficiency Handle<String> nameSymbol = String::NewSymbol("Applifecycle"); Handle<FunctionTemplate> t = titanium::Proxy::inheritProxyTemplate( titanium::KrollModule::getProxyTemplate() , javaClass, nameSymbol); proxyTemplate = Persistent<FunctionTemplate>::New(t); proxyTemplate->Set(titanium::Proxy::inheritSymbol, FunctionTemplate::New(titanium::Proxy::inherit<ApplifecycleModule>)->GetFunction()); titanium::ProxyFactory::registerProxyPair(javaClass, *proxyTemplate); // Method bindings -------------------------------------------------------- Local<ObjectTemplate> prototypeTemplate = proxyTemplate->PrototypeTemplate(); Local<ObjectTemplate> instanceTemplate = proxyTemplate->InstanceTemplate(); // Delegate indexed property get and set to the Java proxy. instanceTemplate->SetIndexedPropertyHandler(titanium::Proxy::getIndexedProperty, titanium::Proxy::setIndexedProperty); // Constants -------------------------------------------------------------- // Dynamic properties ----------------------------------------------------- // Accessors -------------------------------------------------------------- return proxyTemplate; }
int ArrayType::PlatformNew(JNIEnv *jniEnv, Handle<Object> *val) { int result = OK; if(function.IsEmpty()) { functionTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(PlatformCtor)); functionTemplate->SetClassName(sClassName); Local<ObjectTemplate> instanceTemplate = functionTemplate->InstanceTemplate(); instanceTemplate->SetInternalFieldCount(2); instanceTemplate->SetAccessor(env->getConv()->getArrayConv()->getSLength(), PlatformLengthGet, PlatformLengthSet); instanceTemplate->SetIndexedPropertyHandler(PlatformElementGet, PlatformElementSet); function = Persistent<Function>::New(functionTemplate->GetFunction()); /* set prototype to inherit from Array */ function->Set(String::New("prototype"), Array::New()->GetPrototype()); } if(result == OK) { Local<Object> local = function->NewInstance(); result = local.IsEmpty() ? ErrorVM : OK; if(result == OK) { local->SetPointerInInternalField(1, this); *val = local; } } return result; }
Local<v8::Object> mongoToV8( const BSONObj& m , bool array, bool readOnly ){ // handle DBRef. needs to come first. isn't it? (metagoto) static string ref = "$ref"; if ( ref == m.firstElement().fieldName() ) { const BSONElement& id = m["$id"]; if (!id.eoo()) { // there's no check on $id exitence in sm implementation. risky ? v8::Function* dbRef = getNamedCons( "DBRef" ); v8::Handle<v8::Value> argv[2]; argv[0] = mongoToV8Element(m.firstElement()); argv[1] = mongoToV8Element(m["$id"]); return dbRef->NewInstance(2, argv); } } Local< v8::ObjectTemplate > readOnlyObjects; // Hoping template construction is fast... Local< v8::ObjectTemplate > internalFieldObjects = v8::ObjectTemplate::New(); internalFieldObjects->SetInternalFieldCount( 1 ); Local<v8::Object> o; if ( array ) { // NOTE Looks like it's impossible to add interceptors to non array objects in v8. o = v8::Array::New(); } else if ( !readOnly ) { o = v8::Object::New(); } else { // NOTE Our readOnly implemention relies on undocumented ObjectTemplate // functionality that may be fragile, but it still seems like the best option // for now -- fwiw, the v8 docs are pretty sparse. I've determined experimentally // that when property handlers are set for an object template, they will attach // to objects previously created by that template. To get this to work, though, // it is necessary to initialize the template's property handlers before // creating objects from the template (as I have in the following few lines // of code). // NOTE In my first attempt, I configured the permanent property handlers before // constructiong the object and replaced the Set() calls below with ForceSet(). // However, it turns out that ForceSet() only bypasses handlers for named // properties and not for indexed properties. readOnlyObjects = v8::ObjectTemplate::New(); // NOTE This internal field will store type info for special db types. For // regular objects the field is unnecessary - for simplicity I'm creating just // one readOnlyObjects template for objects where the field is & isn't necessary, // assuming that the overhead of an internal field is slight. readOnlyObjects->SetInternalFieldCount( 1 ); readOnlyObjects->SetNamedPropertyHandler( 0 ); readOnlyObjects->SetIndexedPropertyHandler( 0 ); o = readOnlyObjects->NewInstance(); } mongo::BSONObj sub; for ( BSONObjIterator i(m); i.more(); ) { const BSONElement& f = i.next(); Local<Value> v; switch ( f.type() ){ case mongo::Code: o->Set( v8::String::New( f.fieldName() ), newFunction( f.valuestr() ) ); break; case CodeWScope: if ( f.codeWScopeObject().isEmpty() ) log() << "warning: CodeWScope doesn't transfer to db.eval" << endl; o->Set( v8::String::New( f.fieldName() ), newFunction( f.codeWScopeCode() ) ); break; case mongo::String: o->Set( v8::String::New( f.fieldName() ) , v8::String::New( f.valuestr() ) ); break; case mongo::jstOID: { v8::Function * idCons = getObjectIdCons(); v8::Handle<v8::Value> argv[1]; argv[0] = v8::String::New( f.__oid().str().c_str() ); o->Set( v8::String::New( f.fieldName() ) , idCons->NewInstance( 1 , argv ) ); break; } case mongo::NumberDouble: case mongo::NumberInt: o->Set( v8::String::New( f.fieldName() ) , v8::Number::New( f.number() ) ); break; case mongo::Array: case mongo::Object: sub = f.embeddedObject(); o->Set( v8::String::New( f.fieldName() ) , mongoToV8( sub , f.type() == mongo::Array, readOnly ) ); break; case mongo::Date: o->Set( v8::String::New( f.fieldName() ) , v8::Date::New( f.date() ) ); break; case mongo::Bool: o->Set( v8::String::New( f.fieldName() ) , v8::Boolean::New( f.boolean() ) ); break; case mongo::jstNULL: case mongo::Undefined: // duplicate sm behavior o->Set( v8::String::New( f.fieldName() ) , v8::Null() ); break; case mongo::RegEx: { v8::Function * regex = getNamedCons( "RegExp" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::String::New( f.regex() ); argv[1] = v8::String::New( f.regexFlags() ); o->Set( v8::String::New( f.fieldName() ) , regex->NewInstance( 2 , argv ) ); break; } case mongo::BinData: { Local<v8::Object> b = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance(); int len; const char *data = f.binData( len ); v8::Function* binData = getNamedCons( "BinData" ); v8::Handle<v8::Value> argv[3]; argv[0] = v8::Number::New( len ); argv[1] = v8::Number::New( f.binDataType() ); argv[2] = v8::String::New( data, len ); o->Set( v8::String::New( f.fieldName() ), binData->NewInstance(3, argv) ); break; } case mongo::Timestamp: { Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance(); sub->Set( v8::String::New( "time" ) , v8::Date::New( f.timestampTime() ) ); sub->Set( v8::String::New( "i" ) , v8::Number::New( f.timestampInc() ) ); sub->SetInternalField( 0, v8::Uint32::New( f.type() ) ); o->Set( v8::String::New( f.fieldName() ) , sub ); break; } case mongo::NumberLong: { Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance(); unsigned long long val = f.numberLong(); v8::Function* numberLong = getNamedCons( "NumberLong" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::Integer::New( val >> 32 ); argv[1] = v8::Integer::New( (unsigned long)(val & 0x00000000ffffffff) ); o->Set( v8::String::New( f.fieldName() ), numberLong->NewInstance(2, argv) ); break; } case mongo::MinKey: { Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance(); sub->Set( v8::String::New( "$MinKey" ), v8::Boolean::New( true ) ); sub->SetInternalField( 0, v8::Uint32::New( f.type() ) ); o->Set( v8::String::New( f.fieldName() ) , sub ); break; } case mongo::MaxKey: { Local<v8::Object> sub = readOnly ? readOnlyObjects->NewInstance() : internalFieldObjects->NewInstance(); sub->Set( v8::String::New( "$MaxKey" ), v8::Boolean::New( true ) ); sub->SetInternalField( 0, v8::Uint32::New( f.type() ) ); o->Set( v8::String::New( f.fieldName() ) , sub ); break; } case mongo::DBRef: { v8::Function* dbPointer = getNamedCons( "DBPointer" ); v8::Handle<v8::Value> argv[2]; argv[0] = v8::String::New( f.dbrefNS() ); argv[1] = newId( f.dbrefOID() ); o->Set( v8::String::New( f.fieldName() ), dbPointer->NewInstance(2, argv) ); break; } default: cout << "can't handle type: "; cout << f.type() << " "; cout << f.toString(); cout << endl; break; } } if ( !array && readOnly ) { readOnlyObjects->SetNamedPropertyHandler( 0, NamedReadOnlySet, 0, NamedReadOnlyDelete ); readOnlyObjects->SetIndexedPropertyHandler( 0, IndexedReadOnlySet, 0, IndexedReadOnlyDelete ); } return o; }