#include "java.h" #include #include "javaObject.h" #include "methodCallBaton.h" /*static*/ v8::Persistent Java::s_ct; /*static*/ void Java::Init(v8::Handle target) { v8::HandleScope scope; v8::Local t = v8::FunctionTemplate::New(New); s_ct = v8::Persistent::New(t); s_ct->InstanceTemplate()->SetInternalFieldCount(1); s_ct->SetClassName(v8::String::NewSymbol("Java")); NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstance", newInstance); NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstanceSync", newInstanceSync); target->Set(v8::String::NewSymbol("Java"), s_ct->GetFunction()); } /*static*/ v8::Handle Java::New(const v8::Arguments& args) { v8::HandleScope scope; Java *self = new Java(); self->Wrap(args.This()); return args.This(); } Java::Java() { this->m_jvm = NULL; this->m_env = NULL; createJVM(&this->m_jvm, &this->m_env); } Java::~Java() { } /*static*/ void Java::createJVM(JavaVM** jvm, JNIEnv** env) { JavaVM* jvmTemp; JavaVMInitArgs args; args.version = JNI_VERSION_1_4; JNI_GetDefaultJavaVMInitArgs(&args); JNI_CreateJavaVM(&jvmTemp, (void **)env, &args); *jvm = jvmTemp; } /*static*/ v8::Handle Java::newInstance(const v8::Arguments& args) { v8::HandleScope scope; Java* self = node::ObjectWrap::Unwrap(args.This()); JNIEnv* env = self->getJavaEnv(); int argsEnd = args.Length(); // argument - className if(args.Length() < 1 || !args[0]->IsString()) { return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 0 must be a string"))); } v8::Local classNameObj = v8::Local::Cast(args[0]); v8::String::AsciiValue classNameVal(classNameObj); std::string className = *classNameVal; // argument - callback v8::Handle callback; if(args[args.Length()-1]->IsFunction()) { callback = args[argsEnd-1]; argsEnd--; } else { callback = v8::Null(); } std::list methodArgTypes; jarray methodArgs = v8ToJava(env, args, 1, argsEnd, &methodArgTypes); jclass clazz = javaFindClass(env, className); std::list constructors = javaReflectionGetConstructors(env, clazz); jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgTypes); // run NewInstanceBaton* baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback); baton->run(); return v8::Undefined(); } /*static*/ v8::Handle Java::newInstanceSync(const v8::Arguments& args) { v8::HandleScope scope; Java* self = node::ObjectWrap::Unwrap(args.This()); JNIEnv* env = self->getJavaEnv(); int argsEnd = args.Length(); // argument - className if(args.Length() < 1 || !args[0]->IsString()) { return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 0 must be a string"))); } v8::Local classNameObj = v8::Local::Cast(args[0]); v8::String::AsciiValue classNameVal(classNameObj); std::string className = *classNameVal; std::list methodArgTypes; jarray methodArgs = v8ToJava(env, args, 1, argsEnd, &methodArgTypes); jclass clazz = javaFindClass(env, className); std::list constructors = javaReflectionGetConstructors(env, clazz); jobject method = javaFindBestMatchingConstructor(env, constructors, methodArgTypes); // run v8::Handle callback = v8::Object::New(); NewInstanceBaton* baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback); v8::Handle result = baton->runSync(); delete baton; return scope.Close(result); }