cjolif      01/10/08 08:04:39

  Modified:    sources/org/apache/batik/script DocumentProxy.java
                        Interpreter.java
               sources/org/apache/batik/script/jacl JaclInterpreter.java
               sources/org/apache/batik/script/jpython
                        JPythonInterpreter.java
               sources/org/apache/batik/script/rhino
                        EventTargetWrapper.java RhinoInterpreter.java
  Log:
  Add to the Interpreter interface an evaluate method that take a String in
  addition to the one that uses a Reader.
  Implement it, in the different Interpreter concrete classes.
  
  This new method allows in the RhinoIntepreter to easily do some cache
  on the compilation of small pieces of ECMAScript code. This avoid
  the re-compilation (and thus creation of dynamic Java Classes) at
  each time an evaluation is performed.
  
  The idea and a first draft solution was proposed by George Moudry.
  
  Revision  Changes    Path
  1.3       +5 -1      xml-batik/sources/org/apache/batik/script/DocumentProxy.java
  
  Index: DocumentProxy.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/script/DocumentProxy.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DocumentProxy.java        2001/05/14 16:47:47     1.2
  +++ DocumentProxy.java        2001/10/08 15:04:39     1.3
  @@ -30,9 +30,13 @@
    * Proxy to a <code>Document</code> using a <code>WeakReference</code> to
    * allow the document to be discared when not used outside of the intepreter.
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christophe Jolif</a>
  - * @version $Id: DocumentProxy.java,v 1.2 2001/05/14 16:47:47 tkormann Exp $
  + * @version $Id: DocumentProxy.java,v 1.3 2001/10/08 15:04:39 cjolif Exp $
    */
   public class DocumentProxy implements Document {
  +    /**
  +     * The <code>WeakReference</code> to the actual
  +     * <code>Document</code>.
  +     */
       protected WeakReference ref = null;
   
       public DocumentProxy(Document document)
  
  
  
  1.4       +11 -1     xml-batik/sources/org/apache/batik/script/Interpreter.java
  
  Index: Interpreter.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/script/Interpreter.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Interpreter.java  2001/01/24 13:51:54     1.3
  +++ Interpreter.java  2001/10/08 15:04:39     1.4
  @@ -16,7 +16,7 @@
    * An hight level interface that represents an interpreter engine of
    * a particular scripting language.
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christophe Jolif</a>
  - * @version $Id: Interpreter.java,v 1.3 2001/01/24 13:51:54 cjolif Exp $
  + * @version $Id: Interpreter.java,v 1.4 2001/10/08 15:04:39 cjolif Exp $
    */
   public interface Interpreter extends org.apache.batik.i18n.Localizable {
       /**
  @@ -27,6 +27,16 @@
        */
       public Object evaluate(Reader scriptreader)
           throws InterpreterException, IOException;
  +    /**
  +     * This method should evaluate a piece of script using a <code>String</code>
  +     * instead of a <code>Reader</code>. This usually allows do easily do some
  +     * caching.
  +     * @param script the piece of script
  +     * @return if no exception is thrown during the call, should return the
  +     * value of the last expression evaluated in the script
  +     */
  +    public Object evaluate(String script)
  +        throws InterpreterException;
       /**
        * This method should register a particular Java <code>Object</code> in
        * the environment of the interpreter.
  
  
  
  1.4       +15 -10    
xml-batik/sources/org/apache/batik/script/jacl/JaclInterpreter.java
  
  Index: JaclInterpreter.java
  ===================================================================
  RCS file: 
/home/cvs/xml-batik/sources/org/apache/batik/script/jacl/JaclInterpreter.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JaclInterpreter.java      2001/01/24 14:50:58     1.3
  +++ JaclInterpreter.java      2001/10/08 15:04:39     1.4
  @@ -20,7 +20,7 @@
    * A simple implementation of <code>Interpreter</code> interface to use
    * JACL Tcl parser.
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christophe Jolif</a>
  - * @version $Id: JaclInterpreter.java,v 1.3 2001/01/24 14:50:58 cjolif Exp $
  + * @version $Id: JaclInterpreter.java,v 1.4 2001/10/08 15:04:39 cjolif Exp $
    */
   public class JaclInterpreter implements org.apache.batik.script.Interpreter {
       private Interp interpreter = null;
  @@ -37,16 +37,21 @@
   
       public Object evaluate(Reader scriptreader)
           throws InterpreterException, IOException {
  +        // oups jacl doesn't accept reader in its eval method :-(
  +        StringBuffer sbuffer = new StringBuffer();
  +        char[] buffer = new char[1024];
  +        int val = 0;
  +        while ((val = scriptreader.read(buffer)) != -1) {
  +            sbuffer.append(buffer, 0, val);
  +        }
  +        String str = sbuffer.toString();
  +        return evaluate(str, 0);
  +    }
  +
  +    public Object evaluate(String script)
  +        throws InterpreterException {
           try {
  -            // oups jacl doesn't accept reader in its eval method :-(
  -            StringBuffer sbuffer = new StringBuffer();
  -            char[] buffer = new char[1024];
  -            int val = 0;
  -            while ((val = scriptreader.read(buffer)) != -1) {
  -                sbuffer.append(buffer, 0, val);
  -            }
  -            String str = sbuffer.toString();
  -            interpreter.eval(str, 0);
  +            interpreter.eval(script, 0);
           } catch (TclException e) {
               throw new InterpreterException(e, e.getMessage(), -1, -1);
           } catch (RuntimeException re) {
  
  
  
  1.4       +15 -9     
xml-batik/sources/org/apache/batik/script/jpython/JPythonInterpreter.java
  
  Index: JPythonInterpreter.java
  ===================================================================
  RCS file: 
/home/cvs/xml-batik/sources/org/apache/batik/script/jpython/JPythonInterpreter.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JPythonInterpreter.java   2001/01/24 14:51:00     1.3
  +++ JPythonInterpreter.java   2001/10/08 15:04:39     1.4
  @@ -20,7 +20,7 @@
    * A simple implementation of <code>Interpreter</code> interface to use
    * JPython python parser.
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christophe Jolif</a>
  - * @version $Id: JPythonInterpreter.java,v 1.3 2001/01/24 14:51:00 cjolif Exp $
  + * @version $Id: JPythonInterpreter.java,v 1.4 2001/10/08 15:04:39 cjolif Exp $
    */
   public class JPythonInterpreter implements org.apache.batik.script.Interpreter {
       private PythonInterpreter interpreter = null;
  @@ -33,16 +33,22 @@
   
       public Object evaluate(Reader scriptreader)
           throws InterpreterException, IOException {
  +        // oups jpython doesn't accept reader in its eval method :-(
  +        StringBuffer sbuffer = new StringBuffer();
  +        char[] buffer = new char[1024];
  +        int val = 0;
  +        while ((val = scriptreader.read(buffer)) != -1) {
  +            sbuffer.append(buffer,0, val);
  +        }
  +        String str = sbuffer.toString();
  +        return evaluate(str);
  +    }
  +
  +    public Object evaluate(String script)
  +        throws InterpreterException {
           try {
  -            // oups jpython doesn't accept reader in its eval method :-(
  -            StringBuffer sbuffer = new StringBuffer();
  -            char[] buffer = new char[1024];
  -            int val = 0;
  -            while ((val = scriptreader.read(buffer)) != -1) {
  -                sbuffer.append(buffer,0, val);
  -            }
               String str = sbuffer.toString();
  -            interpreter.exec(str);
  +            interpreter.exec(script);
           } catch (org.python.core.PyException e) {
               throw new InterpreterException(e, e.getMessage(), -1, -1);
           } catch (RuntimeException re) {
  
  
  
  1.5       +2 -2      
xml-batik/sources/org/apache/batik/script/rhino/EventTargetWrapper.java
  
  Index: EventTargetWrapper.java
  ===================================================================
  RCS file: 
/home/cvs/xml-batik/sources/org/apache/batik/script/rhino/EventTargetWrapper.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- EventTargetWrapper.java   2001/06/01 13:54:06     1.4
  +++ EventTargetWrapper.java   2001/10/08 15:04:39     1.5
  @@ -28,13 +28,13 @@
   import org.apache.batik.script.InterpreterException;
   
   /**
  - * A class that wrap an <code>EventTarget</code> instance to expose
  + * A class that wraps an <code>EventTarget</code> instance to expose
    * it in the Rhino engine. Then calling <code>addEventListener</code>
    * with a Rhino function as parameter should redirect the call to
    * <code>addEventListener</code> with a Java function object calling
    * the Rhino function.
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christophe Jolif</a>
  - * @version $Id: EventTargetWrapper.java,v 1.4 2001/06/01 13:54:06 cjolif Exp $
  + * @version $Id: EventTargetWrapper.java,v 1.5 2001/10/08 15:04:39 cjolif Exp $
    */
   class EventTargetWrapper extends NativeJavaObject {
   
  
  
  
  1.7       +101 -5    
xml-batik/sources/org/apache/batik/script/rhino/RhinoInterpreter.java
  
  Index: RhinoInterpreter.java
  ===================================================================
  RCS file: 
/home/cvs/xml-batik/sources/org/apache/batik/script/rhino/RhinoInterpreter.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- RhinoInterpreter.java     2001/06/01 13:54:07     1.6
  +++ RhinoInterpreter.java     2001/10/08 15:04:39     1.7
  @@ -11,6 +11,9 @@
   import java.io.IOException;
   import java.io.Reader;
   import java.io.Writer;
  +import java.io.StringReader;
  +import java.util.Iterator;
  +import java.util.LinkedList;
   import java.util.Locale;
   
   import org.w3c.dom.events.EventTarget;
  @@ -19,10 +22,11 @@
   import org.apache.batik.script.InterpreterException;
   
   import org.mozilla.javascript.Context;
  +import org.mozilla.javascript.Function;
   import org.mozilla.javascript.ImporterTopLevel;
   import org.mozilla.javascript.JavaScriptException;
  -import org.mozilla.javascript.Function;
   import org.mozilla.javascript.NativeJavaPackage;
  +import org.mozilla.javascript.Script;
   import org.mozilla.javascript.Scriptable;
   import org.mozilla.javascript.ScriptableObject;
   import org.mozilla.javascript.WrappedException;
  @@ -31,7 +35,7 @@
    * A simple implementation of <code>Interpreter</code> interface to use
    * Rhino ECMAScript interpreter.
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christophe Jolif</a>
  - * @version $Id: RhinoInterpreter.java,v 1.6 2001/06/01 13:54:07 cjolif Exp $
  + * @version $Id: RhinoInterpreter.java,v 1.7 2001/10/08 15:04:39 cjolif Exp $
    */
   public class RhinoInterpreter implements Interpreter {
       private static String[] TO_BE_IMPORTED = {
  @@ -45,8 +49,21 @@
           "org.w3c.dom.views"
       };
   
  +    private static class Entry {
  +        String str;
  +        Script script;
  +        Entry(String str, Script script) {
  +            this.str = str;
  +            this.script = script;
  +        }
  +    };
  +
  +    // store last 32 precompiled objects.
  +    private static final int MAX_CACHED_SCRIPTS = 32;
  +
       private Context context = null;
       private ScriptableObject globalObject = null;
  +    private LinkedList compiledScripts = new LinkedList();
   
       /**
        * Build a <code>Interpreter</code> for ECMAScript using Rhino.
  @@ -86,16 +103,18 @@
           return context;
       }
   
  +
       // org.apache.batik.script.Intepreter implementation
   
       /**
  -     * This method evaluates a piece of ECMA script.
  +     * This method evaluates a piece of ECMAScript.
        * @param scriptreader a <code>java.io.Reader</code> on the piece of script
        * @return if no exception is thrown during the call, should return the
  -     * value of the last expression evaluated in the script
  +     * value of the last expression evaluated in the script.
        */
       public Object evaluate(Reader scriptreader)
  -        throws InterpreterException, IOException {
  +        throws InterpreterException, IOException
  +    {
           Object rv = null;
           Context ctx = Context.enter(context);
           try {
  @@ -103,6 +122,83 @@
                                       scriptreader,
                                       "<SVG>",
                                       1, null);
  +        } catch (JavaScriptException e) {
  +            // exception from JavaScript (possibly wrapping a Java Ex)
  +            if (e.getValue() instanceof Exception) {
  +                Exception ex = (Exception)e.getValue();
  +                throw new InterpreterException(ex, ex.getMessage(), -1, -1);
  +            } else
  +                throw new InterpreterException(e, e.getMessage(), -1, -1);
  +        } catch (WrappedException we) {
  +            // main Rhino RuntimeException
  +            throw
  +                new InterpreterException((Exception)we.getWrappedException(),
  +                                         we.getWrappedException().getMessage(),
  +                                         -1, -1);
  +        } catch (RuntimeException re) {
  +            // other RuntimeExceptions
  +            throw new InterpreterException(re, re.getMessage(), -1, -1);
  +        } finally {
  +            Context.exit();
  +        }
  +        return rv;
  +    }
  +
  +    /**
  +     * This method evaluates a piece of ECMA script.
  +     * The first time a String is passed, it is compiled and evaluated.
  +     * At next call, the piece of script will only be evaluated to
  +     * prevent from recompiling it.
  +     * @param scriptstr the piece of script
  +     * @return if no exception is thrown during the call, should return the
  +     * value of the last expression evaluated in the script.
  +     */
  +    public Object evaluate(String scriptstr)
  +        throws InterpreterException
  +    {
  +        Context ctx = Context.enter(context);
  +        Script script = null;
  +        Entry et = null;
  +        Iterator it = compiledScripts.iterator();
  +        // between nlog(n) and log(n) because it is
  +        // an AbstractSequentialList
  +        while (it.hasNext()) {
  +            if ((et = (Entry)(it.next())).str == scriptstr) {
  +                // if it is not at the end, remove it because
  +                // it will change from place (it is faster
  +                // to remove it now)
  +                script = et.script;
  +                it.remove();
  +                break;
  +            }
  +        }
  +        if (script == null) {
  +            // this script has not been compiled yet or has been fogotten
  +            // since the compilation:
  +            // compile it and store it for future use.
  +            try {
  +                script = ctx.compileReader(globalObject,
  +                                           new StringReader(scriptstr),
  +                                           "<SVG>",
  +                                           1, null);
  +            } catch (IOException io) {
  +                // can't happen because we use a String...
  +            }
  +            if (compiledScripts.size()+1 > MAX_CACHED_SCRIPTS) {
  +                // too many cached items - we should delete the oldest entry.
  +                // all of this is very fast on linkedlist
  +                compiledScripts.removeFirst();
  +            }
  +            // stroring is done here:
  +            compiledScripts.addLast(new Entry(scriptstr, script));
  +        } else {
  +            // this script has been compiled before,
  +            // just update it's index so it won't get deleted soon.
  +            compiledScripts.addLast(et);
  +        }
  +        Object rv = null;
  +        try {
  +            rv = script.exec(ctx, globalObject);
           } catch (JavaScriptException e) {
               // exception from JavaScript (possibly wrapping a Java Ex)
               if (e.getValue() instanceof Exception) {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to