Java tutorial
/******************************************************************************* * * Copyright 2010 Alexandru Craciun, and individual contributors as indicated * by the @authors tag. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. ******************************************************************************/ /* Generated By:JJTree: Do not edit this line. ASTNumericExpression.java Version 4.3 */ /* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ package org.netxilia.spi.impl.formula.parser; import org.joda.time.DateTimeConstants; import org.joda.time.Duration; import org.joda.time.LocalDateTime; import org.joda.time.Period; import org.joda.time.ReadablePeriod; import org.netxilia.api.formula.IFormulaContext; import org.netxilia.api.utils.DateUtils; import org.netxilia.api.value.DateValue; import org.netxilia.api.value.ErrorValue; import org.netxilia.api.value.ErrorValueType; import org.netxilia.api.value.GenericValueType; import org.netxilia.api.value.IGenericValue; import org.netxilia.api.value.NumberValue; /** * An AST node representing a binary numeric expression. */ public class ASTNumericExpression extends ASTBinaryExpression { public ASTNumericExpression(int id) { super(id, "Numeric"); } public ASTNumericExpression(FormulaParser p, int id) { super(p, id, "Numeric"); } private ReadablePeriod period(double value) { int days = (int) value; int millis = (int) (value - days); return Period.days(days).plusMillis(millis); } private IGenericValue dateOperations(IGenericValue gvLeft, IGenericValue gvRight) { // D + P, P + D, D - D, D - P if (gvLeft.getValueType() == GenericValueType.DATE) { if ("+".equals(operator)) { // D + P LocalDateTime result = DateUtils .toLocalDateTime(gvLeft.getDateValue(), DateValue.ORIGIN.toLocalDateTime()) .plus(period(gvRight.getNumberValue().doubleValue())); return new DateValue(result); } if ("-".equals(operator)) { if (gvRight.getValueType() == GenericValueType.DATE) { // D - D Double result = (double) (new Duration(gvRight.getDateValue().toDateTime(DateValue.ORIGIN), gvLeft.getDateValue().toDateTime(DateValue.ORIGIN)).getMillis()) / DateTimeConstants.MILLIS_PER_DAY; return new NumberValue(result); } else { // D - P LocalDateTime result = DateUtils .toLocalDateTime(gvLeft.getDateValue(), DateValue.ORIGIN.toLocalDateTime()) .minus(period(gvRight.getNumberValue().doubleValue())); return new DateValue(result); } } // other operations are not allowed - fall through number operations } else if (gvRight.getValueType() == GenericValueType.DATE) { if ("+".equals(operator)) { // P + D LocalDateTime result = DateUtils .toLocalDateTime(gvRight.getDateValue(), DateValue.ORIGIN.toLocalDateTime()) .plus(period(gvLeft.getNumberValue().doubleValue())); return new DateValue(result); } } return null; } @Override public IGenericValue eval(IFormulaContext context) { ASTBaseNode nLeft = (ASTBaseNode) jjtGetChild(0); ASTBaseNode nRight = (ASTBaseNode) jjtGetChild(1); IGenericValue gvLeft = nLeft.eval(context); IGenericValue gvRight = nRight.eval(context); if (gvLeft.getValueType() == GenericValueType.ERROR) { return gvLeft; } if (gvRight.getValueType() == GenericValueType.ERROR) { return gvRight; } // date operations if (gvLeft.getValueType() == GenericValueType.DATE || gvRight.getValueType() == GenericValueType.DATE) { IGenericValue result = dateOperations(gvLeft, gvRight); if (result != null) { return result; } } // number operations Double vLeft = gvLeft.getNumberValue(); Double vRight = gvRight.getNumberValue(); if ((vLeft == null) || (vRight == null)) { return new ErrorValue(ErrorValueType.VALUE); } double result, left = vLeft.doubleValue(), right = vRight.doubleValue(); if ("+".equals(operator)) { result = left + right; } else if ("-".equals(operator)) { result = left - right; } else if ("*".equals(operator)) { result = left * right; } else if ("/".equals(operator)) { if (Math.abs(right) < NumberValue.APPROXIMATE_ZERO) { return new ErrorValue(ErrorValueType.DIV_ZERO); } result = left / right; } else if ("^".equals(operator)) { result = Math.pow(left, right); } else { throw new IllegalStateException("BUG: Unknown operator " + operator); } return new NumberValue(Double.valueOf(result)); } } /* JavaCC - OriginalChecksum=7b1c18675f52787340e0cdf8aef060cc (do not edit this line) */