|
19 | 19 | NODE_SET_PROTOTYPE_METHOD(s_ct, "newInstanceSync", newInstanceSync); |
20 | 20 | NODE_SET_PROTOTYPE_METHOD(s_ct, "callStaticMethod", callStaticMethod); |
21 | 21 | NODE_SET_PROTOTYPE_METHOD(s_ct, "callStaticMethodSync", callStaticMethodSync); |
| 22 | + NODE_SET_PROTOTYPE_METHOD(s_ct, "newArray", newArray); |
| 23 | + NODE_SET_PROTOTYPE_METHOD(s_ct, "newByte", newByte); |
22 | 24 |
|
23 | 25 | target->Set(v8::String::NewSymbol("Java"), s_ct->GetFunction()); |
24 | 26 | } |
@@ -179,6 +181,9 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) { |
179 | 181 | NewInstanceBaton* baton = new NewInstanceBaton(self, clazz, method, methodArgs, callback); |
180 | 182 | v8::Handle<v8::Value> result = baton->runSync(); |
181 | 183 | delete baton; |
| 184 | + if(result->IsNativeError()) { |
| 185 | + return ThrowException(result); |
| 186 | + } |
182 | 187 | return scope.Close(result); |
183 | 188 | } |
184 | 189 |
|
@@ -307,5 +312,103 @@ v8::Handle<v8::Value> Java::createJVM(JavaVM** jvm, JNIEnv** env) { |
307 | 312 | StaticMethodCallBaton* baton = new StaticMethodCallBaton(self, clazz, method, methodArgs, callback); |
308 | 313 | v8::Handle<v8::Value> result = baton->runSync(); |
309 | 314 | delete baton; |
| 315 | + if(result->IsNativeError()) { |
| 316 | + return ThrowException(result); |
| 317 | + } |
310 | 318 | return scope.Close(result); |
311 | 319 | } |
| 320 | + |
| 321 | +/*static*/ v8::Handle<v8::Value> Java::newArray(const v8::Arguments& args) { |
| 322 | + v8::HandleScope scope; |
| 323 | + Java* self = node::ObjectWrap::Unwrap<Java>(args.This()); |
| 324 | + v8::Handle<v8::Value> ensureJvmResults = self->ensureJvm(); |
| 325 | + if(!ensureJvmResults->IsUndefined()) { |
| 326 | + return ensureJvmResults; |
| 327 | + } |
| 328 | + JNIEnv* env = self->getJavaEnv(); |
| 329 | + |
| 330 | + // argument - className |
| 331 | + if(args.Length() < 1 || !args[0]->IsString()) { |
| 332 | + return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 0 must be a string"))); |
| 333 | + } |
| 334 | + v8::Local<v8::String> classNameObj = v8::Local<v8::String>::Cast(args[0]); |
| 335 | + v8::String::AsciiValue classNameVal(classNameObj); |
| 336 | + std::string className = *classNameVal; |
| 337 | + |
| 338 | + // argument - array |
| 339 | + if(args.Length() < 2 || !args[1]->IsArray()) { |
| 340 | + return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 1 must be an array"))); |
| 341 | + } |
| 342 | + v8::Local<v8::Array> arrayObj = v8::Local<v8::Array>::Cast(args[1]); |
| 343 | + |
| 344 | + // find class and method |
| 345 | + jarray results; |
| 346 | + if(strcmp(className.c_str(), "byte") == 0) { |
| 347 | + results = env->NewByteArray(arrayObj->Length()); |
| 348 | + for(uint32_t i=0; i<arrayObj->Length(); i++) { |
| 349 | + int methodArgType; |
| 350 | + v8::Local<v8::Value> item = arrayObj->Get(i); |
| 351 | + jobject val = v8ToJava(env, item, &methodArgType); |
| 352 | + jclass byteClazz = env->FindClass("java/lang/Byte"); |
| 353 | + jmethodID byte_byteValue = env->GetMethodID(byteClazz, "byteValue", "()B"); |
| 354 | + jbyte byteValues[1]; |
| 355 | + byteValues[0] = env->CallByteMethod(val, byte_byteValue); |
| 356 | + env->SetByteArrayRegion((jbyteArray)results, i, 1, byteValues); |
| 357 | + } |
| 358 | + } |
| 359 | + |
| 360 | + else |
| 361 | + { |
| 362 | + jclass clazz = javaFindClass(env, className); |
| 363 | + if(clazz == NULL) { |
| 364 | + std::ostringstream errStr; |
| 365 | + errStr << "Could not create class " << className.c_str(); |
| 366 | + return ThrowException(javaExceptionToV8(env, errStr.str())); |
| 367 | + } |
| 368 | + |
| 369 | + // create array |
| 370 | + results = env->NewObjectArray(arrayObj->Length(), clazz, NULL); |
| 371 | + |
| 372 | + for(uint32_t i=0; i<arrayObj->Length(); i++) { |
| 373 | + int methodArgType; |
| 374 | + v8::Local<v8::Value> item = arrayObj->Get(i); |
| 375 | + jobject val = v8ToJava(env, item, &methodArgType); |
| 376 | + env->SetObjectArrayElement((jobjectArray)results, i, val); |
| 377 | + if(env->ExceptionOccurred()) { |
| 378 | + std::ostringstream errStr; |
| 379 | + v8::String::AsciiValue valStr(item); |
| 380 | + errStr << "Could not add item \"" << *valStr << "\" to array."; |
| 381 | + return ThrowException(javaExceptionToV8(env, errStr.str())); |
| 382 | + } |
| 383 | + } |
| 384 | + } |
| 385 | + |
| 386 | + return scope.Close(JavaObject::New(self, results)); |
| 387 | +} |
| 388 | + |
| 389 | +/*static*/ v8::Handle<v8::Value> Java::newByte(const v8::Arguments& args) { |
| 390 | + v8::HandleScope scope; |
| 391 | + Java* self = node::ObjectWrap::Unwrap<Java>(args.This()); |
| 392 | + v8::Handle<v8::Value> ensureJvmResults = self->ensureJvm(); |
| 393 | + if(!ensureJvmResults->IsUndefined()) { |
| 394 | + return ensureJvmResults; |
| 395 | + } |
| 396 | + JNIEnv* env = self->getJavaEnv(); |
| 397 | + |
| 398 | + if(args.Length() != 1) { |
| 399 | + return ThrowException(v8::Exception::TypeError(v8::String::New("newByte only takes 1 argument"))); |
| 400 | + } |
| 401 | + |
| 402 | + // argument - value |
| 403 | + if(!args[0]->IsNumber()) { |
| 404 | + return ThrowException(v8::Exception::TypeError(v8::String::New("Argument 0 must be a number"))); |
| 405 | + } |
| 406 | + |
| 407 | + v8::Local<v8::Number> val = args[0]->ToNumber(); |
| 408 | + |
| 409 | + jclass clazz = env->FindClass("java/lang/Byte"); |
| 410 | + jmethodID constructor = env->GetMethodID(clazz, "<init>", "(B)V"); |
| 411 | + jobject newObj = env->NewObject(clazz, constructor, (jbyte)val->Value()); |
| 412 | + |
| 413 | + return scope.Close(JavaObject::New(self, newObj)); |
| 414 | +} |
0 commit comments