Skip to content

Commit 91daf0e

Browse files
committed
call method sync
1 parent 713d1ae commit 91daf0e

6 files changed

Lines changed: 91 additions & 31 deletions

File tree

src/java.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,27 @@ Java::~Java() {
8282
}
8383

8484
/*static*/ v8::Handle<v8::Value> Java::newInstanceSync(const v8::Arguments& args) {
85-
return v8::Undefined();
85+
v8::HandleScope scope;
86+
Java* self = node::ObjectWrap::Unwrap<Java>(args.This());
87+
JNIEnv* env = self->getJavaEnv();
88+
89+
// argument - className
90+
if(args.Length() < 1 || !args[0]->IsString()) {
91+
return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 0 must be a string")));
92+
}
93+
v8::Local<v8::String> classNameObj = v8::Local<v8::String>::Cast(args[0]);
94+
v8::String::AsciiValue classNameVal(classNameObj);
95+
std::string className = *classNameVal;
96+
97+
std::list<jobject> methodArgs; // TODO: build args
98+
jclass clazz = javaFindClass(env, className);
99+
std::list<jobject> constructors = javaReflectionGetConstructors(env, clazz);
100+
jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgs);
101+
102+
// run
103+
v8::Handle<v8::Value> callback = v8::Object::New();
104+
NewInstanceBaton* baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback);
105+
v8::Handle<v8::Value> result = baton->runSync();
106+
delete baton;
107+
return scope.Close(result);
86108
}

src/javaObject.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,15 @@
2929
jclass methodClazz = env->FindClass("java/lang/reflect/Method");
3030
jmethodID method_getNameMethod = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;");
3131
for(std::list<jobject>::iterator it = self->m_methods.begin(); it != self->m_methods.end(); it++) {
32-
const char* methodNameStr = javaToString(env, (jstring)env->CallObjectMethod(*it, method_getNameMethod)).c_str();
33-
v8::Handle<v8::String> methodName = v8::String::New(methodNameStr);
34-
v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName);
32+
std::string methodNameStr = javaToString(env, (jstring)env->CallObjectMethod(*it, method_getNameMethod));
33+
34+
v8::Handle<v8::String> methodName = v8::String::New(methodNameStr.c_str());
35+
v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName);
3536
javaObjectObj->Set(methodName, methodCallTemplate->GetFunction());
37+
38+
v8::Handle<v8::String> methodNameSync = v8::String::New((methodNameStr + "Sync").c_str());
39+
v8::Local<v8::FunctionTemplate> methodCallSyncTemplate = v8::FunctionTemplate::New(methodCallSync, methodName);
40+
javaObjectObj->Set(methodNameSync, methodCallSyncTemplate->GetFunction());
3641
}
3742

3843
return scope.Close(javaObjectObj);
@@ -70,7 +75,7 @@ JavaObject::~JavaObject() {
7075

7176
jobject method = javaFindBestMatchingMethod(env, self->m_methods, *methodName, methodArgs);
7277
if(method == NULL) {
73-
return v8::Undefined();
78+
return v8::Undefined(); // TODO: callback with error
7479
}
7580

7681
// run
@@ -79,3 +84,25 @@ JavaObject::~JavaObject() {
7984

8085
return v8::Undefined();
8186
}
87+
88+
/*static*/ v8::Handle<v8::Value> JavaObject::methodCallSync(const v8::Arguments& args) {
89+
v8::HandleScope scope;
90+
JavaObject* self = node::ObjectWrap::Unwrap<JavaObject>(args.This());
91+
JNIEnv *env = self->m_java->getJavaEnv();
92+
93+
v8::String::AsciiValue methodName(args.Data());
94+
95+
std::list<jobject> methodArgs; // TODO: build args
96+
97+
jobject method = javaFindBestMatchingMethod(env, self->m_methods, *methodName, methodArgs);
98+
if(method == NULL) {
99+
return v8::Undefined();
100+
}
101+
102+
// run
103+
v8::Handle<v8::Value> callback = v8::Object::New();
104+
InstanceMethodCallBaton* baton = new InstanceMethodCallBaton(self->m_java, self, method, methodArgs, callback);
105+
v8::Handle<v8::Value> result = baton->runSync();
106+
delete baton;
107+
return scope.Close(result);;
108+
}

src/javaObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class JavaObject : public node::ObjectWrap {
2424
JavaObject(Java* java, jobject obj);
2525
~JavaObject();
2626
static v8::Handle<v8::Value> methodCall(const v8::Arguments& args);
27+
static v8::Handle<v8::Value> methodCallSync(const v8::Arguments& args);
2728

2829
static v8::Persistent<v8::FunctionTemplate> s_ct;
2930
Java* m_java;

src/methodCallBaton.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "java.h"
44
#include "javaObject.h"
55

6-
MethodCallBaton::MethodCallBaton(Java* java, jobject method, std::list<jobject> args, v8::Handle<v8::Value> &callback) {
6+
MethodCallBaton::MethodCallBaton(Java* java, jobject method, std::list<jobject>& args, v8::Handle<v8::Value>& callback) {
77
JNIEnv *env = java->getJavaEnv();
88

99
m_java = java;
@@ -29,6 +29,12 @@ void MethodCallBaton::run() {
2929
ev_ref(EV_DEFAULT_UC);
3030
}
3131

32+
v8::Handle<v8::Value> MethodCallBaton::runSync() {
33+
JNIEnv *env = m_java->getJavaEnv();
34+
execute(env);
35+
return resultsToV8(env);
36+
}
37+
3238
/*static*/ void MethodCallBaton::EIO_MethodCall(eio_req* req) {
3339
MethodCallBaton* self = static_cast<MethodCallBaton*>(req->data);
3440
JNIEnv *env = javaAttachCurrentThread(self->m_java->getJvm());
@@ -49,28 +55,30 @@ void MethodCallBaton::after(JNIEnv *env) {
4955
if(m_callback->IsFunction()) {
5056
v8::Handle<v8::Value> argv[2];
5157
argv[0] = v8::Undefined();
52-
switch(m_resultType) {
53-
case TYPE_INT:
54-
{
55-
jclass integerClazz = env->FindClass("java/lang/Integer");
56-
jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
57-
int result = env->CallIntMethod(m_result, integer_intValue);
58-
argv[1] = v8::Integer::New(result);
59-
}
60-
break;
61-
case TYPE_OBJECT:
62-
argv[1] = JavaObject::New(m_java, m_result);
63-
break;
64-
case TYPE_STRING:
65-
argv[1] = v8::String::New(javaObjectToString(env, m_result).c_str());
66-
break;
67-
}
58+
argv[1] = resultsToV8(env);
6859
v8::Function::Cast(*m_callback)->Call(v8::Context::GetCurrent()->Global(), 2, argv);
6960
}
7061

7162
env->DeleteGlobalRef(m_result);
7263
}
7364

65+
v8::Handle<v8::Value> MethodCallBaton::resultsToV8(JNIEnv *env) {
66+
switch(m_resultType) {
67+
case TYPE_INT:
68+
{
69+
jclass integerClazz = env->FindClass("java/lang/Integer");
70+
jmethodID integer_intValue = env->GetMethodID(integerClazz, "intValue", "()I");
71+
int result = env->CallIntMethod(m_result, integer_intValue);
72+
return v8::Integer::New(result);
73+
}
74+
case TYPE_OBJECT:
75+
return JavaObject::New(m_java, m_result);
76+
case TYPE_STRING:
77+
return v8::String::New(javaObjectToString(env, m_result).c_str());
78+
}
79+
return v8::Undefined();
80+
}
81+
7482
void NewInstanceBaton::execute(JNIEnv *env) {
7583
jclass constructorClazz = env->FindClass("java/lang/reflect/Constructor");
7684
jmethodID constructor_newInstance = env->GetMethodID(constructorClazz, "newInstance", "([Ljava/lang/Object;)Ljava/lang/Object;");
@@ -108,8 +116,8 @@ NewInstanceBaton::NewInstanceBaton(
108116
Java* java,
109117
jclass clazz,
110118
jobject method,
111-
std::list<jobject> args,
112-
v8::Handle<v8::Value> &callback) : MethodCallBaton(java, method, args, callback) {
119+
std::list<jobject>& args,
120+
v8::Handle<v8::Value>& callback) : MethodCallBaton(java, method, args, callback) {
113121
JNIEnv *env = m_java->getJavaEnv();
114122
m_clazz = (jclass)env->NewGlobalRef(clazz);
115123
}
@@ -123,8 +131,8 @@ InstanceMethodCallBaton::InstanceMethodCallBaton(
123131
Java* java,
124132
JavaObject* obj,
125133
jobject method,
126-
std::list<jobject> args,
127-
v8::Handle<v8::Value> &callback) : MethodCallBaton(java, method, args, callback) {
134+
std::list<jobject>& args,
135+
v8::Handle<v8::Value>& callback) : MethodCallBaton(java, method, args, callback) {
128136
m_javaObject = obj;
129137
m_javaObject->Ref();
130138
}

src/methodCallBaton.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@ class JavaObject;
1313

1414
class MethodCallBaton {
1515
public:
16-
MethodCallBaton(Java* java, jobject method, std::list<jobject> args, v8::Handle<v8::Value> &callback);
16+
MethodCallBaton(Java* java, jobject method, std::list<jobject>& args, v8::Handle<v8::Value>& callback);
1717
virtual ~MethodCallBaton();
1818

1919
static void EIO_MethodCall(eio_req* req);
2020
static int EIO_AfterMethodCall(eio_req* req);
2121
void run();
22+
v8::Handle<v8::Value> runSync();
2223

2324
protected:
2425
virtual void execute(JNIEnv *env) = 0;
2526
virtual void after(JNIEnv *env);
27+
v8::Handle<v8::Value> resultsToV8(JNIEnv *env);
2628

2729
Java* m_java;
2830
v8::Persistent<v8::Value> m_callback;
@@ -34,7 +36,7 @@ class MethodCallBaton {
3436

3537
class InstanceMethodCallBaton : public MethodCallBaton {
3638
public:
37-
InstanceMethodCallBaton(Java* java, JavaObject* obj, jobject method, std::list<jobject> args, v8::Handle<v8::Value> &callback);
39+
InstanceMethodCallBaton(Java* java, JavaObject* obj, jobject method, std::list<jobject>& args, v8::Handle<v8::Value>& callback);
3840
virtual ~InstanceMethodCallBaton();
3941

4042
protected:
@@ -45,7 +47,7 @@ class InstanceMethodCallBaton : public MethodCallBaton {
4547

4648
class NewInstanceBaton : public MethodCallBaton {
4749
public:
48-
NewInstanceBaton(Java* java, jclass clazz, jobject method, std::list<jobject> args, v8::Handle<v8::Value> &callback);
50+
NewInstanceBaton(Java* java, jclass clazz, jobject method, std::list<jobject>& args, v8::Handle<v8::Value>& callback);
4951
virtual ~NewInstanceBaton();
5052

5153
protected:

test/simple-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ exports['Simple'] = nodeunit.testCase({
2121
}
2222
});
2323
},
24-
/*
24+
2525
"create an instance of a class and call methods (getName) (sync)": function(test) {
2626
var list = java.newInstanceSync("java.util.ArrayList");
2727
var clazz = list.getClassSync();
2828
var result = clazz.getNameSync();
2929
test.equal(result, "java.util.ArrayList");
3030
test.done();
3131
},
32-
*/
32+
3333
"create an instance of a class and call methods (size) (async)": function(test) {
3434
java.newInstance("java.util.ArrayList", function(err, list) {
3535
if(err) { console.log(err); return; }

0 commit comments

Comments
 (0)