/*static*/ v8::Handle<v8::Value> JavaObject::fieldGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap<JavaObject>(info.This()); JNIEnv *env = self->m_java->getJavaEnv(); JavaScope javaScope(env); v8::String::AsciiValue propertyCStr(property); std::string propertyStr = *propertyCStr; jobject field = javaFindField(env, self->m_class, propertyStr); if(field == NULL) { std::ostringstream errStr; errStr << "Could not find field " << propertyStr; v8::Handle<v8::Value> ex = javaExceptionToV8(env, errStr.str()); return ThrowException(ex); } jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); jmethodID field_get = env->GetMethodID(fieldClazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); // get field value jobject val = env->CallObjectMethod(field, field_get, self->m_obj); if(env->ExceptionOccurred()) { std::ostringstream errStr; errStr << "Could not get field " << propertyStr; v8::Handle<v8::Value> ex = javaExceptionToV8(env, errStr.str()); return ThrowException(ex); } v8::Handle<v8::Value> result = javaToV8(self->m_java, env, val); return scope.Close(result); }
/*static*/ void JavaObject::fieldSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap<JavaObject>(info.This()); JNIEnv *env = self->m_java->getJavaEnv(); JavaScope javaScope(env); jobject newValue = v8ToJava(env, value); v8::String::AsciiValue propertyCStr(property); std::string propertyStr = *propertyCStr; jobject field = javaFindField(env, self->m_class, propertyStr); if(field == NULL) { std::ostringstream errStr; errStr << "Could not find field " << propertyStr; v8::Handle<v8::Value> ex = javaExceptionToV8(env, errStr.str()); ThrowException(ex); return; } jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); jmethodID field_set = env->GetMethodID(fieldClazz, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); //printf("newValue: %s\n", javaObjectToString(env, newValue).c_str()); // set field value env->CallObjectMethod(field, field_set, self->m_obj, newValue); if(env->ExceptionOccurred()) { std::ostringstream errStr; errStr << "Could not set field " << propertyStr; v8::Handle<v8::Value> ex = javaExceptionToV8(env, errStr.str()); ThrowException(ex); return; } }
/*static*/ v8::Handle<v8::Value> JavaObject::methodCallSync(const v8::Arguments& args) { v8::HandleScope scope; JavaObject* self = node::ObjectWrap::Unwrap<JavaObject>(args.This()); JNIEnv *env = self->m_java->getJavaEnv(); JavaScope javaScope(env); v8::String::AsciiValue methodName(args.Data()); std::string methodNameStr = *methodName; int argsStart = 0; int argsEnd = args.Length(); jobjectArray methodArgs = v8ToJava(env, args, argsStart, argsEnd); jobject method = javaFindMethod(env, self->m_class, methodNameStr, methodArgs); if(method == NULL) { std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, args, argsStart, argsEnd); v8::Handle<v8::Value> ex = javaExceptionToV8(env, msg); return ThrowException(ex); } // run v8::Handle<v8::Value> callback = v8::Undefined(); InstanceMethodCallBaton* baton = new InstanceMethodCallBaton(self->m_java, self, method, methodArgs, callback); v8::Handle<v8::Value> result = baton->runSync(); delete baton; if(result->IsNativeError()) { return ThrowException(result); } return scope.Close(result); }
v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) { v8::HandleScope scope; if(m_error) { v8::Handle<v8::Value> err = javaExceptionToV8(env, m_error, m_errorString); return scope.Close(err); } return scope.Close(javaToV8(m_java, env, m_result)); }
v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternateMessage) { v8::HandleScope scope; jthrowable ex = env->ExceptionOccurred(); env->ExceptionClear(); return scope.Close(javaExceptionToV8(env, ex, alternateMessage)); }