package com.esri.geoevent.processor.cacheawarefieldcalculator.expression; public abstract class Operator { final boolean leftAssociative; final String symbol; final int precedence; final int operandCount; /** * Create a new {@link Operator} for two operands * * @param symbol * the symbol to be used in expressions to identify this operation * @param leftAssociative * true is the operation is left associative * @param precedence * the precedence of the operation */ protected Operator(final String symbol, final boolean leftAssociative, final int precedence) { super(); this.leftAssociative = leftAssociative; this.symbol = symbol; this.precedence = precedence; this.operandCount = 2; } /** * Create a new {@link Operator} * * @param symbol * the symbol to be used in expressions to identify this operation * @param leftAssociative * true is the operation is left associative * @param precedence * the precedence of the operation * @param operandCount * the number of operands of the operation. A value of 1 means the * operation takes one operand. Any other value means the operation * takes 2 arguments. */ protected Operator(final String symbol, final boolean leftAssociative, final int precedence, final int operandCount) { super(); this.leftAssociative = leftAssociative; this.symbol = symbol; this.precedence = precedence; this.operandCount = operandCount == 1 ? 1 : 2; } /** * Create a left associative {@link Operator} with precedence value of 1 * that uses two operands * * @param symbol * the {@link String} to use a symbol for this operation */ protected Operator(final String symbol) { super(); this.leftAssociative = true; this.symbol = symbol; this.precedence = 1; this.operandCount = 2; } /** * Create a left associative {@link Operator} for two operands * * @param symbol * the {@link String} to use a symbol for this operation * @param precedence * the precedence of the operation */ protected Operator(final String symbol, final int precedence) { super(); this.leftAssociative = true; this.symbol = symbol; this.precedence = precedence; this.operandCount = 2; } /** * Apply the custom operation on the two operands and return the result as an * Object An example implementation for a multiplication could look like this: * * <pre> * <code>{@code} * Object applyOperation(Object[] values) { * return values[0]*values[1]; * } * </pre> * * </code> * * @param values * the operands for the operation. If the {@link Operator} uses * only one operand such as a factorial the operation has to be * applied to the first element of the values array. If the * {@link Operator} uses two operands the operation has to be * applied to the first two items in the values array, with special * care given to the operator associativity. The operand to the left * of the symbol is the first element in the array while the operand * to the right is the second element of the array. * @return the result of the operation */ protected abstract Object applyOperation(Object[] values); }