diff --git a/src/helma/scripting/rhino/RhinoEngine.java b/src/helma/scripting/rhino/RhinoEngine.java index 33ed4f810..b2445b0be 100644 --- a/src/helma/scripting/rhino/RhinoEngine.java +++ b/src/helma/scripting/rhino/RhinoEngine.java @@ -523,15 +523,17 @@ public DocApplication getDoc() { */ public void serialize(Object obj, OutputStream out) throws IOException { core.contextFactory.enter(); + engines.set(this); try { // use a special ScriptableOutputStream that unwraps Wrappers ScriptableOutputStream sout = new ScriptableOutputStream(out, core.global) { protected Object replaceObject(Object obj) throws IOException { - // FIXME doesn't work because we need a transactor thread for deserialization - // if (obj instanceof Wrapper) - // obj = ((Wrapper) obj).unwrap(); - // if (obj instanceof helma.objectmodel.db.Node) - // return ((helma.objectmodel.db.Node) obj).getHandle(); + if (obj instanceof HopObject) + return new HopObjectProxy((HopObject) obj); + if (obj instanceof helma.objectmodel.db.Node) + return new HopObjectProxy((helma.objectmodel.db.Node) obj); + if (obj instanceof GlobalObject) + return new GlobalProxy((GlobalObject) obj); if (obj instanceof ApplicationBean) return new ScriptBeanProxy("app"); if (obj instanceof RequestBean) @@ -543,8 +545,8 @@ protected Object replaceObject(Object obj) throws IOException { return super.replaceObject(obj); } }; - sout.addExcludedName("Xml"); - sout.addExcludedName("global"); + // sout.addExcludedName("Xml"); + // sout.addExcludedName("global"); sout.writeObject(obj); sout.flush(); @@ -564,15 +566,12 @@ protected Object replaceObject(Object obj) throws IOException { */ public Object deserialize(InputStream in) throws IOException, ClassNotFoundException { core.contextFactory.enter(); + engines.set(this); try { ObjectInputStream sin = new ScriptableInputStream(in, core.global) { protected Object resolveObject(Object obj) throws IOException { - if (obj instanceof NodeHandle) { - // FIXME doesn't work unless we have a transactor thread - // Object node = ((NodeHandle) obj).getNode(app.getNodeManager().safe); - // return Context.toObject(node, global); - } else if (obj instanceof ScriptBeanProxy) { - return ((ScriptBeanProxy) obj).getObject(); + if (obj instanceof SerializationProxy) { + return ((SerializationProxy) obj).getObject(RhinoEngine.this); } return super.resolveObject(obj); } @@ -687,24 +686,4 @@ public Skin getSkin(String protoName, String skinName) throws IOException { return skin; } - /** - * Serialization proxy for app, req, res, path objects. - */ - class ScriptBeanProxy implements Serializable { - String name; - - ScriptBeanProxy(String name) { - this.name = name; - } - - /** - * Lookup the actual object in the current scope - * @return the object represented by this proxy - */ - Object getObject() { - return global.get(name, global); - } - - } - } diff --git a/src/helma/scripting/rhino/SerializationProxy.java b/src/helma/scripting/rhino/SerializationProxy.java new file mode 100644 index 000000000..c179d99f1 --- /dev/null +++ b/src/helma/scripting/rhino/SerializationProxy.java @@ -0,0 +1,113 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 2008 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + +package helma.scripting.rhino; + +import helma.objectmodel.INode; +import helma.objectmodel.db.NodeHandle; +import org.mozilla.javascript.Context; + +import java.io.Serializable; + +/** + * Serialization proxy/placeholder interface. This is used for + * for various Helma and Rhino related classes.. + */ +public interface SerializationProxy extends Serializable { + public Object getObject(RhinoEngine engine); +} + +/** + * Serialization proxy for app, req, res, path objects. + */ +class ScriptBeanProxy implements SerializationProxy { + String name; + + ScriptBeanProxy(String name) { + this.name = name; + } + + /** + * Lookup the actual object in the current scope + * + * @return the object represented by this proxy + */ + public Object getObject(RhinoEngine engine) { + return engine.global.get(name, engine.global); + } + +} + +/** + * Serialization proxy for global scope + */ +class GlobalProxy implements SerializationProxy { + boolean shared; + + GlobalProxy(GlobalObject scope) { + shared = !scope.isThreadScope; + } + + /** + * Lookup the actual object in the current scope + * + * @return the object represented by this proxy + */ + public Object getObject(RhinoEngine engine) { + return shared ? engine.core.global : engine.global; + } +} + +/** + * Serialization proxy for various flavors of HopObjects/Nodes + */ +class HopObjectProxy implements SerializationProxy { + Object ref; + boolean wrapped = false; + + HopObjectProxy(HopObject obj) { + INode n = obj.getNode(); + if (n == null) + ref = obj.getClassName(); + else { + if (n instanceof helma.objectmodel.db.Node) + ref = new NodeHandle(((helma.objectmodel.db.Node) n).getKey()); + else + ref = n; + } + wrapped = true; + } + + HopObjectProxy(helma.objectmodel.db.Node node) { + ref = new NodeHandle(node.getKey()); + } + + /** + * Lookup the actual object in the current scope + * + * @return the object represented by this proxy + */ + public Object getObject(RhinoEngine engine) { + if (ref instanceof String) + return engine.core.getPrototype((String) ref); + else if (ref instanceof NodeHandle) { + Object n = ((NodeHandle) ref).getNode(engine.app.getWrappedNodeManager()); + return wrapped ? Context.toObject(n, engine.global) : n; + } + return Context.toObject(ref, engine.global); + } + +}