//TODO: this can be relaxed for order preserving operations
if(!(crit.getOperator() == CompareCriteria.EQ || crit.getOperator() == CompareCriteria.NE)) {
return crit;
}
boolean isFormat = false;
Function leftFunction = (Function) crit.getLeftExpression();
String funcName = leftFunction.getName().toLowerCase();
String inverseFunction = null;
if(funcName.startsWith("parse")) { //$NON-NLS-1$
String type = funcName.substring(5);
if (!PARSE_FORMAT_TYPES.contains(type)) {
return crit;
}
inverseFunction = "format" + type; //$NON-NLS-1$
} else if(funcName.startsWith("format")) { //$NON-NLS-1$
String type = funcName.substring(6);
if (!PARSE_FORMAT_TYPES.contains(type)) {
return crit;
}
inverseFunction = "parse" + type; //$NON-NLS-1$
isFormat = true;
} else {
return crit;
}
Expression rightExpr = crit.getRightExpression();
if (!(rightExpr instanceof Constant)) {
return crit;
}
Expression leftExpr = leftFunction.getArgs()[0];
Expression formatExpr = leftFunction.getArgs()[1];
if(!(formatExpr instanceof Constant)) {
return crit;
}
String format = (String)((Constant)formatExpr).getValue();
FunctionLibrary funcLib = this.metadata.getFunctionLibrary();
FunctionDescriptor descriptor = funcLib.findFunction(inverseFunction, new Class[] { rightExpr.getType(), formatExpr.getType() });
if(descriptor == null){
return crit;
}
Object value = ((Constant)rightExpr).getValue();
try {
Object result = descriptor.invokeFunction(new Object[] {((Constant)rightExpr).getValue(), format});
result = leftFunction.getFunctionDescriptor().invokeFunction(new Object[] { result, format } );
if (((Comparable)value).compareTo(result) != 0) {
return getSimpliedCriteria(crit, leftExpr, crit.getOperator() != CompareCriteria.EQ, true);
}
} catch(FunctionExecutionException e) {
//Not all numeric formats are invertable, so just return the criteria as it may still be valid