/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Header:$ */ package org.apache.beehive.netui.tags; import org.apache.beehive.netui.script.ExpressionEvaluationException; import org.apache.beehive.netui.script.ExpressionEvaluator; import org.apache.beehive.netui.script.ExpressionEvaluatorFactory; import org.apache.beehive.netui.script.ExpressionUpdateException; import org.apache.beehive.netui.script.common.ImplicitObjectUtil; import org.apache.beehive.netui.util.Bundle; import org.apache.beehive.netui.util.logging.Logger; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.el.VariableResolver; public class ExpressionHandling { private static final Logger logger = Logger.getInstance(ExpressionHandling.class); private ExpressionEvaluator ee = null; // cache the expression evaluator private INetuiTag _tag; public ExpressionHandling(INetuiTag tag) { _tag = tag; } /** * An internal method that is used for evaluating the dataSource * attribute. The dataSource attribute is handled specially * becuase it must be of a particular format in order to be usable by * NetUI tags. This requirement exists in order to facilitate * round-tripping the dataSource attribute as the * name attribute of HTML tags. Upon a POST, the name * attribute is used as an l-value for an update expression in order * to push any POST-ed data back into the bean from whence it came. */ /** * Ensure that the passed in data source is a valid expression. * @param dataSource * @param attrName * @param errorId * @return String * @throws javax.servlet.jsp.JspException */ public String ensureValidExpression(String dataSource, String attrName, String errorId) throws JspException { try { boolean isExpr = isExpression(dataSource); // @perf: if the isExpr call fails, this is an error condition, and the containsExpression // call cost is irrelevant if (!isExpr && containsExpression(dataSource)) { String s = Bundle.getString(errorId, new Object[]{dataSource}); _tag.registerTagError(s, null); return null; } if (!isExpr) { String s = Bundle.getString(errorId, new Object[]{dataSource}); _tag.registerTagError(s, null); return null; } } catch (Exception e) { // pass throw JspExceptions if (e instanceof JspException) throw (JspException) e; String s = Bundle.getString(errorId, new Object[]{dataSource}); _tag.registerTagError(s, e); return null; } return dataSource; } /** * @param expression * @param attrName * @return Object * @throws JspException */ public Object evaluateExpression(String expression, String attrName, PageContext ctxt) throws JspException { return evaluateExpressionInternal(expression, attrName, ctxt); } /** * This method will update the object identified by the expr parameter with * the value. If the * @param expr * @param value * @throws org.apache.beehive.netui.script.ExpressionUpdateException * */ public void updateExpression(String expr, Object value, PageContext pageContext) throws ExpressionUpdateException, JspException { if (isExpression(expr)) { VariableResolver vr = ImplicitObjectUtil.getUpdateVariableResolver(pageContext.getRequest(), pageContext.getResponse(), false); ExpressionEvaluatorFactory.getInstance().update(expr, value, vr, false); } else { String s = Bundle.getString("Tags_BindingUpdateExpressionError", new Object[]{expr}); _tag.registerTagError(s, null); } } /** * Return a boolean indicating if the string contains an expression or not. * @param expression a String that may or may not contain an expresion. * @return true if the string contains an expression. */ private boolean containsExpression(String expression) { // this shouldn't happen because we have checked in isExpression that the expression isn't null assert (expression != null) : "The parameter expression must not be null."; return getExpressionEvaluator().containsExpression(expression); } /** */ private boolean isExpression(String expression) { if (expression == null) return false; return getExpressionEvaluator().isExpression(expression); } /** * This is the real implementation of evaluateExpression. * @param expression * @param attrName * @return * @throws JspException */ private Object evaluateExpressionInternal(String expression, String attrName, PageContext pageContext) throws JspException { if (logger.isDebugEnabled()) logger.debug("evaluate expression=\"" + expression + "\""); Object result = null; try { VariableResolver vr = ImplicitObjectUtil.getReadVariableResolver(pageContext); result = getExpressionEvaluator().evaluateStrict(expression, vr); } catch (ExpressionEvaluationException ee) { // if there is an expression evaluation error set the error and return null if (logger.isWarnEnabled()) logger.warn(Bundle.getString("Tags_ExpressionEvaluationFailure", expression)); // create the expression info an add it to the error tracking EvalErrorInfo info = new EvalErrorInfo(); info.evalExcp = ee; info.expression = expression; info.attr = attrName; info.tagType = _tag.getTagName(); // report the error _tag.registerTagError(info); return null; } catch (Exception e) { String s = Bundle.getString("Tags_ExpressionEvaluationException", new Object[]{expression, e.toString()}); _tag.registerTagError(s, e); return null; } if (logger.isDebugEnabled()) logger.debug("resulting object: " + result); return result; } /** * Return a cached instance of an ExpressionEvaluator. This will be cached by the * tag and release during localRelease. * @return the ExpressionEvalutor for tis tag. */ private ExpressionEvaluator getExpressionEvaluator() { if (ee == null) ee = ExpressionEvaluatorFactory.getInstance(); assert(ee != null); return ee; } }