You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by ek...@apache.org on 2006/03/24 18:27:16 UTC

svn commit: r388583 [1/2] - in /beehive/trunk/netui: src/pageflow/org/apache/beehive/netui/script/ src/pageflow/org/apache/beehive/netui/script/common/ src/pageflow/org/apache/beehive/netui/script/common/bundle/ src/pageflow/org/apache/beehive/netui/sc...

Author: ekoneil
Date: Fri Mar 24 09:27:11 2006
New Revision: 388583

URL: http://svn.apache.org/viewcvs?rev=388583&view=rev
Log:
Significant low-level work in the NetUI expression language.  This change contains a bunch of performance enhancements that should decrease the amount of memory consumed by each parsed expression by 30-50%.  It also includes a bunch of internal API cleanup which is okay because the o.a.b.n.script.el package isn't part of the public API.

Also adds a bunch of Javadoc to the internal APIs.

BB: self
Test: NetUI pass


Added:
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/MapFacade.java   (contents, props changed)
      - copied, changed from r387052, beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/AbstractAttributeMap.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/RequestAttributeMapFacade.java   (contents, props changed)
      - copied, changed from r387052, beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/RequestAttributeMap.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/SessionAttributeMapFacade.java   (contents, props changed)
      - copied, changed from r387052, beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/SessionAttributeMap.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/WrappedObject.java   (contents, props changed)
      - copied, changed from r387052, beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/BindingContext.java
Removed:
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/AbstractAttributeMap.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/BindingContext.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/RequestAttributeMap.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/SessionAttributeMap.java
Modified:
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/ExpressionEvaluatorFactory.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderBean.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderStack.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/bundle/StrutsBundleNode.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionEvaluatorImpl.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionTerm.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/LiteralTerm.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIReadVariableResolver.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIUpdateVariableResolver.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ParsedExpression.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/Term.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ArrayIndexToken.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ContextToken.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ExpressionToken.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/IdentifierToken.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/MapKeyToken.java
    beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/util/ParseUtils.java
    beehive/trunk/netui/src/util/org/apache/beehive/netui/util/iterator/EnumerationIterator.java
    beehive/trunk/netui/test/src/junitTests/org/apache/beehive/netui/test/script/ExpressionUpdateTest.java
    beehive/trunk/netui/test/webapps/drt/testRecorder/tests/CtBindingReport.xml

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/ExpressionEvaluatorFactory.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/ExpressionEvaluatorFactory.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/ExpressionEvaluatorFactory.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/ExpressionEvaluatorFactory.java Fri Mar 24 09:27:11 2006
@@ -41,6 +41,7 @@
     private static ExpressionEngineFactory DEFAULT_FACTORY;
 
     static {
+        /* todo: add default beahvrior */
         try {
             DEFAULT_FACTORY = initialize(FACTORY_MAP);
         }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/BundleMap.java Fri Mar 24 09:27:11 2006
@@ -54,7 +54,6 @@
     extends AbstractScriptableMap {
 
     public static final String DEFAULT_STRUTS_BUNDLE_NAME = "default";
-
     private static final Logger LOGGER = Logger.getInstance(BundleMap.class);
 
     private HashMap _registeredBundles = null;
@@ -215,8 +214,8 @@
         else {
             if(value != null)
                 LOGGER.warn("Can not resolve the default module bundle."
-                                + "  The object resolved from the request is of type "
-                                + value.getClass().toString());
+                    + "  The object resolved from the request is of type "
+                    + value.getClass().toString());
             return null;
         }
     }
@@ -235,9 +234,10 @@
             return (MessageResources)value;
         else {
             if(value != null)
-                LOGGER.warn("Can not resolve module bundle with name \"" + name
-                                + "\".  The object resolved from ServletContext is of type "
-                                + value.getClass().toString());
+                LOGGER.warn("Can not resolve module bundle with name \"" +
+                    name
+                    + "\".  The object resolved from ServletContext is of type "
+                    + value.getClass().toString());
             return null;
         }
     }
@@ -254,8 +254,12 @@
         String registeredBundles = formatBundleNames(createBundleList());
         String strutsBundles = formatBundleNames(createStrutsBundleList());
 
-        String msg = "The bundle named \"" + name + "\" was not found in the list of registered bundles with names "
-                     + registeredBundles + " or implicit bundle names " + strutsBundles + ".";
+        String msg = "The bundle named \"" +
+            name +
+            "\" was not found in the list of registered bundles with names "
+            + registeredBundles +
+            " or implicit bundle names " +
+            strutsBundles + ".";
 
         LOGGER.error(msg);
         throw new RuntimeException(msg);
@@ -372,7 +376,11 @@
 
             String result = _bundle.getString(key.toString());
             if(result == null) {
-                String msg = "The bundle property name \"" + key + "\" could not be found in the properties bundle \"" + _propertiesName + "\".";
+                String msg = "The bundle property name \"" +
+                    key +
+                    "\" could not be found in the properties bundle \"" +
+                    _propertiesName +
+                    "\".";
                 LOGGER.error(msg);
                 throw new IllegalArgumentException(msg);
             } 

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderBean.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderBean.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderBean.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderBean.java Fri Mar 24 09:27:11 2006
@@ -17,10 +17,8 @@
  */
 package org.apache.beehive.netui.script.common;
 
-import org.apache.beehive.netui.util.logging.Logger;
-
 /**
- *
+ * JavaBean that provides a delegate wrapper for an implementation of the {@link IDataAccessProvider} interface.
  */
 public class DataAccessProviderBean {
 
@@ -31,18 +29,22 @@
     }
 
     public Object getItem() {
+        assert _provider != null;
         return _provider.getCurrentItem();
     }
 
     public Object getContainer() {
+        assert _provider != null;
         return new DataAccessProviderBean(_provider.getProviderParent());
     }
 
     public int getIndex() {
+        assert _provider != null;
         return _provider.getCurrentIndex();
     }
 
     public Object getMetadata() {
+        assert _provider != null;
         return _provider.getCurrentMetadata();
     }
 }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderStack.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderStack.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderStack.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/DataAccessProviderStack.java Fri Mar 24 09:27:11 2006
@@ -20,6 +20,11 @@
 import java.util.Stack;
 import javax.servlet.jsp.JspContext;
 
+/**
+ * This class is used by the framework to store a stack of {@link IDataAccessProvider} objevcts.  This
+ * is used when nesting user interface elements that all expose some {@link IDataAccessProvider} in
+ * order to keep track of a parent's current item in a data set.
+ */
 public class DataAccessProviderStack {
 
     private static final String KEY = DataAccessProviderStack.class.getName();
@@ -61,7 +66,7 @@
             return lastTop;
         }
 
-        // todo: should this thrown an IllegalStateException?
+        // todo: should this throw an IllegalStateException?
 
         return null;
     }
@@ -71,18 +76,22 @@
     }
 
     public boolean isEmpty() {
+        assert _stack != null;
         return _stack.empty();
     }
 
     public DataAccessProviderBean peek() {
+        assert _stack != null;
         return (DataAccessProviderBean)_stack.peek();
     }
 
     public DataAccessProviderBean pop() {
+        assert _stack != null;
         return (DataAccessProviderBean)_stack.pop();
     }
 
     public void push(DataAccessProviderBean bean) {
+        assert _stack != null;
         _stack.push(bean);
     }
 

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/ImplicitObjectUtil.java Fri Mar 24 09:27:11 2006
@@ -25,7 +25,6 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.jsp.JspContext;
-import javax.servlet.jsp.PageContext;
 import javax.servlet.jsp.el.VariableResolver;
 
 import org.apache.beehive.netui.pageflow.FacesBackingBean;
@@ -38,7 +37,8 @@
 import org.apache.beehive.netui.util.logging.Logger;
 
 /**
- *
+ * Utilities for loading NetUI implicit objects into various data binding scopes such as the
+ * PageContext, ServletRequest, HttpSession, and ServletContext.
  */
 public class ImplicitObjectUtil {
 
@@ -56,14 +56,50 @@
     /* do not construct */
     private ImplicitObjectUtil() {}
 
+    /**
+     * Load the NetUI framework's implicit objects into the request.
+     * @param request the request
+     * @param response the response
+     * @param servletContext the servlet context
+     * @param currentPageFlow the current page flow
+     */
+    public static void loadImplicitObjects(HttpServletRequest request,
+                                           HttpServletResponse response,
+                                           ServletContext servletContext,
+                                           PageFlowController currentPageFlow) {
+        // @todo: new feature -- add an interceptor chain used to provide pluggability for adding
+        // new implicit objects to the request
+        loadPageFlow(request, currentPageFlow);
+
+        // @todo: need to move bundleMap creation to a BundleMapFactory
+        BundleMap bundleMap = new BundleMap(request, servletContext);
+        loadBundleMap(request, bundleMap);
+    }
+
+    /**
+     * Load the given <code>form</code> into the {@link JspContext} object.  Because the
+     * framework supports any bean action forms, the type of the form is {@link Object}
+     * @param jspContext the jsp context
+     * @param form the form object
+     */
     public static void loadActionForm(JspContext jspContext, Object form) {
         jspContext.setAttribute(ACTION_FORM_IMPLICIT_OBJECT_KEY, unwrapForm(form));
     }
 
+    /**
+     * Remove any action form present in the {@link JspContext}.
+     * @param jspContext the jsp context
+     */
     public static void unloadActionForm(JspContext jspContext) {
         jspContext.removeAttribute(ACTION_FORM_IMPLICIT_OBJECT_KEY);
     }
 
+    /**
+     * Load Page Flow related implicit objects into the request.  This method will set the
+     * Page Flow itself and any available page inputs into the request.
+     * @param request the request
+     * @param pageFlow the current page flow
+     */
     public static void loadPageFlow(ServletRequest request, PageFlowController pageFlow) {
         if(pageFlow != null)
             request.setAttribute(PAGE_FLOW_IMPLICIT_OBJECT_KEY, pageFlow);
@@ -72,29 +108,70 @@
         request.setAttribute(PAGE_INPUT_IMPLICIT_OBJECT_KEY, map != null ? map : Collections.EMPTY_MAP);
     }
 
-    public static void loadFacesBackingBean(ServletRequest request, FacesBackingBean fbb) {
-        if(fbb != null)
-            request.setAttribute(BACKING_IMPLICIT_OBJECT_KEY, fbb);
+    /**
+     * Load the JSF backing bean into the request.
+     * @param request the request
+     * @param facesBackingBean the JSF backing bean
+     */
+    public static void loadFacesBackingBean(ServletRequest request, FacesBackingBean facesBackingBean) {
+        if(facesBackingBean != null)
+            request.setAttribute(BACKING_IMPLICIT_OBJECT_KEY, facesBackingBean);
     }
-    
+
+    /**
+     * Unload the JSF backing bean from the request
+     * @param request the request
+     */
     public static void unloadFacesBackingBean(ServletRequest request) {
         request.removeAttribute(BACKING_IMPLICIT_OBJECT_KEY);
     }
-    
+
+    /**
+     * Load the shared flow into the request.
+     * @param request the request
+     * @param sharedFlows the current shared flows
+     */
     public static void loadSharedFlow(ServletRequest request, Map/*<String, SharedFlowController>*/ sharedFlows) {
         if(sharedFlows != null)
             request.setAttribute(SHARED_FLOW_IMPLICIT_OBJECT_KEY, sharedFlows);
     }
 
+    /**
+     * Load the global app into the request
+     * @param request the request
+     * @param globalApp the global app
+     */
     public static void loadGlobalApp(ServletRequest request, GlobalApp globalApp) {
         if(globalApp != null)
             request.setAttribute(GLOBAL_APP_IMPLICIT_OBJECT_KEY, globalApp);
     }
 
-    public static void loadBundleMap(ServletRequest servletRequest, BundleMap bundleMap) {
-        servletRequest.setAttribute(BUNDLE_IMPLICIT_OBJECT_KEY, bundleMap);
+    /**
+     * Load the resource bundle binding map into the request.
+     * @param request the request
+     * @param bundleMap the {@link java.util.Map} of resource bundles
+     */
+    public static void loadBundleMap(ServletRequest request, BundleMap bundleMap) {
+        request.setAttribute(BUNDLE_IMPLICIT_OBJECT_KEY, bundleMap);
+    }
+
+    /**
+     * Load the output form bean into the request.
+     * @param request the request
+     * @param bean the output form bean
+     */
+    public static void loadOutputFormBean(ServletRequest request, Object bean) {
+        if(bean != null)
+            request.setAttribute(OUTPUT_FORM_BEAN_OBJECT_KEY, bean);
     }
 
+    /**
+     * If applicable, unwrap the given <code>form</code> object to its native backing object.  If
+     * the type of this form is a {@link AnyBeanActionForm}, the type returned will be the
+     * native object backing the wrapper.
+     * @param form the form
+     * @return the unwrapped form
+     */
     public static Object unwrapForm(Object form) {
         if(LOGGER.isDebugEnabled() && form instanceof AnyBeanActionForm)
             LOGGER.debug("using form of type: " + form.getClass().getName());
@@ -104,69 +181,96 @@
         else return form;
     }
 
+    /**
+     * Get the {@link Map} of shared flow objects from the request.
+     *
+     * @param request
+     * @return the shared flows
+     */
     public static Map/*<String, SharedFlowController>*/ getSharedFlow(ServletRequest request) {
-        return (Map/*<String, SharedFlowController>*/)request.getAttribute(SHARED_FLOW_IMPLICIT_OBJECT_KEY);
+        return (Map)request.getAttribute(SHARED_FLOW_IMPLICIT_OBJECT_KEY);
     }
 
-    public static final PageFlowController getPageFlow(ServletRequest request, ServletResponse response) {
+    /**
+     * Internal method!
+     *
+     * This method is used by the expression engine to get the current page flow.  If no page flow is
+     * found, an exception will be thrown.
+     * @param request the request
+     * @param response the response
+     * @return the page flow
+     */
+    public static PageFlowController getPageFlow(ServletRequest request, ServletResponse response) {
         assert request instanceof HttpServletRequest;
 
         PageFlowController jpf = PageFlowUtils.getCurrentPageFlow((HttpServletRequest)request);
         if(jpf != null)
             return jpf;
         else {
-            // @todo: i18n
-            RuntimeException re = new RuntimeException("There is no current PageFlow for the expression.");
-            if(LOGGER.isErrorEnabled()) LOGGER.error("", re);
-            throw re;
+            String message = "There is no current Page Flow!";
+            LOGGER.error(message);
+            throw new RuntimeException(message);
         }
     }
 
+    /**
+     * Internal method!
+     *
+     * This method is used by the expression engine to get the current global app.  If no global app
+     * is found, an exception will be thrown.
+     * @param request the request
+     * @param response the response
+     * @return the global app
+     */
     public static GlobalApp getGlobalApp(ServletRequest request, ServletResponse response) {
         assert request instanceof HttpServletRequest;
         GlobalApp ga = PageFlowUtils.getGlobalApp((HttpServletRequest)request);
         if(ga == null) {
-            RuntimeException re = new RuntimeException("Can not create the globalApp binding context; the GlobalApp object is null.");
-            if(LOGGER.isErrorEnabled()) LOGGER.error("", re);
-            throw re;
+            String message = "There is no current GlobalApp!";
+            LOGGER.error(message);
+            throw new RuntimeException(message);
         }
-
         return ga;
     }
 
     /**
+     * Internal method!
      *
+     * Create a {@link VariableResolver} that contains the implicit objects available for expression
+     * updates.
      */
-    public static VariableResolver getUpdateVariableResolver(ServletRequest request, ServletResponse response, boolean isHandlingPost) {
+    public static VariableResolver getUpdateVariableResolver(ServletRequest request,
+                                                             ServletResponse response,
+                                                             boolean isHandlingPost) {
         Object form = ImplicitObjectUtil.unwrapForm(request.getAttribute(org.apache.struts.taglib.html.Constants.BEAN_KEY));
-
-        /* todo: need to provide get(Read|Update)VariableResolver methods on the ExpressionEngineFactory */
         return new NetUIUpdateVariableResolver(form, request, response, isHandlingPost);
     }
 
-    public static VariableResolver getUpdateVariableResolver(Object form, ServletRequest request, ServletResponse response, boolean isHandlingPost) {
+    /**
+     * Internal method!
+     *
+     * Create a {@link VariableResolver} that contains the implicit objects available for expression
+     * updates.
+     */
+    public static VariableResolver getUpdateVariableResolver(Object form,
+                                                             ServletRequest request,
+                                                             ServletResponse response,
+                                                             boolean isHandlingPost) {
         Object realForm = ImplicitObjectUtil.unwrapForm(form);
-
-        /* todo: need to provide get(Read|Update)VariableResolver methods on the ExpressionEngineFactory */
         return new NetUIUpdateVariableResolver(realForm, request, response, isHandlingPost);
     }
 
-    public static VariableResolver getReadVariableResolver(PageContext pageContext) {
-        assert pageContext != null;
-        return pageContext.getVariableResolver();
-    }
-
-    public static void loadImplicitObjects(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext, PageFlowController curJpf) {
-        // @todo: feature: need to add support for chaining in user-code to run when setting implicit objects on the request
-        loadPageFlow(request, curJpf);
-        
-        // @todo: need to move bundleMap creation to a BundleMapFactory
-        BundleMap bundleMap = new BundleMap(request, servletContext);
-        loadBundleMap(request, bundleMap);
-    }
-
-    public static void loadOutputFormBean(ServletRequest request, Object bean) {
-        if(bean != null)
-            request.setAttribute(OUTPUT_FORM_BEAN_OBJECT_KEY, bean);
+    /**
+     * Internal method!
+     *
+     * Create a {@link VariableResolver} that contains the implicit objects available for
+     * expression reads.
+     *
+     * @param jspContext the jsp context
+     * @return the variable resolver
+     */
+    public static VariableResolver getReadVariableResolver(JspContext jspContext) {
+        assert jspContext != null;
+        return jspContext.getVariableResolver();
     }
 }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/bundle/StrutsBundleNode.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/bundle/StrutsBundleNode.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/bundle/StrutsBundleNode.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/common/bundle/StrutsBundleNode.java Fri Mar 24 09:27:11 2006
@@ -37,10 +37,12 @@
     }
 
     public boolean containsKey(String key) {
+        assert _messageResource != null;
         return _messageResource.getMessage(_locale, key) != null;
     }
 
     public String getString(String key) {
+        assert _messageResource != null;
         return _messageResource.getMessage(_locale, key);
     }
 

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionEvaluatorImpl.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionEvaluatorImpl.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionEvaluatorImpl.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionEvaluatorImpl.java Fri Mar 24 09:27:11 2006
@@ -34,9 +34,11 @@
     implements ExpressionEvaluator {
 
     private static final Logger LOGGER = Logger.getInstance(ExpressionEvaluatorImpl.class);
-    private static final boolean DEBUG_ENABLED = LOGGER.isDebugEnabled();
     private static final boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
 
+    /**
+     * Factory that creates an instance of an {@link ExpressionEvaluator} for this expression language.
+     */
     public static class NetUIELEngineFactory
         extends org.apache.beehive.netui.script.ExpressionEngineFactory {
 
@@ -51,22 +53,25 @@
         try {
             vr = new NetUIReadVariableResolver(variableResolver);
             return ParseUtils.evaluate(expression, vr);
-        } catch(Exception e) {
+        }
+        catch(Exception e) {
             String contextStr = ParseUtils.getContextString(vr.getAvailableVariables());
-            String msg = "Caught exception when evaluating expression \"" + expression + "\" with available binding contexts " +
-                contextStr + ". Root cause: " + ParseUtils.getRootCause(e).toString();
-
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg, e);
-
+            String msg =
+                "Caught exception when evaluating expression \"" +
+                    expression +
+                    "\" with available binding contexts " +
+                    contextStr +
+                    ". Root cause: " +
+                    ParseUtils.getRootCause(e).toString();
+            LOGGER.error(msg, e);
             throw new ExpressionEvaluationException(msg, expression, e);
         }
     }
 
     public void update(String expression, Object value, VariableResolver variableResolver, boolean requestParameter)
         throws ExpressionUpdateException {
-        assert variableResolver instanceof NetUIVariableResolver;
 
+        assert variableResolver instanceof NetUIVariableResolver;
         NetUIVariableResolver vr = (NetUIVariableResolver)variableResolver;
 
         try {
@@ -76,32 +81,37 @@
             ParseUtils.update(expression, value, vr);
         } catch(Exception e) {
             String contextStr = ParseUtils.getContextString(vr.getAvailableVariables());
-            String msg = "Exception when attempting to update the expression \"" + expression +
-                "\" with available binding contexts " + contextStr +
-                ". Root cause: " + ParseUtils.getRootCause(e).toString();
-
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg, e);
+            String msg = "Exception when attempting to update the expression \"" +
+                expression +
+                "\" with available binding contexts " +
+                contextStr +
+                ". Root cause: " +
+                ParseUtils.getRootCause(e).toString();
 
+            LOGGER.error(msg, e);
             ExpressionUpdateException eee = new ExpressionUpdateException(msg, expression, e);
             eee.setLocalizedMessage(msg);
-
             throw eee;
         }
     }
 
-    /* todo: fix the lookup index to be Object */
     public String changeContext(String expression, String oldContext, String newContext, int lookupIndex)
         throws ExpressionEvaluationException {
+
         try {
             ParsedExpression pe = ParseUtils.parse(expression);
             return pe.changeContext(oldContext, newContext, new Integer(lookupIndex));
-        } catch(Exception e) {
-            String msg = "Error when trying to replace old context '" + oldContext + "' with new context '" +
-                newContext + "' and index '" + lookupIndex + "': " + ParseUtils.getRootCause(e).toString();
-
-            if(LOGGER.isErrorEnabled()) LOGGER.error(msg, e);
+        }
+        catch(Exception e) {
+            String msg = "Error when trying to replace old context '" +
+                oldContext +
+                "' with new context '" +
+                newContext +
+                "' and index '" +
+                lookupIndex + "': " +
+                ParseUtils.getRootCause(e).toString();
 
+            LOGGER.error(msg, e);
             throw new ExpressionEvaluationException(msg, e);
         }
     }
@@ -111,9 +121,14 @@
         try {
             ParsedExpression pe = ParseUtils.parse(expression);
             return pe.qualify(contextName);
-        } catch(Exception e) {
-            String msg = "Error when trying to create an expression in namespace \"" + contextName + "\" with fragment \"" +
-                expression + "\".  Root cause: " + ParseUtils.getRootCause(e).toString();
+        }
+        catch(Exception e) {
+            String msg = "Error when trying to create an expression in namespace \"" +
+                contextName +
+                "\" with fragment \"" +
+                expression +
+                "\".  Root cause: " +
+                ParseUtils.getRootCause(e).toString();
 
             throw new ExpressionEvaluationException(msg, e);
         }
@@ -123,31 +138,31 @@
         try {
             ParsedExpression pe = ParseUtils.parse(expression);
             return pe.isExpression();
-        } catch(Exception e) {
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error("Exception parsing expression \"" + expression + "\".  Cause: " +
-                    ParseUtils.getRootCause(e).toString(), e);
+        }
+        catch(Exception e) {
+            LOGGER.error("Exception parsing expression \"" +
+                expression +
+                "\".  Cause: " +
+                ParseUtils.getRootCause(e).toString(), e);
 
             if(e instanceof IllegalExpressionException)
                 throw (IllegalExpressionException)e;
             else if(e instanceof ExpressionParseException)
                 throw new IllegalExpressionException(e);
-            else
-                return false;
+            else return false;
         }
     }
 
     public boolean containsExpression(String expression) {
-        if(expression == null) return false;
+        if(expression == null)
+            return false;
 
         try {
             ParsedExpression pe = ParseUtils.parse(expression);
             assert pe != null;
             return pe.containsExpression();
         } catch(Exception e) {
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error("Exception checking for expressions in \"" + expression + "\"", e);
-
+            LOGGER.error("Exception checking for expressions in \"" + expression + "\"", e);
             return false;
         }
     }
@@ -157,7 +172,9 @@
             ParsedExpression pe = ParseUtils.parse(expression);
             assert pe != null;
             return pe.getAtomicExpressionTerm();
-        } else
-            throw new IllegalExpressionException("The expression \"" + expression + "\" can not be parsed as it is not an atomic expression.");
+        }
+        else throw new IllegalExpressionException("The expression \"" +
+            expression +
+            "\" can not be parsed as it is not an atomic expression.");
     }
 }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionTerm.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionTerm.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionTerm.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ExpressionTerm.java Fri Mar 24 09:27:11 2006
@@ -17,11 +17,8 @@
  */
 package org.apache.beehive.netui.script.el;
 
-import org.apache.beehive.netui.util.internal.InternalStringBuilder;
-
-import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.apache.beehive.netui.script.Expression;
@@ -30,12 +27,14 @@
 import org.apache.beehive.netui.script.el.tokens.ExpressionToken;
 import org.apache.beehive.netui.script.el.tokens.IdentifierToken;
 import org.apache.beehive.netui.script.el.tokens.MapKeyToken;
-import org.apache.beehive.netui.script.el.util.BindingContext;
+import org.apache.beehive.netui.script.el.util.WrappedObject;
 import org.apache.beehive.netui.script.el.util.ParseUtils;
+import org.apache.beehive.netui.util.internal.InternalStringBuilder;
 import org.apache.beehive.netui.util.logging.Logger;
 
 /**
- *
+ * This class represents an executable expression that is evaluated against an object and can read or 
+ * write properties, arrays, lists, and maps on that object.
  */
 public class ExpressionTerm
     extends Expression
@@ -44,58 +43,94 @@
     private static Logger LOGGER = Logger.getInstance(ExpressionTerm.class);
     private static boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
 
-    private List _tokens = null;
-    private String _exprStr = null;
-    private ContextToken _context = null;
-    private ExpressionToken[] _tokenArray = null;
+    private String _expressionString = null;
+    private boolean _sealed = false;
+    private ContextToken _implicitObjectToken = null;
+    private ExpressionToken[] _tokenArray = new ExpressionToken[0];
     private List _noModTokens = null;
 
     public ExpressionTerm() {
         super();
-        _tokens = new ArrayList();
     }
 
     public void seal() {
-        _context = (ContextToken)_tokens.get(0);
-        _tokenArray = new ExpressionToken[_tokens.size()];
+        _sealed = true;
+
+        assert _tokenArray[0] instanceof ContextToken;
+        _implicitObjectToken = (ContextToken)_tokenArray[0];
 
         InternalStringBuilder buf = new InternalStringBuilder();
-        for(int i = 0; i < _tokens.size(); i++) {
-            buf.append(((ExpressionToken)_tokens.get(i)).getTokenString());
-            _tokenArray[i] = (ExpressionToken)_tokens.get(i);
-        }
+        for(int i = 0; i < _tokenArray.length; i++)
+            buf.append(_tokenArray[i].getTokenString());
 
-        _exprStr = buf.toString();
+        _expressionString = buf.toString();
+    }
 
-        _noModTokens = Collections.unmodifiableList(_tokens);
+    public Object read(NetUIVariableResolver vr) {
+        assert _tokenArray != null;
+        return _evaluate(_tokenArray.length, vr);
     }
 
     public String getContext() {
-        return _context.getName();
+        assert _implicitObjectToken != null;
+        return _implicitObjectToken.getName();
     }
 
     public List getTokens() {
+        if(_noModTokens == null) {
+            _noModTokens = new LinkedList();
+            for(int i = 0; i < _tokenArray.length; i++)
+                _noModTokens.add(_tokenArray[i]);
+            _noModTokens = Collections.unmodifiableList(_noModTokens);
+        }
+
         return _noModTokens;
     }
 
+    public int getTokenCount() {
+        assert _tokenArray != null;
+        return _tokenArray.length;
+    }
+
+    public ExpressionToken getToken(int index) {
+        assert _tokenArray != null;
+        assert index >= 0;
+        assert index < _tokenArray.length;
+        return _tokenArray[index];
+    }
+
+    public String getExpressionString() {
+        return _expressionString;
+    }
+
+    public String toString() {
+        return _expressionString;
+    }
+
     public String getExpression(int start) {
-        if(start >= _tokens.size())
-            throw new IllegalStateException("The index \"" + start + "\" is an invalid reference into an expression with \"" +
-                _tokens.size() + "\" _tokens.");
+        if(start >= _tokenArray.length)
+            throw new IllegalStateException("The index \"" +
+                start +
+                "\" is an invalid reference into an expression with \"" +
+                _tokenArray.length +
+                "\" _tokens.");
 
         boolean needDot = true;
         InternalStringBuilder buf = new InternalStringBuilder();
         buf.append("{");
-        for(int i = start; i < _tokens.size(); i++) {
-            ExpressionToken tok = (ExpressionToken)_tokens.get(i);
+        for(int i = start; i < _tokenArray.length; i++) {
+            ExpressionToken tok = _tokenArray[i];
             if(tok instanceof ArrayIndexToken) {
                 buf.append(tok.getTokenString());
                 needDot = false;
-            } else if(tok instanceof IdentifierToken) {
-                if(needDot && i != start) buf.append(".");
+            }
+            else if(tok instanceof IdentifierToken) {
+                if(needDot && i != start)
+                    buf.append(".");
                 buf.append(tok.toString());
                 needDot = true;
-            } else if(tok instanceof MapKeyToken) {
+            }
+            else if(tok instanceof MapKeyToken) {
                 buf.append(tok.getTokenString());
                 needDot = false;
             }
@@ -105,136 +140,98 @@
     }
 
     public void addToken(ExpressionToken token) {
-        _tokens.add(token);
-    }
-
-    public Iterator getExpressionTokens() {
-        return _tokens.iterator();
-    }
-
-    public int getTokenCount() {
-        return _tokenArray.length;
-    }
-
-    public ExpressionToken getToken(int index) {
-        // @TODO: error checking
-        return _tokenArray[index];
-    }
+        if(_sealed)
+            throw new IllegalStateException("Can't add token to already sealed expression");
 
-    public String getExpressionString() {
-        return _exprStr;
-    }
-
-    public Object evaluate(NetUIVariableResolver vr) {
-        return _evaluate(_tokens.size(), vr);
+        assert _tokenArray != null;
+        ExpressionToken[] newToken = new ExpressionToken[_tokenArray.length + 1];
+        System.arraycopy(_tokenArray, 0, newToken, 0, _tokenArray.length);
+        newToken[_tokenArray.length] = token;
+        _tokenArray = newToken;
     }
 
     public void update(Object newValue, NetUIVariableResolver vr) {
-        // find leaf
-        Object branch = _evaluate(_tokens.size() - 1, vr);
 
-        ExpressionToken token = _tokenArray[_tokens.size() - 1];
+        // Execute the expression up to the last token.  This will return the object that should be updated
+        Object branch = _evaluate(_tokenArray.length - 1, vr);
+
+        // Get the token to update
+        ExpressionToken token = _tokenArray[_tokenArray.length - 1];
 
         if(TRACE_ENABLED)
             LOGGER.trace("Update leaf token: " + token + " on object: " + branch);
 
-        // apply value
-        token.update(branch, newValue);
+        // update the object
+        token.write(branch, newValue);
     }
 
-    /* todo: perf. this could be done more effectively / efficiently */
-    public String changeContext(String oldContext, String newContext, Object index) {
+    public String changeContext(String previousImplicitObject, String newImplicitObject, Object lookupKey) {
         String thisExpr = getExpressionString();
 
         if(TRACE_ENABLED)
-            LOGGER.trace("oldContext: " + oldContext + " newContext: " + newContext + " thisExpr: " + thisExpr);
+            LOGGER.trace("previous implicit object: " + previousImplicitObject + " new implicit object: " + newImplicitObject + " expression: " + thisExpr);
 
         // needs to be checked for atomicity
-        ParsedExpression pe = ParseUtils.parse(newContext);
+        ParsedExpression pe = ParseUtils.parse(newImplicitObject);
 
         if(!pe.isExpression()) {
             String msg = "The expression can not be qualified into new _context because the new _context is not atomic.";
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
 
         // this isn't a failure; it just means that there isn't anything else to replace
-        if(!thisExpr.startsWith(oldContext)) {
+        if(!thisExpr.startsWith(previousImplicitObject))
             return "{" + thisExpr + "}";
-        }
 
-        if(index instanceof Integer && ((Integer)index).intValue() > 32767) {
-            String msg = "Can not create an indexed expression with an array index greater than the Java array limit array length \"" +
+        if(lookupKey instanceof Integer && ((Integer)lookupKey).intValue() > 32767) {
+            String msg = "Can not create an indexed expression with an array index greater than " +
+                "the Java array limit array length \"" +
                 thisExpr + "\"";
-
-            if(LOGGER.isWarnEnabled())
-                LOGGER.warn(msg);
+            LOGGER.warn(msg);
             throw new RuntimeException(msg);
         }
 
-        String ctxStr = pe.getExpressionString();
-
-        ctxStr = ctxStr + "[" + index + "]";
+        newImplicitObject = pe.getExpressionString() + "[" + lookupKey + "]";
 
         if(TRACE_ENABLED)
-            LOGGER.trace("thisExpr: " + thisExpr + " ctxStr: " + ctxStr);
+            LOGGER.trace("expression: " + thisExpr + " implicit object: " + newImplicitObject);
 
-        thisExpr = thisExpr.replaceFirst(oldContext, ctxStr);
+        thisExpr = thisExpr.replaceFirst(previousImplicitObject, newImplicitObject);
 
         InternalStringBuilder buf = new InternalStringBuilder();
-        buf.append("{");
-        buf.append(thisExpr);
-        buf.append("}");
-
+        buf.append("{").append(thisExpr).append("}");
         return buf.toString();
     }
 
     public String qualify(String contextName) {
         InternalStringBuilder buf = new InternalStringBuilder();
-        buf.append("{");
-        buf.append(contextName);
-        buf.append(".");
-        buf.append(getExpressionString());
-        buf.append("}");
-
-        return buf.toString();
-    }
-
-    public String toString() {
-        InternalStringBuilder buf = new InternalStringBuilder();
-        buf.append("ExpressionTerm:\n");
-        for(int i = 0; i < _tokens.size(); i++) {
-            buf.append("  " + _tokens.get(i).toString() + "\n");
-        }
+        buf.append("{").append(contextName).append(".").append(getExpressionString()).append("}");
         return buf.toString();
     }
 
     private Object _evaluate(int index, NetUIVariableResolver vr) {
-        Object result = null;
+        assert _tokenArray != null;
 
-        if(_tokens.size() == 1) {
-            if(TRACE_ENABLED) 
-                LOGGER.trace("found single term expression");
-
-            result = vr.resolveVariable(_context.getName());
-
-            if(result != null && result instanceof BindingContext) {
-                if(TRACE_ENABLED)
-                    LOGGER.trace("result is of type BindingContext; return type: " + (((BindingContext)result).unwrap().getClass()));
-
-                return ((BindingContext)result).unwrap();
-            } else
-                return result;
-        } else {
-            for(int i = 0; i < index; i++) {
-                if(i == 0) {
-                    result = vr.resolveVariable(_context.getName());
-                } else
-                    result = _tokenArray[i].evaluate(result);
-            }
+        Object result = vr.resolveVariable(getContext());
 
-            return result;
+        /*
+        This is a special case used to unwrap something that has been wrapped in
+        a Map facade but that delegates to some underlying implementation.  For
+        example, an HttpSession might be wrapped inside of a Map facade in order
+        to expose it as a Map for reads / updates in the expression engine.
+         */
+        if(_tokenArray.length == 1 && result instanceof WrappedObject) {
+            result = ((WrappedObject)result).unwrap();
+        }
+        /*
+        Otherwise, read each additional term in the expression with the result of the previous term.
+         */
+        else {
+            for(int i = 1; i < index; i++)
+                result = _tokenArray[i].read(result);
         }
+
+        return result;
     }
 }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/LiteralTerm.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/LiteralTerm.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/LiteralTerm.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/LiteralTerm.java Fri Mar 24 09:27:11 2006
@@ -35,12 +35,11 @@
 
         /* todo:  probably being lazy in not fixing the grammar */
         if(text.equals("\\{"))
-            this._text = "{";
-        else
-            this._text = text;
+            _text = "{";
+        else _text = text;
 
         if(TRACE_ENABLED)
-            LOGGER.trace("LiteralTerm _text: " + text + " this._text: " + this._text);
+            LOGGER.trace("LiteralTerm: " + text);
     }
 
     public void seal() {
@@ -50,7 +49,7 @@
         return _text;
     }
 
-    public Object evaluate(NetUIVariableResolver vr) {
+    public Object read(NetUIVariableResolver vr) {
         return _text;
     }
 

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIReadVariableResolver.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIReadVariableResolver.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIReadVariableResolver.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIReadVariableResolver.java Fri Mar 24 09:27:11 2006
@@ -18,8 +18,8 @@
 package org.apache.beehive.netui.script.el;
 
 import javax.servlet.jsp.el.VariableResolver;
+import javax.servlet.jsp.el.ELException;
 
-import org.apache.beehive.netui.script.IllegalExpressionException;
 import org.apache.beehive.netui.util.logging.Logger;
 
 /**
@@ -38,16 +38,13 @@
     }
 
     public Object resolveVariable(String name) {
-
         try {
             return _vr.resolveVariable(name);
-        } catch(javax.servlet.jsp.el.ELException ele) {
-            RuntimeException re = new RuntimeException("Could not resolve variable named \"" + name + "\"", new IllegalExpressionException());
-
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error("", re);
-
-            throw re;
+        }
+        catch(ELException e) {
+            String message = "Could not resolve variable named \"" + name + "\".  Cause: " + e;
+            LOGGER.error(message, e);
+            throw new RuntimeException(message, e);
         }
     }
 

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIUpdateVariableResolver.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIUpdateVariableResolver.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIUpdateVariableResolver.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/NetUIUpdateVariableResolver.java Fri Mar 24 09:27:11 2006
@@ -20,18 +20,12 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.jsp.el.VariableResolver;
 
 import org.apache.beehive.netui.script.IllegalExpressionException;
 import org.apache.beehive.netui.script.common.ImplicitObjectUtil;
-import org.apache.beehive.netui.script.el.util.RequestAttributeMap;
-import org.apache.beehive.netui.script.el.util.SessionAttributeMap;
+import org.apache.beehive.netui.script.el.util.RequestAttributeMapFacade;
+import org.apache.beehive.netui.script.el.util.SessionAttributeMapFacade;
 import org.apache.beehive.netui.util.logging.Logger;
-import org.apache.beehive.netui.pageflow.SharedFlowController;
-import org.apache.beehive.netui.pageflow.PageFlowController;
-import org.apache.beehive.netui.pageflow.GlobalApp;
-
-import java.util.Map;
 
 /**
  *
@@ -46,7 +40,10 @@
     private ServletRequest _request = null;
     private ServletResponse _response = null;
 
-    public NetUIUpdateVariableResolver(Object form, ServletRequest request, ServletResponse response, boolean requestParameter) {
+    public NetUIUpdateVariableResolver(Object form,
+                                       ServletRequest request,
+                                       ServletResponse response,
+                                       boolean requestParameter) {
         super();
 
         _requestParameter = requestParameter;
@@ -59,33 +56,30 @@
         if(name.equals("actionForm"))
             return _form;
         else if(name.equals("pageFlow"))
-            return getPageFlow(_request, _response);
+            return ImplicitObjectUtil.getPageFlow(_request, _response);
         else if(name.equals("globalApp"))
-            return getGlobalApp(_request, _response);
+            return ImplicitObjectUtil.getGlobalApp(_request, _response);
         else if(name.equals("sharedFlow"))
-            return getSharedFlow(_request, _response);
+            return ImplicitObjectUtil.getSharedFlow(_request);
         else if(name.equals("requestScope")) {
-            if(_requestParameter == false)
-                return new RequestAttributeMap(_request);
+            if(!_requestParameter)
+                return new RequestAttributeMapFacade(_request);
             else
                 throw new IllegalExpressionException("The request data binding context can not be updated from a request parameter.");
         } else if(name.equals("sessionScope")) {
-            if(_requestParameter == false)
-                return new SessionAttributeMap(((HttpServletRequest)_request).getSession());
-            else
-                throw new IllegalExpressionException("The session data binding context can not be updated from a request parameter.");
+            if(!_requestParameter)
+                return new SessionAttributeMapFacade(((HttpServletRequest)_request).getSession());
+            else throw new IllegalExpressionException("The session data binding context can not be updated from a request parameter.");
         }
         // @bug: need to get the ServletContext from somewhere
         else if(name.equals("applicationScope")) {
-            if(_requestParameter == false)
+            if(!_requestParameter)
                 return null;
-            else
-                throw new IllegalExpressionException("The application data binding context can not be updated from a request parameter.");
-        } else {
+            else throw new IllegalExpressionException("The application data binding context can not be updated from a request parameter.");
+        }
+        else {
             String msg = "Could not resolve variable named \"" + name + "\" for an expression update.";
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
-
+            LOGGER.error(msg);
             throw new IllegalExpressionException(msg);
         }
     }
@@ -93,19 +87,6 @@
     public String[] getAvailableVariables() {
         if(_requestParameter)
             return new String[]{"actionForm", "pageFlow", "globalApp"};
-        else
-            return new String[]{"actionForm", "pageFlow", "globalApp", "request", "session", "application"};
-    }
-
-    private static final Map/*<String, SharedFlowController>*/ getSharedFlow(ServletRequest request, ServletResponse response) {
-        return ImplicitObjectUtil.getSharedFlow(request);
-    }
-
-    private static final PageFlowController getPageFlow(ServletRequest request, ServletResponse response) {
-        return ImplicitObjectUtil.getPageFlow(request, response);
-    }
-
-    private static final GlobalApp getGlobalApp(ServletRequest request, ServletResponse response) {
-        return ImplicitObjectUtil.getGlobalApp(request, response);
+        else return new String[]{"actionForm", "pageFlow", "globalApp", "request", "session", "application"};
     }
 }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ParsedExpression.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ParsedExpression.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ParsedExpression.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/ParsedExpression.java Fri Mar 24 09:27:11 2006
@@ -18,55 +18,56 @@
 package org.apache.beehive.netui.script.el;
 
 import org.apache.beehive.netui.util.internal.InternalStringBuilder;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.LinkedList;
-
 import org.apache.beehive.netui.util.logging.Logger;
 
 /**
- *
+ * This class represents a complete and parsed expression string.  An expression can be made up
+ * of any number of ExpressionTerm and LiteralTerm objects.  If this parsed expression contains
+ * a single ExpressionTerm, it is considered "atomic" because it references a single property on
+ * a single object.
  */
 public class ParsedExpression {
 
     private static Logger LOGGER = Logger.getInstance(ParsedExpression.class);
-
-    /* cache the debug status; this needs to be _fast_ */
     private static final boolean TRACE_ENABLED = LOGGER.isTraceEnabled();
     private static final String EMPTY_STRING = "";
 
-    private LinkedList/*<Term>*/ _terms = new LinkedList/*<Term>*/();
+    private String _expressionString;
     private boolean _isExpression = false;
     private boolean _containsExpression = false;
+
+    /**
+     * An atomic expression is the common case, so keep a pointer to the first element in the array
+     * in order to avoid doing a cast from Term to ExpressionTerm when evaluating an expression.  This
+     * trades off space for time, but it's a small amount of space relatively speaking.
+     */
     private ExpressionTerm _atomicExpression = null;
-    private Term[] _termArray = null;
-    private String _exprStr;
+    private Term[] _termArray = new Term[0];
 
     public void seal() {
-        _termArray = new Term[_terms.size()];
-
         InternalStringBuilder buf = new InternalStringBuilder();
-        for(int i = 0; i < _terms.size(); i++) {
-            Term t = (Term)_terms.get(i);
+        for(int i = 0; i < _termArray.length; i++) {
+            Term t = _termArray[i];
+            assert t != null;
+
             t.seal();
 
             if(t instanceof ExpressionTerm) {
-                if(_terms.size() == 1) {
-                    _atomicExpression = (ExpressionTerm)_terms.get(0);
+                if(_termArray.length == 1) {
+                    _atomicExpression = (ExpressionTerm)t;
                     _isExpression = true;
                 }
                 _containsExpression = true;
-            } else if(t instanceof LiteralTerm) {
+            }
+            else if(t instanceof LiteralTerm) {
                 String lit = t.getExpressionString();
                 if(lit != null && lit.indexOf("{") > -1)
                     _containsExpression = true;
             }
 
-            _termArray[i] = (Term)_terms.get(i);
             buf.append(t.getExpressionString());
         }
-        _exprStr = buf.toString();
+        _expressionString = buf.toString();
     }
 
     public boolean isExpression() {
@@ -78,11 +79,15 @@
     }
 
     public void addTerm(Term term) {
-        _terms.add(term);
+        assert _termArray != null;
+        Term[] newTerms = new Term[_termArray.length + 1];
+        System.arraycopy(_termArray, 0, newTerms, 0, _termArray.length);
+        newTerms[_termArray.length] = term;
+        _termArray = newTerms;
     }
 
     public int getTokenCount() {
-        return _terms.size();
+        return _termArray.length;
     }
 
     public Term getTerm(int i) {
@@ -98,22 +103,25 @@
 
     public Object evaluate(NetUIVariableResolver vr) {
         if(TRACE_ENABLED)
-            LOGGER.trace("evaluate expression: " + _exprStr);
+            LOGGER.trace("evaluate expression: " + _expressionString);
 
         if(_isExpression) {
             if(TRACE_ENABLED)
                 LOGGER.trace("atoimc expression");
 
-            return _atomicExpression.evaluate(vr);
+            return _atomicExpression.read(vr);
         } else {
             InternalStringBuilder buf = new InternalStringBuilder();
 
-            for(int i = 0; i < _terms.size(); i++) {
+            for(int i = 0; i < _termArray.length; i++) {
                 if(TRACE_ENABLED)
-                    LOGGER.trace("term[" + i + "]: " + _termArray[i].getClass().getName() +
-                        " expression string: " + _termArray[i].getExpressionString());
+                    LOGGER.trace(
+                        "term[" + i + "]: " +
+                        _termArray[i].getClass().getName() +
+                        " expression string: " +
+                        _termArray[i].getExpressionString());
 
-                Object result = _termArray[i].evaluate(vr);
+                Object result = _termArray[i].read(vr);
 
                 buf.append(result != null ? result.toString() : EMPTY_STRING);
             }
@@ -125,8 +133,7 @@
     public void update(Object value, NetUIVariableResolver vr) {
         if(!_isExpression) {
             String msg = "The expression can not be updated because it is not atomic.";
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
 
@@ -136,36 +143,22 @@
     public String changeContext(String oldContext, String newContext, Object index) {
         if(!_isExpression) {
             String msg = "The expression can not change context because it is not atomic.";
-
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
-
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
 
         return _atomicExpression.changeContext(oldContext, newContext, index);
     }
 
-    public String qualify(String contextName) {
-        /* todo: could check to see if first term is literal */
-
-        return "{" + contextName + "." + getExpressionString() + "}";
+    public String qualify(String implicitObjectName) {
+        return "{" + implicitObjectName + "." + getExpressionString() + "}";
     }
 
-    // only call on atomic expressions
     public String getExpressionString() {
-        if(_isExpression)
-            return _atomicExpression.getExpressionString();
-        else
-            return _exprStr;
+        return _expressionString;
     }
 
     public String toString() {
-        InternalStringBuilder builder = new InternalStringBuilder();
-        for(Iterator i = _terms.iterator(); i.hasNext();) {
-            Term term = (Term)i.next();
-            builder.append(term.toString());
-        }
-        return builder.toString();
+        return _expressionString;
     }
 }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/Term.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/Term.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/Term.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/Term.java Fri Mar 24 09:27:11 2006
@@ -22,10 +22,10 @@
  */
 public interface Term {
 
-    public Object evaluate(NetUIVariableResolver vr);
+    void seal();
 
-    public String getExpressionString();
+    Object read(NetUIVariableResolver vr);
 
-    public void seal();
+    String getExpressionString();
 }
    

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ArrayIndexToken.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ArrayIndexToken.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ArrayIndexToken.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ArrayIndexToken.java Fri Mar 24 09:27:11 2006
@@ -35,28 +35,39 @@
         _index = Integer.parseInt(identifier);
     }
 
-    public void update(Object root, Object newValue) {
-        if(root instanceof List)
-            listUpdate((List)root, _index, newValue);
-        else if(root.getClass().isArray())
-            arrayUpdate(root, _index, newValue);
-        else {
-            RuntimeException re = new RuntimeException("The _index \"" + _index + "\" can not be used to look-up the type of a property" +
-                " on an object that is not an array or list.");
-            LOGGER.error("", re);
-            throw re;
-        }
-    }
-
-    public Object evaluate(Object value) {
+    /**
+     * Evaluate an array index token.  This token takes the form "[1234]" where
+     * "1234" is the index into the array.  The token is identified as this because
+     * an integer number appears between the square brackets.
+     *
+     * @param value the object from which to read a value at the index represented by this token
+     * @return the value of the item at this array index
+     */
+    public Object read(Object value) {
         if(value instanceof List)
             return listLookup((List)value, _index);
         else if(value.getClass().isArray())
             return arrayLookup(value, _index);
         else {
-            RuntimeException re = new RuntimeException("The _index \"" + _index + "\" can not be used to look-up a property on an object that is not an array or list.");
-            LOGGER.error("", re);
-            throw re;
+            String message = "The index \"" +
+            _index +
+            "\" can not be used to index a property on an object that is not an Array or a List";
+            LOGGER.error(message);
+            throw new RuntimeException(message);
+        }
+    }
+
+    public void write(Object root, Object value) {
+        if(root instanceof List)
+            listUpdate((List)root, _index, value);
+        else if(root.getClass().isArray())
+            arrayUpdate(root, _index, value);
+        else {
+            String message = "The index " +
+                _index +
+                "\" can not be used to update a property on an object that is not an Array or a List";
+            LOGGER.error(message);
+            throw new RuntimeException(message);
         }
     }
 

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ContextToken.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ContextToken.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ContextToken.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ContextToken.java Fri Mar 24 09:27:11 2006
@@ -17,6 +17,10 @@
  */
 package org.apache.beehive.netui.script.el.tokens;
 
+/**
+ * Token that represents the implicit object -- aka the binding context.  This is the
+ * outer most data item referenced by an expression.
+ */
 public class ContextToken
     extends ExpressionToken {
 
@@ -26,15 +30,15 @@
         _context = context;
     }
 
-    public void update(Object value, Object newValue) {
+    public Object read(Object value) {
+        return null;
     }
 
-    public String getName() {
-        return _context;
+    public void write(Object value, Object newValue) {
     }
 
-    public Object evaluate(Object value) {
-        return null;
+    public String getName() {
+        return _context;
     }
 
     public String getTokenString() {

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ExpressionToken.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ExpressionToken.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ExpressionToken.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/ExpressionToken.java Fri Mar 24 09:27:11 2006
@@ -18,7 +18,6 @@
 package org.apache.beehive.netui.script.el.tokens;
 
 import java.lang.reflect.Array;
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
@@ -33,55 +32,78 @@
 public abstract class ExpressionToken {
 
     private static final Logger LOGGER = Logger.getInstance(ArrayIndexToken.class);
-
     private static final PropertyCache PROPERTY_CACHE = new PropertyCache();
 
-    public abstract Object evaluate(Object value);
+    public abstract Object read(Object object);
 
-    public abstract void update(Object root, Object newValue);
+    public abstract void write(Object object, Object value);
 
     public abstract String getTokenString();
 
-    /*
-     *
-     * Property Lookup
-     *
-     */
-    protected final Object mapLookup(Map map, Object identifier) {
-        if(LOGGER.isTraceEnabled())
-            LOGGER.trace("mapLookup");
-        return map.get(identifier);
-    }
-
-    protected final Object beanLookup(Object bean, Object identifier) {
-        if(LOGGER.isTraceEnabled())
-            LOGGER.trace("beanLookup: " + identifier);
+    /**
+     * Lookup the <code>key</code> in the <code>map</code>.
+     * @param map the map
+     * @param key the key
+     * @return the value found at <code>map.get(key)</code> or <code>null</code> if no value was found
+     */
+    protected final Object mapLookup(Map map, Object key) {
+        LOGGER.trace("get value from Map");
+        return map.get(key);
+    }
 
-        return ParseUtils.getProperty(bean, identifier.toString(), PROPERTY_CACHE);
+    /**
+     * Get a JavaBean property from the given <code>value</code>
+     * @param value the JavaBean
+     * @param propertyName the property name
+     * @return the value of the property from the object <code>value</code>
+     */
+    protected final Object beanLookup(Object value, Object propertyName) {
+        LOGGER.trace("get JavaBean property : " + propertyName);
+        return ParseUtils.getProperty(value, propertyName.toString(), PROPERTY_CACHE);
     }
 
+    /**
+     * Get the value in a {@link List} at <code>index</code>.
+     * @param list the List
+     * @param index the index
+     * @return the value returned from <code>list.get(index)</code>
+     */
     protected final Object listLookup(List list, int index) {
-        if(LOGGER.isTraceEnabled())
-            LOGGER.trace("listLookup: " + index);
-
+        LOGGER.trace("get value in List index " + index);
         return list.get(index);
     }
 
+    /**
+     * Get the value from <code>array</code> at <code>index</code>
+     * @param array the array
+     * @param index the index
+     * @return the value returned from <code>Array.get(array, index)</code>
+     */
     protected final Object arrayLookup(Object array, int index) {
-        if(LOGGER.isTraceEnabled())
-            LOGGER.trace("arrayLookup: " + index);
-
+        LOGGER.trace("get value from array index " + index);
         return Array.get(array, index);
     }
 
-    protected final void mapUpdate(Map map, Object identifier, Object value) {
-        Object o = map.get(identifier);
+    /**
+     * Update the value of <code>key</code> in <code>map</code>
+     * @param map the map
+     * @param key the key
+     * @param value the value
+     */
+    protected final void mapUpdate(Map map, Object key, Object value) {
+        Object o = map.get(key);
+        /*
+          If a value exists in map.get(key), convert the "value" parameter into
+          the type of map.get(key).  It's a best guess as to what the type of the
+          Map _should_ be without any further reflective information about the
+          types contained in the map.
+         */
         if(o != null) {
             Class type = o.getClass();
             value = ParseUtils.convertType(value, type);
         }
 
-        map.put(identifier, value);
+        map.put(key, value);
     }
 
     protected final void arrayUpdate(Object array, int index, Object value) {
@@ -97,12 +119,17 @@
         } catch(Exception e) {
             String msg = "An error occurred setting a value at index \"" + index + "\" on an array with component types \"" +
                 elementType + "\".  Cause: " + e.toString();
-
-            if(LOGGER.isErrorEnabled()) LOGGER.error(msg);
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
     }
 
+    /**
+     * Update a {@link List} with the Object <code>value</code> at <code>index</code>.
+     * @param list the List
+     * @param index the index
+     * @param value the new value
+     */
     protected final void listUpdate(List list, int index, Object value) {
         Object converted = value;
 
@@ -134,52 +161,63 @@
             // lists, so changing this just gives a better exception message that "ArrayIndexOutOfBounds".  :)
             // 
             // September 2, 2003
-            // ekoneil@bea.com
+            // ekoneil@apache.com
             // 
-            String msg = "An error occurred setting a value at index \"" + index + "\" because the list is " +
+            String msg = "An error occurred setting a value at index \"" +
+                index +
+                "\" because the list is " +
                 (list != null ? (" of size " + list.size()) : "null") + ".  " +
                 "Be sure to allocate enough items in the List to accomodate any updates which may occur against the list.";
 
-            if(LOGGER.isErrorEnabled()) LOGGER.error(msg);
-
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
     }
 
+    /**
+     * Update a JavaBean property named <code>identifier</code> with the given <code>value</code>.
+     * @param bean the JavaBean
+     * @param identifier the property name
+     * @param value the new value
+     */
     protected final void beanUpdate(Object bean, Object identifier, Object value) {
-        if(LOGGER.isTraceEnabled())
-            LOGGER.trace("Update bean \"" + bean + "\" property \"" + identifier + "\"");
+        LOGGER.trace("Update bean \"" + bean + "\" property \"" + identifier + "\"");
+
+        String propertyName = identifier.toString();
 
-        String id = identifier.toString();
         Class beanType = bean.getClass();
-        Class propType = PROPERTY_CACHE.getPropertyType(beanType, id);
+        Class propType = PROPERTY_CACHE.getPropertyType(beanType, propertyName);
+        // Get the type of the JavaBean property given reflected information from the JavaBean's type
         if(propType != null) {
             try {
-                if(java.util.List.class.isAssignableFrom(propType)) {
-                    Method lm = PROPERTY_CACHE.getPropertyGetter(beanType, id);
-                    if(lm != null) {
-                        List list = (List)lm.invoke(bean, (Object[])null);
+                // The type of the JavaBean property is a List.  To update it, get the List and
+                // append the value to the end of the List.
+                if(List.class.isAssignableFrom(propType)) {
+                    Method listGetter = PROPERTY_CACHE.getPropertyGetter(beanType, propertyName);
+                    if(listGetter != null) {
+                        List list = (List)listGetter.invoke(bean, (Object[])null);
                         applyValuesToList(value, list);
                         return;
                     }
-                } else {
-                    Method m = PROPERTY_CACHE.getPropertySetter(beanType, id);
+                }
+                // The JavaBean is an Object, so set the Bean's property with the given value
+                else {
+                    Method setter = PROPERTY_CACHE.getPropertySetter(beanType, propertyName);
 
-                    if(m != null) {
-                        if(LOGGER.isTraceEnabled())
-                            LOGGER.trace("Set property via setter method: [" + m + "]");
+                    if(setter != null) {
+                        LOGGER.trace("Set property via setter method: [" + setter + "]");
 
-                        Class targetType = m.getParameterTypes()[0];
+                        Class targetType = setter.getParameterTypes()[0];
                         Object converted = ParseUtils.convertType(value, targetType);
 
-                        m.invoke(bean, new Object[]{converted});
+                        setter.invoke(bean, new Object[]{converted});
                         return;
                     }
                 }
-            } catch(Exception e) {
-                String msg = "Could not update proprety named \"" + id + "\" on bean of type \"" + beanType + "\".  Cause: " + e;
-                if(LOGGER.isErrorEnabled())
-                    LOGGER.error(msg, e);
+            }
+            catch(Exception e) {
+                String msg = "Could not update proprety named \"" + propertyName + "\" on bean of type \"" + beanType + "\".  Cause: " + e;
+                LOGGER.error(msg, e);
                 throw new RuntimeException(msg, e);
             }
         }
@@ -189,34 +227,44 @@
         throw new RuntimeException(msg);
     }
 
-    protected final int parseIndex(String identifier) {
+    /**
+     * Attempt to convert a String indexString into an integer index.
+     * @param indexString the index string
+     * @return the converted integer
+     */
+    protected final int parseIndex(String indexString) {
         try {
-            return Integer.parseInt(identifier);
+            return Integer.parseInt(indexString);
         } catch(Exception e) {
-            String msg = "Error performing an array look-up with the index \"" + identifier + "\". Cause: " + e;
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg, e);
-
+            String msg = "Error converting \"" + indexString + "\" into an integer.  Cause: " + e;
+            LOGGER.error(msg, e);
             throw new RuntimeException(msg, e);
         }
     }
 
+    /**
+     * Set a list of values on a {@link List}.  The behavior of this method is different given
+     * the type of <code>value</code>:<br/>
+     * - value is java.lang.String[]: add each item in the String[] to the list
+     * - value is a String: add the value to the list
+     * - otherwise, add the value to the end of the list
+     * @param value the value to apply to a list
+     * @param list the {@link List}
+     */
     private static void applyValuesToList(Object value, List list) {
         if(list == null) {
             String msg = "Can not add a value to a null java.util.List";
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
 
         if(value instanceof String[]) {
             String[] ary = (String[])value;
-            for(int i = 0; i < ary.length; i++) {
+            for(int i = 0; i < ary.length; i++)
                 list.add(ary[i]);
-            }
-        } else if(value instanceof String) {
-            list.add(value);
         }
+        else if(value instanceof String)
+            list.add(value);
         // types that are not String[] or String are just set on the object
         else list.add(value);
     }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/IdentifierToken.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/IdentifierToken.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/IdentifierToken.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/IdentifierToken.java Fri Mar 24 09:27:11 2006
@@ -23,7 +23,9 @@
 import org.apache.beehive.netui.util.logging.Logger;
 
 /**
- *
+ * General representation of an identifier in an expression.  For example, in the expression
+ * <code>actionForm.foo.bar</code>, both <code>foo</code> and <code>bar</code> are tokens of this
+ * type.
  */
 public class IdentifierToken
     extends ExpressionToken {
@@ -37,54 +39,68 @@
         _identifier = identifier;
     }
 
-    public Object evaluate(Object value) {
-        /* todo: error handling */
-        if(value == null) {
-            String msg = "Can not evaluate the identifier \"" + _identifier + "\" on a null value object.";
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
+    /**
+     * Read the object represetned by this token from the given object.
+     * @param object the object from which to read
+     * @return the read object
+     */
+    public Object read(Object object) {
+        if(object == null) {
+            String msg = "Can not evaluate the identifier \"" + _identifier + "\" on a null object.";
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
 
         if(TRACE_ENABLED)
-            LOGGER.trace("Read property " + _identifier + " on value of type " + value.getClass().getName());
+            LOGGER.trace("Read property " + _identifier + " on object of type " + object.getClass().getName());
 
-        if(value instanceof Map) {
-            return mapLookup((Map)value, _identifier);
-        } else if(value instanceof List) {
+        if(object instanceof Map)
+            return mapLookup((Map)object, _identifier);
+        else if(object instanceof List) {
             int i = parseIndex(_identifier);
-            return listLookup((List)value, i);
-        } else if(value.getClass().isArray()) {
+            return listLookup((List)object, i);
+        }
+        else if(object.getClass().isArray()) {
             int i = parseIndex(_identifier);
-            return arrayLookup(value, i);
-        } else
-            return beanLookup(value, _identifier);
+            return arrayLookup(object, i);
+        }
+        else return beanLookup(object, _identifier);
     }
 
-    public void update(Object root, Object newValue) {
-        /* todo: error handling */
-        if(root == null) {
+    /**
+     * Update the value represented by this token on the given object <code>object</code> with
+     * the value <code>value</code>.
+     * @param object the object to update
+     * @param value the new value
+     */
+    public void write(Object object, Object value) {
+        if(object == null) {
             String msg = "Can not update the identifier \"" + _identifier + "\" on a null value object.";
-            if(LOGGER.isErrorEnabled())
-                LOGGER.error(msg);
+            LOGGER.error(msg);
             throw new RuntimeException(msg);
         }
 
         if(TRACE_ENABLED)
-            LOGGER.trace("Update property named \"" + _identifier + "\" on object of type: \"" + root.getClass().getName() + "\"");
+            LOGGER.trace("Update property named \"" + _identifier + "\" on object of type: \"" + object.getClass().getName() + "\"");
 
-        if(root instanceof Map)
-            mapUpdate((Map)root, _identifier, newValue);
-        else if(root instanceof List) {
+        if(object instanceof Map)
+            mapUpdate((Map)object, _identifier, value);
+        else if(object instanceof List) {
             int i = parseIndex(_identifier);
-            listUpdate((List)root, i, newValue);
-        } else if(root.getClass().isArray()) {
+            listUpdate((List)object, i, value);
+        }
+        else if(object.getClass().isArray()) {
             int i = parseIndex(_identifier);
-            arrayUpdate(root, i, newValue);
-        } else
-            beanUpdate(root, _identifier, newValue);
+            arrayUpdate(object, i, value);
+        }
+        else beanUpdate(object, _identifier, value);
     }
 
+    /**
+     * Get the String representation of this token.  Note, this assumes that the token was
+     * preceeded with a ".".
+     * @return the String representing this token
+     */
     public String getTokenString() {
         return "." + _identifier;
     }

Modified: beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/MapKeyToken.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/MapKeyToken.java?rev=388583&r1=388582&r2=388583&view=diff
==============================================================================
--- beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/MapKeyToken.java (original)
+++ beehive/trunk/netui/src/pageflow/org/apache/beehive/netui/script/el/tokens/MapKeyToken.java Fri Mar 24 09:27:11 2006
@@ -17,14 +17,13 @@
  */
 package org.apache.beehive.netui.script.el.tokens;
 
-import org.apache.beehive.netui.util.internal.InternalStringBuilder;
-
 import java.util.Map;
 
+import org.apache.beehive.netui.util.internal.InternalStringBuilder;
 import org.apache.beehive.netui.util.logging.Logger;
 
 /**
- *
+ * Token that represents a Map lookup token.
  */
 public class MapKeyToken
     extends ExpressionToken {
@@ -32,17 +31,17 @@
     private static final Logger LOGGER = Logger.getInstance(MapKeyToken.class);
 
     private String _identifier = null;
-    private boolean _dblQuote = false;
+    private char _quoteChar = '\'';
 
     public MapKeyToken(String identifier) {
-        this._identifier = identifier;
-
+        assert identifier != null;
+        assert identifier.length() >= 2;
+        
         if(identifier.startsWith("\""))
-            _dblQuote = true;
-
+            _quoteChar = '"';
         // convert the Java string to an EcmaScript string.  Strip the quotes that exist because they're
         // always there for this token.
-        this._identifier = convertToEcmaScriptString(this._identifier.substring(1, identifier.length() - 1));
+        _identifier = convertToEcmaScriptString(identifier.substring(1, identifier.length() - 1));
     }
 
     /**
@@ -54,9 +53,9 @@
         InternalStringBuilder buf = new InternalStringBuilder(len);
         for(int i = 0; i < len; i++) {
             char c = string.charAt(i);
-            // skip the \\ and consume the next character either appending it or turning it back into the single character
-            // that it should have been in the first place.
-            // 
+            // skip the \\ and consume the next character either appending it or turning it back
+            // into the single character that it should have been in the first place.
+            
             // if slash and not at the last character...
             if(c == '\\' && i + 1 < len) {
                 i++;
@@ -74,37 +73,42 @@
                 else if(c == 'f')
                     c = '\f';
                 else if(c == 'r') c = '\r';
-                // @TODO: unicode escaping...
+                // @todo: unicode escaping?
             }
 
             buf.append(c);
         }
 
-        if(LOGGER.isTraceEnabled())
-            LOGGER.trace("converted String to JavaScript compliant string: " + buf.toString());
+        LOGGER.trace("converted String to JavaScript compliant string: " + buf.toString());
 
         return buf.toString();
     }
 
-    public void update(Object root, Object newValue) {
-        if(root instanceof Map)
-            mapUpdate((Map)root, _identifier, newValue);
-        else
-            beanUpdate(root, _identifier, newValue);
+    /**
+     * Read the value represented by this token from the given <code>object</code>.
+     * @param object the object
+     * @return the value of this property on object
+     */
+    public Object read(Object object) {
+        if(object instanceof Map)
+            return mapLookup((Map)object, _identifier);
+        else return beanLookup(object, _identifier);
     }
 
-    public Object evaluate(Object value) {
-        if(value instanceof Map)
-            return mapLookup((Map)value, _identifier);
-        else
-            return beanLookup(value, _identifier);
+    /**
+     * Update a the value represented by this token on the given <code>object</code> with the
+     * new value.
+     * @param object the object
+     * @param value the new value of this property on the object
+     */
+    public void write(Object object, Object value) {
+        if(object instanceof Map)
+            mapUpdate((Map)object, _identifier, value);
+        else beanUpdate(object, _identifier, value);
     }
 
     public String getTokenString() {
-        if(_dblQuote)
-            return "[\"" + _identifier + "\"]";
-        else
-            return "['" + _identifier + "']";
+        return _quoteChar + _identifier + _quoteChar;
     }
 
     public String toString() {