001: package com.calipso.reportgenerator.reportcalculator.arithmetic;
002:
003: import java.util.Map;
004: import java.util.Collection;
005: import java.io.Serializable;
006:
007: /**
008: * Resuelve expressiones aritmeticas
009: */
010:
011: public abstract class ArithmeticExpression implements Serializable {
012:
013: /**
014: * Retorna el resultado para la expresion que recibe
015: * por parametro.
016: * @param expression
017: * @return
018: */
019: public static ArithmeticExpression newFrom(String expression) {
020: String exp = prepareExpression(expression);
021: Object[] tokens = getTokens(exp);
022: if (tokens.length == 1) {
023: return ValueArithmeticExp
024: .newValueExpFrom(prepareExpression(tokens[0]
025: .toString()));
026: } else {
027: ArithmeticExpression subExp1 = ArithmeticExpression
028: .newFrom(tokens[0].toString());
029: ArithmeticExpression subExp2 = ArithmeticExpression
030: .newFrom(tokens[2].toString());
031: return OperationArithmeticExp.newOperationFrom(subExp1,
032: tokens[1].toString(), subExp2);
033: }
034: }
035:
036: /**
037: * Prepara una expression previamente a ser resuelta.
038: * @param expression
039: * @return
040: */
041: private static String prepareExpression(String expression) {
042: String exp = expression.trim();
043: if (exp.charAt(0) == '(' && exp.charAt(exp.length() - 1) == ')') {
044: if (!(exp.indexOf(")") < exp.indexOf("(", 1))) {
045: return exp.substring(1, exp.length() - 1);
046: }
047: }
048: return exp;
049: }
050:
051: /**
052: * Devuelve el indice del operador primario de la expresion
053: * @param expression
054: * @return
055: */
056: private static int indexOfOperator(String expression) {
057: int index = -1;
058: int alternateIndex = -1;
059: int parenthesis = 0;
060: for (int i = 0; i < expression.length(); i++) {
061: char current = expression.charAt(i);
062: if (current == '(') {
063: parenthesis++;
064: } else {
065: if (current == ')') {
066: parenthesis--;
067: } else {
068: if ((parenthesis == 0)) {
069: if (current == '+' || current == '-') {
070: index = i;
071: break;
072: } else {
073: if (current == '*' || current == '/') {
074: alternateIndex = i;
075: }
076: }
077: }
078: }
079: }
080: }
081: if (index == -1) {
082: index = alternateIndex;
083: }
084: return index;
085: }
086:
087: /**
088: * En base al indice del operador primario parte en dos
089: * la expresion, ubica cada porcion en un array de 3 posiciones
090: * siendo la posicion del medio la que contiene el operador
091: * primario y retorna dicho array.
092: * @param expression
093: * @return
094: */
095: private static Object[] getTokens(String expression) {
096: int index = indexOfOperator(expression);
097: if (index == -1) {
098: return new Object[] { expression };
099: } else {
100: Object[] array = new Object[3];
101: array[0] = expression.substring(0, index);
102: array[1] = expression.substring(index, index + 1);
103: array[2] = expression.substring(index + 1);
104: return array;
105: }
106: }
107:
108: public abstract float value(Map context);
109:
110: public void getVariables(Collection variables) {
111: //Do nothing
112: }
113: }
|