edburns%acm.org 2471024921 a=edburns
r=ashuk
bug=2069

Native code for spec compliant webclient impl.


git-svn-id: svn://10.0.0.236/trunk@62196 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-04 01:37:20 +00:00

273 lines
7.2 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is RaptorCanvas.
*
* The Initial Developer of the Original Code is Kirk Baker and
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
* Rights Reserved.
*
* Contributor(s): Kirk Baker <kbaker@eb.com>
* Ian Wilkinson <iw@ennoble.com>
* Mark Lin <mark.lin@eng.sun.com>
* Mark Goddard
* Ed Burns <edburns@acm.org>
* Ann Sunhachawee
*/
#include "jni_util.h"
JavaVM *gVm = NULL;
void util_ThrowExceptionToJava (JNIEnv * env, const char * message)
{
if (env->ExceptionOccurred()) {
env->ExceptionClear();
}
jclass excCls = env->FindClass("java/lang/Exception");
if (excCls == 0) { // Unable to find the exception class, give up.
if (env->ExceptionOccurred())
env->ExceptionClear();
return;
}
// Throw the exception with the error code and description
jmethodID jID = env->GetMethodID(excCls, "<init>", "(Ljava/lang/String;)V"); // void Exception(String)
if (jID != NULL) {
jstring exceptionString = env->NewStringUTF(message);
jthrowable newException = (jthrowable) env->NewObject(excCls, jID, exceptionString);
if (newException != NULL) {
env->Throw(newException);
}
else {
if (env->ExceptionOccurred())
env->ExceptionClear();
}
} else {
if (env->ExceptionOccurred())
env->ExceptionClear();
}
} // ThrowExceptionToJava()
void util_PostEvent(WebShellInitContext * initContext, PLEvent * event)
{
PL_ENTER_EVENT_QUEUE_MONITOR(initContext->actionQueue);
::PL_PostEvent(initContext->actionQueue, event);
PL_EXIT_EVENT_QUEUE_MONITOR(initContext->actionQueue);
} // PostEvent()
void *util_PostSynchronousEvent(WebShellInitContext * initContext, PLEvent * event)
{
void * voidResult = nsnull;
PL_ENTER_EVENT_QUEUE_MONITOR(initContext->actionQueue);
voidResult = ::PL_PostSynchronousEvent(initContext->actionQueue, event);
PL_EXIT_EVENT_QUEUE_MONITOR(initContext->actionQueue);
return voidResult;
} // PostSynchronousEvent()
void util_SendEventToJava(JNIEnv *yourEnv, jobject nativeEventThread,
jobject webclientEventListener,
jlong eventType)
{
if (NULL == gVm) {
return;
}
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION_1_2);
if (NULL == env) {
return;
}
jthrowable exception;
if (NULL != (exception = env->ExceptionOccurred())) {
env->ExceptionDescribe();
}
jclass clazz = env->GetObjectClass(nativeEventThread);
jmethodID mid = env->GetMethodID(clazz, "nativeEventOccurred",
"(Lorg/mozilla/webclient/WebclientEventListener;J)V");
if ( mid != NULL) {
env->CallVoidMethod(nativeEventThread, mid, webclientEventListener,
eventType);
} else {
printf("cannot call the Java Method!\n");
}
}
/**
* @return: the string name of the current java thread. Must be freed!
*/
char *util_GetCurrentThreadName(JNIEnv *env)
{
jclass threadClass = env->FindClass("java/lang/Thread");
jobject currentThread;
jstring name;
char *result = NULL;
const char *cstr;
jboolean isCopy;
if (NULL != threadClass) {
jmethodID currentThreadID =
env->GetStaticMethodID(threadClass,"currentThread",
"()Ljava/lang/Thread;");
currentThread = env->CallStaticObjectMethod(threadClass,
currentThreadID);
if (NULL != currentThread) {
jmethodID getNameID = env->GetMethodID(threadClass,
"getName",
"()Ljava/lang/String;");
name = (jstring) env->CallObjectMethod(currentThread, getNameID,
NULL);
result = strdup(cstr = env->GetStringUTFChars(name, &isCopy));
if (JNI_TRUE == isCopy) {
env->ReleaseStringUTFChars(name, cstr);
}
}
}
return result;
}
// static
void util_DumpJavaStack(JNIEnv *env)
{
jclass threadClass = env->FindClass("java/lang/Thread");
if (NULL != threadClass) {
jmethodID dumpStackID = env->GetStaticMethodID(threadClass,
"dumpStack",
"()V");
env->CallStaticVoidMethod(threadClass, dumpStackID);
}
}
JNIEXPORT jvalue JNICALL
JNU_CallMethodByName(JNIEnv *env,
jboolean *hasException,
jobject obj,
const char *name,
const char *signature,
...)
{
jvalue result;
va_list args;
va_start(args, signature);
result = JNU_CallMethodByNameV(env, hasException, obj, name, signature,
args);
va_end(args);
return result;
}
JNIEXPORT jvalue JNICALL
JNU_CallMethodByNameV(JNIEnv *env,
jboolean *hasException,
jobject obj,
const char *name,
const char *signature,
va_list args)
{
jclass clazz;
jmethodID mid;
jvalue result;
const char *p = signature;
printf("jni_util: call method by name if 0");
/* find out the return type */
while (*p && *p != ')')
p++;
p++;
result.i = 0;
if (env->EnsureLocalCapacity(3) < 0)
goto done2;
printf("jni_util: call method by name if 1");
clazz = env->GetObjectClass(obj);
printf("jni_util: call method by name 2");
mid = env->GetMethodID(clazz, name, signature);
printf("jni_util: call method by name 3");
if (mid == 0)
goto done1;
printf("jni_util: call method by name if 4");
switch (*p) {
case 'V':
env->CallVoidMethodV(obj, mid, args);
break;
case '[':
case 'L':
result.l = env->CallObjectMethodV(obj, mid, args);
break;
case 'Z':
result.z = env->CallBooleanMethodV(obj, mid, args);
break;
case 'B':
result.b = env->CallByteMethodV(obj, mid, args);
break;
case 'C':
result.c = env->CallCharMethodV(obj, mid, args);
break;
case 'S':
result.s = env->CallShortMethodV(obj, mid, args);
break;
case 'I':
result.i = env->CallIntMethodV(obj, mid, args);
break;
case 'J':
result.j = env->CallLongMethodV(obj, mid, args);
break;
case 'F':
result.f = env->CallFloatMethodV(obj, mid, args);
break;
case 'D':
result.d = env->CallDoubleMethodV(obj, mid, args);
break;
default:
env->FatalError("JNU_CallMethodByNameV: illegal signature");
}
done1:
env->DeleteLocalRef(clazz);
done2:
if (hasException) {
*hasException = env->ExceptionCheck();
}
return result;
}
JNIEXPORT void * JNICALL
JNU_GetEnv(JavaVM *vm, jint version)
{
// void *result;
//vm->GetEnv(&result, version);
JNIEnv *result = NULL;
vm->AttachCurrentThread((void **)&result, (void *) version);
return result;
}