r9652 - in helma-ng/trunk: modules/helma src/org/helma/javascript src/org/helma/repository

[email protected] Wed, 22 Apr 2009 15:09:56 +0200 (CEST)
Newsgroups gmane.comp.java.helma.cvs
Message-ID <20090422130956.640683D0D6@mia>
Author: hannes
Date: 2009-04-22 15:09:56 +0200 (Wed, 22 Apr 2009)
New Revision: 9652

Modified:
   helma-ng/trunk/modules/helma/system.js
   helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java
   helma-ng/trunk/src/org/helma/repository/Trackable.java
Log:
Add serialization support to RhinoEngine and helma/system.

Details at http://dev.helma.org/trac/helma/changeset/9652

Modified: helma-ng/trunk/modules/helma/system.js
===================================================================
--- helma-ng/trunk/modules/helma/system.js	2009-04-21 23:41:59 UTC (rev 9651)
+++ helma-ng/trunk/modules/helma/system.js	2009-04-22 13:09:56 UTC (rev 9652)
@@ -14,6 +14,8 @@
         'getRhinoEngine',
         'getOptimizationLevel',
         'setOptimizationLevel',
+        'serialize',
+        'deserialize',
         'args');
 
 var rhino = org.mozilla.javascript;
@@ -78,6 +80,22 @@
     getRhinoEngine().setOptimizationLevel(level);
 }
 
+function serialize(object, output) {
+    if (!(output instanceof java.io.OutputStream)) {
+        output = new java.io.ByteArrayOutputStream();
+        getRhinoEngine().serialize(object, output);
+        return output.toByteArray();
+    }
+    getRhinoEngine().serialize(object, output);    
+}
+
+function deserialize(input) {
+    if (!(input instanceof java.io.InputStream)) {
+        input = new java.io.ByteArrayInputStream(input);
+    }
+    return getRhinoEngine().deserialize(input);
+}
+
 /**
  * Evaluate a module script on an existing scope instead of creating a
  * new module scope. This can be used to mimic traditional JavaScript

Modified: helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java
===================================================================
--- helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java	2009-04-21 23:41:59 UTC (rev 9651)
+++ helma-ng/trunk/src/org/helma/javascript/RhinoEngine.java	2009-04-22 13:09:56 UTC (rev 9652)
@@ -22,10 +22,10 @@
 import org.helma.tools.launcher.HelmaClassLoader;
 import org.helma.util.*;
 import org.mozilla.javascript.*;
+import org.mozilla.javascript.serialize.ScriptableOutputStream;
+import org.mozilla.javascript.serialize.ScriptableInputStream;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.FileNotFoundException;
+import java.io.*;
 import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.net.MalformedURLException;
@@ -570,6 +570,74 @@
         loader.addURL(resource.getUrl());
     }
 
+    /**
+     * Provide object serialization for this engine's scripted objects. If no special
+     * provisions are required, this method should just wrap the stream with an
+     * ObjectOutputStream and write the object.
+     *
+     * @param obj the object to serialize
+     * @param out the stream to write to
+     * @throws java.io.IOException
+     */
+    public void serialize(Object obj, OutputStream out) throws IOException {
+        final Context cx = contextFactory.enterContext();
+        try {
+            // use a special ScriptableOutputStream that unwraps Wrappers
+            ScriptableOutputStream sout = new ScriptableOutputStream(out, topLevelScope) {
+                protected Object replaceObject(Object obj) throws IOException {
+                    if (obj == topLevelScope) {
+                        return new SerializedScopeProxy(null);
+                    } else if (obj instanceof ModuleScope) {
+                        return new SerializedScopeProxy(((ModuleScope) obj).getName());
+                    }
+                    return super.replaceObject(obj);
+                }
+            };
+
+            sout.writeObject(obj);
+            sout.flush();
+        } finally {
+            Context.exit();
+        }
+    }
+
+    /**
+     * Provide object deserialization for this engine's scripted objects. If no special
+     * provisions are required, this method should just wrap the stream with an
+     * ObjectIntputStream and read the object.
+     *
+     * @param in the stream to read from
+     * @return the deserialized object
+     * @throws java.io.IOException
+     */
+    public Object deserialize(InputStream in) throws IOException, ClassNotFoundException {
+        final Context cx = contextFactory.enterContext();
+        try {
+            ObjectInputStream sin = new ScriptableInputStream(in, topLevelScope) {
+                protected Object resolveObject(Object obj) throws IOException {
+                    if (obj instanceof SerializedScopeProxy) {
+                        return ((SerializedScopeProxy) obj).getObject(cx, RhinoEngine.this);
+                    } 
+                    return super.resolveObject(obj);
+                }
+            };
+            return sin.readObject();
+        } finally {
+            Context.exit();
+        }
+    }
+
+    private static class SerializedScopeProxy implements Serializable {
+        String moduleName;
+        SerializedScopeProxy(String moduleName) {
+            this.moduleName = moduleName;
+        }
+
+        Object getObject(Context cx, RhinoEngine engine) throws IOException {
+            return moduleName == null ? engine.topLevelScope : engine.loadModule(cx, moduleName, null);
+        }
+    }
+
     public HelmaContextFactory getContextFactory() {
         return contextFactory;
     }

Modified: helma-ng/trunk/src/org/helma/repository/Trackable.java
===================================================================
--- helma-ng/trunk/src/org/helma/repository/Trackable.java	2009-04-21 23:41:59 UTC (rev 9651)
+++ helma-ng/trunk/src/org/helma/repository/Trackable.java	2009-04-22 13:09:56 UTC (rev 9652)
@@ -2,12 +2,13 @@
 
 import java.net.URL;
 import java.net.MalformedURLException;
+import java.io.Serializable;
 
 /**
  * Parent interface for both Repository and Resource interfaces. 
  * Describes an entity defined by a file-system like path.
  */
-public interface Trackable {
+public interface Trackable extends Serializable {
 
     /**
      * Returns the date the resource was last modified