|
3 | 3 | #include "java.h" |
4 | 4 | #include "utils.h" |
5 | 5 | #include <sstream> |
| 6 | +#include <algorithm> |
6 | 7 |
|
7 | | -/*static*/ v8::Persistent<v8::FunctionTemplate> JavaObject::s_ct; |
| 8 | +std::map<std::string, v8::Persistent<v8::FunctionTemplate> > sFunctionTemplates; |
8 | 9 |
|
9 | 10 | /*static*/ void JavaObject::Init(v8::Handle<v8::Object> target) { |
10 | | - v8::HandleScope scope; |
11 | | - |
12 | | - v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(); |
13 | | - s_ct = v8::Persistent<v8::FunctionTemplate>::New(t); |
14 | | - s_ct->InstanceTemplate()->SetInternalFieldCount(1); |
15 | | - s_ct->SetClassName(v8::String::NewSymbol("JavaObject")); |
16 | | - |
17 | | - target->Set(v8::String::NewSymbol("JavaObject"), s_ct->GetFunction()); |
18 | 11 | } |
19 | 12 |
|
20 | 13 | /*static*/ v8::Local<v8::Object> JavaObject::New(Java *java, jobject obj) { |
|
23 | 16 | JNIEnv *env = java->getJavaEnv(); |
24 | 17 | PUSH_LOCAL_JAVA_FRAME(); |
25 | 18 |
|
26 | | - v8::Local<v8::Function> ctor = s_ct->GetFunction(); |
27 | | - v8::Local<v8::Object> javaObjectObj = ctor->NewInstance(); |
28 | | - JavaObject *self = new JavaObject(java, obj); |
29 | | - self->Wrap(javaObjectObj); |
| 19 | + jclass objClazz = env->GetObjectClass(obj); |
| 20 | + jclass classClazz = env->FindClass("java/lang/Class"); |
| 21 | + jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;"); |
| 22 | + jobject classNameJava = env->CallObjectMethod(objClazz, class_getName); |
| 23 | + std::string className = javaObjectToString(env, classNameJava); |
| 24 | + std::replace(className.begin(), className.end(), '.', '_'); |
| 25 | + std::replace(className.begin(), className.end(), '$', '_'); |
| 26 | + std::replace(className.begin(), className.end(), '[', 'a'); |
| 27 | + className = "nodeJava_" + className; |
| 28 | + |
| 29 | + v8::Persistent<v8::FunctionTemplate> persistentFuncTemplate; |
| 30 | + if(sFunctionTemplates.find(className) != sFunctionTemplates.end()) { |
| 31 | + //printf("existing className: %s\n", className.c_str()); |
| 32 | + persistentFuncTemplate = sFunctionTemplates[className]; |
| 33 | + } else { |
| 34 | + //printf("create className: %s\n", className.c_str()); |
| 35 | + |
| 36 | + v8::Local<v8::FunctionTemplate> funcTemplate = v8::FunctionTemplate::New(); |
| 37 | + funcTemplate->InstanceTemplate()->SetInternalFieldCount(1); |
| 38 | + funcTemplate->SetClassName(v8::String::NewSymbol(className.c_str())); |
| 39 | + |
| 40 | + std::list<jobject> methods; |
| 41 | + javaReflectionGetMethods(env, objClazz, &methods, false); |
| 42 | + jclass methodClazz = env->FindClass("java/lang/reflect/Method"); |
| 43 | + jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); |
| 44 | + for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); it++) { |
| 45 | + jstring methodNameJava = (jstring)env->CallObjectMethod(*it, method_getName); |
| 46 | + std::string methodNameStr = javaToString(env, methodNameJava); |
| 47 | + |
| 48 | + v8::Handle<v8::String> methodName = v8::String::New(methodNameStr.c_str()); |
| 49 | + v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName); |
| 50 | + funcTemplate->PrototypeTemplate()->Set(methodName, methodCallTemplate->GetFunction()); |
| 51 | + |
| 52 | + v8::Handle<v8::String> methodNameSync = v8::String::New((methodNameStr + "Sync").c_str()); |
| 53 | + v8::Local<v8::FunctionTemplate> methodCallSyncTemplate = v8::FunctionTemplate::New(methodCallSync, methodName); |
| 54 | + funcTemplate->PrototypeTemplate()->Set(methodNameSync, methodCallSyncTemplate->GetFunction()); |
| 55 | + |
| 56 | + env->DeleteLocalRef(methodNameJava); |
| 57 | + env->DeleteLocalRef(*it); |
| 58 | + } |
30 | 59 |
|
31 | | - std::list<jobject> methods; |
32 | | - javaReflectionGetMethods(env, self->m_class, &methods, false); |
33 | | - jclass methodClazz = env->FindClass("java/lang/reflect/Method"); |
34 | | - jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); |
35 | | - for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); it++) { |
36 | | - jstring methodNameJava = (jstring)env->CallObjectMethod(*it, method_getName); |
37 | | - std::string methodNameStr = javaToString(env, methodNameJava); |
38 | | - |
39 | | - v8::Handle<v8::String> methodName = v8::String::New(methodNameStr.c_str()); |
40 | | - v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName); |
41 | | - javaObjectObj->Set(methodName, methodCallTemplate->GetFunction()); |
42 | | - |
43 | | - v8::Handle<v8::String> methodNameSync = v8::String::New((methodNameStr + "Sync").c_str()); |
44 | | - v8::Local<v8::FunctionTemplate> methodCallSyncTemplate = v8::FunctionTemplate::New(methodCallSync, methodName); |
45 | | - javaObjectObj->Set(methodNameSync, methodCallSyncTemplate->GetFunction()); |
46 | | - } |
| 60 | + std::list<jobject> fields; |
| 61 | + javaReflectionGetFields(env, objClazz, &fields); |
| 62 | + jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); |
| 63 | + jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;"); |
| 64 | + for(std::list<jobject>::iterator it = fields.begin(); it != fields.end(); it++) { |
| 65 | + jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName); |
| 66 | + std::string fieldNameStr = javaToString(env, fieldNameJava); |
47 | 67 |
|
48 | | - std::list<jobject> fields; |
49 | | - javaReflectionGetFields(env, self->m_class, &fields); |
50 | | - jclass fieldClazz = env->FindClass("java/lang/reflect/Field"); |
51 | | - jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;"); |
52 | | - for(std::list<jobject>::iterator it = fields.begin(); it != fields.end(); it++) { |
53 | | - jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName); |
54 | | - std::string fieldNameStr = javaToString(env, fieldNameJava); |
| 68 | + v8::Handle<v8::String> fieldName = v8::String::New(fieldNameStr.c_str()); |
| 69 | + funcTemplate->PrototypeTemplate()->SetAccessor(fieldName, fieldGetter, fieldSetter); |
| 70 | + |
| 71 | + env->DeleteLocalRef(fieldNameJava); |
| 72 | + env->DeleteLocalRef(*it); |
| 73 | + } |
55 | 74 |
|
56 | | - v8::Handle<v8::String> fieldName = v8::String::New(fieldNameStr.c_str()); |
57 | | - javaObjectObj->SetAccessor(fieldName, fieldGetter, fieldSetter); |
| 75 | + sFunctionTemplates[className] = persistentFuncTemplate = v8::Persistent<v8::FunctionTemplate>::New(funcTemplate); |
58 | 76 | } |
59 | 77 |
|
| 78 | + v8::Local<v8::Function> ctor = persistentFuncTemplate->GetFunction(); |
| 79 | + v8::Local<v8::Object> javaObjectObj = ctor->NewInstance(); |
| 80 | + javaObjectObj->SetHiddenValue(v8::String::New("__isJavaObject"), v8::Boolean::New(true)); |
| 81 | + JavaObject *self = new JavaObject(java, obj); |
| 82 | + self->Wrap(javaObjectObj); |
| 83 | + |
60 | 84 | POP_LOCAL_JAVA_FRAME(); |
61 | 85 |
|
62 | 86 | return scope.Close(javaObjectObj); |
|
0 commit comments