package com.esri.geoevent.processor.cacheawarefieldcalculator.expression;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.esri.ges.core.geoevent.Field;
import com.esri.ges.core.geoevent.FieldDefinition;
import com.esri.ges.core.geoevent.FieldExpression;
import com.esri.ges.core.geoevent.GeoEvent;
import com.esri.ges.core.geoevent.GeoEventCache;
import com.esri.ges.core.geoevent.GeoEventPropertyName;
import com.esri.ges.util.Converter;
/**
* This is Expression Builder implementation used to create a Calculable
* instance for the user
*/
public class ExpressionBuilder
{
/**
* Property name for unary precedence choice. You can set
* System.getProperty(PROPERTY_UNARY_HIGH_PRECEDENCE,"false") in order to
* change evaluation from an expression like "-3^2" from "(-3)^2" to "-(3^2)"
*/
public static final String PROPERTY_UNARY_HIGH_PRECEDENCE = "unary.precedence.high";
// private final Map<String, Object> variables = new LinkedHashMap<String, Object>();
private final Map<String, Function> functions;
private final Map<String, Operator> builtInOperators;
private Map<String, Operator> customOperators = new HashMap<String, Operator>();
private final List<Character> validOperatorSymbols;
private final boolean highUnaryPrecedence;
private String expression;
private GeoEvent geoEvent;
private GeoEventCache geoEventCache;
/**
* Create a new ExpressionBuilder
*
* @param expression
* the expression to evaluate
*/
public ExpressionBuilder(GeoEvent geoEvent, GeoEventCache geoEventCache, String expression)
{
this.geoEvent = geoEvent;
this.geoEventCache = geoEventCache;
highUnaryPrecedence = System.getProperty(PROPERTY_UNARY_HIGH_PRECEDENCE) == null || !System.getProperty(PROPERTY_UNARY_HIGH_PRECEDENCE).equals("false");
functions = getBuiltinFunctions();
builtInOperators = getBuiltinOperators();
validOperatorSymbols = getValidOperators();
this.expression = substituteUnaryOperators(expression, builtInOperators);
}
private List<Character> getValidOperators()
{
return Arrays.asList('!', '#', '$', '&', ';', ':', '~', '<', '>', '|', '=');
}
private Map<String, Operator> getBuiltinOperators()
{
Operator add = new Operator("+")
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
{
if (values[0] instanceof Byte)
{
byte value_0 = ((Number)values[0]).byteValue();
if (values[1] instanceof Byte)
return value_0 + ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 + ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 + ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 + ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 + ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 + ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Short)
{
short value_0 = ((Number)values[0]).shortValue();
if (values[1] instanceof Byte)
return value_0 + ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 + ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 + ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 + ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 + ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 + ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Integer)
{
int value_0 = ((Number)values[0]).intValue();
if (values[1] instanceof Byte)
return value_0 + ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 + ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 + ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 + ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 + ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 + ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Long)
{
long value_0 = ((Number)values[0]).longValue();
if (values[1] instanceof Byte)
return value_0 + ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 + ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 + ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 + ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 + ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 + ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Float)
{
float value_0 = ((Number)values[0]).floatValue();
if (values[1] instanceof Byte)
return value_0 + ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 + ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 + ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 + ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 + ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 + ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Double)
{
double value_0 = ((Number)values[0]).doubleValue();
if (values[1] instanceof Byte)
return value_0 + ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 + ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 + ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 + ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 + ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 + ((Number)values[1]).doubleValue();
}
}
else if (values[0] instanceof Date)
{
values[0] = ((Date)values[0]).getTime();
return applyOperation(values);
}
else if (values[1] instanceof Date)
{
values[1] = ((Date)values[1]).getTime();
return applyOperation(values);
}
return values[0].toString() + values[1].toString();
}
};
Operator sub = new Operator("-")
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
{
if (values[0] instanceof Byte)
{
byte value_0 = ((Number)values[0]).byteValue();
if (values[1] instanceof Byte)
return value_0 - ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 - ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 - ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 - ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 - ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 - ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Short)
{
short value_0 = ((Number)values[0]).shortValue();
if (values[1] instanceof Byte)
return value_0 - ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 - ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 - ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 - ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 - ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 - ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Integer)
{
int value_0 = ((Number)values[0]).intValue();
if (values[1] instanceof Byte)
return value_0 - ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 - ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 - ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 - ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 - ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 - ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Long)
{
long value_0 = ((Number)values[0]).longValue();
if (values[1] instanceof Byte)
return value_0 - ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 - ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 - ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 - ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 - ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 - ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Float)
{
float value_0 = ((Number)values[0]).floatValue();
if (values[1] instanceof Byte)
return value_0 - ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 - ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 - ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 - ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 - ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 - ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Double)
{
double value_0 = ((Number)values[0]).doubleValue();
if (values[1] instanceof Byte)
return value_0 - ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 - ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 - ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 - ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 - ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 - ((Number)values[1]).doubleValue();
}
}
else if (values[0] instanceof Date)
{
values[0] = ((Date)values[0]).getTime();
return applyOperation(values);
}
else if (values[1] instanceof Date)
{
values[1] = ((Date)values[1]).getTime();
return applyOperation(values);
}
return null;
}
};
Operator mul = new Operator("*", 3)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
{
if (values[0] instanceof Byte)
{
byte value_0 = ((Number)values[0]).byteValue();
if (values[1] instanceof Byte)
return value_0 * ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 * ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 * ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 * ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 * ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 * ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Short)
{
short value_0 = ((Number)values[0]).shortValue();
if (values[1] instanceof Byte)
return value_0 * ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 * ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 * ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 * ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 * ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 * ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Integer)
{
int value_0 = ((Number)values[0]).intValue();
if (values[1] instanceof Byte)
return value_0 * ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 * ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 * ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 * ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 * ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 * ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Long)
{
long value_0 = ((Number)values[0]).longValue();
if (values[1] instanceof Byte)
return value_0 * ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 * ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 * ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 * ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 * ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 * ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Float)
{
float value_0 = ((Number)values[0]).floatValue();
if (values[1] instanceof Byte)
return value_0 * ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 * ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 * ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 * ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 * ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 * ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Double)
{
double value_0 = ((Number)values[0]).doubleValue();
if (values[1] instanceof Byte)
return value_0 * ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 * ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 * ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 * ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 * ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 * ((Number)values[1]).doubleValue();
}
}
else if (values[0] instanceof Date)
{
values[0] = ((Date)values[0]).getTime();
return applyOperation(values);
}
else if (values[1] instanceof Date)
{
values[1] = ((Date)values[1]).getTime();
return applyOperation(values);
}
return null;
}
};
Operator div = new Operator("/", 3)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number && ((Number)values[1]).doubleValue() != 0)
{
if (values[0] instanceof Byte)
{
byte value_0 = ((Number)values[0]).byteValue();
if (values[1] instanceof Byte)
return value_0 / ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 / ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 / ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 / ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 / ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 / ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Short)
{
short value_0 = ((Number)values[0]).shortValue();
if (values[1] instanceof Byte)
return value_0 / ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 / ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 / ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 / ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 / ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 / ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Integer)
{
int value_0 = ((Number)values[0]).intValue();
if (values[1] instanceof Byte)
return value_0 / ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 / ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 / ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 / ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 / ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 / ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Long)
{
long value_0 = ((Number)values[0]).longValue();
if (values[1] instanceof Byte)
return value_0 / ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 / ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 / ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 / ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 / ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 / ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Float)
{
float value_0 = ((Number)values[0]).floatValue();
if (values[1] instanceof Byte)
return value_0 / ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 / ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 / ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 / ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 / ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 / ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Double)
{
double value_0 = ((Number)values[0]).doubleValue();
if (values[1] instanceof Byte)
return value_0 / ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 / ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 / ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 / ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 / ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 / ((Number)values[1]).doubleValue();
}
}
else if (values[0] instanceof Date)
{
values[0] = ((Date)values[0]).getTime();
return applyOperation(values);
}
else if (values[1] instanceof Date)
{
values[1] = ((Date)values[1]).getTime();
return applyOperation(values);
}
return null;
}
};
Operator mod = new Operator("%", true, 3)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number && ((Number)values[1]).doubleValue() != 0)
{
if (values[0] instanceof Byte)
{
byte value_0 = ((Number)values[0]).byteValue();
if (values[1] instanceof Byte)
return value_0 % ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 % ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 % ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 % ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 % ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 % ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Short)
{
short value_0 = ((Number)values[0]).shortValue();
if (values[1] instanceof Byte)
return value_0 % ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 % ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 % ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 % ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 % ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 % ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Integer)
{
int value_0 = ((Number)values[0]).intValue();
if (values[1] instanceof Byte)
return value_0 % ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 % ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 % ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 % ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 % ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 % ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Long)
{
long value_0 = ((Number)values[0]).longValue();
if (values[1] instanceof Byte)
return value_0 % ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 % ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 % ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 % ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 % ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 % ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Float)
{
float value_0 = ((Number)values[0]).floatValue();
if (values[1] instanceof Byte)
return value_0 % ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 % ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 % ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 % ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 % ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 % ((Number)values[1]).doubleValue();
}
else if (values[0] instanceof Double)
{
double value_0 = ((Number)values[0]).doubleValue();
if (values[1] instanceof Byte)
return value_0 % ((Number)values[1]).byteValue();
else if (values[1] instanceof Short)
return value_0 % ((Number)values[1]).shortValue();
else if (values[1] instanceof Integer)
return value_0 % ((Number)values[1]).intValue();
else if (values[1] instanceof Long)
return value_0 % ((Number)values[1]).longValue();
else if (values[1] instanceof Float)
return value_0 % ((Number)values[1]).floatValue();
else if (values[1] instanceof Double)
return value_0 % ((Number)values[1]).doubleValue();
}
}
else if (values[0] instanceof Date)
{
values[0] = ((Date)values[0]).getTime();
return applyOperation(values);
}
else if (values[1] instanceof Date)
{
values[1] = ((Date)values[1]).getTime();
return applyOperation(values);
}
return null;
}
};
Operator umin = new Operator("\"", false, this.highUnaryPrecedence ? 8 : 5, 1)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number)
{
if (values[0] instanceof Double)
return -((Number)values[0]).doubleValue();
else if (values[0] instanceof Float)
return -((Number)values[0]).floatValue();
else if (values[0] instanceof Long)
return -((Number)values[0]).longValue();
else if (values[0] instanceof Integer)
return -((Number)values[0]).intValue();
else if (values[0] instanceof Short)
return -((Number)values[0]).shortValue();
else if (values[0] instanceof Byte)
return -((Number)values[0]).byteValue();
}
return values[0];
}
};
Operator pow = new Operator("^", false, 5, 2)
{
@Override
protected Object applyOperation(Object[] values)
{
return (values != null && values.length == 2 && values[0] instanceof Number && values[1] instanceof Number) ? Math.pow(((Number)values[0]).doubleValue(), ((Number)values[1]).doubleValue()) : null;
}
};
Operator logicalAND = new Operator("&&", 11)
{
@Override
protected Object applyOperation(Object[] values)
{
return (values[0] instanceof Boolean && values[1] instanceof Boolean) ? (Boolean) values[0] && (Boolean) values[1] : false;
}
};
Operator logicalOR = new Operator("||", 12)
{
@Override
protected Object applyOperation(Object[] values)
{
return (values[0] instanceof Boolean && values[1] instanceof Boolean) ? (Boolean) values[0] || (Boolean) values[1] : false;
}
};
Operator logicalNOT = new Operator("!", true, 2, 1)
{
@Override
protected Object applyOperation(Object[] values)
{
return (values[0] instanceof Boolean) ? !((Boolean)values[0]) : false;
}
};
Operator gt = new Operator(">", false, 6)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
return ((Number)values[0]).doubleValue() > ((Number)values[1]).doubleValue();
else if (values[0] instanceof Date && values[1] instanceof Date)
return ((Date)values[0]).compareTo((Date)values[1]) > 0;
else if (values[0] instanceof String && values[1] instanceof String)
return ((String)values[0]).compareTo((String)values[1]) > 0;
else
return false;
}
};
Operator gte = new Operator(">=", false, 6)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
return ((Number)values[0]).doubleValue() >= ((Number)values[1]).doubleValue();
else if (values[0] instanceof Date && values[1] instanceof Date)
return ((Date)values[0]).compareTo((Date)values[1]) >= 0;
else if (values[0] instanceof String && values[1] instanceof String)
return ((String)values[0]).compareTo((String)values[1]) >= 0;
else
return false;
}
};
Operator eq = new Operator("==", false, 7)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
return ((Number)values[0]).doubleValue() == ((Number)values[1]).doubleValue();
else if (values[0] instanceof Date && values[1] instanceof Date)
return ((Date)values[0]).compareTo((Date)values[1]) == 0;
else if (values[0] instanceof Boolean && values[1] instanceof Boolean)
return ((Boolean)values[0]).compareTo((Boolean)values[1]) == 0;
else if (values[0] instanceof String && values[1] instanceof String)
return ((String)values[0]).compareTo((String)values[1]) == 0;
else
return false;
}
};
Operator ne = new Operator("!=", false, 7)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
return ((Number)values[0]).doubleValue() != ((Number)values[1]).doubleValue();
else if (values[0] instanceof Date && values[1] instanceof Date)
return ((Date)values[0]).compareTo((Date)values[1]) != 0;
else if (values[0] instanceof Boolean && values[1] instanceof Boolean)
return ((Boolean)values[0]).compareTo((Boolean)values[1]) != 0;
else if (values[0] instanceof String && values[1] instanceof String)
return ((String)values[0]).compareTo((String)values[1]) != 0;
else
return false;
}
};
Operator lt = new Operator("<", false, 6)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
return ((Number)values[0]).doubleValue() < ((Number)values[1]).doubleValue();
else if (values[0] instanceof Date && values[1] instanceof Date)
return ((Date)values[0]).compareTo((Date)values[1]) < 0;
else if (values[0] instanceof String && values[1] instanceof String)
return ((String)values[0]).compareTo((String)values[1]) < 0;
else
return false;
}
};
Operator lte = new Operator("<=", false, 6)
{
@Override
protected Object applyOperation(Object[] values)
{
if (values[0] instanceof Number && values[1] instanceof Number)
return ((Number)values[0]).doubleValue() <= ((Number)values[1]).doubleValue();
else if (values[0] instanceof Date && values[1] instanceof Date)
return ((Date)values[0]).compareTo((Date)values[1]) <= 0;
else if (values[0] instanceof String && values[1] instanceof String)
return ((String)values[0]).compareTo((String)values[1]) <= 0;
else
return false;
}
};
Map<String, Operator> operations = new HashMap<String, Operator>();
operations.put("+", add);
operations.put("-", sub);
operations.put("*", mul);
operations.put("/", div);
operations.put("%", mod);
operations.put("\"", umin);
operations.put("^", pow);
operations.put("&&", logicalAND);
operations.put("||", logicalOR);
operations.put("!", logicalNOT);
operations.put(">", gt);
operations.put(">=", gte);
operations.put("==", eq);
operations.put("!=", ne);
operations.put("<", lt);
operations.put("<=", lte);
return operations;
}
private Map<String, Function> getBuiltinFunctions()
{
try
{
Map<String, Function> functions = new HashMap<String, Function>();
// Math functions
functions.put("E", new Function("E", 0)
{
@Override
public Object applyFunction(Object... args)
{
return Math.E;
}
});
functions.put("PI", new Function("PI", 0)
{
@Override
public Object applyFunction(Object... args)
{
return Math.PI;
}
});
functions.put("abs", new Function("abs")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1 && args[0] instanceof Number)
if (args[0] instanceof Integer || args[0] instanceof Byte || args[0] instanceof Short)
return Math.abs(((Number)args[0]).intValue());
else if (args[0] instanceof Long)
return Math.abs(((Number)args[0]).longValue());
else if (args[0] instanceof Float)
return Math.abs(((Number)args[0]).floatValue());
else if (args[0] instanceof Double)
return Math.abs(((Number)args[0]).doubleValue());
return null;
}
});
functions.put("acos", new Function("acos")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.acos(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("asin", new Function("asin")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.asin(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("atan", new Function("atan")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.atan(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("atan2", new Function("atan2", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number) ? Math.atan2(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue()) : null;
}
});
functions.put("cbrt", new Function("cbrt")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.cbrt(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("ceil", new Function("ceil")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.ceil(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("copySign", new Function("copySign", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number)
if (args[0] instanceof Double || args[1] instanceof Double)
return Math.copySign(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue());
else
return Math.copySign(((Number)args[0]).floatValue(), ((Number)args[1]).floatValue());
return null;
}
});
functions.put("cos", new Function("cos")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.cos(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("cosh", new Function("cosh")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.cosh(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("exp", new Function("exp")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.exp(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("expm1", new Function("expm1")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.expm1(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("floor", new Function("floor")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.floor(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("getExponent", new Function("getExponent")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1 && args[0] instanceof Number)
if (args[0] instanceof Float || args[0] instanceof Integer || args[0] instanceof Byte || args[0] instanceof Short)
return Math.getExponent(((Number)args[0]).floatValue());
else if (args[0] instanceof Double || args[0] instanceof Long)
return Math.getExponent(((Number)args[0]).doubleValue());
return null;
}
});
functions.put("hypot", new Function("hypot", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number) ? Math.hypot(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue()) : null;
}
});
functions.put("IEEEremainder", new Function("IEEEremainder", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number) ? Math.IEEEremainder(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue()) : null;
}
});
functions.put("log", new Function("log")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.log(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("log10", new Function("log10")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.log10(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("log1p", new Function("log1p")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.log1p(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("max", new Function("max", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number)
{
boolean isInt0 = args[0] instanceof Integer || args[0] instanceof Byte || args[0] instanceof Short;
boolean isInt1 = args[1] instanceof Integer || args[1] instanceof Byte || args[1] instanceof Short;
if (isInt0 && isInt1)
return Math.max(((Number)args[0]).intValue(), ((Number)args[1]).intValue());
else if ((args[0] instanceof Long || isInt0) && (args[1] instanceof Long || isInt1))
return Math.max(((Number)args[0]).longValue(), ((Number)args[1]).longValue());
else if (!(args[0] instanceof Double) && !(args[1] instanceof Double))
return Math.max(((Number)args[0]).floatValue(), ((Number)args[1]).floatValue());
else
return Math.max(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue());
}
return null;
}
});
functions.put("min", new Function("min", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number)
{
boolean isInt0 = args[0] instanceof Integer || args[0] instanceof Byte || args[0] instanceof Short;
boolean isInt1 = args[1] instanceof Integer || args[1] instanceof Byte || args[1] instanceof Short;
if (isInt0 && isInt1)
return Math.min(((Number)args[0]).intValue(), ((Number)args[1]).intValue());
else if ((args[0] instanceof Long || isInt0) && (args[1] instanceof Long || isInt1))
return Math.min(((Number)args[0]).longValue(), ((Number)args[1]).longValue());
else if (!(args[0] instanceof Double) && !(args[1] instanceof Double))
return Math.min(((Number)args[0]).floatValue(), ((Number)args[1]).floatValue());
else
return Math.min(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue());
}
return null;
}
});
functions.put("nextAfter", new Function("nextAfter", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number)
if (args[0] instanceof Double)
return Math.nextAfter(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue());
else
return Math.nextAfter(((Number)args[0]).floatValue(), ((Number)args[1]).doubleValue());
return null;
}
});
functions.put("nextUp", new Function("nextUp")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1 && args[0] instanceof Number)
if (args[0] instanceof Double)
return Math.nextUp(((Number)args[0]).doubleValue());
else
return Math.nextUp(((Number)args[0]).floatValue());
return null;
}
});
functions.put("pow", new Function("pow", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number) ? Math.pow(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue()) : null;
}
});
functions.put("random", new Function("random", 0)
{
@Override
public Object applyFunction(Object... args)
{
return Math.random();
}
});
functions.put("rint", new Function("rint")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.rint(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("round", new Function("round")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1 && args[0] instanceof Number)
if (args[0] instanceof Double)
return Math.round(((Number)args[0]).doubleValue());
else
return Math.round(((Number)args[0]).floatValue());
return null;
}
});
functions.put("scalb", new Function("scalb", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2 && args[0] instanceof Number && args[1] instanceof Number)
if (args[0] instanceof Double)
return Math.scalb(((Number)args[0]).doubleValue(), ((Number)args[1]).intValue());
else
return Math.scalb(((Number)args[0]).floatValue(), ((Number)args[1]).intValue());
return null;
}
});
functions.put("signum", new Function("signum")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1 && args[0] instanceof Number)
if (args[0] instanceof Double)
return Math.signum(((Number)args[0]).doubleValue());
else
return Math.signum(((Number)args[0]).floatValue());
return null;
}
});
functions.put("sin", new Function("sin")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.sin(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("sinh", new Function("sinh")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.sinh(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("sqrt", new Function("sqrt")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.sqrt(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("tan", new Function("tan")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.tan(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("tanh", new Function("tanh")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.tanh(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("toDegrees", new Function("toDegrees")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.toDegrees(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("toRadians", new Function("toRadians")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1 && args[0] instanceof Number) ? Math.toRadians(((Number)args[0]).doubleValue()) : null;
}
});
functions.put("ulp", new Function("ulp")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1 && args[0] instanceof Number)
if (args[0] instanceof Double)
return Math.ulp(((Number)args[0]).doubleValue());
else
return Math.ulp(((Number)args[0]).floatValue());
return null;
}
});
// String manipulation functions
functions.put("length", new Function("length")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? String.valueOf(args[0]).length() : null;
}
});
functions.put("isEmpty", new Function("isEmpty")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? String.valueOf(args[0]).isEmpty() : null;
}
});
functions.put("isNull", new Function("isNull")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? args[0] == null : null;
}
});
functions.put("equals", new Function("equals", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2)
{
if (args[0] != null && args[1] != null)
{
if (args[0] instanceof Number && args[1] instanceof Number)
return ((Number)args[0]).doubleValue() == ((Number)args[1]).doubleValue();
else if (args[0] instanceof Date && args[1] instanceof Date)
return ((Date)args[0]).compareTo((Date)args[1]) == 0;
else if (args[0] instanceof Boolean && args[1] instanceof Boolean)
return ((Boolean)args[0]).compareTo((Boolean)args[1]) == 0;
else if (args[0] instanceof String && args[1] instanceof String)
return ((String)args[0]).compareTo((String)args[1]) == 0;
}
else if(args[0] == null && args[1] == null)
return true;
}
return false;
}
});
functions.put("equalsIgnoreCase", new Function("equalsIgnoreCase", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).equalsIgnoreCase(String.valueOf(args[1])) : false;
}
});
functions.put("compareTo", new Function("compareTo", 2)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 2)
{
if (args[0] != null && args[1] != null)
{
if (args[0] instanceof Number && args[1] instanceof Number)
return Double.compare(((Number)args[0]).doubleValue(), ((Number)args[1]).doubleValue());
else if (args[0] instanceof Date && args[1] instanceof Date)
return ((Date)args[0]).compareTo((Date)args[1]);
else if (args[0] instanceof Boolean && args[1] instanceof Boolean)
return ((Boolean)args[0]).compareTo((Boolean)args[1]);
else if (args[0] instanceof String && args[1] instanceof String)
return ((String)args[0]).compareTo((String)args[1]);
}
else if(args[0] == null && args[1] == null)
return 0;
}
return null;
}
});
functions.put("compareToIgnoreCase", new Function("compareToIgnoreCase", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).compareToIgnoreCase(String.valueOf(args[1])) : null;
}
});
functions.put("startsWith", new Function("startsWith", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).startsWith(String.valueOf(args[1])) : null;
}
});
functions.put("endsWith", new Function("endsWith", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).endsWith(String.valueOf(args[1])) : null;
}
});
functions.put("indexOf", new Function("indexOf", 3)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 3)
{
String src = null;
String str = null;
Integer fromIndex = null;
if (args[0] != null)
{
src = String.valueOf(args[0]);
str = String.valueOf(args[1]);
fromIndex = Converter.convertToInteger(args[2]);
}
else
{
src = String.valueOf(args[1]);
str = String.valueOf(args[2]);
}
try
{
return (fromIndex != null) ? src.indexOf(str, fromIndex) : src.indexOf(str);
}
catch (IndexOutOfBoundsException e)
{
;
}
return src;
}
return null;
}
});
functions.put("lastIndexOf", new Function("lastIndexOf", 3)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 3)
{
String src = null;
String str = null;
Integer fromIndex = null;
if (args[0] != null)
{
src = String.valueOf(args[0]);
str = String.valueOf(args[1]);
fromIndex = Converter.convertToInteger(args[2]);
}
else
{
src = String.valueOf(args[1]);
str = String.valueOf(args[2]);
}
try
{
return (fromIndex != null) ? src.lastIndexOf(str, fromIndex) : src.lastIndexOf(str);
}
catch (IndexOutOfBoundsException e)
{
;
}
return src;
}
return null;
}
});
functions.put("substring", new Function("substring", 3)
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 3)
{
String src = null;
Integer beginIndex = null;
Integer endIndex = null;
if (args[0] != null)
{
src = String.valueOf(args[0]);
beginIndex = Converter.convertToInteger(args[1]);
endIndex = Converter.convertToInteger(args[2]);
}
else
{
src = String.valueOf(args[1]);
beginIndex = Converter.convertToInteger(args[2]);
}
try
{
return endIndex != null ? src.substring(beginIndex, endIndex) : src.substring(beginIndex);
}
catch (IndexOutOfBoundsException e)
{
;
}
return src;
}
return null;
}
});
functions.put("concat", new Function("concat", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).concat(String.valueOf(args[1])) : null;
}
});
functions.put("matches", new Function("matches", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).matches(String.valueOf(args[1])) : null;
}
});
functions.put("contains", new Function("contains", 2)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 2) ? String.valueOf(args[0]).contains(String.valueOf(args[1])) : null;
}
});
functions.put("replaceFirst", new Function("replaceFirst", 3)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 3) ? String.valueOf(args[0]).replaceFirst(String.valueOf(args[1]), String.valueOf(args[2])) : null;
}
});
functions.put("replaceAll", new Function("replaceAll", 3)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 3) ? String.valueOf(args[0]).replaceAll(String.valueOf(args[1]), String.valueOf(args[2])) : null;
}
});
functions.put("replace", new Function("replace", 3)
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 3) ? String.valueOf(args[0]).replace(String.valueOf(args[1]), String.valueOf(args[2])) : null;
}
});
functions.put("toLowerCase", new Function("toLowerCase")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? String.valueOf(args[0]).toLowerCase() : null;
}
});
functions.put("toUpperCase", new Function("toUpperCase")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? String.valueOf(args[0]).toUpperCase() : null;
}
});
functions.put("trim", new Function("trim")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? String.valueOf(args[0]).trim() : null;
}
});
functions.put("valueOf", new Function("valueOf")
{
@Override
public Object applyFunction(Object... args)
{
return (args != null && args.length == 1) ? String.valueOf(args[0]) : null;
}
});
// GeoEvent processor functions
functions.put("receivedTime", new Function("receivedTime", 0)
{
@Override
public Object applyFunction(Object... args)
{
if (geoEvent != null)
if (geoEvent.hasProperty(GeoEventPropertyName.RECEIVED_TIME))
return geoEvent.getProperty(GeoEventPropertyName.RECEIVED_TIME);
return null;
}
});
functions.put("currentTime", new Function("currentTime", 0)
{
@Override
public Object applyFunction(Object... args)
{
return new Date();
}
});
functions.put("previousGeoEvent", new Function("previousGeoEvent")
{
@Override
public Object applyFunction(Object... args)
{
if (args != null && args.length == 1)
{
GeoEvent previousGeoEvent = geoEventCache.getPreviousGeoEvent(geoEvent);
if (previousGeoEvent != null)
{
FieldExpression fe = new FieldExpression(String.valueOf(args[0]));
if (fe.isValid())
{
Field f = previousGeoEvent.getField(fe);
if (f != null)
return f.getValue();
}
}
}
return null;
}
});
return functions;
}
catch (InvalidFunctionException e)
{
// this should not happen...
throw new RuntimeException(e);
}
}
public boolean isCacheRequired()
{
try
{
for (final Token token : new Tokenizer(null, functions, builtInOperators).getTokens(expression))
{
if (token instanceof FunctionToken)
if ("previousGeoEvent".equals(((FunctionToken)token).getName()))
return true;
}
}
catch (Exception e)
{
;
}
return false;
}
/**
* build a new {@link Calculable} from the expression
*
* @return the {@link Calculable} which can be used to evaluate the expression
* @throws UnknownFunctionException
* when an unrecognized function name is used in the expression
* @throws UnparsableExpressionException
* if the expression could not be parsed
*/
public Calculable build() throws UnknownFunctionException, UnparsableExpressionException
{
for (Operator op : customOperators.values())
for (int i=0; i < op.symbol.length(); i++)
if (!validOperatorSymbols.contains(op.symbol.charAt(i)))
throw new UnparsableExpressionException("" + op.symbol + " is not a valid symbol for an operator please choose from: !,#,ยง,$,&,;,:,~,<,>,|,=");
builtInOperators.putAll(customOperators);
if (geoEvent != null)
{
for (FieldDefinition fd : geoEvent.getGeoEventDefinition().getFieldDefinitions())
checkVariableName(fd.getName());
return RPNConverter.toRPNExpression(expression, geoEvent, functions, builtInOperators);
}
return null;
}
private void checkVariableName(String varName) throws UnparsableExpressionException
{
char[] name = varName.toCharArray();
for (int i=0; i < name.length; i++)
{
if (i == 0)
{
if (!Character.isLetter(name[i]) && name[i] != '_')
throw new UnparsableExpressionException(varName + " is not a valid variable name: character '" + name[i] + " at " + i);
}
else
{
if (!Character.isLetter(name[i]) && !Character.isDigit(name[i]) && name[i] != '_')
throw new UnparsableExpressionException(varName + " is not a valid variable name: character '" + name[i] + " at " + i);
}
}
}
private static String substituteUnaryOperators(String expr, Map<String, Operator> operators)
{
final StringBuilder exprBuilder = new StringBuilder(expr.length());
final char[] data = expr.toCharArray();
char lastChar = ' ';
boolean isLiteral = false;
StringBuilder lastOperation = new StringBuilder();
for (int i=0; i < expr.length(); i++)
{
if (exprBuilder.length() > 0)
lastChar = exprBuilder.charAt(exprBuilder.length() - 1);
final char c = data[i];
if (i > 0 && isOperatorCharacter(expr.charAt(i - 1), operators))
{
if (!operators.containsKey(lastOperation.toString() + expr.charAt(i - 1)))
lastOperation.delete(0, lastOperation.length());
lastOperation.append(expr.charAt(i - 1));
}
else if (i > 0 && !Character.isWhitespace(expr.charAt(i - 1)))
lastOperation.delete(0, lastOperation.length());
switch (c)
{
case '+':
if (i > 0 && lastChar != '(' && lastChar != ',' && operators.get(lastOperation.toString()) == null)
exprBuilder.append(c);
break;
case '-':
if (i > 0 && lastChar != '(' && lastChar != ',' && operators.get(lastOperation.toString()) == null)
exprBuilder.append(c);
else
{
isLiteral = false;
exprBuilder.append('\"');
}
break;
case '\'':
isLiteral = !isLiteral;
exprBuilder.append(c);
break;
default:
if (isLiteral)
exprBuilder.append(c);
else if (!Character.isWhitespace(c))
exprBuilder.append(c);
}
}
return exprBuilder.toString();
}
private static boolean isOperatorCharacter(char c, Map<String, Operator> operators)
{
for (String symbol : operators.keySet())
if (symbol.indexOf(c) != -1)
return true;
return false;
}
/**
* add a custom function instance for the evaluator to recognize
*
* @param function
* the {@link Function} to add
* @return the {@link ExpressionBuilder} instance
*/
public ExpressionBuilder withCustomFunction(Function function)
{
functions.put(function.name, function);
return this;
}
public ExpressionBuilder withCustomFunctions(Collection<Function> functions)
{
for (Function f : functions)
withCustomFunction(f);
return this;
}
/**
* set a {@link Operator} to be used in the expression
*
* @param operation
* the {@link Operator} to be used
* @return the {@link ExpressionBuilder} instance
*/
public ExpressionBuilder withOperation(Operator operation)
{
customOperators.put(operation.symbol, operation);
return this;
}
/**
* set a {@link Collection} of {@link Operator} to use in the expression
*
* @param operations
* the {@link Collection} of {@link Operator} to use
* @return the {@link ExpressionBuilder} instance
*/
public ExpressionBuilder withOperations(Collection<Operator> operations)
{
for (Operator op : operations)
withOperation(op);
return this;
}
/**
* set the mathematical expression for parsing
*
* @param expression
* a mathematical expression
* @return the {@link ExpressionBuilder} instance
*/
public ExpressionBuilder withExpression(String expression)
{
this.expression = expression;
return this;
}
public static void main(String[] args)
{
Boolean b = true;
Integer i = 1;
Integer j = new Integer(b.toString());
System.out.println(i+j);
}
}