|
|
To give Java objects a JavaScript interface, Resin wraps the Java with
automatically generated classes. The wrapper classes convert between
Java and JavaScript types, mashalling and unmarshalling call
arguments.
Resin's wrapping tries to abide by the rule of least surprises.
Wrapped objects as a developer expects. However, because of the
differences between Java and JavaScript, the details of making them
mesh are somewhat lengthy.
The Packages object lets scripts directly access Java
classes. The properties of the Packages object are Java
packages and classes.
As a convenience, the variable 'java' is preset to 'Packages.java'
and 'caucho' is preset to 'Packages.com.caucho'.
Java Vector
a = new Packages.java.util.Vector();
a.addElement("a");
a.addElement("b");
|
The pseudo-code in the following tables are based on the EcmaScript
definitions.
Resin to Java
Java Type |
pseudo-code |
boolean |
obj.toBoolean() |
byte |
(byte) obj.toInt32() |
short |
(short) obj.toInt32() |
char |
obj.toString()[0] |
int |
obj.toInt32() |
long |
(long) obj.toNumber() |
float |
(float) obj.toNumber() |
double |
obj.toNumber() |
String |
obj.toString() |
Object |
obj.toJavaObject() |
toJavaObject
JavaScript |
Java |
null |
null |
undefined |
null |
boolean |
java.lang.Boolean |
date |
java.lang.Date |
string |
java.lang.String |
number |
java.lang.Double |
wrapper |
wrapper contents |
regexp |
com.caucho.regexp.Regexp |
Object |
unchanged, com.caucho.es.ESBase |
Note: Java Number 's are converted to JavaScript numbers,
so the Number object is not preserved.
Java to Resin
Java |
JavaScript |
null |
null |
boolean |
boolean |
byte |
number |
short |
number |
char |
string |
int |
number |
long |
number |
float |
number |
double |
number |
java.lang.String |
string |
java.util.Date |
date |
java.lang.Number |
number |
Object |
Object wrapper |
Scripts can call methods on the wrapped object. Each method is
wrapped in a JavaScript function but will only work when
this is the wrapped object.
map = new java.util.HashMap();
map.put("foo", "bar");
writeln(map.get);
writeln(map.get("foo"));
writeln(map.get("bar"));
|
function get() { [native code] }
bar
null
|
Method Overloading
Methods may be overloaded by argument length. Methods may not be
overloaded by argument type. Type-overloaded methods are ignored.
For example, the StringBuffer append call is not
available in Resin.
Method Calls
Method calls follow these steps:
- Select overloaded method by argument length
- Convert JavaScript arguments to Java
- Call the method
- Convert any Java return value to JavaScript
Resin exposes several types of properties to the script: fields,
simple bean get/set properties, bean indexed properties, and named
properties. Fields always take precedence.
Fields
Resin exposes public Java fields as properties. Wrapped instances can
access object and static properties, while wrapped classes can only
access static properties.
Note: Fields override design pattern properties, i.e. bean properties.
Test.java
public class Test {
public static int foo = 3;
public int bar = 9;
}
|
test.es
Test = Packages.Test;
t = new Test();
writeln("Test " + Test.foo + " " + Test.bar);
writeln(Test.bar);
writeln("test " + t.foo + " " + t.bar);
|
Test 3 undefined
test 3 9
|
Simple Bean Properties
The bean properties are a convenience for some common method
patterns. In all cases, the method interface always exists.
Methods matching foo getXXX() and
void setXXX(foo a) are treated as simple JavaScript
properties.
Test.java
public class Test {
private int a = 19;
public int getA() { return a; }
public void setA(int value) { a = value }
}
|
test.es
t = new Packages.Test();
writeln(t.a);
t.a++;
writeln(t.a);
|
19
20
|
Indexed Bean Properties
Resin treats indexed properties as arrays using an extensions of the
Bean indexed property pattern. In addition to the
Foo getXXX(int) and void
setXXX(int, Foo) methods, Resin will use int
getXXXLength() to determine an array length.
Test.java
public class Test {
String []data = new String[4] { "fee", "fie", "foe", "fum"};
public String getString(int i) {
return data[i];
}
public void setString(int i, String value) {
data[i] = value;
}
public int getStringLength() {
return data.length;
}
}
|
test.es
test = new Packages.Test();
writeln(test.string[0] + " " + test.string[test.length - 1]);
writeln(test.reverse().join());
|
fee fum
fum,foe,fie,fee
|
Named Bean Properties
Resin treats named properties as objections extending the Bean properties.
It the named properties recognize the Foo
getXXX(int) and void setXXX(int, Foo) methods,
Resin will use Iterator getXXXNames() to iterate through
the members of the property.
Java Def |
Java Call |
JavaScript |
String getFoo(String name) |
test.getFoo("bar") |
test.foo.bar |
void setFoo(String name, String value) |
test.setFoo("bar", "fie") |
test.foo.bar = "fie"; |
Iterator getFooNames() |
test.getFooNames() |
for (name in test.foo) { ... } |
Test.java
public class Test {
HashMap data = new HashMap();
public String getFoo(String name) {
return data.get(name);
}
public void setFoo(String name, String value) {
data.set(name, value);
}
public Iterator getFooNames() {
return data.keySet().iterator();
}
}
|
test.es
test = new Packages.Test();
test.foo["bar"] = 13;
test.foo["baz"] = 14;
writeln(test.foo.bar + " " + test.foo.baz + " " +
test.foo.fie)
for (a in test.foo) {
writeln(a + " " + test.foo[a]);
}
|
13 14 null
bar 13
baz 14
|
Copyright © 1998-2000 Caucho Technology. All rights reserved.
Last modified: Thu, 16 Sep 1999 14:56:49 -0700 (PDT)
|