changeset 9725:66eee7a12e81

8089842: JavaScript2Java Bridge: A char value cannot be set from JavaScript Reviewed-by: kcr, mbilla
author arajkumar
date Tue, 19 Apr 2016 15:54:49 +0530
parents a2edf89bd58d
children 903a7850775e
files modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp modules/web/src/test/java/test/javafx/scene/web/JavaScriptBridgeTest.java
diffstat 2 files changed, 63 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp	Thu Apr 21 11:34:32 2016 -0400
+++ b/modules/web/src/main/native/Source/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp	Tue Apr 19 15:54:49 2016 +0530
@@ -178,8 +178,19 @@
     return jarray;
 }
 
+static jchar toJCharValue(const JSValue& value, ExecState* exec)
+{
+    // If JS type is string and target Java type is char, then
+    // return the first unicode character.
+    if (value.isString()) {
+        String stringValue = value.toString(exec)->value(exec);
+        return (jchar)stringValue[0];
+    }
+    return (jchar)value.toNumber(exec);
+}
 
-jobject convertUndefinedToJObject() {
+jobject convertUndefinedToJObject()
+{
     static JGObject jgoUndefined;
     if (!jgoUndefined) {
         JNIEnv* env = getJNIEnv();
@@ -191,7 +202,6 @@
     return jgoUndefined;
 }
 
-
 jvalue convertValueToJValue(ExecState* exec, RootObject* rootObject, JSValue value, JavaType javaType, const char* javaClassName)
 {
     JSLockHolder lock(exec);
@@ -269,6 +279,13 @@
                     JNIEnv* env = getJNIEnv();
                     jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.deprecatedCharacters(), stringValue.length());
                     result.l = javaString;
+                } else if (value.isString() && !strcmp(javaClassName, "java.lang.Character")) {
+                    JNIEnv* env = getJNIEnv();
+                    static JGClass clazz(env->FindClass("java/lang/Character"));
+                    jmethodID meth = env->GetStaticMethodID(clazz, "valueOf", "(C)Ljava/lang/Character;");
+                    jchar charValue = toJCharValue(value, exec);
+                    jobject javaChar = env->CallStaticObjectMethod(clazz, meth, charValue);
+                    result.l = javaChar;
                 } else if (value.isNumber()) {
                     JNIEnv* env = getJNIEnv();
                     if (value.isInt32() && (!strcmp(javaClassName, "java.lang.Number") || !strcmp(javaClassName, "java.lang.Integer") || !strcmp(javaClassName, "java.lang.Object"))) {
@@ -321,7 +338,7 @@
 
     case JavaTypeChar:
         {
-            result.c = (jchar)value.toNumber(exec);
+            result.c = toJCharValue(value, exec);
         }
         break;
 
--- a/modules/web/src/test/java/test/javafx/scene/web/JavaScriptBridgeTest.java	Thu Apr 21 11:34:32 2016 -0400
+++ b/modules/web/src/test/java/test/javafx/scene/web/JavaScriptBridgeTest.java	Tue Apr 19 15:54:49 2016 +0530
@@ -326,6 +326,8 @@
         public Integer i1; // direct access
         public Boolean b0; // using setter
         public Boolean b1; // direct access
+        public Character c0; // using setter
+        public Character c1; // direct access
 
         public void setNumberVal(Number n) {
             n0 = n;
@@ -342,6 +344,10 @@
         public void setBooleanVal(Boolean b) {
             b0 = b;
         }
+
+        public void setCharacterVal(Character c) {
+            c0 = c;
+        }
     }
 
     public @Test void testMethodCallWithWrapperObjects() {
@@ -374,6 +380,43 @@
             assertEquals(true, obj.b1.booleanValue());
             web.executeScript("obj.b1 = false");
             assertEquals(false, obj.b1.booleanValue());
+            // Test java.lang.Character
+            web.executeScript("obj.setCharacterVal('o')");
+            assertEquals('o', obj.c0.charValue());
+            web.executeScript("obj.c1 = '1'");
+            assertEquals('1', obj.c1.charValue());
+        });
+    }
+
+    // JDK-8089842
+    public static class CharMember {
+        public char c;
+    }
+
+    public @Test void testJSStringToJavaCharSpecilization() {
+        final WebEngine web = getEngine();
+
+        submit(() -> {
+            CharMember charTest = new CharMember();
+            bind("charTest", charTest);
+            // ascii char
+            web.executeScript("charTest.c = 'o';");
+            assertEquals('o', charTest.c);
+            web.executeScript("charTest.c = undefined;");
+            assertEquals('\0', charTest.c);
+            web.executeScript("charTest.c = '11111111o';");
+            assertEquals('1', charTest.c);
+            web.executeScript("charTest.c = null;");
+            assertEquals('\0', charTest.c);
+            web.executeScript("charTest.c = ' ';");
+            assertEquals(' ', charTest.c);
+            web.executeScript("charTest.c = '';");
+            assertEquals('\0', charTest.c);
+            web.executeScript("charTest.c = 65;");
+            assertEquals('A', charTest.c);
+            // unicode
+            web.executeScript("charTest.c = '\u03A9';");
+            assertEquals('Ω', charTest.c);
         });
     }