@@ -15,7 +15,7 @@ std::list<jobject> javaReflectionGetMethods(JNIEnv *env, jclass clazz) {
1515 jmethodID clazz_getMethods = env->GetMethodID (clazzclazz, " getMethods" , " ()[Ljava/lang/reflect/Method;" );
1616 jclass methodClazz = env->FindClass (" java/lang/reflect/Method" );
1717 jmethodID method_getModifiers = env->GetMethodID (methodClazz, " getModifiers" , " ()I" );
18-
18+
1919 jobjectArray methodObjects = (jobjectArray)env->CallObjectMethod (clazz, clazz_getMethods);
2020 jsize methodCount = env->GetArrayLength (methodObjects);
2121 for (jsize i=0 ; i<methodCount; i++) {
@@ -37,7 +37,7 @@ std::list<jobject> javaReflectionGetFields(JNIEnv *env, jclass clazz) {
3737 jmethodID clazz_getFields = env->GetMethodID (clazzclazz, " getFields" , " ()[Ljava/lang/reflect/Field;" );
3838 jclass fieldClazz = env->FindClass (" java/lang/reflect/Field" );
3939 jmethodID field_getModifiers = env->GetMethodID (fieldClazz, " getModifiers" , " ()I" );
40-
40+
4141 jobjectArray fieldObjects = (jobjectArray)env->CallObjectMethod (clazz, clazz_getFields);
4242 jsize fieldCount = env->GetArrayLength (fieldObjects);
4343 for (jsize i=0 ; i<fieldCount; i++) {
@@ -104,7 +104,9 @@ jobject javaFindBestMatchingMethod(
104104 JNIEnv *env,
105105 std::list<jobject>& methods,
106106 const char *methodName,
107- std::list<jvalueType>& argTypes) {
107+ jobjectArray args) {
108+
109+ jsize argsSize = env->GetArrayLength (args);
108110
109111 std::list<jobject> possibleMatches;
110112 jclass methodClazz = env->FindClass (" java/lang/reflect/Method" );
@@ -114,8 +116,8 @@ jobject javaFindBestMatchingMethod(
114116 for (std::list<jobject>::iterator it = methods.begin (); it != methods.end (); it++) {
115117 std::string itMethodName = javaToString (env, (jstring)env->CallObjectMethod (*it, method_getNameMethod));
116118 if (itMethodName == methodName) {
117- jarray parameters = (jarray )env->CallObjectMethod (*it, method_getParameterTypes);
118- if (env->GetArrayLength (parameters) == (jsize)argTypes. size () ) {
119+ jobjectArray parameters = (jobjectArray )env->CallObjectMethod (*it, method_getParameterTypes);
120+ if (env->GetArrayLength (parameters) == argsSize ) {
119121 possibleMatches.push_back (*it);
120122 }
121123 }
@@ -127,13 +129,31 @@ jobject javaFindBestMatchingMethod(
127129 if (possibleMatches.size () == 1 ) {
128130 return possibleMatches.front ();
129131 } else {
130- // TODO: argument match
132+ // second pass to check arguments
133+ for (std::list<jobject>::iterator it = possibleMatches.begin (); it != possibleMatches.end (); it++) {
134+ jobjectArray possibleMatchArgs = (jobjectArray)env->CallObjectMethod (*it, method_getParameterTypes);
135+ jsize i;
136+ for (i=0 ; i<argsSize; i++) {
137+ jobject arg = env->GetObjectArrayElement (args, i);
138+ // jclass argClass = env->GetObjectClass(arg);
139+ jclass possibleMatchArgClass = (jclass)env->GetObjectArrayElement (possibleMatchArgs, i);
140+ jboolean isAssignableFrom = env->IsInstanceOf (arg, possibleMatchArgClass);
141+ // printf("match\n\t%s\n\t%s\n\t%d\n", javaObjectToString(env,argClass).c_str(), javaObjectToString(env,possibleMatchArgClass).c_str(), isAssignableFrom);
142+ if (!isAssignableFrom)
143+ break ;
144+ }
145+ if (i == argsSize) {
146+ return *it;
147+ }
148+ }
149+
131150 /*
132151 printf("javaFindBestMatchingMethod: multiple matches (choosing the first)\n");
133152 for(std::list<jobject>::iterator it = possibleMatches.begin(); it != possibleMatches.end(); it++) {
134153 printf(" %s\n", javaObjectToString(env, *it).c_str());
135154 }
136155 */
156+
137157 return possibleMatches.front ();
138158 }
139159
@@ -143,15 +163,17 @@ jobject javaFindBestMatchingMethod(
143163jobject javaFindBestMatchingConstructor (
144164 JNIEnv *env,
145165 std::list<jobject>& constructors,
146- std::list<jvalueType>& argTypes) {
166+ jobjectArray args) {
167+
168+ jsize argsSize = env->GetArrayLength (args);
147169
148170 std::list<jobject> possibleMatches;
149171 jclass constructorClazz = env->FindClass (" java/lang/reflect/Constructor" );
150172 jmethodID constructor_getParameterTypes = env->GetMethodID (constructorClazz, " getParameterTypes" , " ()[Ljava/lang/Class;" );
151173
152174 for (std::list<jobject>::iterator it = constructors.begin (); it != constructors.end (); it++) {
153175 jarray parameters = (jarray)env->CallObjectMethod (*it, constructor_getParameterTypes);
154- if (env->GetArrayLength (parameters) == (jsize)argTypes. size () ) {
176+ if (env->GetArrayLength (parameters) == argsSize ) {
155177 possibleMatches.push_back (*it);
156178 }
157179 }
@@ -193,7 +215,7 @@ jvalueType javaGetType(JNIEnv *env, jclass type) {
193215 jclass clazzClazz = env->FindClass (" java/lang/Class" );
194216 jmethodID class_isArray = env->GetMethodID (clazzClazz, " isArray" , " ()Z" );
195217 jmethodID class_getComponentType = env->GetMethodID (clazzClazz, " getComponentType" , " ()Ljava/lang/Class;" );
196-
218+
197219 jboolean isArray = env->CallBooleanMethod (type, class_isArray);
198220 if (isArray) {
199221 jclass componentTypeClass = (jclass)env->CallObjectMethod (type, class_getComponentType);
@@ -255,7 +277,7 @@ jobject javaFindField(JNIEnv* env, jclass clazz, std::string fieldName) {
255277 return NULL ;
256278}
257279
258- jobject v8ToJava (JNIEnv* env, v8::Local<v8::Value> arg, jvalueType *methodArgType ) {
280+ jobject v8ToJava (JNIEnv* env, v8::Local<v8::Value> arg) {
259281 if (arg->IsNull () || arg->IsUndefined ()) {
260282 return NULL ;
261283 }
@@ -266,31 +288,26 @@ jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg, jvalueType *methodArgTyp
266288 jclass objectClazz = env->FindClass (" java/lang/Object" );
267289 jobjectArray result = env->NewObjectArray (arraySize, objectClazz, NULL );
268290 for (uint32_t i=0 ; i<arraySize; i++) {
269- jvalueType argType;
270- jobject val = v8ToJava (env, array->Get (i), &argType);
291+ jobject val = v8ToJava (env, array->Get (i));
271292 env->SetObjectArrayElement (result, i, val);
272293 }
273- *methodArgType = TYPE_ARRAY_OBJECT;
274294 return result;
275295 }
276-
296+
277297 if (arg->IsString ()) {
278- *methodArgType = TYPE_STRING;
279298 v8::String::AsciiValue val (arg->ToString ());
280299 return env->NewStringUTF (*val);
281300 }
282301
283302 if (arg->IsInt32 ()) {
284303 jint val = arg->ToInt32 ()->Value ();
285- *methodArgType = TYPE_INT;
286304 jclass clazz = env->FindClass (" java/lang/Integer" );
287305 jmethodID constructor = env->GetMethodID (clazz, " <init>" , " (I)V" );
288306 return env->NewObject (clazz, constructor, val);
289307 }
290308
291309 if (arg->IsBoolean ()) {
292310 jboolean val = arg->ToBoolean ()->Value ();
293- *methodArgType = TYPE_BOOLEAN;
294311 jclass clazz = env->FindClass (" java/lang/Boolean" );
295312 jmethodID constructor = env->GetMethodID (clazz, " <init>" , " (Z)V" );
296313 return env->NewObject (clazz, constructor, val);
@@ -301,29 +318,23 @@ jobject v8ToJava(JNIEnv* env, v8::Local<v8::Value> arg, jvalueType *methodArgTyp
301318 v8::String::AsciiValue constructorName (obj->GetConstructorName ());
302319 if (strcmp (*constructorName, " JavaObject" ) == 0 ) {
303320 JavaObject* javaObject = node::ObjectWrap::Unwrap<JavaObject>(obj);
304- *methodArgType = TYPE_OBJECT;
305321 return javaObject->getObject ();
306322 }
307323 }
308324
309325 // TODO: handle other arg types
310326 v8::String::AsciiValue typeStr (arg);
311327 printf (" Unhandled type: %s\n " , *typeStr);
312- *methodArgType = TYPE_OBJECT;
313328 return NULL ;
314329}
315330
316- jarray v8ToJava (JNIEnv* env, const v8::Arguments& args, int start, int end, std::list<jvalueType> *methodArgTypes ) {
331+ jobjectArray v8ToJava (JNIEnv* env, const v8::Arguments& args, int start, int end) {
317332 jclass clazz = env->FindClass (" java/lang/Object" );
318333 jobjectArray results = env->NewObjectArray (end-start, clazz, NULL );
319334
320335 for (int i=start; i<end; i++) {
321- jvalueType methodArgType;
322- jobject val = v8ToJava (env, args[i], &methodArgType);
336+ jobject val = v8ToJava (env, args[i]);
323337 env->SetObjectArrayElement (results, i - start, val);
324- if (methodArgTypes) {
325- methodArgTypes->push_back (methodArgType);
326- }
327338 }
328339
329340 return results;
@@ -340,21 +351,21 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, jthrowable ex, const std::s
340351 jmethodID stringWriter_constructor = env->GetMethodID (stringWriterClazz, " <init>" , " ()V" );
341352 jmethodID stringWriter_toString = env->GetMethodID (stringWriterClazz, " toString" , " ()Ljava/lang/String;" );
342353 jobject stringWriter = env->NewObject (stringWriterClazz, stringWriter_constructor);
343-
354+
344355 jclass printWriterClazz = env->FindClass (" java/io/PrintWriter" );
345356 jmethodID printWriter_constructor = env->GetMethodID (printWriterClazz, " <init>" , " (Ljava/io/Writer;)V" );
346357 jobject printWriter = env->NewObject (printWriterClazz, printWriter_constructor, stringWriter);
347-
358+
348359 jclass throwableClazz = env->FindClass (" java/lang/Throwable" );
349360 jmethodID throwable_printStackTrace = env->GetMethodID (throwableClazz, " printStackTrace" , " (Ljava/io/PrintWriter;)V" );
350361 env->CallObjectMethod (ex, throwable_printStackTrace, printWriter);
351-
362+
352363 jstring strObj = (jstring)env->CallObjectMethod (stringWriter, stringWriter_toString);
353364 std::string stackTrace = javaToString (env, strObj);
354365
355366 msg << " \n " << stackTrace;
356- }
357-
367+ }
368+
358369 return scope.Close (v8::Exception::Error (v8::String::New (msg.str ().c_str ())));
359370}
360371
@@ -366,31 +377,31 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternat
366377
367378v8::Handle<v8::Value> javaArrayToV8 (Java* java, JNIEnv* env, jvalueType itemType, jobjectArray objArray) {
368379 v8::HandleScope scope;
369-
380+
370381 if (objArray == NULL ) {
371382 return v8::Null ();
372383 }
373-
384+
374385 // printf("javaArrayToV8: %d %s\n", itemType, javaObjectToString(env, objArray).c_str());
375-
386+
376387 jsize arraySize = env->GetArrayLength (objArray);
377388 // printf("array size: %d\n", arraySize);
378-
379- v8::Handle<v8::Array> result = v8::Array::New (arraySize);
380- for (jsize i=0 ; i<arraySize; i++) {
389+
390+ v8::Handle<v8::Array> result = v8::Array::New (arraySize);
391+ for (jsize i=0 ; i<arraySize; i++) {
381392 jobject obj = env->GetObjectArrayElement (objArray, i);
382393 v8::Handle<v8::Value> item = javaToV8 (java, env, itemType, obj);
383394 result->Set (i, item);
384395 }
385-
396+
386397 return scope.Close (result);
387398}
388399
389400v8::Handle<v8::Value> javaToV8 (Java* java, JNIEnv* env, jvalueType resultType, jobject obj) {
390401 v8::HandleScope scope;
391-
402+
392403 // printf("javaToV8: %d %s\n", resultType, javaObjectToString(env, obj).c_str());
393-
404+
394405 if ((resultType & VALUE_TYPE_ARRAY) == VALUE_TYPE_ARRAY) {
395406 v8::Handle<v8::Value> result = javaArrayToV8 (java, env, (jvalueType)(resultType & ~VALUE_TYPE_ARRAY), (jobjectArray)obj);
396407 return scope.Close (result);
0 commit comments