You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2005/06/25 02:06:46 UTC

svn commit: r201699 - in /xmlgraphics/batik/trunk: ./ sources/org/apache/batik/script/ sources/org/apache/batik/script/rhino/

Author: deweese
Date: Fri Jun 24 17:06:45 2005
New Revision: 201699

URL: http://svn.apache.org/viewcvs?rev=201699&view=rev
Log:
1) The InterpreterPool now issues an appropriate error when it can't
   find an interpreter for a script element.
2) The RhinoInterpreter no longer uses the ExtendedContext, just the
   regular Context.

Modified:
    xmlgraphics/batik/trunk/build.xml
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/EventTargetWrapper.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreter.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/WindowWrapper.java

Modified: xmlgraphics/batik/trunk/build.xml
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/build.xml?rev=201699&r1=201698&r2=201699&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/build.xml (original)
+++ xmlgraphics/batik/trunk/build.xml Fri Jun 24 17:06:45 2005
@@ -1151,6 +1151,10 @@
           description="Runs test suite whose file or uri is passed as an input">
     <java fork="yes"
           classname="${class-prefix}.test.xml.XMLTestSuiteRunner">
+<!-- Using -Xincgc makes the memory leak tests _much_ more accurate but
+     Also slows down the regard run by 3-4x,  In general I suggest running
+     just the memory leak tests with -Xincgc, I might also experiment with
+     a higher -Xms setting. -->
 <!--      <jvmarg value="-Xincgc" /> -->
 <!--      <jvmarg value="-Xrunhprof:format=b" /> -->
 <!--      <jvmarg value="-Xrunhprof:net=localhost:1234,format=b" /> -->

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java?rev=201699&r1=201698&r2=201699&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/InterpreterPool.java Fri Jun 24 17:06:45 2005
@@ -96,13 +96,14 @@
      */
     public Interpreter createInterpreter(Document document, String language) {
         InterpreterFactory factory = (InterpreterFactory)factories.get(language);
-        Interpreter interpreter = null;
-        if (factory != null)
-            interpreter = factory.createInterpreter
+        if (factory == null) return null;
+
+        Interpreter interpreter = factory.createInterpreter
                 (((SVGOMDocument)document).getURLObject());
-        if (document != null) {
+        if (interpreter == null) return null;
+
+        if (document != null)
             interpreter.bindObject(BIND_NAME_DOCUMENT, document);
-        }
 
         return interpreter;
     }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/EventTargetWrapper.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/EventTargetWrapper.java?rev=201699&r1=201698&r2=201699&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/EventTargetWrapper.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/EventTargetWrapper.java Fri Jun 24 17:06:45 2005
@@ -54,8 +54,8 @@
      * The Java function object calling the Rhino function.
      */
     static class FunctionEventListener implements EventListener {
-        private Function function;
-        private RhinoInterpreter interpreter;
+        protected Function function;
+        protected RhinoInterpreter interpreter;
         FunctionEventListener(Function f, RhinoInterpreter i) {
             function = f;
             interpreter = i;
@@ -74,11 +74,11 @@
     }
 
     static class HandleEventListener implements EventListener {
-        private final static String HANDLE_EVENT = "handleEvent";
+        public final static String HANDLE_EVENT = "handleEvent";
 
-        private Scriptable scriptable;
-        private Object[] array = new Object[1];
-        private RhinoInterpreter interpreter;
+        public Scriptable scriptable;
+        public Object[] array = new Object[1];
+        public RhinoInterpreter interpreter;
 
         HandleEventListener(Scriptable s, RhinoInterpreter interpreter) {
             scriptable = s;
@@ -189,11 +189,13 @@
      * cases.
      */
     static class FunctionAddProxy extends FunctionProxy {
-        private Map listenerMap;
-
-        FunctionAddProxy(Function delegate, Map listenerMap) {
+        protected Map              listenerMap;
+        protected RhinoInterpreter interpreter;
+        FunctionAddProxy(RhinoInterpreter interpreter,
+                         Function delegate, Map listenerMap) {
             super(delegate);
             this.listenerMap = listenerMap;
+            this.interpreter = interpreter;
         }
 
         public Object call(Context ctx, Scriptable scope,
@@ -202,8 +204,7 @@
             NativeJavaObject  njo = (NativeJavaObject)thisObj;
             if (args[1] instanceof Function) {
                 EventListener evtListener = new FunctionEventListener
-                    ((Function)args[1],
-                     ((RhinoInterpreter.ExtendedContext)ctx).getInterpreter());
+                    ((Function)args[1], interpreter);
                 listenerMap.put(args[1], new SoftReference(evtListener));
                 // we need to marshall args
                 Class[] paramTypes = { String.class, Function.class,
@@ -218,8 +219,7 @@
             if (args[1] instanceof NativeObject) {
                 EventListener evtListener =
                     new HandleEventListener((Scriptable)args[1],
-                                            ((RhinoInterpreter.ExtendedContext)
-                                             ctx).getInterpreter());
+                                            interpreter);
                 listenerMap.put(args[1], new SoftReference(evtListener));
                 // we need to marshall args
                 Class[] paramTypes = { String.class, Scriptable.class,
@@ -236,7 +236,7 @@
     }
 
     static class FunctionRemoveProxy extends FunctionProxy {
-        private Map listenerMap;
+        public Map listenerMap;
 
         FunctionRemoveProxy(Function delegate, Map listenerMap) {
             super(delegate);
@@ -287,18 +287,20 @@
     // the keys are the underlying Java object, in order
     // to remove potential memory leaks use a WeakHashMap to allow
     // to collect entries as soon as the underlying Java object is
-    // not anymore available.
-    private static WeakHashMap mapOfListenerMap;
+    // not available anymore.
+    protected static WeakHashMap mapOfListenerMap;
 
-    private final static String ADD_NAME    = "addEventListener";
-    private final static String REMOVE_NAME = "removeEventListener";
-    private final static Class[] ARGS_TYPE = { String.class,
+    public final static String ADD_NAME    = "addEventListener";
+    public final static String REMOVE_NAME = "removeEventListener";
+    public final static Class[] ARGS_TYPE = { String.class,
                                                EventListener.class,
                                                Boolean.TYPE };
-    private final static String NAME = "name";
 
-    EventTargetWrapper(Scriptable scope, EventTarget object) {
+    protected RhinoInterpreter interpreter;
+    EventTargetWrapper(Scriptable scope, EventTarget object,
+                       RhinoInterpreter interpreter) {
         super(scope, object, null);
+        this.interpreter = interpreter;
     }
 
     /**
@@ -309,12 +311,14 @@
         if (name.equals(ADD_NAME)) {
             // prevent creating a Map for all JavaScript objects
             // when we need it only from time to time...
-            method = new FunctionAddProxy((Function)method, initMap());
+            method = new FunctionAddProxy(interpreter, 
+                                          (Function)method, initMap());
         }
         if (name.equals(REMOVE_NAME)) {
             // prevent creating a Map for all JavaScript objects
             // when we need it only from time to time...
-            method = new FunctionRemoveProxy((Function)method, initMap());
+            method = new FunctionRemoveProxy
+                ((Function)method, initMap());
         }
         return method;
     }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreter.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreter.java?rev=201699&r1=201698&r2=201699&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreter.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/RhinoInterpreter.java Fri Jun 24 17:06:45 2005
@@ -28,9 +28,8 @@
 import java.security.PrivilegedAction;
 import java.util.Iterator;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Locale;
-import java.util.Map;
-import java.util.HashMap;
 
 import org.apache.batik.bridge.InterruptedBridgeException;
 import org.apache.batik.script.Interpreter;
@@ -103,8 +102,7 @@
 
     private ScriptableObject globalObject = null;
     private LinkedList compiledScripts = new LinkedList();
-    private WrapFactory wrapFactory =
-        new BatikWrapFactory(this);
+    private WrapFactory wrapFactory = new BatikWrapFactory(this);
 
     /**
      * The Rhino 'security domain'. We use the RhinoClassLoader
@@ -122,6 +120,18 @@
         = new BatikSecurityController();
 
     /**
+     * Default Context for scripts. This is used only for efficiency
+     * reason.
+     */
+    protected Context defaultContext;
+
+    /**
+     * Context vector, to make sure we are not
+     * setting the security context too many times
+     */
+    protected List contexts = new LinkedList();
+
+    /**
      * Build a <code>Interpreter</code> for ECMAScript using Rhino.
      *
      * @param documentURL the URL for the document which references
@@ -180,9 +190,11 @@
      * on the context.
      */
     public Context enterContext(){
-        Context ctx = Context.getCurrentContext();
-        if (ctx == null) {
-            ctx = new ExtendedContext();
+        Context ctx = Context.enter();
+        if (ctx == defaultContext)
+            return ctx;
+
+        if (!contexts.contains(ctx)) {
             ctx.setWrapFactory(wrapFactory);
             ctx.setSecurityController(securityController);
             ctx.setClassShutter(new RhinoClassShutter());
@@ -192,9 +204,9 @@
                 ctx.setOptimizationLevel(-1);
                 ctx.setCachingEnabled(false);
             }
+            contexts.add(ctx);
         }
-        ctx = Context.enter(ctx);
-
+        defaultContext = ctx;
         return ctx;
     }
 
@@ -378,66 +390,22 @@
         enterContext();
         try {
             if (name.equals(BIND_NAME_WINDOW) && object instanceof Window) {
+                ((WindowWrapper)globalObject).window = (Window)object;
                 window = (Window)object;
                 object = globalObject;
             }
-            try {
                 Scriptable jsObject;
                 jsObject = Context.toObject(object, globalObject);
-                objects.put(name, jsObject);
-                if (ScriptableObject.getProperty(globalObject, name) ==
-                    ScriptableObject.NOT_FOUND)
-                    globalObject.defineProperty
-                        (name, new RhinoGetDelegate(name),
-                         rhinoGetter, null, ScriptableObject.READONLY);
-            } catch (PropertyException pe) {
-                pe.printStackTrace();
-            }
+            globalObject.put(name, globalObject, jsObject);
         } finally {
             Context.exit();
         }
     }
-    /**
-     * HashTable to store properties bounds on the global object.
-     * So they don't end up in the JavaMethods static table.
-     */
-    Map objects = new HashMap(4);
-
-    /**
-     * Class to act as 'get' delegate for Rhino.  This uses the
-     * currentContext to get the current Interpreter object which
-     * allows it to lookup the object requested.  This gets around the
-     * fact that the global object gets referenced from a static
-     * context but the Context does not.
-     */
-    public static class RhinoGetDelegate {
-        String name;
-        RhinoGetDelegate(String name) {
-            this.name = name;
-        }
-        public Object get(ScriptableObject so) {
-            Context ctx = Context.getCurrentContext();
-            if (ctx == null ) return null;
-            return ((ExtendedContext)ctx).getInterpreter().objects.get(name);
-        }
-    }
-    // The method to use for getting the value from the
-    // RhinoGetDelegate.
-    static Method rhinoGetter;
-    static {
-        try {
-            Class [] getterArgs = { ScriptableObject.class };
-            rhinoGetter = RhinoGetDelegate.class.getDeclaredMethod
-                ("get", getterArgs);
-        } catch (NoSuchMethodException nsm) { }
-    }
-
 
     /**
      * To be used by <code>EventTargetWrapper</code>.
      */
-    void callHandler(Function handler,
-                     Object arg)
+    void callHandler(Function handler, Object arg)
         throws JavaScriptException {
         Context ctx = enterContext();
         try {
@@ -485,6 +453,7 @@
         throws JavaScriptException {
         Context ctx = enterContext();
         try {
+            System.err.println("GlobalObj: " + globalObject);
             Object [] args = ab.buildArguments();
            handler.call(ctx, handler.getParentScope(), globalObject, args );
         } finally {
@@ -503,7 +472,7 @@
      * Build the wrapper for objects implement <code>EventTarget</code>.
      */
     Scriptable buildEventTargetWrapper(EventTarget obj) {
-        return new EventTargetWrapper(globalObject, obj);
+        return new EventTargetWrapper(globalObject, obj, this);
     }
 
     /**
@@ -548,23 +517,5 @@
      */
     public String formatMessage(String key, Object[] args) {
         return null;
-    }
-
-    public class ExtendedContext extends Context {
-        public ExtendedContext() {
-            super();
-        }
-
-        public RhinoInterpreter getInterpreter() {
-            return RhinoInterpreter.this;
-        }
-
-        public Window getWindow() {
-            return RhinoInterpreter.this.getWindow();
-        }
-
-        public ScriptableObject getGlobalObject() {
-            return RhinoInterpreter.this.getGlobalObject();
-        }
     }
 }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/WindowWrapper.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/WindowWrapper.java?rev=201699&r1=201698&r2=201699&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/WindowWrapper.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/script/rhino/WindowWrapper.java Fri Jun 24 17:06:45 2005
@@ -47,12 +47,23 @@
     private final static Object[] EMPTY_ARGUMENTS = new Object[0];
 
     /**
+     * The rhino interpreter.
+     */
+    protected RhinoInterpreter interpreter;
+    
+    /**
+     * The wrapped window.
+     */
+    protected Window window;
+
+    /**
      * Creates a new WindowWrapper.
      */
     public WindowWrapper(Context context) {
         super(context);
-        String[] names = { "setInterval", "setTimeout", "clearInterval", "clearTimeout",
-                           "parseXML", "getURL", "alert", "confirm", "prompt" };
+        String[] names = { "setInterval", "setTimeout", "clearInterval", 
+                           "clearTimeout", "parseXML", "getURL", "alert", 
+                           "confirm", "prompt" };
         try {
             this.defineFunctionProperties(names, WindowWrapper.class,
                                           ScriptableObject.DONTENUM);
@@ -78,7 +89,9 @@
                                      Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
+
         if (len < 2) {
             throw Context.reportRuntimeError("invalid argument count");
         }
@@ -105,7 +118,8 @@
                                     Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
         if (len < 2) {
             throw Context.reportRuntimeError("invalid argument count");
         }
@@ -132,7 +146,8 @@
                                      Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
         if (len >= 1) {
             window.clearInterval(Context.toType(args[0], Object.class));
         }
@@ -147,7 +162,8 @@
                                     Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
         if (len >= 1) {
             window.clearTimeout(Context.toType(args[0], Object.class));
         }
@@ -162,8 +178,8 @@
                                   Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        final Window window = 
-            ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        final Window window = ww.window;
         if (len < 2) {
             throw Context.reportRuntimeError("invalid argument count");
         }
@@ -190,8 +206,8 @@
                               Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        final Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
-        final ScriptableObject go = ((RhinoInterpreter.ExtendedContext)cx).getGlobalObject();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        final Window window = ww.window;
         if (len < 2) {
             throw Context.reportRuntimeError("invalid argument count");
         }
@@ -201,10 +217,10 @@
         Window.URLResponseHandler urlHandler = null;
         if (args[1] instanceof Function) {
             urlHandler = new GetURLFunctionWrapper
-                (interp, (Function)args[1], go);
+                (interp, (Function)args[1], ww);
         } else {
             urlHandler = new GetURLObjectWrapper
-                (interp, (NativeObject)args[1], go);
+                (interp, (NativeObject)args[1], ww);
         }
         final Window.URLResponseHandler fw = urlHandler;
 
@@ -239,8 +255,8 @@
                                Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        final Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
-        final ScriptableObject go = ((RhinoInterpreter.ExtendedContext)cx).getGlobalObject();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        final Window window = ww.window;
         if (len < 3) {
             throw Context.reportRuntimeError("invalid argument count");
         }
@@ -251,10 +267,10 @@
         Window.URLResponseHandler urlHandler = null;
         if (args[2] instanceof Function) {
             urlHandler = new GetURLFunctionWrapper
-                (interp, (Function)args[2], go);
+                (interp, (Function)args[2], ww);
         } else {
             urlHandler = new GetURLObjectWrapper
-                (interp, (NativeObject)args[2], go);
+                (interp, (NativeObject)args[2], ww);
         }
         final Window.URLResponseHandler fw = urlHandler;
 
@@ -300,7 +316,8 @@
                              Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
         if (len >= 1) {
             String message =
                 (String)Context.toType(args[0], String.class);
@@ -317,7 +334,8 @@
                                   Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
         if (len >= 1) {
             String message =
                 (String)Context.toType(args[0], String.class);
@@ -338,7 +356,8 @@
                                 Function funObj)
         throws JavaScriptException {
         int len = args.length;
-        Window window = ((RhinoInterpreter.ExtendedContext)cx).getWindow();
+        WindowWrapper ww = (WindowWrapper)thisObj;
+        Window window = ww.window;
         switch (len) {
         case 0:
             return Context.toObject("", thisObj);
@@ -417,18 +436,18 @@
         protected Function function;
 
         /**
-         * The Scope for callback
+         * The WindowWrapper
          */
-        protected ScriptableObject scope;
+        protected WindowWrapper windowWrapper;
 
         /**
          * Creates a wrapper.
          */
         public GetURLFunctionWrapper(RhinoInterpreter ri, Function fct,
-                                     ScriptableObject sc) {
+                                     WindowWrapper ww) {
             interpreter = ri;
             function = fct;
-            scope = sc;
+            windowWrapper = ww;
         }
 
         /**
@@ -443,7 +462,8 @@
             try {
                 interpreter.callHandler
                     (function, 
-                     new GetURLDoneArgBuilder(success, mime, content, scope));
+                     new GetURLDoneArgBuilder(success, mime, 
+                                              content, windowWrapper));
             } catch (JavaScriptException e) {
                 throw new WrappedException(e);
             }
@@ -469,7 +489,7 @@
         /**
          * The Scope for the callback.
          */
-        private ScriptableObject scope;
+        private WindowWrapper windowWrapper;
 
         private static final String COMPLETE = "operationComplete";
 
@@ -478,10 +498,10 @@
          */
         public GetURLObjectWrapper(RhinoInterpreter ri,
                                    ScriptableObject obj,
-                                   ScriptableObject sc) {
+                                   WindowWrapper ww) {
             interpreter = ri;
             object = obj;
-            scope = sc;
+            windowWrapper = ww;
         }
 
         /**
@@ -496,7 +516,8 @@
             try {
                 interpreter.callMethod
                     (object, COMPLETE,
-                     new GetURLDoneArgBuilder(success, mime, content, scope));
+                     new GetURLDoneArgBuilder(success, mime, 
+                                              content, windowWrapper));
             } catch (JavaScriptException e) {
                 Context.exit();
                 throw new WrappedException(e);
@@ -508,14 +529,14 @@
         implements RhinoInterpreter.ArgumentsBuilder {
         boolean success;
         String mime, content;
-        ScriptableObject scope;
+        WindowWrapper windowWrapper;
         public GetURLDoneArgBuilder(boolean success, 
                                     String mime, String content,
-                                    ScriptableObject scope) {
+                                    WindowWrapper ww) {
             this.success = success;
             this.mime    = mime;
             this.content = content;
-            this.scope   = scope;
+            this.windowWrapper = ww;
         }
 
         public Object[] buildArguments() {
@@ -524,11 +545,11 @@
                    (success) ? Boolean.TRUE : Boolean.FALSE);
             if (mime != null) {
                 so.put("contentType", so,
-                       Context.toObject(mime, scope));
+                       Context.toObject(mime, windowWrapper));
             }
             if (content != null) {
                 so.put("content", so,
-                       Context.toObject(content, scope));
+                       Context.toObject(content, windowWrapper));
             }
             return new Object [] { so };
         }