Added capability to pass JS arrays as arguments to Java methods.

This commit is contained in:
fur%netscape.com 1999-09-01 14:37:21 +00:00
Родитель ea3a16ee62
Коммит 57e72d2b3a
6 изменённых файлов: 94 добавлений и 7 удалений

Просмотреть файл

@ -50,8 +50,7 @@ were integrated with Netscape Navigator versions 4.x and earlier.  For info
on LiveConnect version 1, which was used in Navigator versions 3 and 4, and Enterprise
Server 3, see <a href="http://developer.netscape.com/find/find.cgi?scope=LiveConnect&browse-category=&ui=sr&chunk-size=&page=1&taxonomy=DevEdge+Online">Netscape's
DevEdge site</a> or any number of 3rd-party publications.)
<h4>
LiveConnect version 3 (10/31/98)</h4>
<h4> LiveConnect version 3 (8/31/99)</h4>
<ul>
<li> In previous versions of LiveConnect, when more than one overloaded Java
@ -115,7 +114,17 @@ LiveConnect version 3 (10/31/98)</h4>
a language feature that debuted in JavaScript 1.4.&nbsp; Now, when JavaScript
calls into Java, any Java exceptions are converted to JS exceptions which
can be caught using JS try-catch statements.&nbsp; Similarly, JS exceptions
are propagated to Java wrapped in an instance of <i>netscape.javascript.JSException</i>.</li>
are propagated to Java wrapped in an instance of <i>netscape.javascript.JSException</i>.<BR>
<BR>
</li>
<li>JavaScript Array objects can now be passed to Java methods that expect a
Java array as an argument. <BR>
LiveConnect will create a new Java array of the appropriate type with a length
equal to that of the JS Array object. Each element of the Java array is filled
in by converting the corresponding element of the JS array, including undefined
elements, to an equivalent Java value. Note: Since the contents of the JS
array are copied, side-effects made by the invoked Java method to the Java
array will not be reflected in the JS array argument. </li>
</ul>
<h4>

Просмотреть файл

@ -74,6 +74,7 @@ report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg)
jclass jlObject; /* java.lang.Object */
jclass jlrMethod; /* java.lang.reflect.Method */
jclass jlrField; /* java.lang.reflect.Field */
jclass jlrArray; /* java.lang.reflect.Array */
jclass jlVoid; /* java.lang.Void */
jclass jlrConstructor; /* java.lang.reflect.Constructor */
jclass jlThrowable; /* java.lang.Throwable */
@ -106,6 +107,8 @@ jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
jmethodID jlrArray_newInstance; /* java.lang.reflect.Array.newInstance() */
jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
jmethodID jlDouble_Double; /* java.lang.Double constructor */
@ -229,6 +232,7 @@ init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
LOAD_CLASS(java/lang/reflect/Method, jlrMethod);
LOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
LOAD_CLASS(java/lang/reflect/Field, jlrField);
LOAD_CLASS(java/lang/reflect/Array, jlrArray);
LOAD_CLASS(java/lang/Throwable, jlThrowable);
LOAD_CLASS(java/lang/System, jlSystem);
LOAD_CLASS(java/lang/Boolean, jlBoolean);
@ -256,6 +260,9 @@ init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
LOAD_METHOD(java.lang.reflect.Field, getType, "()Ljava/lang/Class;", jlrField);
LOAD_METHOD(java.lang.reflect.Field, getModifiers, "()I", jlrField);
LOAD_STATIC_METHOD(java.lang.reflect.Array,
newInstance, "(Ljava/lang/Class;I)Ljava/lang/Object;",jlrArray);
LOAD_METHOD(java.lang.Throwable, toString, "()Ljava/lang/String;", jlThrowable);
LOAD_METHOD(java.lang.Throwable, getMessage, "()Ljava/lang/String;", jlThrowable);
@ -555,6 +562,7 @@ JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod);
UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
UNLOAD_CLASS(java/lang/reflect/Field, jlrField);
UNLOAD_CLASS(java/lang/reflect/Array, jlrArray);
UNLOAD_CLASS(java/lang/Throwable, jlThrowable);
UNLOAD_CLASS(java/lang/System, jlSystem);
UNLOAD_CLASS(java/lang/Boolean, jlBoolean);

Просмотреть файл

@ -76,6 +76,54 @@ convert_js_obj_to_JSObject_wrapper(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj
return (*java_value != NULL);
}
/* Copy an array from JS to Java; Create a new Java array and populate its
elements, one by one, with the result of converting each JS array element
to the type of the array component. */
static JSBool
convert_js_array_to_java_array(JSContext *cx, JNIEnv *jEnv, JSObject *js_array,
JavaSignature *signature,
jobject *java_valuep)
{
jsuint i;
jsval js_val;
jsuint length;
jclass component_class;
jarray java_array;
JavaSignature *array_component_signature;
if (!JS_GetArrayLength(cx, js_array, &length))
return JS_FALSE;
/* Get the Java class of each element of the array */
array_component_signature = signature->array_component_signature;
component_class = array_component_signature->java_class;
/* Create a new empty Java array with the same length as the JS array */
java_array = (*jEnv)->CallStaticObjectMethod(jEnv, jlrArray, jlrArray_newInstance,
component_class, length);
if (!java_array) {
jsj_ReportJavaError(cx, jEnv, "Error while constructing empty array of %s",
jsj_GetJavaClassName(cx, jEnv, component_class));
return JS_FALSE;
}
/* Convert each element of the JS array to an element of the Java array.
If an error occurs, there is no need to worry about releasing the
individual elements of the Java array - they will eventually be GC'ed
by the JVM. */
for (i = 0; i < length; i++) {
if (!JS_LookupElement(cx, js_array, i, &js_val))
return JS_FALSE;
if (!jsj_SetJavaArrayElement(cx, jEnv, java_array, i, array_component_signature, js_val))
return JS_FALSE;
}
/* Return the result array */
*java_valuep = java_array;
return JS_TRUE;
}
jstring
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str)
{
@ -169,6 +217,15 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
return jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
java_value, is_local_refp);
/* JS Arrays are converted, element by element, to Java arrays */
} else if (JS_IsArrayObject(cx, js_obj) && (signature->type == JAVA_SIGNATURE_ARRAY)) {
if (convert_js_array_to_java_array(cx, jEnv, js_obj, signature, java_value)) {
if (java_value && *java_value)
*is_local_refp = JS_TRUE;
return JS_TRUE;
}
return JS_FALSE;
} else {
/* Otherwise, see if the target type is the netscape.javascript.JSObject
wrapper class or one of its subclasses, in which case a
@ -227,7 +284,9 @@ jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignatu
/* Fall through, to attempt conversion to a java.lang.String ... */
}
/* If no other conversion is possible, see if the target type is java.lang.String */
/* If the source JS type is either a string or undefined, or if no conversion
is possible from a number, boolean or JS object, see if the target type is
java.lang.String */
if ((*jEnv)->IsAssignableFrom(jEnv, jlString, target_java_class)) {
/* Convert to JS string, if necessary, and then to a Java Unicode string */
@ -503,6 +562,7 @@ conversion_error:
if (java_value) {
const char *jsval_string;
const char *class_name;
JSString *jsstr;
jsval_string = NULL;
@ -512,8 +572,11 @@ conversion_error:
if (!jsval_string)
jsval_string = "";
class_name = jsj_ConvertJavaSignatureToHRString(cx, signature);
JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
JSJMSG_CANT_CONVERT_JS, jsval_string, signature->name);
JSJMSG_CANT_CONVERT_JS, jsval_string,
class_name);
return JS_FALSE;
}
return success;

Просмотреть файл

@ -65,6 +65,7 @@ typedef enum JSJType {
JSJTYPE_JAVACLASS, /* JavaClass */
JSJTYPE_JAVAOBJECT, /* JavaObject */
JSJTYPE_JAVAARRAY, /* JavaArray */
JSJTYPE_JSARRAY, /* JS Array */
JSJTYPE_OBJECT, /* Any other JS Object, including functions */
JSJTYPE_LIMIT
} JSJType;
@ -939,6 +940,8 @@ compute_jsj_type(JSContext *cx, jsval v)
return JSJTYPE_JAVAARRAY;
if (JS_InstanceOf(cx, js_obj, &JavaClass_class, 0))
return JSJTYPE_JAVACLASS;
if (JS_IsArrayObject(cx, js_obj))
return JSJTYPE_JSARRAY;
return JSJTYPE_OBJECT;
} else if (JSVAL_IS_NUMBER(v)) {
return JSJTYPE_NUMBER;
@ -978,7 +981,8 @@ static int rank_table[JSJTYPE_LIMIT][JAVA_SIGNATURE_LIMIT] = {
{99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 1, 99, 2, 3, 4}, /* JavaClass */
{99, 7, 8, 6, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 1}, /* JavaObject */
{99, 99, 99, 99, 99, 99, 99, 99, 0, 0, 99, 99, 99, 99, 0, 1}, /* JavaArray */
{99, 9, 10, 8, 7, 6, 5, 4, 99, 99, 99, 99, 99, 1, 2, 3}, /* other JS object */
{99, 99, 99, 99, 99, 99, 99, 99, 2, 99, 99, 99, 99, 1, 3, 4}, /* JS Array */
{99, 9, 10, 8, 7, 6, 5, 4, 99, 99, 99, 99, 99, 1, 2, 3} /* other JS object */
};
/*

Просмотреть файл

@ -248,6 +248,7 @@ extern JSClass JavaMember_class;
*/
extern jclass jlObject; /* java.lang.Object */
extern jclass jlrConstructor; /* java.lang.reflect.Constructor */
extern jclass jlrArray; /* java.lang.reflect.Array */
extern jclass jlThrowable; /* java.lang.Throwable */
extern jclass jlSystem; /* java.lang.System */
extern jclass jlClass; /* java.lang.Class */
@ -278,6 +279,8 @@ extern jmethodID jlrField_getName; /* java.lang.reflect.Field.getNam
extern jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
extern jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
extern jmethodID jlrArray_newInstance; /* java.lang.reflect.Array.newInstance() */
extern jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
extern jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */