jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg) { if(arg->IsNull() || arg->IsUndefined()) { return NULL; } if(arg->IsArray()) { v8::Local<v8::Array> array = v8::Array::Cast(*arg); uint32_t arraySize = array->Length(); jclass objectClazz = env->FindClass("java/lang/Object"); jobjectArray result = env->NewObjectArray(arraySize, objectClazz, NULL); for(uint32_t i=0; i<arraySize; i++) { jobject val = v8ToJava(env, array->Get(i)); env->SetObjectArrayElement(result, i, val); } return result; } if(arg->IsString()) { v8::String::AsciiValue val(arg->ToString()); return env->NewStringUTF(*val); } if(arg->IsInt32() || arg->IsUint32()) { jint val = arg->ToInt32()->Value(); jclass clazz = env->FindClass("java/lang/Integer"); jmethodID constructor = env->GetMethodID(clazz, "<init>", "(I)V"); return env->NewObject(clazz, constructor, val); } if(arg->IsNumber()) { jdouble val = arg->ToNumber()->Value(); jclass clazz = env->FindClass("java/lang/Double"); jmethodID constructor = env->GetMethodID(clazz, "<init>", "(D)V"); return env->NewObject(clazz, constructor, val); } if(arg->IsBoolean()) { jboolean val = arg->ToBoolean()->Value(); jclass clazz = env->FindClass("java/lang/Boolean"); jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Z)V"); return env->NewObject(clazz, constructor, val); } if(arg->IsObject()) { v8::Local<v8::Object> obj = v8::Object::Cast(*arg); v8::String::AsciiValue constructorName(obj->GetConstructorName()); if(strcmp(*constructorName, "JavaObject") == 0) { JavaObject* javaObject = node::ObjectWrap::Unwrap<JavaObject>(obj); return javaObject->getObject(); } } // TODO: handle other arg types v8::String::AsciiValue typeStr(arg); printf("Unhandled type: %s\n", *typeStr); return NULL; }
jobject v8ToJava_javaObject(JNIEnv* env, v8::Local<v8::Object> obj) { JavaObject* javaObject = node::ObjectWrap::Unwrap<JavaObject>(obj); jobject jobj = javaObject->getObject(); jclass nodeDynamicProxyClass = env->FindClass("node/NodeDynamicProxyClass"); if(env->IsInstanceOf(jobj, nodeDynamicProxyClass)) { jfieldID ptrField = env->GetFieldID(nodeDynamicProxyClass, "ptr", "J"); DynamicProxyData* proxyData = (DynamicProxyData*)(long)env->GetLongField(jobj, ptrField); if(!dynamicProxyDataVerify(proxyData)) { return NULL; } jclass dynamicInterface = javaFindClass(env, proxyData->interfaceName); if(dynamicInterface == NULL) { printf("Could not find interface %s\n", proxyData->interfaceName.c_str()); return NULL; } jclass classClazz = env->FindClass("java/lang/Class"); jobjectArray classArray = env->NewObjectArray(1, classClazz, NULL); env->SetObjectArrayElement(classArray, 0, dynamicInterface); jmethodID class_getClassLoader = env->GetMethodID(classClazz, "getClassLoader", "()Ljava/lang/ClassLoader;"); jobject classLoader = env->CallObjectMethod(dynamicInterface, class_getClassLoader); if(classLoader == NULL) { jclass objectClazz = env->FindClass("java/lang/Object"); jmethodID object_getClass = env->GetMethodID(objectClazz, "getClass", "()Ljava/lang/Class;"); jobject jobjClass = env->CallObjectMethod(jobj, object_getClass); classLoader = env->CallObjectMethod(jobjClass, class_getClassLoader); } jclass proxyClass = env->FindClass("java/lang/reflect/Proxy"); jmethodID proxy_newProxyInstance = env->GetStaticMethodID(proxyClass, "newProxyInstance", "(Ljava/lang/ClassLoader;[Ljava/lang/Class;Ljava/lang/reflect/InvocationHandler;)Ljava/lang/Object;"); if(classLoader == NULL) { printf("Could not get classloader for Proxy\n"); return NULL; } if(classArray == NULL) { printf("Could not create class array for Proxy\n"); return NULL; } if(jobj == NULL) { printf("Not a valid object to wrap\n"); return NULL; } jobj = env->CallStaticObjectMethod(proxyClass, proxy_newProxyInstance, classLoader, classArray, jobj); } return jobj; }