package railo.runtime.functions.decision;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import railo.runtime.PageContext;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.FunctionException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.function.Function;
import railo.runtime.op.Caster;
import railo.runtime.op.Decision;
/**
*
*/
public final class IsValid implements Function {
private static final long serialVersionUID = -1383105304624662986L;
/**
* check for many diff types
* @param pc
* @param type
* @param value
* @return
* @throws ExpressionException
*/
public static boolean call(PageContext pc, String type, Object value) throws ExpressionException {
type=type.trim();
if("range".equalsIgnoreCase(type))
throw new FunctionException(pc,"isValid",1,"type","for [range] you have to define a min and max value");
if("regex".equalsIgnoreCase(type) || "regular_expression".equalsIgnoreCase(type))
throw new FunctionException(pc,"isValid",1,"type","for [regex] you have to define a pattern");
return Decision.isValid(type, value);
}
/**
* regex check
* @param pc
* @param type
* @param value
* @param objPattern
* @return
* @throws PageException
*/
public static boolean call(PageContext pc, String type, Object value, Object objPattern) throws PageException {
type=type.trim();
if(!"regex".equalsIgnoreCase(type) && !"regular_expression".equalsIgnoreCase(type))
throw new FunctionException(pc,"isValid",1,"type","wrong attribute count for type ["+type+"]");
return regex(Caster.toString(value,null),Caster.toString(objPattern));
}
public static boolean regex(String value,String strPattern) {
if(value==null)
return false;
try {
Pattern pattern = new Perl5Compiler().compile(strPattern, Perl5Compiler.MULTILINE_MASK);
PatternMatcherInput input = new PatternMatcherInput(value);
return new Perl5Matcher().matches(input, pattern);
} catch (MalformedPatternException e) {
return false;
}
}
public static boolean call(PageContext pc, String type, Object value, Object objMin, Object objMax) throws PageException {
// for named argument calls
if(objMax==null) {
if(objMin==null) return call(pc, type, value);
return call(pc, type, value, objMin);
}
type=type.trim().toLowerCase();
// numeric
if("range".equals(type) || "integer".equals(type) || "float".equals(type) || "numeric".equals(type) || "number".equals(type) ) {
double number=Caster.toDoubleValue(value,Double.NaN);
if(!Decision.isValid(number)) return false;
double min=toRangeNumber(pc,objMin,3,"min");
double max=toRangeNumber(pc,objMax,4,"max");
return number>=min && number<=max;
}
else if("string".equals(type)){
String str=Caster.toString(value,null);
if(str==null) return false;
double min=toRangeNumber(pc,objMin,3,"min");
double max=toRangeNumber(pc,objMax,4,"max");
return str.length()>=min && str.length()<=max;
}
else
throw new FunctionException(pc,"isValid",1,"type","wrong attribute count for type ["+type+"]");
}
private static double toRangeNumber(PageContext pc,Object objMin, int index,String name) throws FunctionException {
double d=Caster.toDoubleValue(objMin,Double.NaN);
if(!Decision.isValid(d))
throw new FunctionException(pc,"isValid",index,name,"value must be numeric");
return d;
}
}