You are viewing a plain text version of this content. The canonical link for it is here.
Posted to taglibs-dev@jakarta.apache.org by ho...@apache.org on 2002/01/24 01:24:40 UTC

cvs commit: jakarta-taglibs/standard/src/org/apache/taglibs/standard/lang/javascript JavascriptExpressionEvaluator.java

horwat      02/01/23 16:24:40

  Modified:    standard/examples/web/ecmascript ArrayAccess.jsp
                        MapAccess.jsp index.html
               standard/examples/src/org/apache/taglibs/jsptl/examples/startup
                        Init.java
               standard/src/org/apache/taglibs/standard/lang/javascript
                        JavascriptExpressionEvaluator.java
  Added:       standard/examples/web/ecmascript ParameterAccess.jsp
               standard/src/org/apache/taglibs/standard/lang/javascript/adapter
                        NativeJavaList.java NativeJavaMap.java
  Log:
  Ecmascript EL enhancements:
  	- direct associative container access
  	- List object access using the [] operator
  
  Submitted by: Christopher Lenz
  
  Revision  Changes    Path
  1.2       +20 -10    jakarta-taglibs/standard/examples/web/ecmascript/ArrayAccess.jsp
  
  Index: ArrayAccess.jsp
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/examples/web/ecmascript/ArrayAccess.jsp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ArrayAccess.jsp	21 Nov 2001 07:34:32 -0000	1.1
  +++ ArrayAccess.jsp	24 Jan 2002 00:24:40 -0000	1.2
  @@ -3,31 +3,41 @@
   
   <html>
   <head>
  -  <title>JSTL: EcmaScript EL Support -- Simple Array Access Example</title>
  +  <title>JSTL: EcmaScript EL Support -- Simple Array and List Access Example</title>
   </head>
   <body bgcolor="#FFFFFF">
  -<h3>Array Access</h3>
  +<h3>Array and List Access</h3>
   
  -<p>EcmaScript uses the [] notation to access array elements. If the first operand is an array then the second operand (the one that goes between the brackets) should be an expression that evaluates to an integer. If the first operand is a reference to an object then the second operand should be an expression that evaluates to a string that names a property of the object.
  +<p>EcmaScript uses the [] notation to access array elements. If the first operand is an array then the second operand (the one that goes between the brackets) should be an expression that evaluates to an integer. If the first operand is a reference to an object then the second operand should be an expression that evaluates to a string that names a property of the object. The same principles work for accessing List objects (Vectors, for example).</p>
   
   <p>Here is an example:</p>
   
   <h4>Favorite Actor and Role</h4>
   
  -<% request.setAttribute("myArray", new String[] {"Harrison", "Ford", "Indiana", "Jones"}); %>
  +<%
  +   String[] array =  new String[] {"Harrison", "Ford", "Indiana", "Jones"};
  +   request.setAttribute("myArray", array);
  +   List list = new Vector();
  +   for (int i = 0; i < array.length; i++) {
  +      list.add(array[i]);
  +   }
  +   request.setAttribute("myList", list);
  +%>
  +
   
   <table border="1">
     <tr>
  -    <th>Array Index</th>
  -    <th>Value</th>
  +    <th>Index</th>
  +    <th>Array Value</th>
  +    <th>List Value</th>
     </tr>
     <c:forEach var="i" begin="0" end="3" status="status">
  -    <c:declare id="status" type="javax.servlet.jsp.jstl.core.IteratorTagStatus"/>
       <tr>
  -        <%-- demonstrating how to use expression to get index --%>
  -      <td>Array[<c:expr value="$i"/>]</td>
  -        <%-- demonstrating how to use status object to get index --%>
  +      <%-- demonstrating how to use expression to get index --%>
  +      <td><c:expr value="$i"/></td>
  +      <%-- demonstrating how to use status object to get index --%>
         <td><c:expr value="$myArray[status.index]"/></td>
  +      <td><c:expr value="$myList[status.index]"/></td>
       </tr>
     </c:forEach>
   </table>
  
  
  
  1.3       +40 -2     jakarta-taglibs/standard/examples/web/ecmascript/MapAccess.jsp
  
  Index: MapAccess.jsp
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/examples/web/ecmascript/MapAccess.jsp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MapAccess.jsp	21 Nov 2001 21:33:28 -0000	1.2
  +++ MapAccess.jsp	24 Jan 2002 00:24:40 -0000	1.3
  @@ -2,13 +2,14 @@
   
   <html>
   <head>
  -  <title>JSTL: EcmaScript EL Support -- Simple Map.Entry Access Example</title>
  +  <title>JSTL: EcmaScript EL Support -- Simple Map Access Example</title>
   </head>
   <body bgcolor="#FFFFFF">
  -<h3>Map.Entry Access</h3>
  +<h3>Map Access</h3>
   
   <p>In EcmaScript you can access the key and corresponding value of the Map.Entry object directly.</p>
   
  +
   <p>Here is an example:</p>
   
   <h4>Customer list of system properties</h4>
  @@ -27,6 +28,43 @@
     </tr>
   </c:forEach>
   </table>
  +<br>
  +
  +<hr>
  +
  +<p>
  +  There are also provisions to access values in a Map by explicitly specifying
  +  the key using the index operator. If the keys are strings, this will even
  +  work using standard property access syntax, i.e. <code>$map.key</code>
  +</p>
  +<p>
  +  Examples:
  +</p>
  +<table border="1">
  +  <tr>
  +    <th>Expression</th>
  +    <th>Value</th>
  +  </tr>
  +  <tr>
  +    <td><code>$numberMap[7]</code></td>
  +    <td><c:expr value="$numberMap[7]"/></td>
  +  </tr>
  +  <tr>
  +    <td><code>$stringMap['eight']</code></td>
  +    <td><c:expr value="$stringMap['eight']"/></td>
  +  </tr>
  +  <tr>
  +    <td><code>$stringMap.nine</code></td>
  +    <td><c:expr value="$stringMap.nine"/></td>
  +  </tr>
  +  <tr>
  +    <td><code>$stringMap[variable]</code></td>
  +    <c:set var="variable" value="one"/>
  +    <td><c:expr value="$stringMap[variable]"/></td>
  +  </tr>
  +</table>
  +</p>
  +
   
   </body>
   </html>
  
  
  
  1.8       +7 -3      jakarta-taglibs/standard/examples/web/ecmascript/index.html
  
  Index: index.html
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/examples/web/ecmascript/index.html,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- index.html	2 Jan 2002 18:49:29 -0000	1.7
  +++ index.html	24 Jan 2002 00:24:40 -0000	1.8
  @@ -75,10 +75,10 @@
     <a href="ConditionalOperator.jsp"><img src="../images/execute.gif" width="24" height="24" border="0"></a> 
   </h3>
   Conditional Operator is a shortcut for an if/else statement.<br>
  -<h3>Array Access&nbsp;&nbsp; <a href="../ShowSource.jsp?filename=/ecmascript/ArrayAccess.jsp"><img src="../images/code.gif" width="24" height="24" border="0"></a> 
  +<h3>Array and List Access&nbsp;&nbsp; <a href="../ShowSource.jsp?filename=/ecmascript/ArrayAccess.jsp"><img src="../images/code.gif" width="24" height="24" border="0"></a>
     <a href="ArrayAccess.jsp"><img src="../images/execute.gif" width="24" height="24" border="0"></a> 
   </h3>
  -Individual elements of an array can be accessed using the [] notation.<br>
  +Individual elements of an array or List can be accessed using the [] notation.<br>
   <h3>Property Access&nbsp;&nbsp; <a href="../ShowSource.jsp?filename=/ecmascript/PropertyAccess.jsp"><img src="../images/code.gif" width="24" height="24" border="0"></a> 
     <a href="PropertyAccess.jsp"><img src="../images/execute.gif" width="24" height="24" border="0"></a> 
   </h3>
  @@ -86,7 +86,11 @@
   <h3>Map Access&nbsp;&nbsp; <a href="../ShowSource.jsp?filename=/ecmascript/MapAccess.jsp"><img src="../images/code.gif" width="24" height="24" border="0"></a> 
     <a href="MapAccess.jsp"><img src="../images/execute.gif" width="24" height="24" border="0"></a> 
   </h3>
  -The key and value of a Map.Entry object can be accessed directly.<br>
  +Map entries can be accessed using the [] notation, or using the Map.Entry class.<br>
  +<h3>Parameter Access&nbsp;&nbsp; <a href="../ShowSource.jsp?filename=/ecmascript/ParameterAccess.jsp"><img src="../images/code.gif" width="24" height="24" border="0"></a>
  +  <a href="ParameterAccess.jsp"><img src="../images/execute.gif" width="24" height="24" border="0"></a>
  +</h3>
  +Request parameters can be accessed through a predefined Map object &quot;params&quot;.<br>
   <h3>Function Call&nbsp;&nbsp; <a href="../ShowSource.jsp?filename=/ecmascript/FunctionCall.jsp"><img src="../images/code.gif" width="24" height="24" border="0"></a> 
     <a href="FunctionCall.jsp"><img src="../images/execute.gif" width="24" height="24" border="0"></a> 
   </h3>
  
  
  
  1.1                  jakarta-taglibs/standard/examples/web/ecmascript/ParameterAccess.jsp
  
  Index: ParameterAccess.jsp
  ===================================================================
  <%@ taglib prefix="c" uri="http://java.sun.com/jstl/ea/core" %>
  
  <html>
  <head>
    <title>JSTL: EcmaScript EL Support -- Simple Parameter Access Example</title>
  </head>
  <body bgcolor="#FFFFFF">
  <h3>Parameter Access</h3>
  
  <p>
    Request parameters can be accessed through a Map object called 
    &quot;params&quot;. See the <a href="MapAccess.jsp">Map Access</a> page for 
    information on how to conveniently access Map objects. As request parameters 
    can have multiple values, the map entries are actually arrays, so the index 
    operator needs to be used to access the actual string value of the parameter.
  </p>
  
  <hr>
  
  <p>
    Enter a value for the parameter &quot;test&quot;, which will be displayed 
    below using this technique.
  </p>
  <form>
    <table border="0" cellspacing="0" cellpadding="10">
      <tr> 
        <td> 
          <input type="text" size="40" name="test" value="">
        </td>
        <td>
          <input type="submit" name="Submit" value="Submit">
        </td>
      </tr>
    </table>
  </form>
  
  <c:if test="$params.test != null">
    <hr>
    <p>Here is the parameter value:</p>
    <table border="1">
      <tr>
        <th>Expression</th>
        <th>Output</th>
      </tr>
      <tr>
        <td><code>$params['test'][0]</code></td>
        <td><c:expr value="$params['test'][0]"/></td>
      </tr>
      <tr>
        <td><code>$params.test[0]</code></td>
        <td><c:expr value="$params.test[0]"/></td>
      </tr>
    </table>
    </p>
  </c:if>
  
  </body>
  </html>
  
  
  
  
  1.1                  jakarta-taglibs/standard/src/org/apache/taglibs/standard/lang/javascript/adapter/NativeJavaList.java
  
  Index: NativeJavaList.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  
  package org.apache.taglibs.standard.lang.javascript.adapter;
  
  import java.util.List;
  
  import org.mozilla.javascript.NativeJavaObject;
  import org.mozilla.javascript.Scriptable;
  import org.mozilla.javascript.Undefined;
  
  /**
   * Wrapper class than enables the JavascriptExpressionEvaluator to handle List
   * objects like native arrays.
   * 
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   * @version $Revision: 1.1 $
   */
  public class NativeJavaList
      extends NativeJavaObject {
      
      // ---------------------------------------------------- Instance Variables
      
      /**
       * The actual List object we wrap around.
       */
      private List list = null;
      
      // ---------------------------------------------------------- Constructors
      
      /**
       * Constructor.
       */
      public NativeJavaList(Scriptable scope,
                            List list) {
          super(scope, list, List.class);
          this.list = list;
      }
      
      // ---------------------------------------Scriptable Object Implementation
      
      /**
       * Implemented to provide a JavaScript class name.
       * 
       * @see org.mozilla.javascript.Scriptable#getClassName()
       */
      public String getClassName() {
          return "JavaList";
      }
      
      /**
       * First tries to retrieve an object from the list using the given index. 
       * If no such element is found, delegates to the super class.
       * 
       * @see org.mozilla.javascript.Scriptable#get(int,Scriptable)
       */
      public Object get(int index, Scriptable start) {
          Object o = list.get(index);
          // Should we check IndexOutOfBounds here ?
          if (o == null) {
              o = new Undefined();
          }
          return o;
      }
      
  }
  
  
  
  1.1                  jakarta-taglibs/standard/src/org/apache/taglibs/standard/lang/javascript/adapter/NativeJavaMap.java
  
  Index: NativeJavaMap.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  
  package org.apache.taglibs.standard.lang.javascript.adapter;
  
  import java.util.Map;
  
  import org.mozilla.javascript.NativeJavaObject;
  import org.mozilla.javascript.Scriptable;
  import org.mozilla.javascript.Undefined;
  
  /**
   * Wrapper class than enables the JavascriptExpressionEvaluator to handle Map 
   * objects like Java Beans. This means that entries in the map can be 
   * retrieved like properties of the JavaScript objects.
   * 
   * @author <a href="mailto:cmlenz@apache.org">Christopher Lenz</a>
   * @version $Revision: 1.1 $
   */
  public class NativeJavaMap
      extends NativeJavaObject {
      
      // ---------------------------------------------------- Instance Variables
      
      /**
       * The actual Map object we wrap around.
       */
      private Map map = null;
      
      // ---------------------------------------------------------- Constructors
      
      /**
       * Constructor.
       */
      public NativeJavaMap(Scriptable scope,
                           Map map) {
          super(scope, map, Map.class);
          this.map = map;
      }
      
      // ---------------------------------------Scriptable Object Implementation
      
      /**
       * Implemented to provide a JavaScript class name.
       * 
       * @see org.mozilla.javascript.Scriptable#getClassName()
       */
      public String getClassName() {
          return "JavaMap";
      }
      
      /**
       * First tries to retrieve an object from the map using the index value as 
       * an Integer-type key. If no such entry is found, delegates to the super 
       * class.
       * 
       * @see org.mozilla.javascript.Scriptable#get(int,Scriptable)
       */
      public Object get(int index, Scriptable start) {
          Object o = map.get(new Integer(index));
          if (o == null) {
              o = super.get(index, start);
          }
          if (o == null) {
              o = new Undefined();
          }
          return o;
      }
      
      /**
       * First tries to retrieve an object from the map using the provided name 
       * as String-type key. If no such entry is found, delegates to the super 
       * class.
       * 
       * @see org.mozilla.javascript.Scriptable#get(String,Scriptable)
       */
      public Object get(String name, Scriptable start) {
          Object o = map.get(name);
          if (o == null) {
              o = super.get(name, start);
          }
          if (o == null) {
              o = new Undefined();
          }
          return o;
      }
      
  }
  
  
  
  1.4       +18 -2     jakarta-taglibs/standard/examples/src/org/apache/taglibs/jsptl/examples/startup/Init.java
  
  Index: Init.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/examples/src/org/apache/taglibs/jsptl/examples/startup/Init.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Init.java	4 Dec 2001 01:17:40 -0000	1.3
  +++ Init.java	24 Jan 2002 00:24:40 -0000	1.4
  @@ -65,7 +65,7 @@
    * used in the "examples" webapp.
    *
    * @author Pierre Delisle
  - * @version $Revision: 1.3 $ $Date: 2001/12/04 01:17:40 $
  + * @version $Revision: 1.4 $ $Date: 2002/01/24 00:24:40 $
    */
   public class Init implements ServletContextListener {
       
  @@ -123,7 +123,23 @@
           sce.getServletContext().setAttribute("stringArray", stringArray);
   
   	/**
  -	 * Map (Properties)
  +        * String-keyed Map
  +        */
  +        Hashtable stringMap = new Hashtable();
  +        sce.getServletContext().setAttribute("stringMap", stringMap);
  +        stringMap.put("one", "uno");
  +        stringMap.put("two", "dos");
  +        stringMap.put("three", "tres");
  +        stringMap.put("four", "cuatro");
  +        stringMap.put("five", "cinco");
  +        stringMap.put("six", "seis");
  +        stringMap.put("seven", "siete");
  +        stringMap.put("eight", "ocho");
  +        stringMap.put("nine", "nueve");
  +        stringMap.put("ten", "diez");
  +
  +        /**
  +         * Integer-keyed Map
   	 */
   	// we use a Hashtable so we can get an Enumeration easily, below
           Hashtable numberMap = new Hashtable();
  
  
  
  1.6       +64 -27    jakarta-taglibs/standard/src/org/apache/taglibs/standard/lang/javascript/JavascriptExpressionEvaluator.java
  
  Index: JavascriptExpressionEvaluator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-taglibs/standard/src/org/apache/taglibs/standard/lang/javascript/JavascriptExpressionEvaluator.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- JavascriptExpressionEvaluator.java	20 Dec 2001 16:21:12 -0000	1.5
  +++ JavascriptExpressionEvaluator.java	24 Jan 2002 00:24:40 -0000	1.6
  @@ -58,15 +58,20 @@
   import javax.servlet.jsp.*;
   import javax.servlet.jsp.tagext.*; 
   import java.util.Enumeration;
  +import java.util.List;
  +import java.util.Map;
   import java.lang.Boolean;
   
  +import org.apache.taglibs.standard.lang.javascript.adapter.NativeJavaList;
  +import org.apache.taglibs.standard.lang.javascript.adapter.NativeJavaMap;
   import org.apache.taglibs.standard.lang.support.ExpressionEvaluator;
   import org.apache.taglibs.standard.lang.spel.Evaluator;
   import org.mozilla.javascript.*;
   
   
   
  -public class JavascriptExpressionEvaluator implements ExpressionEvaluator {
  +public class JavascriptExpressionEvaluator
  +    implements ExpressionEvaluator, WrapHandler {
   
       /** 
        * Translation time validation of an expression. 
  @@ -93,21 +98,27 @@
           Object result = null;
           Evaluator evalLiteral = new Evaluator();
   
  -	// Creates and enters a Context. Context stores information
  -	// about the execution environment of a script
  -	Context cx = Context.enter();
  +        // Creates and enters a Context. Context stores information
  +        // about the execution environment of a script
  +        Context cx = Context.enter();
  +        cx.setWrapHandler(this);
   
  -	// Initialize standard objects
  -	Scriptable scope = cx.initStandardObjects(null);
  +        // Initialize standard objects
  +        Scriptable scope = cx.initStandardObjects(null);
   
  -        // Put PageContext attributes/parameters in Rhino Scope
  -        putAttributesInScope(scope, cx, pageContext, PageContext.APPLICATION_SCOPE);
  -        putAttributesInScope(scope, cx, pageContext, PageContext.SESSION_SCOPE);
  -        putAttributesInScope(scope, cx, pageContext, PageContext.REQUEST_SCOPE);
  -        putAttributesInScope(scope, cx, pageContext, PageContext.PAGE_SCOPE);
   
  +        // Put PageContext attributes/parameters in Rhino Scope
  +        putAttributesInScope(scope, cx, pageContext,
  +                             PageContext.APPLICATION_SCOPE);
  +        putAttributesInScope(scope, cx, pageContext,
  +                             PageContext.SESSION_SCOPE);
  +        putAttributesInScope(scope, cx, pageContext,
  +                             PageContext.REQUEST_SCOPE);
  +        putAttributesInScope(scope, cx, pageContext,
  +                             PageContext.PAGE_SCOPE);
  +        putParametersInScope(scope, cx, pageContext);
   
  -	// Evaluate string
  +        // Evaluate string
           try {
               // skip $, use the SPEL evaluate literal method 'cuz why reinvent the wheel?
               if (expression.startsWith("$")) {
  @@ -120,10 +131,13 @@
               if (result instanceof Wrapper)
                   result = ((Wrapper) result).unwrap();
   
  -            if (result instanceof NativeString)
  +            if (result instanceof NativeString) {
                   result = result.toString();
  -            if (result instanceof NativeBoolean)
  +            } else if (result instanceof NativeBoolean) {
                   result = new Boolean(result.toString());
  +            } else if (result instanceof Undefined) {
  +                result = null;
  +            }
   
   	} catch (JavaScriptException jse) {
   	    throw new JspException(jse.getMessage(), jse);
  @@ -142,12 +156,39 @@
       }
   
       /**
  +     * Implementation of the org.mozilla.javascript.WrapHandler interface.
  +     * This method overrides the default wrapping of native Java objects in
  +     * JavaScript objects to provide custom adapters for Lists and Maps.
  +     * When this method returns <code>null</code>, Rhino will use the default
  +     * wrapping.
  +     *
  +     * @see org.mozilla.javascript#wrap(Scriptable,Object,Class)
  +     */
  +    public Object wrap(Scriptable scope,
  +                       Object obj,
  +                       Class staticType) {
  +        if (obj == null) {
  +            return null;
  +        }
  +
  +        if (obj instanceof List) {
  +           return new NativeJavaList(scope, (List)obj);
  +        } else if (obj instanceof Map) {
  +            return new NativeJavaMap(scope, (Map)obj);
  +        }
  +
  +        return null;
  +    }
  +
  +
  +
  +    /**
        * put PageContext attributes into Rhino scope
        */
  -    void putAttributesInScope(Scriptable rhinoScope, 
  -                              Context rhinoContext, 
  -                              PageContext pageContext, 
  -                              int scope) {
  +    private void putAttributesInScope(Scriptable rhinoScope, 
  +                                      Context rhinoContext, 
  +                                      PageContext pageContext, 
  +                                      int scope) {
           Enumeration attributes = null;
           Object value = null;
           String attribute = null;
  @@ -167,18 +208,14 @@
       /**
        * put PageContext parameters into Rhino scope
        */
  -    void putParametersInScope(Scriptable rhinoScope, 
  -                              Context rhinoContext, 
  -                              PageContext pageContext) {
  +    private void putParametersInScope(Scriptable rhinoScope, 
  +                                      Context rhinoContext, 
  +                                      PageContext pageContext) {
           Enumeration attributes = null;
           Object value = null;
           String attribute = null;
           
  -        attributes = (pageContext.getRequest()).getParameterNames();
  -        while (attributes !=null && attributes.hasMoreElements()) {
  -            attribute = (String)attributes.nextElement();
  -            value = (pageContext.getRequest()).getParameter(attribute);
  -            rhinoScope.put(attribute, rhinoScope, rhinoContext.toObject(value, rhinoScope));
  -        }
  +        Map params = pageContext.getRequest().getParameterMap();
  +        rhinoScope.put("params", rhinoScope, params);
       }
   }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>