Author: mrdon
Date: Tue Feb 15 23:08:47 2005
New Revision: 154003

URL: http://svn.apache.org/viewcvs?view=rev&rev=154003
Log:
Adding new Rhino extensions that better integrate collections into rhino
and a test of adding Groovy-like JVM extensions that utilize closures

Added:
    struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableList.java  
 (with props)
    
struts/flow/trunk/src/java/org/apache/struts/flow/core/SugarWrapFactory.java   
(with props)
Modified:
    struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableMap.java

Added: 
struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableList.java
URL: 
http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableList.java?view=auto&rev=154003
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableList.java 
(added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableList.java 
Tue Feb 15 23:08:47 2005
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+import org.mozilla.javascript.*;
+
+import java.util.*;
+import java.io.Serializable;
+
+/**
+ * Wrap a java.util.List for JavaScript.
+ */
+public class ScriptableList extends NativeJavaObject implements Scriptable, 
Wrapper, Serializable {
+
+    private List list;
+
+    public ScriptableList() {
+        this.list = list;
+    }
+
+    public ScriptableList(List list) {
+        this.list = list;
+        this.javaObject = javaObject;
+    }
+    
+    public ScriptableList(Scriptable scope, Object javaObject, Class 
staticType) {
+        super(scope, javaObject, staticType);
+        if (javaObject instanceof List) {
+            this.list = (List)javaObject;
+        } else {
+            throw new IllegalArgumentException("Passed object "+javaObject+" 
is not an instance of List");
+        }
+    }
+
+    public String getClassName() {
+        return staticType.toString();
+    }
+
+    public boolean has(int index, Scriptable start) {
+        return (list.get(index) != null);
+    }
+
+    public Object get(int index, Scriptable start) {
+        return list.get(index);
+    }
+    
+    public Object get(String name, Scriptable start) {
+        if ("each".equals(name)) {
+            return new EachClosure();
+        } else {
+            return super.get(name, start);
+        } 
+    }
+
+    public void put(int index, Scriptable start, Object value) {
+        list.add(index, value);
+    }
+
+    public void delete(int index) {
+        list.remove(index);
+    }
+
+    public Object[] getIds() {
+        
+        //TODO: optimize this :)
+        Integer[] ids = new Integer[list.size()];
+        for (int x=0; x<ids.length; x++) {
+            ids[x] = new Integer(x);
+        }
+        return ids;
+    }
+
+    public Object unwrap() {
+        return this.list;
+    }
+    
+    class EachClosure extends ScriptableObject implements Function {
+        
+        public Object call(Context cx, Scriptable scope, Scriptable thisObj, 
java.lang.Object[] args) {
+            Function func = (Function)args[0];
+            Object[] param = new Object[1];
+            
+            for (Iterator i = list.iterator(); i.hasNext(); ) {
+                param[0] = i.next();
+                func.call(cx, scope, thisObj, param);
+            }
+            return null;
+        }
+         
+        public Scriptable construct(Context cx, Scriptable scope, 
java.lang.Object[] args) {
+            return null;
+        }
+        
+        public String getClassName() {
+            return "EachClosure";
+        }
+    }
+
+}

Propchange: 
struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableList.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: 
struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableMap.java
URL: 
http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableMap.java?view=diff&r1=154002&r2=154003
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableMap.java 
(original)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/ScriptableMap.java 
Tue Feb 15 23:08:47 2005
@@ -1,17 +1,17 @@
 /*
- *  Copyright 1999-2004 The Apache Software Foundation.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package org.apache.struts.flow.core;
 
@@ -20,248 +20,122 @@
 import org.mozilla.javascript.Wrapper;
 
 import java.util.Map;
-import java.util.Iterator;
+import java.io.Serializable;
 
 /**
- *  Wrap a java.util.Map for JavaScript. Borrowed from Cocoon.
- *
- [EMAIL PROTECTED]    CVS $Id: ScriptableMap.java,v 1.1.1.1 2004/05/12 
00:03:45 mrdon
- *      Exp $
+ * Wrap a java.util.Map for JavaScript.
  */
-public class ScriptableMap implements Scriptable, Wrapper {
+public class ScriptableMap extends NativeJavaObject implements Scriptable, 
Wrapper, Serializable {
 
     private Map map;
-    private Scriptable prototype, parent;
-
-
-    /**  Constructor for the ScriptableMap object */
-    public ScriptableMap() { }
+    private String functionPrefix = null;
 
+    public ScriptableMap() {
+        super();
+    }
 
-    /**
-     *  Constructor for the ScriptableMap object
-     *
-     [EMAIL PROTECTED]  map  The map to wrap
-     */
     public ScriptableMap(Map map) {
-        this(map, false);
+        this.map = map;
     }
     
-    /**
-     *  Constructor for the ScriptableMap object
-     *
-     [EMAIL PROTECTED]  map  The map to wrap
-     [EMAIL PROTECTED]  deep Whether to recursively wrap contained Maps
-     */
-    public ScriptableMap(Map map, boolean deep) {
-        this.map = map;
-        if (deep) {
-            Map.Entry entry;
-            for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) {
-                entry = (Map.Entry)i.next();
-                if (entry.getValue() instanceof Map) {
-                    entry.setValue(new ScriptableMap((Map)entry.getValue(), 
deep));
-                }
-            }
+    public ScriptableMap(Scriptable scope, Object javaObject, Class 
staticType, String functionPrefix) {
+        super(scope, javaObject, staticType);
+        this.functionPrefix = functionPrefix;
+        if (javaObject instanceof Map) {
+            this.map = (Map)javaObject;
+        } else {
+            throw new IllegalArgumentException("Passed object "+javaObject+" 
is not an instance of Map");
         }
     }
 
-
-    /**
-     *  Gets the class name
-     *
-     [EMAIL PROTECTED]    The className value
-     */
     public String getClassName() {
         return "Map";
     }
 
-
-    /**
-     *  Whether the Map contains the key
-     *
-     [EMAIL PROTECTED]  name   The key
-     [EMAIL PROTECTED]  start  
-     [EMAIL PROTECTED]        True if found
-     */
     public boolean has(String name, Scriptable start) {
-        return this.map.containsKey(name);
+        return (this.map.containsKey(name) || super.has(name, start));
     }
 
-
     /**
-     *  N/A, no numeric properties
-     *
-     [EMAIL PROTECTED]  index  
-     [EMAIL PROTECTED]  start  
-     [EMAIL PROTECTED]        Always false
+     * no numeric properties
      */
     public boolean has(int index, Scriptable start) {
         return false;
     }
 
-
-    /**
-     *  Gets the value from the map
-     *
-     [EMAIL PROTECTED]  name   The key
-     [EMAIL PROTECTED]  start  N/A
-     [EMAIL PROTECTED]        The value or <code>NOT_FOUND</code>
-     */
     public Object get(String name, Scriptable start) {
-        if (this.map.containsKey(name)) {
-            return this.map.get(name);
+        if (functionPrefix != null && name.startsWith(functionPrefix)) {
+            return super.get(name.substring(functionPrefix.length()), start);
+        } else {
+            if (this.map.containsKey(name)) {
+                return this.map.get(name);
+            } else {
+                return super.get(name, start);
+            }
         }
-
-        return NOT_FOUND;
     }
 
-
-    /**
-     *  N/A
-     *
-     [EMAIL PROTECTED]  index  
-     [EMAIL PROTECTED]  start  
-     [EMAIL PROTECTED]        Always <code>NOT_FOUND</code>
-     */
     public Object get(int index, Scriptable start) {
         return NOT_FOUND;
     }
 
-
-    /**
-     *  Puts the value in the map
-     *
-     [EMAIL PROTECTED]  name   The key
-     [EMAIL PROTECTED]  start  
-     [EMAIL PROTECTED]  value  The value
-     */
     public void put(String name, Scriptable start, Object value) {
         if (value instanceof NativeJavaObject) {
-            value = ((NativeJavaObject) value).unwrap();
+            value = ((NativeJavaObject)value).unwrap();
         }
         map.put(name, value);
     }
 
-
-    /**
-     *  N/A
-     *
-     [EMAIL PROTECTED]  index  
-     [EMAIL PROTECTED]  start  
-     [EMAIL PROTECTED]  value  
-     */
     public void put(int index, Scriptable start, Object value) {
     }
 
-
-    /**
-     *  Removes the key from the map
-     *
-     [EMAIL PROTECTED]  id  The key
-     */
     public void delete(String id) {
         map.remove(id);
     }
 
-
-    /**
-     *  N/A
-     *
-     [EMAIL PROTECTED]  index  
-     */
     public void delete(int index) {
     }
 
-
-    /**
-     *  Gets the prototype 
-     *
-     [EMAIL PROTECTED]    The prototype value
-     */
     public Scriptable getPrototype() {
         return prototype;
     }
 
-
-    /**
-     *  Sets the prototype 
-     *
-     [EMAIL PROTECTED]  prototype  The new prototype value
-     */
     public void setPrototype(Scriptable prototype) {
         this.prototype = prototype;
     }
 
-
-    /**
-     *  Gets the parentScope
-     *
-     [EMAIL PROTECTED]    The parentScope value
-     */
     public Scriptable getParentScope() {
         return parent;
     }
 
-
-    /**
-     *  Sets the parentScope 
-     *
-     [EMAIL PROTECTED]  parent  The new parentScope value
-     */
     public void setParentScope(Scriptable parent) {
         this.parent = parent;
     }
 
-
-    /**
-     *  Gets the keys
-     *
-     [EMAIL PROTECTED]    The ids value
-     */
     public Object[] getIds() {
         return this.map.keySet().toArray();
     }
 
-
-    /**
-     *  Gets the default value
-     *
-     [EMAIL PROTECTED]  typeHint  
-     [EMAIL PROTECTED]           The defaultValue value
-     */
     public Object getDefaultValue(Class typeHint) {
         return this.map.toString();
     }
 
-
-    /**
-     *  Whether the prototype has an instance
-     *
-     [EMAIL PROTECTED]  value  The instance
-     [EMAIL PROTECTED]        True if found
-     */
     public boolean hasInstance(Scriptable value) {
         Scriptable proto = value.getPrototype();
         while (proto != null) {
-            if (proto.equals(this)) {
+            if (proto.equals(this)) 
                 return true;
-            }
             proto = proto.getPrototype();
         }
 
         return false;
     }
 
-
     /**
-     *  Returns the actual Map
-     *
-     [EMAIL PROTECTED]    The Map
+     * Return the java.util.Map that is wrapped by this class.
      */
     public Object unwrap() {
         return this.map;
     }
 
 }
-

Added: 
struts/flow/trunk/src/java/org/apache/struts/flow/core/SugarWrapFactory.java
URL: 
http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/SugarWrapFactory.java?view=auto&rev=154003
==============================================================================
--- 
struts/flow/trunk/src/java/org/apache/struts/flow/core/SugarWrapFactory.java 
(added)
+++ 
struts/flow/trunk/src/java/org/apache/struts/flow/core/SugarWrapFactory.java 
Tue Feb 15 23:08:47 2005
@@ -0,0 +1,93 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts.flow.core;
+
+import org.mozilla.javascript.*;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Wrap a java.util.Collection for JavaScript.
+ */
+public class SugarWrapFactory extends WrapFactory {
+    
+    private String mapFuncPrefix = "fn_";
+    
+    public void setMapFunctionPrefix(String prefix) {
+        this.mapFuncPrefix = prefix;
+    }
+
+    /**
+     * Wrap Java object as Scriptable instance to allow full access to its
+     * methods and fields from JavaScript.
+     * <p>
+     * [EMAIL PROTECTED] #wrap(Context, Scriptable, Object, Class)} and
+     * [EMAIL PROTECTED] #wrapNewObject(Context, Scriptable, Object)} call 
this method
+     * when they can not convert <tt>javaObject</tt> to JavaScript primitive
+     * value or JavaScript array.
+     * @param cx the current Context for this thread
+     * @param scope the scope of the executing script
+     * @param javaObject the object to be wrapped
+     * @param staticType type hint. If security restrictions prevent to wrap
+                object based on its class, staticType will be used instead.
+     * @return the wrapped value which shall not be null
+     */
+    public Scriptable wrapAsJavaObject(Context cx, Scriptable scope,
+        Object javaObject, Class staticType) {
+        
+        Scriptable wrap = null;
+        if (javaObject instanceof Map) {
+            wrap = new ScriptableMap(scope, javaObject, staticType, 
mapFuncPrefix);
+        } else if (javaObject instanceof List) {
+            wrap = new ScriptableList(scope, javaObject, staticType);
+        } else {
+            wrap = super.wrapAsJavaObject(cx, scope, javaObject, staticType);
+        }
+        return wrap;
+    }
+    
+    // temporary method for testing
+    public static final void main(String[] args) throws Exception {
+        // Creates and enters a Context. The Context stores information
+        // about the execution environment of a script.
+        Context cx = Context.enter();
+        try {
+            cx.setWrapFactory(new SugarWrapFactory());
+            // Initialize the standard objects (Object, Function, etc.)
+            // This must be done before scripts can be executed. Returns
+            // a scope object that we use in later calls.
+            Scriptable scope = cx.initStandardObjects();
+
+            // Collect the arguments into a single string.
+            String s = "";
+            for (int i=0; i < args.length; i++) {
+                s += args[i];
+            }
+
+            // Now evaluate the string we've colected.
+            FileReader reader = new FileReader(args[0]);
+            Object result = cx.evaluateReader(scope, reader, args[0], 1, null);
+
+            // Convert the result to a string and print it.
+            System.err.println(cx.toString(result));
+
+        } finally {
+            // Exit from the context.
+            Context.exit();
+        }   
+    }
+
+}

Propchange: 
struts/flow/trunk/src/java/org/apache/struts/flow/core/SugarWrapFactory.java
------------------------------------------------------------------------------
    svn:executable = *



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

Reply via email to