001 package railo.runtime.functions.decision; 002 003 import org.apache.oro.text.regex.MalformedPatternException; 004 import org.apache.oro.text.regex.Pattern; 005 import org.apache.oro.text.regex.PatternMatcherInput; 006 import org.apache.oro.text.regex.Perl5Compiler; 007 import org.apache.oro.text.regex.Perl5Matcher; 008 009 import railo.runtime.PageContext; 010 import railo.runtime.exp.ExpressionException; 011 import railo.runtime.exp.FunctionException; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.ext.function.Function; 014 import railo.runtime.op.Caster; 015 import railo.runtime.op.Decision; 016 017 /** 018 * 019 */ 020 public final class IsValid implements Function { 021 022 private static final long serialVersionUID = -1383105304624662986L; 023 024 /** 025 * check for many diff types 026 * @param pc 027 * @param type 028 * @param value 029 * @return 030 * @throws ExpressionException 031 */ 032 public static boolean call(PageContext pc, String type, Object value) throws ExpressionException { 033 type=type.trim().toLowerCase(); 034 if("range".equals(type)) 035 throw new FunctionException(pc,"isValid",1,"type","for [range] you have to define a min and max value"); 036 if("regex".equals(type) || "regular_expression".equals(type)) 037 throw new FunctionException(pc,"isValid",1,"type","for [regex] you have to define a pattern"); 038 039 return Decision.isValid(type, value); 040 } 041 042 /** 043 * regex check 044 * @param pc 045 * @param type 046 * @param value 047 * @param pattern_or_min 048 * @return 049 * @throws PageException 050 */ 051 public static boolean call(PageContext pc, String type, Object value, Object objPattern) throws PageException { 052 type=type.trim().toLowerCase(); 053 if(!"regex".equals(type) && !"regular_expression".equals(type)) 054 throw new FunctionException(pc,"isValid",1,"type","wrong attribute count for type ["+type+"]"); 055 056 return regex(Caster.toString(value,null),Caster.toString(objPattern)); 057 } 058 059 060 061 062 public static boolean regex(String value,String strPattern) { 063 if(value==null) 064 return false; 065 066 try { 067 Pattern pattern = new Perl5Compiler().compile(strPattern, Perl5Compiler.MULTILINE_MASK); 068 PatternMatcherInput input = new PatternMatcherInput(value); 069 return new Perl5Matcher().matches(input, pattern); 070 } catch (MalformedPatternException e) { 071 return false; 072 } 073 } 074 075 public static boolean call(PageContext pc, String type, Object value, Object objMin, Object objMax) throws PageException { 076 077 // for named argument calls 078 if(objMax==null) { 079 if(objMin==null) return call(pc, type, value); 080 return call(pc, type, value, objMin); 081 } 082 083 type=type.trim().toLowerCase(); 084 085 // numeric 086 if("range".equals(type) || "integer".equals(type) || "float".equals(type) || "numeric".equals(type) || "number".equals(type) ) { 087 088 double number=Caster.toDoubleValue(value,Double.NaN); 089 if(!Decision.isValid(number)) return false; 090 091 double min=toRangeNumber(pc,objMin,3,"min"); 092 double max=toRangeNumber(pc,objMax,4,"max"); 093 094 095 return number>=min && number<=max; 096 } 097 else if("string".equals(type)){ 098 String str=Caster.toString(value,null); 099 if(str==null) return false; 100 101 double min=toRangeNumber(pc,objMin,3,"min"); 102 double max=toRangeNumber(pc,objMax,4,"max"); 103 104 return str.length()>=min && str.length()<=max; 105 } 106 107 else 108 throw new FunctionException(pc,"isValid",1,"type","wrong attribute count for type ["+type+"]"); 109 110 } 111 112 private static double toRangeNumber(PageContext pc,Object objMin, int index,String name) throws FunctionException { 113 double d=Caster.toDoubleValue(objMin,Double.NaN); 114 if(!Decision.isValid(d)) 115 throw new FunctionException(pc,"isValid",index,name,"value must be numeric"); 116 return d; 117 } 118 }