package com.esri.geoevent.processor.cacheawarefieldcalculator.expression; import java.util.List; import java.util.Stack; import com.esri.ges.core.geoevent.GeoEvent; /** * {@link Token} for Operations like +,-,*,/,% and ^ * */ public class OperatorToken extends CalculationToken { private Operator operator; /** * construct a new {@link OperatorToken} * * @param value * the symbol (e.g.: '+') * @param operator * the {@link Operator} of this {@link Token} */ OperatorToken(String value, Operator operator) { super(value); this.operator = operator; } /** * apply the {@link Operator} * * @param values * the Objects to operate on * @return the result of the {@link Operator} */ Object applyOperation(Object... values) { return operator.applyOperation(values); } @Override public boolean equals(Object obj) { if (obj instanceof OperatorToken) { final OperatorToken t = (OperatorToken) obj; return t.getValue().equals(this.getValue()); } return false; } @Override public int hashCode() { return getValue().hashCode(); } @Override void mutateStackForCalculation(Stack<Object> stack, GeoEvent geoEvent) { final Object[] operands = new Object[operator.operandCount]; for (int i=0; i < operator.operandCount; i++) operands[operator.operandCount-i-1] = stack.pop(); stack.push(operator.applyOperation(operands)); } @Override void mutateStackForInfixTranslation(Stack<Token> operatorStack, List<Token> tokens) { Token before; while (!operatorStack.isEmpty() && (before = operatorStack.peek()) != null && (before instanceof OperatorToken || before instanceof FunctionToken)) { if (before instanceof FunctionToken) { operatorStack.pop(); tokens.add(before); } else { final OperatorToken stackOperator = (OperatorToken) before; if ((this.isLeftAssociative() && this.getPrecedence() <= stackOperator.getPrecedence()) || (!this.isLeftAssociative() && this.getPrecedence() < stackOperator.getPrecedence())) tokens.add(operatorStack.pop()); else break; } } operatorStack.push(this); } private boolean isLeftAssociative() { return operator.leftAssociative; } private int getPrecedence() { return operator.precedence; } }