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() {