Ejemplo n.º 1
0
/*
 * Convert a Java object to a number by attempting to call the
 * doubleValue() method on a Java object to get a double result.
 * This usually only works on instances of java.lang.Double, but the code
 * is generalized to work with any Java object that supports this method.
 *
 * Returns JS_TRUE if the call was successful.
 * Returns JS_FALSE if conversion is not possible or an error occurs.
 */
JSBool
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
                                JavaClassDescriptor *class_descriptor,
                                jobject java_obj, jsval *vp)
{
    jdouble d;
    jmethodID doubleValue;
    jclass java_class;

    java_class = class_descriptor->java_class;
    doubleValue = (*jEnv)->GetMethodID(jEnv, java_class, "doubleValue", "()D");
    if (!doubleValue) {
        /* There is no doubleValue() method for the object.  Try toString()
           instead and the JS engine will attempt to convert the result to
           a number. */
        (*jEnv)->ExceptionClear(jEnv);
        return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor,
                                               java_obj, vp);
    }

    d = (*jEnv)->CallDoubleMethod(jEnv, java_obj, doubleValue);
    if ((*jEnv)->ExceptionOccurred(jEnv)) {
        jsj_UnexpectedJavaError(cx, jEnv, "doubleValue() method failed");
        return JS_FALSE;
    }
    return JS_NewDoubleValue(cx, d, vp);
}
Ejemplo n.º 2
0
/*
 * Reflect a Java object into a JS value.  The source object, java_obj, must
 * be of type java.lang.Object or a subclass and may, therefore, be an array.
 */
JSBool
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
                               jobject java_obj, jsval *vp)
{
    JavaClassDescriptor *class_descriptor;
    jclass java_class;
    JSBool ret;

    /* A null in Java-land is also null in JS */
    if (!java_obj) {
        *vp = JSVAL_NULL;
        return JS_TRUE;
    }

    java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);

    class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
    if (!class_descriptor)
        return JS_FALSE;

    switch (class_descriptor->type) {
    case JAVA_SIGNATURE_JAVA_LANG_BOOLEAN:
        ret = jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    case JAVA_SIGNATURE_JAVA_LANG_DOUBLE:
        ret = jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    case JAVA_SIGNATURE_JAVA_LANG_STRING:
        ret = jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    default:
        ret = convert_javaobject_to_jsobject(cx, jEnv, class_descriptor, java_obj, vp);
        break;
    }

    (*jEnv)->DeleteLocalRef(jEnv, java_class);
    jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
    return ret;
}
Ejemplo n.º 3
0
/*
 * Convert a Java object to a number by attempting to call the
 * doubleValue() method on a Java object to get a double result.
 * This usually only works on instances of java.lang.Double, but the code
 * is generalized to work with any Java object that supports this method.
 *
 * Returns JS_TRUE if the call was successful.
 * Returns JS_FALSE if conversion is not possible or an error occurs.
 */
JSBool
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
                                JavaClassDescriptor *class_descriptor,
                                jobject java_obj, jsval *vp)
{
    jdouble d;
    jmethodID doubleValue;
    jclass java_class;

    java_class = class_descriptor->java_class;
    doubleValue = (*jEnv)->GetMethodID(jEnv, java_class, "doubleValue", "()D");
    if (!doubleValue) {
        /* There is no doubleValue() method for the object.  Try toString()
           instead and the JS engine will attempt to convert the result to
           a number. */
        (*jEnv)->ExceptionClear(jEnv);
        return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor,
                                               java_obj, vp);
    }
    /*
     * Sun Java-Plugin team work around bug to be fixed in JRE1.5, where GetMethodID 
     * called with a non-existent method name returns a non-null result.
     * See Mozilla bug 201164.
     */
    if ((*jEnv)->ExceptionOccurred(jEnv)) {
        jsj_UnexpectedJavaError(cx, jEnv, "No doubleValue() method for class %s!",
            class_descriptor->name);
        return JS_FALSE;
    }
    
    d = (*jEnv)->CallDoubleMethod(jEnv, java_obj, doubleValue);
    if ((*jEnv)->ExceptionOccurred(jEnv)) {
        jsj_UnexpectedJavaError(cx, jEnv, "doubleValue() method failed");
        return JS_FALSE;
    }
    return JS_NewDoubleValue(cx, d, vp);
}
Ejemplo n.º 4
0
/*
 * This is a wrapper around JS_ReportError(), useful when an error condition
 * is the result of a JVM failure or exception condition.  It appends the
 * message associated with the pending Java exception to the passed in
 * printf-style format string and arguments.
 */
static void
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
{
    jobject java_obj;
    jclass java_class;
    JavaClassDescriptor *class_descriptor;
    jthrowable java_exception;
    JSType wrapped_exception_type;
    jsval js_exception;
       
    java_obj = NULL;
    class_descriptor = NULL;

    /* Get the exception out of the java environment. */
    java_exception = (*jEnv)->ExceptionOccurred(jEnv);
    if (!java_exception) {
        JSString *err_jsstr;
        char *err = JS_vsmprintf(format, ap);
        if (!err)
            return;
        err_jsstr = JS_NewString(cx, err, strlen(err));
        if (!err_jsstr)
            return;
        JS_SetPendingException(cx, STRING_TO_JSVAL(err_jsstr));
        return;
    }

    
    (*jEnv)->ExceptionClear(jEnv);
    
    /* Check for JSException */
    if (njJSException && 
        (*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
        
        wrapped_exception_type = 
            (*jEnv)->GetIntField(jEnv, java_exception,
            njJSException_wrappedExceptionType);
        
        /* (int) to suppress warning */
        if ((int)wrapped_exception_type != JSTYPE_EMPTY) {
            java_obj = 
                (*jEnv)->GetObjectField(jEnv, java_exception, 
                njJSException_wrappedException);
            
            if ((java_obj == NULL) && 
                (wrapped_exception_type == JSTYPE_OBJECT)) {
                js_exception = JSVAL_NULL;
            } else { 
                java_class = (*jEnv)->GetObjectClass(jEnv, java_obj); 
                class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
                /* OK to delete ref, since above call adds global ref */
                (*jEnv)->DeleteLocalRef(jEnv, java_class);  
                
                /* Convert native JS values back to native types. */
                switch(wrapped_exception_type) {
                case JSTYPE_NUMBER:
                    if (!jsj_ConvertJavaObjectToJSNumber(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_BOOLEAN:
                    if (!jsj_ConvertJavaObjectToJSBoolean(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_STRING:
                    if (!jsj_ConvertJavaObjectToJSString(cx, jEnv,
                        class_descriptor,
                        java_obj, 
                        &js_exception))
                        goto error;
                    break;
                case JSTYPE_VOID:
                    js_exception = JSVAL_VOID;
                    break;
                case JSTYPE_OBJECT:
                case JSTYPE_FUNCTION:
                default:
                    if ((*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
                        js_exception = OBJECT_TO_JSVAL(jsj_UnwrapJSObjectWrapper(jEnv, java_obj));
                        if (!js_exception)
                            goto error;                        
                    } else {
                        if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, 
                            &js_exception)) 
                            goto error;
                    }
                }
            }
        }
        /* Check for internal exception */
    } else {
        if (!JSJ_ConvertJavaObjectToJSValue(cx, java_exception,
            &js_exception)) {
            goto error;
        }
    }
    
    /* Set pending JS exception and clear the java exception. */
    JS_SetPendingException(cx, js_exception);                        
    goto done;

error:
    
    JS_ASSERT(0);
    jsj_LogError("Out of memory while attempting to throw JSException\n");
    
done:
    if (class_descriptor)
        jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
    if (java_obj)
        (*jEnv)->DeleteLocalRef(jEnv, java_obj);
    if (java_exception)
        (*jEnv)->DeleteLocalRef(jEnv, java_exception);
}