Skip to content

Commit 2420170

Browse files
committed
working on method overload
1 parent 0a88454 commit 2420170

8 files changed

Lines changed: 87 additions & 75 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ $ vcbuild.bat
2828
## Installation Mac
2929

3030
```bash
31-
$ ???
3231
$ npm install java
3332
```
3433

src/java.cpp

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
145145
callbackProvided = false;
146146
}
147147

148-
std::list<jvalueType> methodArgTypes;
149-
jarray methodArgs = v8ToJava(env, args, 1, argsEnd, &methodArgTypes);
148+
jobjectArray methodArgs = v8ToJava(env, args, 1, argsEnd);
150149

151150
jclass clazz = javaFindClass(env, className);
152151
if(clazz == NULL) {
@@ -162,7 +161,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
162161
return v8::Undefined();
163162
}
164163
std::list<jobject> constructors = javaReflectionGetConstructors(env, clazz);
165-
jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgTypes);
164+
jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgs);
166165
if(method == NULL) {
167166
std::ostringstream errStr;
168167
errStr << "Could not find constructor";
@@ -209,8 +208,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
209208
std::string className = *classNameVal;
210209
argsStart++;
211210

212-
std::list<jvalueType> methodArgTypes;
213-
jarray methodArgs = v8ToJava(env, args, argsStart, argsEnd, &methodArgTypes);
211+
jobjectArray methodArgs = v8ToJava(env, args, argsStart, argsEnd);
214212

215213
jclass clazz = javaFindClass(env, className);
216214
if(clazz == NULL) {
@@ -219,7 +217,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
219217
return ThrowException(javaExceptionToV8(env, errStr.str()));
220218
}
221219
std::list<jobject> constructors = javaReflectionGetConstructors(env, clazz);
222-
jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgTypes);
220+
jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgs);
223221
if(method == NULL) {
224222
std::ostringstream errStr;
225223
errStr << "Could not find constructor";
@@ -277,8 +275,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
277275
}
278276

279277
// build args
280-
std::list<jvalueType> methodArgTypes;
281-
jarray methodArgs = v8ToJava(env, args, 2, argsEnd, &methodArgTypes);
278+
jobjectArray methodArgs = v8ToJava(env, args, 2, argsEnd);
282279

283280
// find class and method
284281
jclass clazz = javaFindClass(env, className);
@@ -294,7 +291,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
294291
return v8::Undefined();
295292
}
296293
std::list<jobject> staticMethods = javaReflectionGetStaticMethods(env, clazz);
297-
jobject method = javaFindBestMatchingMethod(env, staticMethods, methodName.c_str(), methodArgTypes);
294+
jobject method = javaFindBestMatchingMethod(env, staticMethods, methodName.c_str(), methodArgs);
298295
if(method == NULL) {
299296
std::ostringstream errStr;
300297
errStr << "Could not find method \"" << methodName.c_str() << "\"";
@@ -348,8 +345,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
348345
std::string methodName = *methodNameVal;
349346

350347
// build args
351-
std::list<jvalueType> methodArgTypes;
352-
jarray methodArgs = v8ToJava(env, args, 2, argsEnd, &methodArgTypes);
348+
jobjectArray methodArgs = v8ToJava(env, args, 2, argsEnd);
353349

354350
// find class and method
355351
jclass clazz = javaFindClass(env, className);
@@ -359,7 +355,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
359355
return ThrowException(javaExceptionToV8(env, errStr.str()));
360356
}
361357
std::list<jobject> staticMethods = javaReflectionGetStaticMethods(env, clazz);
362-
jobject method = javaFindBestMatchingMethod(env, staticMethods, methodName.c_str(), methodArgTypes);
358+
jobject method = javaFindBestMatchingMethod(env, staticMethods, methodName.c_str(), methodArgs);
363359
if(method == NULL) {
364360
std::ostringstream errStr;
365361
errStr << "Could not find method \"" << methodName.c_str() << "\"";
@@ -405,9 +401,8 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
405401
if(strcmp(className.c_str(), "byte") == 0) {
406402
results = env->NewByteArray(arrayObj->Length());
407403
for(uint32_t i=0; i<arrayObj->Length(); i++) {
408-
jvalueType methodArgType;
409404
v8::Local<v8::Value> item = arrayObj->Get(i);
410-
jobject val = v8ToJava(env, item, &methodArgType);
405+
jobject val = v8ToJava(env, item);
411406
jclass byteClazz = env->FindClass("java/lang/Byte");
412407
jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B");
413408
jbyte byteValues[1];
@@ -429,9 +424,8 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
429424
results = env->NewObjectArray(arrayObj->Length(), clazz, NULL);
430425

431426
for(uint32_t i=0; i<arrayObj->Length(); i++) {
432-
jvalueType methodArgType;
433427
v8::Local<v8::Value> item = arrayObj->Get(i);
434-
jobject val = v8ToJava(env, item, &methodArgType);
428+
jobject val = v8ToJava(env, item);
435429
env->SetObjectArrayElement((jobjectArray)results, i, val);
436430
if(env->ExceptionOccurred()) {
437431
std::ostringstream errStr;
@@ -561,8 +555,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
561555
if(args.Length() < 3) {
562556
return ThrowException(v8::Exception::TypeError(v8::String::New("setStaticFieldValue requires 3 arguments")));
563557
}
564-
jvalueType methodArgType;
565-
jobject newValue = v8ToJava(env, args[2], &methodArgType);
558+
jobject newValue = v8ToJava(env, args[2]);
566559

567560
// find the class
568561
jclass clazz = javaFindClass(env, className);

src/javaObject.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ JavaObject::~JavaObject() {
8585
callbackProvided = false;
8686
}
8787

88-
std::list<jvalueType> methodArgTypes;
89-
jarray methodArgs = v8ToJava(env, args, 0, argsEnd, &methodArgTypes);
88+
jobjectArray methodArgs = v8ToJava(env, args, 0, argsEnd);
9089

91-
jobject method = javaFindBestMatchingMethod(env, self->m_methods, *methodName, methodArgTypes);
90+
jobject method = javaFindBestMatchingMethod(env, self->m_methods, *methodName, methodArgs);
9291
if(method == NULL) {
9392
return v8::Undefined(); // TODO: callback with error
9493
}
@@ -113,10 +112,9 @@ JavaObject::~JavaObject() {
113112

114113
v8::String::AsciiValue methodName(args.Data());
115114

116-
std::list<jvalueType> methodArgTypes;
117-
jarray methodArgs = v8ToJava(env, args, 0, args.Length(), &methodArgTypes);
115+
jobjectArray methodArgs = v8ToJava(env, args, 0, args.Length());
118116

119-
jobject method = javaFindBestMatchingMethod(env, self->m_methods, *methodName, methodArgTypes);
117+
jobject method = javaFindBestMatchingMethod(env, self->m_methods, *methodName, methodArgs);
120118
if(method == NULL) {
121119
return v8::Undefined();
122120
}
@@ -166,8 +164,7 @@ JavaObject::~JavaObject() {
166164
JavaObject* self = node::ObjectWrap::Unwrap<JavaObject>(info.This());
167165
JNIEnv *env = self->m_java->getJavaEnv();
168166

169-
jvalueType methodArgType;
170-
jobject newValue = v8ToJava(env, value, &methodArgType);
167+
jobject newValue = v8ToJava(env, value);
171168

172169
v8::String::AsciiValue propertyStr(property);
173170
jobject field = javaFindField(env, self->m_class, *propertyStr);

src/utils.cpp

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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(
143163
jobject 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

367378
v8::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

389400
v8::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

Comments
 (0)