#include <jni_class.h>
#include <jni_utility.h>
#include <jni_runtime.h>
using namespace KJS::Bindings;
JavaClass::JavaClass (jobject anInstance)
{
jobject aClass = callJNIObjectMethod(anInstance, "getClass", "()Ljava/lang/Class;");
if (!aClass) {
fprintf (stderr, "%s: unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance);
return;
}
jstring className = (jstring)callJNIObjectMethod(aClass, "getName", "()Ljava/lang/String;");
const char *classNameC = getCharactersFromJString (className);
_name = strdup (classNameC);
releaseCharactersForJString(className, classNameC);
long i;
JNIEnv *env = getJNIEnv();
jarray fields = (jarray)callJNIObjectMethod (aClass, "getFields", "()[Ljava/lang/reflect/Field;");
long numFields = env->GetArrayLength (fields);
_fields = CFDictionaryCreateMutable(NULL, numFields, &kCFTypeDictionaryKeyCallBacks, NULL);
for (i = 0; i < numFields; i++) {
jobject aJField = env->GetObjectArrayElement ((jobjectArray)fields, i);
Field *aField = new JavaField (env, aJField);
CFStringRef fieldName = CFStringCreateWithCString(NULL, aField->name(), kCFStringEncodingASCII);
CFDictionaryAddValue ((CFMutableDictionaryRef)_fields, fieldName, aField);
CFRelease (fieldName);
env->DeleteLocalRef (aJField);
}
jarray methods = (jarray)callJNIObjectMethod (aClass, "getMethods", "()[Ljava/lang/reflect/Method;");
long numMethods = env->GetArrayLength (methods);
_methods = CFDictionaryCreateMutable(NULL, numMethods, &kCFTypeDictionaryKeyCallBacks, NULL);
for (i = 0; i < numMethods; i++) {
jobject aJMethod = env->GetObjectArrayElement ((jobjectArray)methods, i);
Method *aMethod = new JavaMethod (env, aJMethod);
CFStringRef methodName = CFStringCreateWithCString(NULL, aMethod->name(), kCFStringEncodingASCII);
MethodList *methodList = (MethodList *)CFDictionaryGetValue ((CFMutableDictionaryRef)_methods, methodName);
if (!methodList) {
methodList = new MethodList();
CFDictionaryAddValue ((CFMutableDictionaryRef)_methods, methodName, methodList);
}
methodList->addMethod (aMethod);
CFRelease (methodName);
env->DeleteLocalRef (aJMethod);
}
jarray constructors = (jarray)callJNIObjectMethod (aClass, "getConstructors", "()[Ljava/lang/reflect/Constructor;");
_numConstructors = env->GetArrayLength (constructors);
_constructors = new JavaConstructor[_numConstructors];
for (i = 0; i < _numConstructors; i++) {
jobject aConstructor = env->GetObjectArrayElement ((jobjectArray)constructors, i);
_constructors[i] = JavaConstructor (env, aConstructor);
env->DeleteLocalRef (aConstructor);
}
}
JavaClass::~JavaClass () {
free((void *)_name);
CFRelease (_fields);
CFRelease (_methods);
delete [] _constructors;
}
MethodList JavaClass::methodsNamed(const char *name, Instance *instance) const
{
CFStringRef methodName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
MethodList *methodList = (MethodList *)CFDictionaryGetValue(_methods, methodName);
CFRelease (methodName);
if (methodList)
return *methodList;
return MethodList();
}
Field *JavaClass::fieldNamed(const char *name, Instance *instance) const
{
CFStringRef fieldName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
Field *aField = (Field *)CFDictionaryGetValue(_fields, fieldName);
CFRelease (fieldName);
return aField;
};
bool JavaClass::isNumberClass() const
{
return ((strcmp(_name, "java.lang.Byte") == 0 ||
strcmp(_name, "java.lang.Short") == 0 ||
strcmp(_name, "java.lang.Integer") == 0 ||
strcmp(_name, "java.lang.Long") == 0 ||
strcmp(_name, "java.lang.Float") == 0 ||
strcmp(_name, "java.lang.Double") == 0) );
}
bool JavaClass::isBooleanClass() const
{
return strcmp(_name, "java.lang.Boolean") == 0;
}
bool JavaClass::isStringClass() const
{
return strcmp(_name, "java.lang.String") == 0;
}