JavaAdapter serialization contribution from Kemal Bayram.

This commit is contained in:
nboyd%atg.com 2001-11-23 20:40:08 +00:00
Родитель 86d6633b25
Коммит 35421e718f
4 изменённых файлов: 190 добавлений и 2 удалений

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

@ -121,7 +121,10 @@ public class JavaAdapter extends ScriptableObject {
ClassSignature sig = new ClassSignature(superClass, interfaces, obj);
Class adapterClass = (Class) generatedClasses.get(sig);
if (adapterClass == null) {
String adapterName = "adapter" + serial++;
String adapterName;
synchronized (generatedClasses) {
adapterName = "adapter" + serial++;
}
adapterClass = createAdapterClass(cx, obj, adapterName,
superClass, interfaces,
null, null);
@ -134,6 +137,44 @@ public class JavaAdapter extends ScriptableObject {
return getAdapterSelf(adapterClass, adapter);
}
// Needed by NativeJavaObject de-serializer
public static Object createAdapterClass(Class superClass,
Class[] interfaces,
Scriptable obj, Scriptable self)
throws ClassNotFoundException
{
ClassSignature sig = new ClassSignature(superClass, interfaces, obj);
Class adapterClass = (Class) generatedClasses.get(sig);
if (adapterClass == null) {
String adapterName;
synchronized (generatedClasses) {
adapterName = "adapter" + serial++;
}
try {
adapterClass = createAdapterClass(Context.enter(), obj,
adapterName, superClass,
interfaces, null, null);
generatedClasses.put(sig, adapterClass);
} finally {
Context.exit();
}
}
try {
Class[] ctorParms = { Scriptable.class, Scriptable.class };
Object[] ctorArgs = { obj, self };
return adapterClass.getConstructor(ctorParms).newInstance(ctorArgs);
} catch(InstantiationException e) {
} catch(IllegalAccessException e) {
} catch(InvocationTargetException e) {
} catch(NoSuchMethodException e) {
}
throw new ClassNotFoundException("adapter");
}
public static Class createAdapterClass(Context cx, Scriptable jsObj,
String adapterName, Class superClass,
Class[] interfaces,
@ -158,6 +199,7 @@ public class JavaAdapter extends ScriptableObject {
String superName = superClass.getName().replace('.', '/');
generateCtor(cfw, adapterName, superName);
generateSerialCtor(cfw, adapterName, superName);
if (scriptClassName != null)
generateEmptyCtor(cfw, adapterName, superName, scriptClassName);
@ -380,6 +422,33 @@ public class JavaAdapter extends ScriptableObject {
cfw.stopMethod((short)20, null); // TODO: magic number "20"
}
private static void generateSerialCtor(ClassFileWriter cfw, String adapterName,
String superName)
{
cfw.startMethod("<init>",
"(Lorg/mozilla/javascript/Scriptable;Lorg/mozilla/javascript/Scriptable;)V",
ClassFileWriter.ACC_PUBLIC);
// Invoke base class constructor
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.INVOKESPECIAL, superName, "<init>", "()", "V");
// Save parameter in instance variable "delegee"
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.ALOAD_1); // first arg
cfw.add(ByteCode.PUTFIELD, adapterName, "delegee",
"Lorg/mozilla/javascript/Scriptable;");
// save self
cfw.add(ByteCode.ALOAD_0); // this
cfw.add(ByteCode.ALOAD_2); // second arg
cfw.add(ByteCode.PUTFIELD, adapterName, "self",
"Lorg/mozilla/javascript/Scriptable;");
cfw.add(ByteCode.RETURN);
cfw.stopMethod((short)20, null); // TODO: magic number "20"
}
private static void generateEmptyCtor(ClassFileWriter cfw, String adapterName,
String superName, String scriptClassName)
{

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

@ -22,6 +22,7 @@
* Norris Boyd
* Frank Mitchell
* Mike Shaver
* Kemal Bayram
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
@ -38,6 +39,7 @@
package org.mozilla.javascript;
import java.lang.reflect.Array;
import java.io.*;
/**
* This class reflects Java arrays into the JavaScript environment.
@ -152,4 +154,26 @@ public class NativeJavaArray extends NativeJavaObject {
int length;
Class cls;
Scriptable prototype;
public void writeExternal(ObjectOutput out)
throws IOException
{
super.writeExternal(out);
out.writeObject(array);
out.writeInt(length);
out.writeObject(cls.getName());
out.writeObject(prototype);
}
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException
{
super.readExternal(in);
array = in.readObject();
length = in.readInt();
cls = Class.forName((String)in.readObject());
prototype = (Scriptable)in.readObject();
}
}

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

@ -23,6 +23,7 @@
* Frank Mitchell
* Mike Shaver
* Kurt Westerfeld
* Kemal Bayram
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
@ -40,6 +41,7 @@ package org.mozilla.javascript;
import java.lang.reflect.*;
import java.util.Hashtable;
import java.io.*;
/**
* This class reflects Java classes into the JavaScript environment, mainly
@ -272,4 +274,18 @@ public class NativeJavaClass extends NativeJavaObject implements Function {
// beard: need a scope for finding top-level prototypes.
private Scriptable parent;
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeObject(parent);
}
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException
{
super.readExternal(in);
parent = (Scriptable)in.readObject();
fieldAndMethods = members.getFieldAndMethodsObjects(this, javaObject,
true);
}
}

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

@ -23,6 +23,7 @@
* Igor Bukanov
* Frank Mitchell
* Mike Shaver
* Kemal Bayram
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
@ -38,6 +39,7 @@
package org.mozilla.javascript;
import java.io.*;
import java.lang.reflect.*;
import java.util.Hashtable;
import java.util.Enumeration;
@ -53,7 +55,10 @@ import java.util.Enumeration;
* @see NativeJavaClass
*/
public class NativeJavaObject implements Scriptable, Wrapper {
public class NativeJavaObject implements Scriptable, Wrapper, Externalizable {
public NativeJavaObject() {
}
public NativeJavaObject(Scriptable scope, Object javaObject,
JavaMembers members)
@ -68,6 +73,7 @@ public class NativeJavaObject implements Scriptable, Wrapper {
{
this.parent = scope;
this.javaObject = javaObject;
this.staticType = staticType;
Class dynamicType = javaObject != null ? javaObject.getClass()
: staticType;
members = JavaMembers.lookupClass(scope, dynamicType, staticType);
@ -918,9 +924,82 @@ public class NativeJavaObject implements Scriptable, Wrapper {
protected Object javaObject;
protected JavaMembers members;
protected Class staticType;
private Hashtable fieldAndMethods;
static Class jsObjectClass;
static Constructor jsObjectCtor;
static Method jsObjectGetScriptable;
public void writeExternal(ObjectOutput out)
throws IOException
{
out.writeObject(prototype);
out.writeObject(parent);
out.writeObject(staticType != null ? staticType.getClass().getName()
: null);
if (javaObject != null) {
Class joClass = javaObject.getClass();
if (joClass.getName().startsWith("adapter")) {
out.writeBoolean(true);
out.writeObject(joClass.getSuperclass().getName());
Class[] interfaces = joClass.getInterfaces();
String[] interfaceNames = new String[interfaces.length];
for (int i=0; i < interfaces.length; i++)
interfaceNames[i] = interfaces[i].getName();
out.writeObject(interfaceNames);
try {
out.writeObject(joClass.getField("delegee").get(javaObject));
out.writeObject(joClass.getField("self").get(javaObject));
} catch (IllegalAccessException e) {
} catch (NoSuchFieldException e) {
}
} else {
out.writeBoolean(false);
out.writeObject(javaObject);
}
} else {
out.writeBoolean(false);
out.writeObject(null);
}
}
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException
{
prototype = (Scriptable)in.readObject();
parent = (Scriptable)in.readObject();
String className = (String)in.readObject();
staticType = className != null ? Class.forName(className) : null;
if (in.readBoolean()) {
Class superclass = Class.forName((String)in.readObject());
String[] interfaceNames = (String[])in.readObject();
Class[] interfaces = new Class[interfaceNames.length];
for (int i=0; i < interfaceNames.length; i++)
interfaces[i] = Class.forName(interfaceNames[i]);
javaObject = JavaAdapter.createAdapterClass(superclass, interfaces,
(Scriptable)in.readObject(), (Scriptable)in.readObject());
} else {
javaObject = in.readObject();
}
Class dynamicType = javaObject != null ? javaObject.getClass()
: staticType;
members = JavaMembers.lookupClass(parent, dynamicType, staticType);
fieldAndMethods = members.getFieldAndMethodsObjects(this, javaObject,
false);
}
}