#include "config.h"
#include "JavaMethodJSC.h"
#if ENABLE(JAVA_BRIDGE)
#include <runtime/JSObject.h>
#include <runtime/ScopeChain.h>
#include <wtf/text/StringBuilder.h>
using namespace JSC;
using namespace JSC::Bindings;
JavaMethod::JavaMethod(JNIEnv* env, jobject aMethod)
{
jstring returnTypeName = 0;
if (jobject returnType = callJNIMethod<jobject>(aMethod, "getReturnType", "()Ljava/lang/Class;")) {
returnTypeName = static_cast<jstring>(callJNIMethod<jobject>(returnType, "getName", "()Ljava/lang/String;"));
if (!returnTypeName)
returnTypeName = env->NewStringUTF("<Unknown>");
env->DeleteLocalRef(returnType);
}
m_returnTypeClassName = JavaString(env, returnTypeName);
m_returnType = javaTypeFromClassName(m_returnTypeClassName.utf8());
env->DeleteLocalRef(returnTypeName);
jstring methodName = static_cast<jstring>(callJNIMethod<jobject>(aMethod, "getName", "()Ljava/lang/String;"));
if (!methodName)
methodName = env->NewStringUTF("<Unknown>");
m_name = JavaString(env, methodName);
env->DeleteLocalRef(methodName);
if (jarray jparameters = static_cast<jarray>(callJNIMethod<jobject>(aMethod, "getParameterTypes", "()[Ljava/lang/Class;"))) {
unsigned int numParams = env->GetArrayLength(jparameters);
for (unsigned int i = 0; i < numParams; i++) {
jobject aParameter = env->GetObjectArrayElement(static_cast<jobjectArray>(jparameters), i);
jstring parameterName = static_cast<jstring>(callJNIMethod<jobject>(aParameter, "getName", "()Ljava/lang/String;"));
if (!parameterName)
parameterName = env->NewStringUTF("<Unknown>");
m_parameters.append(JavaString(env, parameterName).impl());
env->DeleteLocalRef(aParameter);
env->DeleteLocalRef(parameterName);
}
env->DeleteLocalRef(jparameters);
}
m_signature = 0;
jclass modifierClass = env->FindClass("java/lang/reflect/Modifier");
int modifiers = callJNIMethod<jint>(aMethod, "getModifiers", "()I");
m_isStatic = static_cast<bool>(callJNIStaticMethod<jboolean>(modifierClass, "isStatic", "(I)Z", modifiers));
env->DeleteLocalRef(modifierClass);
}
JavaMethod::~JavaMethod()
{
if (m_signature)
fastFree(m_signature);
}
static void appendClassName(StringBuilder& builder, const char* className)
{
ASSERT(JSC::JSGlobalData::sharedInstance().apiLock().currentThreadIsHoldingLock());
char* c = fastStrDup(className);
char* result = c;
while (*c) {
if (*c == '.')
*c = '/';
c++;
}
builder.append(result);
fastFree(result);
}
const char* JavaMethod::signature() const
{
if (!m_signature) {
StringBuilder signatureBuilder;
signatureBuilder.append('(');
for (unsigned int i = 0; i < m_parameters.size(); i++) {
CString javaClassName = parameterAt(i).utf8();
JavaType type = javaTypeFromClassName(javaClassName.data());
if (type == JavaTypeArray)
appendClassName(signatureBuilder, javaClassName.data());
else {
signatureBuilder.append(signatureFromJavaType(type));
if (type == JavaTypeObject) {
appendClassName(signatureBuilder, javaClassName.data());
signatureBuilder.append(';');
}
}
}
signatureBuilder.append(')');
const char* returnType = m_returnTypeClassName.utf8();
if (m_returnType == JavaTypeArray)
appendClassName(signatureBuilder, returnType);
else {
signatureBuilder.append(signatureFromJavaType(m_returnType));
if (m_returnType == JavaTypeObject) {
appendClassName(signatureBuilder, returnType);
signatureBuilder.append(';');
}
}
String signatureString = signatureBuilder.toString();
m_signature = fastStrDup(signatureString.utf8().data());
}
return m_signature;
}
#endif // ENABLE(JAVA_BRIDGE)