/* * 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. */ package org.apache.cocoon.forms.formmodel.algorithms; import org.apache.avalon.framework.CascadingError; import org.apache.cocoon.forms.datatype.Datatype; import org.apache.cocoon.forms.formmodel.CannotYetResolveWarning; import org.apache.cocoon.forms.formmodel.ExpressionContextImpl; import org.apache.cocoon.forms.formmodel.Form; import org.apache.cocoon.forms.formmodel.Widget; import org.outerj.expression.Expression; import org.outerj.expression.ExpressionContext; import org.outerj.expression.ExpressionException; /** * An xreported expression based algorithm. * <p> * This algorithm can be used to write simple formulas, examples are : * <ul> * <li>20% VAT calculation : eval="(amount / 100) * 20"</li> * <li>100$ volume discount : eval="If(amount > 1000,100,0)" * (read: if amount is greater than 1000 then the result will be 100, otherwise 0)</li> * <li>Number of boxes needed to carry that number of items : eval="Ceiling(items / boxsize)"</li> * <li>Number of items you can add before another box is needed : eval="Reminder(items,boxside)"</li> * </ul> * </p> * <p> * Note: please take care that xreporter expressions are not that accurate when it comes to decimals. The default * divide operator rounds the result, see http://issues.cocoondev.org/browse/XRP-115. Also consider that the * available set of functions can be expanded implementing and using new ones. Please see * <a href="http://outerthought.net/wqm/xreporter/en/expressions.html"> * http://outerthought.net/wqm/xreporter/en/expressions.html</a> for an overview of xreportes expressions and * {@link org.apache.cocoon.forms.expression.IsNullFunction} or * {@link org.apache.cocoon.forms.expression.StringFunction} * for examples of custom xreporter functions. * </p> * @version $Id$ */ public class SimpleFormula extends AbstractBaseAlgorithm { protected Expression formula; public boolean isSuitableFor(Datatype dataType) { return dataType.getTypeClass().isAssignableFrom(formula.getResultType()); } public Object calculate(Form form, Widget parent, Datatype datatype) { ExpressionContext ctx = new ExpressionContextImpl(parent, true); try { return formula.evaluate(ctx); } catch (CannotYetResolveWarning w) { return null; } catch (ExpressionException e) { throw new CascadingError("Error evaluating calculated field formula", e); } } /** * @return Returns the formula. */ public Expression getFormula() { return formula; } /** * @param formula The formula to set. */ public void setFormula(Expression formula) { this.formula = formula; } }