package railo.runtime.op; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.net.URI; import java.sql.Blob; import java.sql.Clob; import java.text.DateFormat; import java.text.ParsePosition; import java.util.Calendar; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import java.util.regex.Pattern; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import railo.commons.date.DateTimeUtil; import railo.commons.date.JREDateTimeUtil; import railo.commons.i18n.FormatUtil; import railo.commons.lang.CFTypes; import railo.commons.lang.StringUtil; import railo.runtime.Component; import railo.runtime.coder.Base64Util; import railo.runtime.converter.WDDXConverter; import railo.runtime.engine.ThreadLocalPageContext; import railo.runtime.exp.ExpressionException; import railo.runtime.exp.PageException; import railo.runtime.ext.function.Function; import railo.runtime.java.JavaObject; import railo.runtime.net.mail.MailUtil; import railo.runtime.op.date.DateCaster; import railo.runtime.op.validators.ValidateCreditCard; import railo.runtime.text.xml.XMLCaster; import railo.runtime.text.xml.XMLUtil; import railo.runtime.text.xml.struct.XMLStruct; import railo.runtime.type.Array; import railo.runtime.type.Closure; import railo.runtime.type.Collection; import railo.runtime.type.Collection.Key; import railo.runtime.type.ObjectWrap; import railo.runtime.type.Objects; import railo.runtime.type.Query; import railo.runtime.type.QueryColumn; import railo.runtime.type.Struct; import railo.runtime.type.UDF; import railo.runtime.type.dt.DateTime; /** * Object to test if a Object is a specific type */ public final class Decision { private static final String STRING_DEFAULT_VALUE = "this is a unique string"; private static Pattern ssnPattern; private static Pattern phonePattern; private static Pattern zipPattern; /** * tests if value is a simple value (Number,String,Boolean,Date,Printable) * @param value value to test * @return is value a simple value */ public static boolean isSimpleValue(Object value){ return (value instanceof Number) || (value instanceof String) || (value instanceof Boolean) || (value instanceof Date) || ((value instanceof Castable) && !(value instanceof Objects) && !(value instanceof Collection)); } /** * tests if value is Numeric * @param value value to test * @return is value numeric */ public static boolean isNumeric(Object value) { if(value instanceof Number) return true; else if(value instanceof String) { return isNumeric(value.toString()); } else return false; } public static boolean isCastableToNumeric(Object o) { if(isNumeric(o)) return true; else if(isBoolean(o)) return true; else if(isDateSimple(o,false)) return true; else if(o == null) return true; else if(o instanceof ObjectWrap) return isCastableToNumeric(((ObjectWrap)o).getEmbededObject("notanumber")); else if(o instanceof Castable) { return Decision.isValid(((Castable)o).castToDoubleValue(Double.NaN)); } return false; } public static boolean isCastableToDate(Object o) { if(isDateAdvanced(o, true)) return true; else if(isBoolean(o)) return true; else if(o instanceof ObjectWrap) return isCastableToDate(((ObjectWrap)o).getEmbededObject("notadate")); else if(o instanceof Castable) { return ((Castable)o).castToDateTime(null)!=null; } return false; } /** * tests if value is Numeric * @param value value to test * @return is value numeric */ public static boolean isNumeric(Object value, boolean alsoBooleans) { if(alsoBooleans && isBoolean(value)) return true; return isNumeric(value); } /** * tests if String value is Numeric * @param str value to test * @return is value numeric */ public static boolean isNumeric(String str) { if(str==null) return false; str=str.trim(); int pos=0; int len=str.length(); if(len==0) return false; char curr=str.charAt(pos); if(curr=='+' || curr=='-') { if(len==++pos) return false; curr=str.charAt(pos); } boolean hasDot=false; boolean hasExp=false; for(;pos<len;pos++) { curr=str.charAt(pos); if(curr<'0') { if(curr=='.') { if(pos+1>=len || hasDot) return false; hasDot=true; } else return false; } else if(curr>'9') { if(curr=='e' || curr=='E') { if(pos+1>=len || hasExp) return false; hasExp=true; hasDot=true; } else return false; } } if(hasExp){ try{ Double.parseDouble(str); return true; } catch( NumberFormatException e){ return false; } } return true; } public static boolean isInteger(Object value) { return isInteger(value,false); } public static boolean isInteger(Object value,boolean alsoBooleans) { if(!alsoBooleans && value instanceof Boolean) return false; double dbl = Caster.toDoubleValue(value,Double.NaN); if(!Decision.isValid(dbl)) return false; int i=(int)dbl; return i==dbl; } /** tests if String value is Hex Value * @param str value to test * @return is value numeric */ public static boolean isHex(String str) { if(str==null || str.length()==0) return false; for(int i=str.length()-1;i>=0;i--) { char c=str.charAt(i); if(!(c>='0' && c<='9')) { c=Character.toLowerCase(c); if(!(c=='a' || c=='b' || c=='c' || c=='d' || c=='e' || c=='f'))return false; } } return true; } /** tests if String value is UUID Value * @param obj value to test * @return is value numeric * @deprecated use instead <code>isUUId(Object obj)</code> */ public static boolean isUUID(Object obj) { return isUUId(obj); } /** tests if String value is UUID Value * @param obj value to test * @return is value numeric */ public static boolean isUUId(Object obj) { String str=Caster.toString(obj,null); if(str==null) return false; if(str.length()==35) { return Decision.isHex(str.substring(0,8)) && str.charAt(8)=='-' && Decision.isHex(str.substring(9,13)) && str.charAt(13)=='-' && Decision.isHex(str.substring(14,18)) && str.charAt(18)=='-' && Decision.isHex(str.substring(19)); } else if(str.length()==32) return Decision.isHex(str); return false; } /** * @param obj * @return * @deprecated use instead <code>isGUId(Object)</code> */ public static boolean isGUID(Object obj) { return isGUId(obj); } public static boolean isGUId(Object obj) { String str=Caster.toString(obj,null); if(str==null) return false; // GUID if(str.length()==36) { return Decision.isHex(str.substring(0,8)) && str.charAt(8)=='-' && Decision.isHex(str.substring(9,13)) && str.charAt(13)=='-' && Decision.isHex(str.substring(14,18)) && str.charAt(18)=='-' && Decision.isHex(str.substring(19,23)) && str.charAt(23)=='-' && Decision.isHex(str.substring(24)); } return false; } public static boolean isGUIdSimple(Object obj) { String str=Caster.toString(obj,null); if(str==null) return false; // GUID if(str.length()==36) { return str.charAt(8)=='-' && str.charAt(13)=='-' && str.charAt(18)=='-' && str.charAt(23)=='-'; } return false; } /** * tests if value is a Boolean (Numbers are not acctepeted) * @param value value to test * @return is value boolean */ public static boolean isBoolean(Object value) { if(value instanceof Boolean) return true; else if(value instanceof String) { return isBoolean(value.toString()); } else if(value instanceof ObjectWrap) return isBoolean(((ObjectWrap)value).getEmbededObject(null)); else return false; } public static boolean isCastableToBoolean(Object value) { if(value instanceof Boolean) return true; if(value instanceof Number) return true; else if(value instanceof String) { String str = (String)value; return isBoolean(str) || isNumeric(str); } else if(value instanceof Castable) { return ((Castable)value).castToBoolean(null)!=null; } else if(value instanceof ObjectWrap) return isCastableToBoolean(((ObjectWrap)value).getEmbededObject(null)); else return false; } public static boolean isBoolean(Object value, boolean alsoNumbers) { if(isBoolean(value)) return true; else if(alsoNumbers) return isNumeric(value); else return false; } /** * tests if value is a Boolean * @param str value to test * @return is value boolean */ public static boolean isBoolean(String str) { //str=str.trim(); if(str.length()<2) return false; switch(str.charAt(0)) { case 't': case 'T': return str.equalsIgnoreCase("true"); case 'f': case 'F': return str.equalsIgnoreCase("false"); case 'y': case 'Y': return str.equalsIgnoreCase("yes"); case 'n': case 'N': return str.equalsIgnoreCase("no"); } return false; } /** * tests if value is DateTime Object * @param value value to test * @param alsoNumbers interpret also a number as date * @return is value a DateTime Object */ public static boolean isDate(Object value,boolean alsoNumbers) { return isDateSimple(value, alsoNumbers); } public static boolean isDateSimple(Object value,boolean alsoNumbers) { return isDateSimple(value, alsoNumbers, false); } public static boolean isDateSimple(Object value,boolean alsoNumbers, boolean alsoMonthString) { //return DateCaster.toDateEL(value)!=null; if(value instanceof DateTime) return true; else if(value instanceof Date) return true; // wrong timezone but this isent importend because date will not be importend else if(value instanceof String) return DateCaster.toDateSimple(value.toString(),alsoNumbers,alsoMonthString,TimeZone.getDefault(),null)!=null; else if(value instanceof ObjectWrap) { return isDateSimple(((ObjectWrap)value).getEmbededObject(null),alsoNumbers); } else if(value instanceof Castable) { return ((Castable)value).castToDateTime(null)!=null; } else if(alsoNumbers && value instanceof Number) return true; else if(value instanceof Calendar) return true; return false; } public static boolean isDateAdvanced(Object value,boolean alsoNumbers) { //return DateCaster.toDateEL(value)!=null; if(value instanceof DateTime) return true; else if(value instanceof Date) return true; // wrong timezone but this isent importend because date will not be importend else if(value instanceof String) return DateCaster.toDateAdvanced(value.toString(),alsoNumbers,TimeZone.getDefault(),null)!=null; else if(value instanceof Castable) { return ((Castable)value).castToDateTime(null)!=null; } else if(alsoNumbers && value instanceof Number) return true; else if(value instanceof ObjectWrap) { return isDateAdvanced(((ObjectWrap)value).getEmbededObject(null),alsoNumbers); } else if(value instanceof Calendar) return true; return false; } private static char[] DATE_DEL=new char[]{'.','/','-'}; public static boolean isUSDate(Object value) { String str = Caster.toString(value,""); return isUSorEuroDateEuro(str,false); } public static boolean isUSDate(String str) { return isUSorEuroDateEuro(str,false); } public static boolean isEuroDate(Object value) { String str = Caster.toString(value,""); return isUSorEuroDateEuro(str,true); } public static boolean isEuroDate(String str) { return isUSorEuroDateEuro(str,true); } private static boolean isUSorEuroDateEuro(String str, boolean isEuro) { if(StringUtil.isEmpty(str)) return false; for(int i=0;i<DATE_DEL.length;i++) { Array arr = railo.runtime.type.util.ListUtil.listToArrayRemoveEmpty(str,DATE_DEL[i]); if(arr.size()!=3) continue; int month=Caster.toIntValue( arr.get(isEuro?2:1,Constants.INTEGER_0),Integer.MIN_VALUE); int day=Caster.toIntValue( arr.get(isEuro?1:2,Constants.INTEGER_0),Integer.MIN_VALUE); int year=Caster.toIntValue( arr.get(3,Constants.INTEGER_0),Integer.MIN_VALUE); if(month==Integer.MIN_VALUE) continue; if(month>12) continue; if(day==Integer.MIN_VALUE) continue; if(day>31) continue; if(year==Integer.MIN_VALUE) continue; if(DateTimeUtil.getInstance().toTime(null,year, month, day, 0, 0, 0,0, Long.MIN_VALUE)==Long.MIN_VALUE) continue; return true; } return false; } public static boolean isCastableToStruct(Object o) { if(isStruct(o)) return true; if(o == null) return false; else if(o instanceof ObjectWrap) { if(o instanceof JavaObject ) return true; return isCastableToStruct(((ObjectWrap)o).getEmbededObject(null)); } if(Decision.isSimpleValue(o)){ return false; } //if(isArray(o) || isQuery(o)) return false; return false; } /** * tests if object is a struct * @param o * @return is struct or not */ public static boolean isStruct(Object o) { if(o instanceof Struct) return true; else if(o instanceof Map)return true; else if(o instanceof Node)return true; return false; } /** * can this type be casted to a array * @param o * @return * @throws PageException */ public static boolean isCastableToArray(Object o) { if(isArray(o)) return true; //else if(o instanceof XMLStruct) return true; else if(o instanceof Struct) { Struct sct=(Struct) o; Iterator<Key> it = sct.keyIterator(); try { while(it.hasNext()) { Caster.toIntValue(it.next().getString()); } return true; } catch (Throwable t) { return false; } } return false; } /** * tests if object is a array * @param o * @return is array or not */ public static boolean isArray(Object o) { if(o instanceof Array) return true; if(o instanceof List) return true; if(isNativeArray(o)) return true; if(o instanceof ObjectWrap) { return isArray(((ObjectWrap)o).getEmbededObject(null)); } return false; } /** * tests if object is a native java array * @param o * @return is a native (java) array */ public static boolean isNativeArray(Object o) { //return o.getClass().isArray(); if(o instanceof Object[]) return true; else if(o instanceof boolean[]) return true; else if(o instanceof byte[]) return true; else if(o instanceof char[]) return true; else if(o instanceof short[]) return true; else if(o instanceof int[]) return true; else if(o instanceof long[]) return true; else if(o instanceof float[]) return true; else if(o instanceof double[]) return true; return false; } /** * tests if object is catable to a binary * @param object * @return boolean */ public static boolean isCastableToBinary(Object object,boolean checkBase64String) { if(isBinary(object))return true; if(object instanceof InputStream) return true; if(object instanceof ByteArrayOutputStream) return true; if(object instanceof Blob) return true; // Base64 String if(!checkBase64String) return false; String str = Caster.toString(object,null); if(str==null) return false; return Base64Util.isBase64(str); } /** * tests if object is a binary * @param object * @return boolean */ public static boolean isBinary(Object object) { if(object instanceof byte[]) return true; if(object instanceof ObjectWrap) return isBinary(((ObjectWrap)object).getEmbededObject("")); return false; } /** * tests if object is a Component * @param object * @return boolean */ public static boolean isComponent(Object object) { return object instanceof Component; } /** * tests if object is a Query * @param object * @return boolean */ public static boolean isQuery(Object object) { if(object instanceof Query)return true; else if(object instanceof ObjectWrap) { return isQuery(((ObjectWrap)object).getEmbededObject(null)); } return false; } public static boolean isQueryColumn(Object object) { if(object instanceof QueryColumn)return true; else if(object instanceof ObjectWrap) { return isQueryColumn(((ObjectWrap)object).getEmbededObject(null)); } return false; } /** * tests if object is a binary * @param object * @return boolean */ public static boolean isUserDefinedFunction(Object object) { return object instanceof UDF; } /** * tests if year is a leap year * @param year year to check * @return boolean */ public static final boolean isLeapYear(int year) { return DateTimeUtil.getInstance().isLeapYear(year); //return new GregorianCalendar().isLeapYear(year); } /** * tests if object is a WDDX Object * @param o Object to check * @return boolean */ public static boolean isWddx(Object o) { if(!(o instanceof String)) return false; String str=o.toString(); if(!(str.indexOf("wddxPacket")>0)) return false; // wrong timezone but this isent importend because date will not be used WDDXConverter converter =new WDDXConverter(TimeZone.getDefault(),false,true); try { converter.deserialize(Caster.toString(o),true); } catch (Exception e) { return false; } return true; } /** * tests if object is a XML Object * @param o Object to check * @return boolean */ public static boolean isXML(Object o) { if(o instanceof Node || o instanceof NodeList) return true; if(o instanceof ObjectWrap) { return isXML(((ObjectWrap)o).getEmbededObject(null)); } try { XMLCaster.toXMLStruct(XMLUtil.parse(XMLUtil.toInputSource(null, o),null,false),false); return true; } catch(Exception outer) { return false; } } public static boolean isVoid(Object o) { if(o==null)return true; else if(o instanceof String) return o.toString().length()==0; else if(o instanceof Number) return ((Number)o).intValue()==0; else if(o instanceof Boolean) return ((Boolean)o).booleanValue()==false ; else if(o instanceof ObjectWrap)return isVoid(((ObjectWrap)o).getEmbededObject(("isnotnull"))); return false; } /** * tests if object is a XML Element Object * @param o Object to check * @return boolean */ public static boolean isXMLElement(Object o) { return o instanceof Element; } /** * tests if object is a XML Document Object * @param o Object to check * @return boolean */ public static boolean isXMLDocument(Object o) { return o instanceof Document; } /** * tests if object is a XML Root Element Object * @param o Object to check * @return boolean */ public static boolean isXMLRootElement(Object o) { if(o instanceof Node) { Node n=(Node)o; if(n instanceof XMLStruct)n=((XMLStruct)n).toNode(); return n.getOwnerDocument()!=null && n.getOwnerDocument().getDocumentElement()==n; } return false; } /** * @param obj * @return returns if string represent a variable name */ public static boolean isVariableName(Object obj) { if(obj instanceof String) return isVariableName((String)obj); return false; } public static boolean isFunction(Object obj) { if(obj instanceof UDF)return true; else if(obj instanceof ObjectWrap) { return isFunction(((ObjectWrap)obj).getEmbededObject(null)); } return false; } public static boolean isClosure(Object obj) { if(obj instanceof Closure)return true; else if(obj instanceof ObjectWrap) { return isClosure(((ObjectWrap)obj).getEmbededObject(null)); } return false; } /** * @param string * @return returns if string represent a variable name */ public static boolean isVariableName(String string) { if(string.length()==0)return false; int len=string.length(); int pos=0; while(pos<len) { char first=string.charAt(pos); if(!((first>='a' && first<='z')||(first>='A' && first<='Z')||(first=='_'))) return false; pos++; for(;pos<len;pos++) { char c=string.charAt(pos); if(!((c>='a' && c<='z')||(c>='A' && c<='Z')||(c>='0' && c<='9')||(c=='_'))) break; } if(pos==len) return true; if(string.charAt(pos)=='.')pos++; } return false; } /** * @param string * @return returns if string represent a variable name */ public static boolean isSimpleVariableName(String string) { if(string.length()==0)return false; char first=string.charAt(0); if(!((first>='a' && first<='z')||(first>='A' && first<='Z')||(first=='_'))) return false; for(int i=string.length()-1;i>0;i--) { char c=string.charAt(i); if(!((c>='a' && c<='z')||(c>='A' && c<='Z')||(c>='0' && c<='9')||(c=='_'))) return false; } return true; } /** * @param key * @return returns if string represent a variable name */ public static boolean isSimpleVariableName(Collection.Key key) { String strKey = key.getLowerString(); if(strKey.length()==0)return false; char first=strKey.charAt(0); if(!((first>='a' && first<='z')||(first=='_'))) return false; for(int i=strKey.length()-1;i>0;i--) { char c=strKey.charAt(i); if(!((c>='a' && c<='z')||(c>='0' && c<='9')||(c=='_'))) return false; } return true; } /** * returns if object is a CFML object * @param o Object to check * @return is or not */ public static boolean isObject(Object o) { return isComponent(o) || (!isArray(o) && !isQuery(o) && !isSimpleValue(o) && !isStruct(o) && !isUserDefinedFunction(o) && !isXML(o)); } /** * @param obj * @return return if a String is "Empty", that means NULL or String with length 0 (whitespaces will not counted) */ public static boolean isEmpty(Object obj) { if(obj instanceof String)return StringUtil.isEmpty((String)obj); return obj==null; } /** * @deprecated use instead <code>StringUtil.isEmpty(String)</code> * @param str * @return return if a String is "Empty", that means NULL or String with length 0 (whitespaces will not counted) */ public static boolean isEmpty(String str) { return StringUtil.isEmpty(str); } /** * @deprecated use instead <code>StringUtil.isEmpty(String)</code> * @param str * @param trim * @return return if a String is "Empty", that means NULL or String with length 0 (whitespaces will not counted) */ public static boolean isEmpty(String str, boolean trim) { return StringUtil.isEmpty(str,trim); } /** * returns if a value is a credit card * @param value * @return is credit card */ public static boolean isCreditCard(Object value) { return ValidateCreditCard.isValid(Caster.toString(value,"0")); } /** * returns if given object is a email * @param value * @return */ public static boolean isEmail(Object value) { return MailUtil.isValidEmail(value); } /** * returns if given object is a social security number (usa) * @param value * @return */ public static boolean isSSN(Object value) { String str = Caster.toString(value,null); if(str==null)return false; if(ssnPattern==null) ssnPattern=Pattern.compile("^[0-9]{3}[-|]{1}[0-9]{2}[-|]{1}[0-9]{4}$"); return ssnPattern.matcher(str.trim()).matches(); } /** * returns if given object is a phone * @param value * @return */ public static boolean isPhone(Object value) { String str = Caster.toString(value,null); if(str==null)return false; if(phonePattern==null) phonePattern=Pattern.compile("^(\\+?1?[ \\-\\.]?([\\(]?([1-9][0-9]{2})[\\)]?))?[ ,\\-,\\.]?([^0-1]){1}([0-9]){2}[ ,\\-,\\.]?([0-9]){4}(( )((x){0,1}([0-9]){1,5}){0,1})?$"); return phonePattern.matcher(str.trim()).matches(); } /** * returns true if the given object is a valid URL * @param value * @return */ public static boolean isURL( Object value ) { String str = Caster.toString( value, null ); if ( str == null ) return false; if ( str.indexOf( ':' ) == -1 ) return false; str = str.toLowerCase().trim(); if ( !str.startsWith( "http://" ) && !str.startsWith( "https://" ) && !str.startsWith( "file://" ) && !str.startsWith( "ftp://" ) && !str.startsWith( "mailto:" ) && !str.startsWith( "news:" ) && !str.startsWith( "urn:" ) ) return false; try { URI uri = new URI( str ); String proto = uri.getScheme(); if ( proto == null ) return false; if ( proto.equals( "http" ) || proto.equals( "https" ) || proto.equals( "file" ) || proto.equals( "ftp" ) ) { if ( uri.getHost() == null ) return false; String path = uri.getPath(); if ( path != null ) { int len = path.length(); for ( int i=0; i<len; i++ ) { if ( "?<>:*|\"".indexOf( path.charAt( i ) ) > -1 ) return false; } } } return true; } catch ( Exception ex ) { return false; } } /** * returns if given object is a zip code * @param value * @return */ public static boolean isZipCode(Object value) { String str = Caster.toString(value,null); if(str==null)return false; if(zipPattern==null) zipPattern=Pattern.compile("([0-9]{5,5})|([0-9]{5,5}[- ]{1}[0-9]{4,4})"); return zipPattern.matcher(str.trim()).matches(); } public static boolean isString(Object o) { if(o instanceof String) return true; else if(o instanceof Boolean) return true; else if(o instanceof Number) return true; else if(o instanceof Date) return true; else if(o instanceof Castable) { return ((Castable)o).castToString(STRING_DEFAULT_VALUE)!=STRING_DEFAULT_VALUE; } else if(o instanceof Clob) return true; else if(o instanceof Node) return true; else if(o instanceof Map || o instanceof List || o instanceof Function) return false; else if(o == null) return true; else if(o instanceof ObjectWrap) return isString(((ObjectWrap)o).getEmbededObject("")); return true; } public static boolean isCastableToString(Object o) { return isString(o); } public static boolean isValid(String type, Object value) throws ExpressionException { type=StringUtil.toLowerCase(type.trim()); char first = type.charAt(0); switch(first) { case 'a': if("any".equals(type)) return true;//isSimpleValue(value); if("array".equals(type)) return isArray(value); break; case 'b': if("binary".equals(type)) return isBinary(value); if("boolean".equals(type)) return isBoolean(value,true); break; case 'c': if("creditcard".equals(type)) return isCreditCard(value); if("component".equals(type)) return isComponent(value); if("cfc".equals(type)) return isComponent(value); break; case 'd': if("date".equals(type)) return isDateAdvanced(value,true); // ist zwar nicht logisch aber ident. zu Neo if("double".equals(type)) return isCastableToNumeric(value); break; case 'e': if("eurodate".equals(type)) return isEuroDate(value); if("email".equals(type)) return isEmail(value); break; case 'f': if("float".equals(type)) return isNumeric(value,true); if("function".equals(type)) return isFunction(value); break; case 'g': if("guid".equals(type)) return isGUId(value); break; case 'i': if("integer".equals(type)) return isInteger(value,false); break; case 'n': if("numeric".equals(type)) return isCastableToNumeric(value); if("number".equals(type)) return isCastableToNumeric(value); if("node".equals(type)) return isXML(value); break; case 'p': if("phone".equals(type)) return isPhone(value); break; case 'q': if("query".equals(type)) return isQuery(value); break; case 's': if("simple".equals(type)) return isSimpleValue(value); if("struct".equals(type)) return isStruct(value); if("ssn".equals(type)) return isSSN(value); if("social_security_number".equals(type))return isSSN(value); if("string".equals(type)) return isString(value); break; case 't': if("telephone".equals(type)) return isPhone(value); if("time".equals(type)) return isDateAdvanced(value,false); break; case 'u': if("usdate".equals(type)) return isUSDate(value); if("uuid".equals(type)) return isUUId(value); if("url".equals(type)) return isURL(value); break; case 'v': if("variablename".equals(type)) return isVariableName(Caster.toString(value,"")); break; case 'x': if("xml".equals(type)) return isXML(value); // DIFF 23 break; case 'z': if("zip".equals(type)) return isZipCode(value); if("zipcode".equals(type)) return isZipCode(value); break; } throw new ExpressionException("invalid type ["+type+"], valid types are [any,array,binary,boolean,component,creditcard,date,time,email,eurodate,float,numeric,guid,integer,query,simple,ssn,string,struct,telephone,URL,UUID,USdate,variableName,zipcode]"); } /** * checks if a value is castable to a certain type * @param type any,array,boolean,binary, ... * @param o value to check * @param alsoPattern also check patterns like creditcards,email,phone ... * @param maxlength only used for email,url, string, ignored otherwise * @return */ public static boolean isCastableTo(String type, Object o, boolean alsoAlias, boolean alsoPattern, int maxlength) { type=StringUtil.toLowerCase(type).trim(); if(type.length()>2) { char first=type.charAt(0); switch(first) { case 'a': if(type.equals("any")) { return true; } else if(type.equals("array")) { return isCastableToArray(o); } break; case 'b': if(type.equals("boolean") || (alsoAlias && type.equals("bool"))) { return isCastableToBoolean(o); } else if(type.equals("binary")) { return isCastableToBinary(o,true); } else if(alsoAlias && type.equals("bigint")) { return isCastableToNumeric(o); } else if(type.equals("base64")) { return Caster.toBase64(o,null,null)!=null; } break; case 'c': if(alsoPattern && type.equals("creditcard")) { return Caster.toCreditCard(o,null)!=null; } if(alsoPattern && type.equals("char")) { if(maxlength>-1) { String str = Caster.toString(o,null); if(str==null) return false; return str.length()<=maxlength; } return isCastableToString(o); } break; case 'd': if(type.equals("date")) { return isDateAdvanced(o, true); } else if(type.equals("datetime")) { return isDateAdvanced(o, true); } else if(alsoAlias && type.equals("double")) { return isCastableToNumeric(o); } else if(alsoAlias && type.equals("decimal")) { return Caster.toDecimal(o,null)!=null; } break; case 'e': if(alsoAlias && type.equals("eurodate")) { return isDateAdvanced(o, true); } else if(alsoPattern && type.equals("email")) { if(maxlength>-1) { String str = Caster.toEmail(o,null); if(str==null) return false; return str.length()<=maxlength; } return Caster.toEmail(o,null)!= null; } break; case 'f': if(alsoAlias && type.equals("float")) { return isCastableToNumeric(o); } if(type.equals("function")) { return isFunction(o); } break; case 'g': if(type.equals("guid")) { return isGUId(o); } break; case 'i': if(alsoAlias && (type.equals("integer") || type.equals("int"))) { return isCastableToNumeric(o); } break; case 'l': if(alsoAlias && type.equals("long")) { return isCastableToNumeric(o); } break; case 'n': if(type.equals("numeric")) { return isCastableToNumeric(o); } else if(type.equals("number")) { return isCastableToNumeric(o); } if(alsoAlias) { if(type.equals("node")) return isXML(o); else if(type.equals("nvarchar") || type.equals("nchar")) { if(maxlength>-1) { String str = Caster.toString(o,null); if(str==null) return false; return str.length()<=maxlength; } return isCastableToString(o); } } break; case 'o': if(type.equals("object")) { return true; } else if(alsoAlias && type.equals("other")) { return true; } break; case 'p': if(alsoPattern && type.equals("phone")) { return Caster.toPhone(o,null)!=null; } break; case 'q': if(type.equals("query")) { return isQuery(o); } if(type.equals("querycolumn")) return isQueryColumn(o); break; case 's': if(type.equals("string")) { if(maxlength>-1) { String str = Caster.toString(o,null); if(str==null) return false; return str.length()<=maxlength; } return isCastableToString(o); } else if(type.equals("struct")) { return isCastableToStruct(o); } else if(alsoAlias && type.equals("short")) { return isCastableToNumeric(o); } else if(alsoPattern && (type.equals("ssn") ||type.equals("social_security_number"))) { return Caster.toSSN(o,null)!=null; } break; case 't': if(type.equals("timespan")) { return Caster.toTimespan(o,null)!=null; } if(type.equals("time")) { return isDateAdvanced(o, true); } if(alsoPattern && type.equals("telephone")) { return Caster.toPhone(o,null)!=null; } if(alsoAlias && type.equals("timestamp")) return isDateAdvanced(o, true); if(alsoAlias && type.equals("text")) { if(maxlength>-1) { String str = Caster.toString(o,null); if(str==null) return false; return str.length()<=maxlength; } return isCastableToString(o); } case 'u': if(type.equals("uuid")) { return isUUId(o); } if(alsoAlias && type.equals("usdate")) { return isDateAdvanced(o, true); } if(alsoPattern && type.equals("url")) { if(maxlength>-1) { String str = Caster.toURL(o,null); if(str==null) return false; return str.length()<=maxlength; } return Caster.toURL(o,null)!=null; } if(alsoAlias && type.equals("udf")) { return isFunction(o); } break; case 'v': if(type.equals("variablename")) { return isVariableName(o); } else if(type.equals("void")) { return isVoid(o);//Caster.toVoid(o,Boolean.TRUE)!=Boolean.TRUE; } else if(alsoAlias && type.equals("variable_name")) { return isVariableName(o); } else if(alsoAlias && type.equals("variable-name")) { return isVariableName(o); } if(type.equals("varchar")) { if(maxlength>-1) { String str = Caster.toString(o,null); if(str==null) return false; return str.length()<=maxlength; } return isCastableToString(o); } break; case 'x': if(type.equals("xml")) { return isXML(o); } break; case 'z': if(alsoPattern && (type.equals("zip") || type.equals("zipcode"))) { return Caster.toZip(o,null)!=null; } break; } } if(o instanceof Component) { Component comp=((Component)o); return comp.instanceOf(type); } if(isArrayType(type) && isArray(o)){ String t=type.substring(0,type.length()-2); Array arr = Caster.toArray(o,null); if(arr!=null){ Iterator<Object> it = arr.valueIterator(); while(it.hasNext()){ if(!isCastableTo(t, it.next(), alsoAlias,alsoPattern,-1)) return false; } return true; } } return false; } private static boolean isArrayType(String type) { return type.endsWith("[]"); } public static boolean isCastableTo(short type,String strType, Object o) { switch(type){ case CFTypes.TYPE_ANY: return true; case CFTypes.TYPE_STRING: return isCastableToString(o); case CFTypes.TYPE_BOOLEAN: return isCastableToBoolean(o); case CFTypes.TYPE_NUMERIC: return isCastableToNumeric(o); case CFTypes.TYPE_STRUCT: return isCastableToStruct(o); case CFTypes.TYPE_ARRAY: return isCastableToArray(o); case CFTypes.TYPE_QUERY: return isQuery(o); case CFTypes.TYPE_QUERY_COLUMN: return isQueryColumn(o); case CFTypes.TYPE_DATETIME: return isDateAdvanced(o, true); case CFTypes.TYPE_VOID: return isVoid(o);//Caster.toVoid(o,Boolean.TRUE)!=Boolean.TRUE; case CFTypes.TYPE_BINARY: return isCastableToBinary(o,true); case CFTypes.TYPE_TIMESPAN: return Caster.toTimespan(o,null)!=null; case CFTypes.TYPE_UUID: return isUUId(o); case CFTypes.TYPE_GUID: return isGUId(o); case CFTypes.TYPE_VARIABLE_NAME:return isVariableName(o); case CFTypes.TYPE_FUNCTION: return isFunction(o); case CFTypes.TYPE_XML: return isXML(o); } if(o instanceof Component) { Component comp=((Component)o); return comp.instanceOf(strType); } if(isArrayType(strType) && isArray(o)){ String _strType=strType.substring(0,strType.length()-2); short _type=CFTypes.toShort(_strType, false, (short)-1); Array arr = Caster.toArray(o,null); if(arr!=null){ Iterator<Object> it = arr.valueIterator(); while(it.hasNext()){ Object obj = it.next(); if(!isCastableTo(_type,_strType, obj)) return false; } return true; } } return false; } public synchronized static boolean isDate(String str,Locale locale, TimeZone tz,boolean lenient) { str=str.trim(); tz=ThreadLocalPageContext.getTimeZone(tz); DateFormat[] df; // get Calendar Calendar c=JREDateTimeUtil.getThreadCalendar(locale); // datetime ParsePosition pp=new ParsePosition(0); df=FormatUtil.getDateTimeFormats(locale,tz,false);//dfc[FORMATS_DATE_TIME]; Date d; for(int i=0;i<df.length;i++) { pp.setErrorIndex(-1); pp.setIndex(0); df[i].setTimeZone(tz); d = df[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; return true; } // date df=FormatUtil.getDateFormats(locale,tz,false); for(int i=0;i<df.length;i++) { pp.setErrorIndex(-1); pp.setIndex(0); df[i].setTimeZone(tz); d=df[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; return true; } // time df=FormatUtil.getTimeFormats(locale,tz,false);//dfc[FORMATS_TIME]; for(int i=0;i<df.length;i++) { pp.setErrorIndex(-1); pp.setIndex(0); df[i].setTimeZone(tz); d=df[i].parse(str,pp); if (pp.getIndex() == 0 || d==null || pp.getIndex()<str.length()) continue; return true; } if(lenient) return isDateSimple(str, false); return false; } /** * Checks if number is valid (not infinity or NaN) * @param dbl * @return */ public static boolean isValid(double dbl) { return !Double.isNaN(dbl) && !Double.isInfinite(dbl); } }