Skip to content

Commit 9d7aea6

Browse files
committed
better type conversion
1 parent 1abf3ba commit 9d7aea6

7 files changed

Lines changed: 103 additions & 131 deletions

File tree

src/java.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,11 +495,6 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
495495

496496
jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
497497
jmethodID field_get = env->GetMethodID(fieldClazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
498-
jmethodID field_getType = env->GetMethodID(fieldClazz, "getType", "()Ljava/lang/Class;");
499-
500-
// get field type
501-
jclass fieldTypeClazz = (jclass)env->CallObjectMethod(field, field_getType);
502-
jvalueType resultType = javaGetType(env, fieldTypeClazz);
503498

504499
// get field value
505500
jobject val = env->CallObjectMethod(field, field_get, NULL);
@@ -509,7 +504,7 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) {
509504
return ThrowException(javaExceptionToV8(env, errStr.str()));
510505
}
511506

512-
return scope.Close(javaToV8(self, env, resultType, val));
507+
return scope.Close(javaToV8(self, env, val));
513508
}
514509

515510
/*static*/ v8::Handle<v8::Value> Java::setStaticFieldValue(const v8::Arguments& args) {

src/javaObject.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,31 +143,27 @@ JavaObject::~JavaObject() {
143143
JavaObject* self = node::ObjectWrap::Unwrap<JavaObject>(info.This());
144144
JNIEnv *env = self->m_java->getJavaEnv();
145145

146-
v8::String::AsciiValue propertyStr(property);
147-
jobject field = javaFindField(env, self->m_class, *propertyStr);
146+
v8::String::AsciiValue propertyCStr(property);
147+
std::string propertyStr = *propertyCStr;
148+
jobject field = javaFindField(env, self->m_class, propertyStr);
148149
if(field == NULL) {
149150
std::ostringstream errStr;
150-
errStr << "Could not find field " << *propertyStr;
151+
errStr << "Could not find field " << propertyStr;
151152
return ThrowException(javaExceptionToV8(env, errStr.str()));
152153
}
153154

154155
jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
155156
jmethodID field_get = env->GetMethodID(fieldClazz, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
156-
jmethodID field_getType = env->GetMethodID(fieldClazz, "getType", "()Ljava/lang/Class;");
157-
158-
// get field type
159-
jclass fieldTypeClazz = (jclass)env->CallObjectMethod(field, field_getType);
160-
jvalueType resultType = javaGetType(env, fieldTypeClazz);
161157

162158
// get field value
163159
jobject val = env->CallObjectMethod(field, field_get, self->m_obj);
164160
if(env->ExceptionOccurred()) {
165161
std::ostringstream errStr;
166-
errStr << "Could not get field " << *propertyStr;
162+
errStr << "Could not get field " << propertyStr;
167163
return ThrowException(javaExceptionToV8(env, errStr.str()));
168164
}
169165

170-
return scope.Close(javaToV8(self->m_java, env, resultType, val));
166+
return scope.Close(javaToV8(self->m_java, env, val));
171167
}
172168

173169
/*static*/ void JavaObject::fieldSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
@@ -177,11 +173,12 @@ JavaObject::~JavaObject() {
177173

178174
jobject newValue = v8ToJava(env, value);
179175

180-
v8::String::AsciiValue propertyStr(property);
181-
jobject field = javaFindField(env, self->m_class, *propertyStr);
176+
v8::String::AsciiValue propertyCStr(property);
177+
std::string propertyStr = *propertyCStr;
178+
jobject field = javaFindField(env, self->m_class, propertyStr);
182179
if(field == NULL) {
183180
std::ostringstream errStr;
184-
errStr << "Could not find field " << *propertyStr;
181+
errStr << "Could not find field " << propertyStr;
185182
ThrowException(javaExceptionToV8(env, errStr.str()));
186183
return;
187184
}
@@ -195,7 +192,7 @@ JavaObject::~JavaObject() {
195192
env->CallObjectMethod(field, field_set, self->m_obj, newValue);
196193
if(env->ExceptionOccurred()) {
197194
std::ostringstream errStr;
198-
errStr << "Could not set field " << *propertyStr;
195+
errStr << "Could not set field " << propertyStr;
199196
ThrowException(javaExceptionToV8(env, errStr.str()));
200197
return;
201198
}

src/methodCallBaton.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) {
7676
return scope.Close(err);
7777
}
7878

79-
return scope.Close(javaToV8(m_java, env, m_resultType, m_result));
79+
return scope.Close(javaToV8(m_java, env, m_result));
8080
}
8181

8282
void NewInstanceBaton::execute(JNIEnv *env) {
@@ -94,16 +94,12 @@ void NewInstanceBaton::execute(JNIEnv *env) {
9494
return;
9595
}
9696

97-
m_resultType = TYPE_OBJECT;
9897
m_result = env->NewGlobalRef(result);
9998
}
10099

101100
void StaticMethodCallBaton::execute(JNIEnv *env) {
102101
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
103102
jmethodID method_invoke = env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
104-
jmethodID method_getReturnType = env->GetMethodID(methodClazz, "getReturnType", "()Ljava/lang/Class;");
105-
106-
jclass returnType = (jclass)env->CallObjectMethod(m_method, method_getReturnType);
107103

108104
/*
109105
printf("calling %s\n", javaObjectToString(env, m_method).c_str());
@@ -113,7 +109,6 @@ void StaticMethodCallBaton::execute(JNIEnv *env) {
113109
}
114110
*/
115111

116-
m_resultType = javaGetType(env, returnType);
117112
jobject result = env->CallObjectMethod(m_method, method_invoke, NULL, m_args);
118113

119114
jthrowable err = env->ExceptionOccurred();
@@ -130,9 +125,6 @@ void StaticMethodCallBaton::execute(JNIEnv *env) {
130125
void InstanceMethodCallBaton::execute(JNIEnv *env) {
131126
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
132127
jmethodID method_invoke = env->GetMethodID(methodClazz, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
133-
jmethodID method_getReturnType = env->GetMethodID(methodClazz, "getReturnType", "()Ljava/lang/Class;");
134-
135-
jclass returnType = (jclass)env->CallObjectMethod(m_method, method_getReturnType);
136128

137129
/*
138130
printf("calling %s\n", javaObjectToString(env, m_method).c_str());
@@ -142,7 +134,6 @@ void InstanceMethodCallBaton::execute(JNIEnv *env) {
142134
}
143135
*/
144136

145-
m_resultType = javaGetType(env, returnType);
146137
jobject result = env->CallObjectMethod(m_method, method_invoke, m_javaObject->getObject(), m_args);
147138

148139
jthrowable err = env->ExceptionOccurred();

src/methodCallBaton.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class MethodCallBaton {
3333
jarray m_args;
3434
jobject m_result;
3535
jobject m_method;
36-
jvalueType m_resultType;
3736
};
3837

3938
class InstanceMethodCallBaton : public MethodCallBaton {

src/utils.cpp

Lines changed: 75 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -86,38 +86,26 @@ void javaDetachCurrentThread(JavaVM* jvm) {
8686
jvalueType javaGetType(JNIEnv *env, jclass type) {
8787
jclass clazzClazz = env->FindClass("java/lang/Class");
8888
jmethodID class_isArray = env->GetMethodID(clazzClazz, "isArray", "()Z");
89-
jmethodID class_getComponentType = env->GetMethodID(clazzClazz, "getComponentType", "()Ljava/lang/Class;");
9089

9190
jboolean isArray = env->CallBooleanMethod(type, class_isArray);
9291
if(isArray) {
93-
jclass componentTypeClass = (jclass)env->CallObjectMethod(type, class_getComponentType);
94-
jvalueType componentType = javaGetType(env, componentTypeClass);
95-
switch(componentType) {
96-
case TYPE_INT: return TYPE_ARRAY_INT;
97-
case TYPE_LONG: return TYPE_ARRAY_LONG;
98-
case TYPE_OBJECT: return TYPE_ARRAY_OBJECT;
99-
case TYPE_STRING: return TYPE_ARRAY_STRING;
100-
case TYPE_BOOLEAN: return TYPE_ARRAY_BOOLEAN;
101-
case TYPE_BYTE: return TYPE_ARRAY_BYTE;
102-
default:
103-
return TYPE_ARRAY_OBJECT;
104-
}
92+
return TYPE_ARRAY;
10593
} else {
10694
// TODO: has to be a better way
10795
std::string str = javaObjectToString(env, type);
10896
const char *typeStr = str.c_str();
10997
//printf("javaGetType: %s\n", typeStr);
110-
if(strcmp(typeStr, "int") == 0) {
98+
if(strcmp(typeStr, "void") == 0) {
99+
return TYPE_VOID;
100+
} else if(strcmp(typeStr, "int") == 0 || strcmp(typeStr, "class java.lang.Integer") == 0) {
111101
return TYPE_INT;
112-
} else if(strcmp(typeStr, "double") == 0) {
102+
} else if(strcmp(typeStr, "double") == 0 || strcmp(typeStr, "class java.lang.Double") == 0) {
113103
return TYPE_DOUBLE;
114-
} else if(strcmp(typeStr, "long") == 0) {
104+
} else if(strcmp(typeStr, "long") == 0 || strcmp(typeStr, "class java.lang.Long") == 0) {
115105
return TYPE_LONG;
116-
} else if(strcmp(typeStr, "void") == 0) {
117-
return TYPE_VOID;
118-
} else if(strcmp(typeStr, "boolean") == 0) {
106+
} else if(strcmp(typeStr, "boolean") == 0 || strcmp(typeStr, "class java.lang.Boolean") == 0) {
119107
return TYPE_BOOLEAN;
120-
} else if(strcmp(typeStr, "byte") == 0) {
108+
} else if(strcmp(typeStr, "byte") == 0 || strcmp(typeStr, "class java.lang.Byte") == 0) {
121109
return TYPE_BYTE;
122110
} else if(strcmp(typeStr, "class java.lang.String") == 0) {
123111
return TYPE_STRING;
@@ -126,13 +114,14 @@ jvalueType javaGetType(JNIEnv *env, jclass type) {
126114
}
127115
}
128116

129-
jclass javaFindClass(JNIEnv* env, std::string className) {
130-
std::replace(className.begin(), className.end(), '.', '/');
131-
jclass clazz = env->FindClass(className.c_str());
117+
jclass javaFindClass(JNIEnv* env, std::string& className) {
118+
std::string searchClassName = className;
119+
std::replace(searchClassName.begin(), searchClassName.end(), '.', '/');
120+
jclass clazz = env->FindClass(searchClassName.c_str());
132121
return clazz;
133122
}
134123

135-
jobject javaFindField(JNIEnv* env, jclass clazz, std::string fieldName) {
124+
jobject javaFindField(JNIEnv* env, jclass clazz, std::string& fieldName) {
136125
jclass clazzclazz = env->GetObjectClass(clazz);
137126
jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
138127
jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;");
@@ -257,84 +246,92 @@ v8::Handle<v8::Value> javaExceptionToV8(JNIEnv* env, const std::string& alternat
257246
return scope.Close(javaExceptionToV8(env, ex, alternateMessage));
258247
}
259248

260-
v8::Handle<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jvalueType itemType, jobjectArray objArray) {
249+
v8::Handle<v8::Value> javaArrayToV8(Java* java, JNIEnv* env, jobjectArray objArray) {
261250
v8::HandleScope scope;
262251

263252
if(objArray == NULL) {
264253
return v8::Null();
265254
}
266255

267-
//printf("javaArrayToV8: %d %s\n", itemType, javaObjectToString(env, objArray).c_str());
256+
//printf("javaArrayToV8: %d %s\n", javaObjectToString(env, objArray).c_str());
268257

269258
jsize arraySize = env->GetArrayLength(objArray);
270259
//printf("array size: %d\n", arraySize);
271260

272261
v8::Handle<v8::Array> result = v8::Array::New(arraySize);
273262
for(jsize i=0; i<arraySize; i++) {
274263
jobject obj = env->GetObjectArrayElement(objArray, i);
275-
v8::Handle<v8::Value> item = javaToV8(java, env, itemType, obj);
264+
v8::Handle<v8::Value> item = javaToV8(java, env, obj);
276265
result->Set(i, item);
277266
}
278267

279268
return scope.Close(result);
280269
}
281270

282-
v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jvalueType resultType, jobject obj) {
271+
v8::Handle<v8::Value> javaToV8(Java* java, JNIEnv* env, jobject obj) {
283272
v8::HandleScope scope;
284273

274+
if(obj == NULL) {
275+
return v8::Null();
276+
}
277+
278+
jclass objClazz = env->GetObjectClass(obj);
279+
jvalueType resultType = javaGetType(env, objClazz);
280+
285281
//printf("javaToV8: %d %s\n", resultType, javaObjectToString(env, obj).c_str());
286282

287-
if((resultType & VALUE_TYPE_ARRAY) == VALUE_TYPE_ARRAY) {
288-
v8::Handle<v8::Value> result = javaArrayToV8(java, env, (jvalueType)(resultType & ~VALUE_TYPE_ARRAY), (jobjectArray)obj);
289-
return scope.Close(result);
290-
} else {
291-
switch(resultType) {
292-
case TYPE_VOID:
293-
return v8::Undefined();
294-
case TYPE_BOOLEAN:
295-
{
296-
jclass booleanClazz = env->FindClass("java/lang/Boolean");
297-
jmethodID boolean_booleanValue = env->GetMethodID(booleanClazz, "booleanValue", "()Z");
298-
bool result = env->CallBooleanMethod(obj, boolean_booleanValue);
299-
return scope.Close(v8::Boolean::New(result));
300-
}
301-
case TYPE_BYTE:
302-
{
303-
jclass byteClazz = env->FindClass("java/lang/Byte");
304-
jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B");
305-
jbyte result = env->CallByteMethod(obj, byte_byteValue);
306-
return scope.Close(v8::Number::New(result));
307-
}
308-
case TYPE_LONG:
309-
{
310-
jclass longClazz = env->FindClass("java/lang/Long");
311-
jmethodID long_longValue = env->GetMethodID(longClazz, "longValue", "()J");
312-
jlong result = env->CallLongMethod(obj, long_longValue);
313-
return scope.Close(v8::Number::New(result));
314-
}
315-
case TYPE_INT:
316-
{
317-
jclass integerClazz = env->FindClass("java/lang/Integer");
318-
jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
319-
jint result = env->CallIntMethod(obj, integer_intValue);
320-
return scope.Close(v8::Integer::New(result));
321-
}
322-
case TYPE_DOUBLE:
323-
{
324-
jclass doubleClazz = env->FindClass("java/lang/Double");
325-
jmethodID double_doubleValue = env->GetMethodID(doubleClazz, "doubleValue", "()D");
326-
jdouble result = env->CallDoubleMethod(obj, double_doubleValue);
327-
return scope.Close(v8::Number::New(result));
328-
}
329-
case TYPE_STRING:
330-
return scope.Close(v8::String::New(javaObjectToString(env, obj).c_str()));
331-
case TYPE_OBJECT:
332-
return scope.Close(JavaObject::New(java, obj));
333-
default:
334-
printf("unhandled type: 0x%03x\n", resultType);
335-
return scope.Close(JavaObject::New(java, obj));
336-
}
283+
switch(resultType) {
284+
case TYPE_ARRAY:
285+
{
286+
v8::Handle<v8::Value> result = javaArrayToV8(java, env, (jobjectArray)obj);
287+
return scope.Close(result);
288+
}
289+
case TYPE_VOID:
290+
return v8::Undefined();
291+
case TYPE_BOOLEAN:
292+
{
293+
jclass booleanClazz = env->FindClass("java/lang/Boolean");
294+
jmethodID boolean_booleanValue = env->GetMethodID(booleanClazz, "booleanValue", "()Z");
295+
bool result = env->CallBooleanMethod(obj, boolean_booleanValue);
296+
return scope.Close(v8::Boolean::New(result));
297+
}
298+
case TYPE_BYTE:
299+
{
300+
jclass byteClazz = env->FindClass("java/lang/Byte");
301+
jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B");
302+
jbyte result = env->CallByteMethod(obj, byte_byteValue);
303+
return scope.Close(v8::Number::New(result));
304+
}
305+
case TYPE_LONG:
306+
{
307+
jclass longClazz = env->FindClass("java/lang/Long");
308+
jmethodID long_longValue = env->GetMethodID(longClazz, "longValue", "()J");
309+
jlong result = env->CallLongMethod(obj, long_longValue);
310+
return scope.Close(v8::Number::New(result));
311+
}
312+
case TYPE_INT:
313+
{
314+
jclass integerClazz = env->FindClass("java/lang/Integer");
315+
jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
316+
jint result = env->CallIntMethod(obj, integer_intValue);
317+
return scope.Close(v8::Integer::New(result));
318+
}
319+
case TYPE_DOUBLE:
320+
{
321+
jclass doubleClazz = env->FindClass("java/lang/Double");
322+
jmethodID double_doubleValue = env->GetMethodID(doubleClazz, "doubleValue", "()D");
323+
jdouble result = env->CallDoubleMethod(obj, double_doubleValue);
324+
return scope.Close(v8::Number::New(result));
325+
}
326+
case TYPE_STRING:
327+
return scope.Close(v8::String::New(javaObjectToString(env, obj).c_str()));
328+
case TYPE_OBJECT:
329+
return scope.Close(JavaObject::New(java, obj));
330+
default:
331+
printf("unhandled type: 0x%03x\n", resultType);
332+
return scope.Close(JavaObject::New(java, obj));
337333
}
334+
338335
return v8::Undefined();
339336
}
340337

0 commit comments

Comments
 (0)