| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <string.h> |
| |
| #include <jni.h> |
| |
| #include "JNIUtils.h" |
| |
| /***** |
| * |
| * NOTE: Whereever I think an exception may occur, I need to check |
| * whether it did and recover appropriately .. otherwise the behavior |
| * of JNI is undefined! |
| * |
| *****/ |
| |
| /* throw a BSFException with the given code and message. */ |
| void bsf_exception (JNIEnv *jenv, int code, char *msg) { |
| jclass bsfexceptclass = |
| (*jenv)->FindClass (jenv, "org/apache/bsf/BSFException"); |
| (*jenv)->ThrowNew (jenv, bsfexceptclass, msg); |
| } |
| |
| /* cvt a pointer to a Long object whose value is the pointer value */ |
| jobject bsf_pointer2longobj (JNIEnv *jenv, void *ptr) { |
| return bsf_makeLong (jenv, (long) ptr); |
| } |
| |
| /* cvt a Long object whose value is the pointer value to the pointer */ |
| void *bsf_longobj2pointer (JNIEnv *jenv, jobject lobj) { |
| jclass longclass = (*jenv)->FindClass (jenv, "java/lang/Long"); |
| jmethodID mi = (*jenv)->GetMethodID (jenv, longclass, "longValue", "()J"); |
| void *ptr = (void *) (*jenv)->CallLongMethod (jenv, lobj, mi); |
| return ptr; |
| } |
| |
| /* convert an object to a string obj */ |
| jstring bsf_obj2jstring (JNIEnv *jenv, jobject obj) { |
| jclass objclass = (*jenv)->GetObjectClass (jenv, obj); |
| jmethodID tostr = (*jenv)->GetMethodID (jenv, objclass, "toString", |
| "()Ljava/lang/String;"); |
| jstring strobj = (jstring) (*jenv)->CallObjectMethod (jenv, obj, tostr); |
| return strobj; |
| } |
| |
| /* cvt an object to a c-string .. wastes memory, but useful for debug */ |
| const char *bsf_obj2cstring (JNIEnv *jenv, jobject obj) { |
| return (*jenv)->GetStringUTFChars (jenv, |
| bsf_obj2jstring (jenv, obj), |
| 0); |
| } |
| |
| /* call the named method with the given args on the given bean */ |
| jobject bsf_createbean (JNIEnv *jenv, char *classname, jobjectArray args) { |
| jclass cl; |
| jmethodID mid; |
| jobject result; |
| |
| /* find the BSFUtils.createBean method ID if needed */ |
| cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); |
| mid = (*jenv)->GetStaticMethodID (jenv, cl, "createBean", |
| "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| return 0; |
| } |
| |
| result = (*jenv)->CallStaticObjectMethod (jenv, cl, mid, |
| (*jenv)->NewStringUTF (jenv, |
| classname), |
| args); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| /* I should really throw a BSF exception here and the caller should |
| check whether an exception was thrown and in that case return. |
| later. */ |
| return 0; |
| } else { |
| return result; |
| } |
| } |
| |
| /* call the named method with the given args on the given bean */ |
| jobject bsf_callmethod (JNIEnv *jenv, jobject target, |
| char *methodname, jobjectArray args) { |
| jclass cl; |
| jmethodID mid; |
| jobject result; |
| |
| /* find the BSFUtils.callBeanMethod method ID if needed */ |
| cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); |
| mid = (*jenv)->GetStaticMethodID (jenv, cl, "callBeanMethod", |
| "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| return 0; |
| } |
| result = (*jenv)->CallStaticObjectMethod (jenv, cl, mid, target, |
| (*jenv)->NewStringUTF (jenv, |
| methodname), |
| args); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| /* I should really throw a BSF exception here and the caller should |
| check whether an exception was thrown and in that case return. |
| later. */ |
| return 0; |
| } else { |
| return result; |
| } |
| } |
| |
| /* return the named bean from the given mgr's bean registry */ |
| jobject bsf_lookupbean (JNIEnv *jenv, jobject mgr, char *beanname) { |
| jmethodID lookupMethod; |
| jobject result; |
| |
| jclass bsfmgrclass = (*jenv)->GetObjectClass (jenv, mgr); |
| lookupMethod = |
| (*jenv)->GetMethodID (jenv, bsfmgrclass, "lookupBean", |
| "(Ljava/lang/String;)Ljava/lang/Object;"); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| return 0; |
| } |
| |
| result = (*jenv)->CallObjectMethod (jenv, mgr, lookupMethod, |
| (*jenv)->NewStringUTF (jenv, beanname)); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| /* I should really throw a BSF exception here and the caller should |
| check whether an exception was thrown and in that case return. |
| later. */ |
| return 0; |
| } else { |
| return result; |
| } |
| } |
| |
| /* return the type signature string component for the given type: |
| I for ints, J for long, ... */ |
| char *bsf_getTypeSignatureString (JNIEnv *jenv, jclass objclass) { |
| jclass cl = 0; |
| jmethodID mid = 0; |
| jstring str; |
| |
| cl = (*jenv)->FindClass (jenv, "org/apache/bsf/util/EngineUtils"); |
| mid = (*jenv)->GetStaticMethodID (jenv, cl, "getTypeSignatureString", |
| "(Ljava/lang/Class;)Ljava/lang/String;"); |
| if ((*jenv)->ExceptionOccurred (jenv)) { |
| (*jenv)->ExceptionDescribe (jenv); |
| (*jenv)->ExceptionClear (jenv); |
| return 0; |
| } |
| str = (jstring) (*jenv)->CallStaticObjectMethod (jenv, cl, mid, objclass); |
| return (char *) bsf_obj2cstring (jenv, str); |
| } |
| |
| /* make objects from primitives */ |
| |
| jobject bsf_makeBoolean (JNIEnv *jenv, int val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Boolean"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(Z)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jboolean) val); |
| } |
| |
| jobject bsf_makeByte (JNIEnv *jenv, int val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Byte"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(B)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jbyte) val); |
| } |
| |
| jobject bsf_makeShort (JNIEnv *jenv, int val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Short"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(S)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jshort) val); |
| } |
| |
| jobject bsf_makeInteger (JNIEnv *jenv, int val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Integer"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(I)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jint) val); |
| } |
| |
| jobject bsf_makeLong (JNIEnv *jenv, long val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Long"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(J)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jlong) val); |
| } |
| |
| jobject bsf_makeFloat (JNIEnv *jenv, float val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Float"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(F)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jfloat) val); |
| } |
| |
| jobject bsf_makeDouble (JNIEnv *jenv, double val) { |
| jclass classobj = (*jenv)->FindClass (jenv, "java/lang/Double"); |
| jmethodID constructor = |
| (*jenv)->GetMethodID (jenv, classobj, "<init>", "(D)V"); |
| return (*jenv)->NewObject (jenv, classobj, constructor, (jdouble) val); |
| } |