FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

GitHub Viewer

#include "javaObject.h" #include "java.h" #include "javaScope.h" #include "utils.h" #include #include /*static*/ std::map JavaObject::sFunctionTemplates; /*static*/ void JavaObject::Init(v8::Handle target) { } /*static*/ v8::Local JavaObject::New(Java *java, jobject obj) { Nan::EscapableHandleScope scope; JNIEnv *env = java->getJavaEnv(); JavaScope javaScope(env); jclass objClazz = env->GetObjectClass(obj); jclass classClazz = env->FindClass("java/lang/Class"); jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;"); jobject classNameJava = env->CallObjectMethod(objClazz, class_getName); checkJavaException(env); std::string className = javaObjectToString(env, classNameJava); std::replace(className.begin(), className.end(), '.', '_'); std::replace(className.begin(), className.end(), '$', '_'); std::replace(className.begin(), className.end(), '[', 'a'); className = "nodeJava_" + className; v8::Local promisify; if(java->DoPromise()) { v8::Local asyncOptions = java->handle()->Get(Nan::New("asyncOptions").ToLocalChecked()).As(); v8::Local promisifyValue = asyncOptions->Get(Nan::New("promisify").ToLocalChecked()); promisify = promisifyValue.As(); } v8::Local funcTemplate; if(sFunctionTemplates.find(className) != sFunctionTemplates.end()) { //printf("existing className: %s\n", className.c_str()); funcTemplate = Nan::New(*sFunctionTemplates[className]); } else { //printf("create className: %s\n", className.c_str()); funcTemplate = Nan::New(); funcTemplate->InstanceTemplate()->SetInternalFieldCount(1); funcTemplate->SetClassName(Nan::New(className.c_str()).ToLocalChecked()); // copy methods to template std::list methods; javaReflectionGetMethods(env, objClazz, &methods, false); jclass methodClazz = env->FindClass("java/lang/reflect/Method"); jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); for(std::list::iterator it = methods.begin(); it != methods.end(); ++it) { jstring methodNameJava = (jstring)env->CallObjectMethod(*it, method_getName); assertNoException(env); std::string methodNameStr = javaToString(env, methodNameJava); v8::Local baseMethodName = Nan::New(methodNameStr.c_str()).ToLocalChecked(); std::string methodNameAsyncStr = methodNameStr; const char* methodNameAsync = methodNameAsyncStr.append(java->AsyncSuffix()).c_str(); v8::Local methodCallTemplate = Nan::New(methodCall, baseMethodName); Nan::SetPrototypeTemplate(funcTemplate, methodNameAsync, methodCallTemplate); std::string methodNameSyncStr = methodNameStr; const char* methodNameSync = methodNameSyncStr.append(java->SyncSuffix()).c_str(); v8::Local methodCallSyncTemplate = Nan::New(methodCallSync, baseMethodName); Nan::SetPrototypeTemplate(funcTemplate, methodNameSync, methodCallSyncTemplate); if (java->DoPromise()) { v8::Local recv = Nan::New(); v8::Local argv[] = { methodCallTemplate->GetFunction() }; v8::Local result = promisify->Call(recv, 1, argv); if (!result->IsFunction()) { fprintf(stderr, "Promisified result is not a function -- asyncOptions.promisify must return a function.\n"); assert(result->IsFunction()); } v8::Local promFunction = result.As(); v8::Local promFunctionTemplate = Nan::New(methodCallPromise, promFunction); std::string methodNamePromiseStr = methodNameStr; const char* methodNamePromise = methodNamePromiseStr.append(java->PromiseSuffix()).c_str(); Nan::SetPrototypeTemplate(funcTemplate, methodNamePromise, promFunctionTemplate); } } // copy fields to template std::list fields; javaReflectionGetFields(env, objClazz, &fields); jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;"); for(std::list::iterator it = fields.begin(); it != fields.end(); ++it) { jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName); checkJavaException(env); std::string fieldNameStr = javaToString(env, fieldNameJava); v8::Local fieldName = Nan::New(fieldNameStr.c_str()).ToLocalChecked(); Nan::SetAccessor(funcTemplate->InstanceTemplate(), fieldName, fieldGetter, fieldSetter); } // copy array methods to template jmethodID class_isArray = env->GetMethodID(classClazz, "isArray", "()Z"); jboolean isArray = env->CallBooleanMethod(objClazz, class_isArray); if(isArray) { v8::Local fieldName = Nan::New("length").ToLocalChecked(); Nan::SetAccessor(funcTemplate->InstanceTemplate(), fieldName, fieldGetter, NULL); Nan::SetIndexedPropertyHandler(funcTemplate->InstanceTemplate(), indexGetter); } Nan::Persistent* persistentFuncTemplate = new Nan::Persistent(); persistentFuncTemplate->Reset(funcTemplate); sFunctionTemplates[className] = persistentFuncTemplate; } v8::Local ctor = Nan::GetFunction(funcTemplate).ToLocalChecked(); v8::Local javaObjectObj = Nan::NewInstance(ctor).ToLocalChecked(); SetHiddenValue(javaObjectObj, Nan::New(V8_HIDDEN_MARKER_JAVA_OBJECT).ToLocalChecked(), Nan::New(true)); JavaObject *self = new JavaObject(java, obj); self->Wrap(javaObjectObj); return scope.Escape(javaObjectObj); } JavaObject::JavaObject(Java *java, jobject obj) { m_java = java; JNIEnv *env = m_java->getJavaEnv(); m_obj = env->NewGlobalRef(obj); m_class = (jclass)env->NewGlobalRef(env->GetObjectClass(obj)); } JavaObject::~JavaObject() { JNIEnv *env = m_java->getJavaEnv(); env->DeleteGlobalRef(m_obj); env->DeleteGlobalRef(m_class); } NAN_METHOD(JavaObject::methodCall) { Nan::HandleScope scope; JavaObject* self = Nan::ObjectWrap::Unwrap(info.This()); JNIEnv *env = self->m_java->getJavaEnv(); JavaScope javaScope(env); v8::String::Utf8Value methodName(info.Data()); std::string methodNameStr = *methodName; int argsStart = 0; int argsEnd = info.Length(); // arguments ARGS_BACK_CALLBACK(); if(!callbackProvided && methodNameStr == "toString") { return methodCallSync(info); } jobjectArray methodArgs = v8ToJava(env, info, argsStart, argsEnd); jobject method = javaFindMethod(env, self->m_class, methodNameStr, methodArgs); if(method == NULL) { std::string msg = methodNotFoundToString(env, self->m_class, methodNameStr, false, info, argsStart, argsEnd); EXCEPTION_CALL_CALLBACK(self->m_java, msg); info.GetReturnValue().SetUndefined(); return; } // run InstanceMethodCallBaton* baton = new InstanceMethodCallBaton(self->m_java, self, method, methodArgs, callback); baton->run(); END_CALLBACK_FUNCTION("\"Method '"

Back | FazBrowse Home | New Git URL