예제 #1
0
std::string methodNotFoundToString(JNIEnv *env, jclass clazz, std::string methodName, bool constructor, const v8::Arguments& args, int argStart, int argEnd) {
  std::ostringstream startOfMessage;
  std::ostringstream msg;

  jclass classClazz = env->FindClass("java/lang/Class");
  jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;");

  startOfMessage << "Could not find method \"" << methodName.c_str() << "(";
  for(int i=argStart; i<argEnd; i++) {
    jobject val = v8ToJava(env, args[i]);
    if(i != argStart) {
      startOfMessage << ", ";
    }
    if(val == NULL) {
      startOfMessage << "(null)";
    } else {
      jclass argClass = env->GetObjectClass(val);
      jstring argClassNameJava = (jstring)env->CallObjectMethod(argClass, class_getName);
      std::string argClassName = javaToString(env, argClassNameJava);
      startOfMessage << argClassName;
    }
  }

  startOfMessage << ")\" on class \""<< javaObjectToString(env, clazz).c_str() << "\".";

  msg << startOfMessage.str() << " Possible matches:\n";

  jclass memberClazz = env->FindClass("java/lang/reflect/Member");
  jmethodID member_getName = env->GetMethodID(memberClazz, "getName", "()Ljava/lang/String;");

  std::list<jobject> methods;
  if(constructor) {
    javaReflectionGetConstructors(env, clazz, &methods);
  } else {
    javaReflectionGetMethods(env, clazz, &methods, true);
  }

  int count = 0;
  for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); ++it) {
    jstring methodNameTestJava = (jstring)env->CallObjectMethod(*it, member_getName);
    std::string methodNameTest = javaToString(env, methodNameTestJava);
    if(methodNameTest == methodName) {
      msg << "  " << javaObjectToString(env, *it).c_str() << "\n";
      count++;
    }
  }

  if(count == 0) {
    std::ostringstream noMethodsMsg;
    noMethodsMsg << startOfMessage.str() << " No methods with that name.";
    return noMethodsMsg.str();
  }

  return msg.str();
}
예제 #2
0
/*static*/ v8::Local<v8::Object> JavaObject::New(Java *java, jobject obj) {
  v8::HandleScope scope;

  JNIEnv *env = java->getJavaEnv();
  obj = env->NewGlobalRef(obj);
  JavaScope javaScope(env);

  jclass objClazz = env->GetObjectClass(obj);
  jclass classClazz = env->FindClass("java/lang/Class");
  jmethodID class_getName = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;");
  jobject classNameJava = env->CallObjectMethod(objClazz, class_getName);
  std::string className = javaObjectToString(env, classNameJava);
  std::replace(className.begin(), className.end(), '.', '_');
  std::replace(className.begin(), className.end(), '$', '_');
  std::replace(className.begin(), className.end(), '[', 'a');
  className = "nodeJava_" + className;

  v8::Persistent<v8::FunctionTemplate> persistentFuncTemplate;
  if(sFunctionTemplates.find(className) != sFunctionTemplates.end()) {
    //printf("existing className: %s\n", className.c_str());
    persistentFuncTemplate = sFunctionTemplates[className];
  } else {
    //printf("create className: %s\n", className.c_str());

    v8::Local<v8::FunctionTemplate> funcTemplate = v8::FunctionTemplate::New();
    funcTemplate->InstanceTemplate()->SetInternalFieldCount(1);
    funcTemplate->SetClassName(v8::String::NewSymbol(className.c_str()));

    std::list<jobject> methods;
    javaReflectionGetMethods(env, objClazz, &methods, false);
    jclass methodClazz = env->FindClass("java/lang/reflect/Method");
    jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;");
    for(std::list<jobject>::iterator it = methods.begin(); it != methods.end(); it++) {
      jstring methodNameJava = (jstring)env->CallObjectMethod(*it, method_getName);
      std::string methodNameStr = javaToString(env, methodNameJava);

      v8::Handle<v8::String> methodName = v8::String::New(methodNameStr.c_str());
      v8::Local<v8::FunctionTemplate> methodCallTemplate = v8::FunctionTemplate::New(methodCall, methodName);
      funcTemplate->PrototypeTemplate()->Set(methodName, methodCallTemplate->GetFunction());

      v8::Handle<v8::String> methodNameSync = v8::String::New((methodNameStr + "Sync").c_str());
      v8::Local<v8::FunctionTemplate> methodCallSyncTemplate = v8::FunctionTemplate::New(methodCallSync, methodName);
      funcTemplate->PrototypeTemplate()->Set(methodNameSync, methodCallSyncTemplate->GetFunction());
    }

    std::list<jobject> fields;
    javaReflectionGetFields(env, objClazz, &fields);
    jclass fieldClazz = env->FindClass("java/lang/reflect/Field");
    jmethodID field_getName = env->GetMethodID(fieldClazz, "getName", "()Ljava/lang/String;");
    for(std::list<jobject>::iterator it = fields.begin(); it != fields.end(); it++) {
      jstring fieldNameJava = (jstring)env->CallObjectMethod(*it, field_getName);
      std::string fieldNameStr = javaToString(env, fieldNameJava);

      v8::Handle<v8::String> fieldName = v8::String::New(fieldNameStr.c_str());
      funcTemplate->InstanceTemplate()->SetAccessor(fieldName, fieldGetter, fieldSetter);
    }

    sFunctionTemplates[className] = persistentFuncTemplate = v8::Persistent<v8::FunctionTemplate>::New(funcTemplate);
  }

  v8::Local<v8::Function> ctor = persistentFuncTemplate->GetFunction();
  v8::Local<v8::Object> javaObjectObj = ctor->NewInstance();
  javaObjectObj->SetHiddenValue(v8::String::New("__isJavaObject"), v8::Boolean::New(true));
  JavaObject *self = new JavaObject(java, obj);
  self->Wrap(javaObjectObj);

  return scope.Close(javaObjectObj);
}