001 package railo.runtime.tag; 002 003 import java.io.IOException; 004 005 import javax.servlet.jsp.tagext.Tag; 006 007 import railo.commons.lang.StringUtil; 008 import railo.runtime.db.SQLCaster; 009 import railo.runtime.db.SQLItemImpl; 010 import railo.runtime.exp.ApplicationException; 011 import railo.runtime.exp.DatabaseException; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.ext.tag.TagImpl; 014 import railo.runtime.op.Caster; 015 import railo.runtime.type.Array; 016 import railo.runtime.type.ArrayImpl; 017 import railo.runtime.type.List; 018 019 /** 020 * Checks the data type of a query parameter. The cfqueryparam tag is nested within a cfquery tag. 021 * It is embedded within the query SQL statement. If you specify its optional parameters, cfqueryparam 022 * also performs data validation. 023 * 024 * 025 * 026 **/ 027 public final class QueryParam extends TagImpl { 028 029 private SQLItemImpl item=new SQLItemImpl(); 030 031 /** Specifies the character that separates values in the list of parameter values in the value 032 ** attribute. The default is a comma. If you specify a list of values for the value attribute, you must 033 ** also specify the list attribute. */ 034 private String separator=","; 035 036 /** Yes or No. Indicates that the parameter value of the value attribute is a list of values, 037 ** separated by a separator character. The default is No */ 038 private boolean list; 039 040 041 /** Maximum length of the parameter. The default value is the length of the string specified in 042 ** the value attribute. */ 043 private double maxlength=-1; 044 045 /** 046 * @see javax.servlet.jsp.tagext.Tag#release() 047 */ 048 public void release() { 049 separator=","; 050 list=false; 051 maxlength=-1; 052 item=new SQLItemImpl(); 053 } 054 055 056 /** set the value list 057 * Yes or No. Indicates that the parameter value of the value attribute is a list of values, 058 * separated by a separator character. The default is No 059 * @param list value to set 060 **/ 061 public void setList(boolean list) { 062 this.list=list; 063 } 064 065 /** set the value null 066 * Yes or No. Indicates whether the parameter is passed as a null. If Yes, the tag ignores the 067 * value attribute. The default is No. 068 * @param nulls value to set 069 **/ 070 public void setNull(boolean nulls) { 071 item.setNulls(nulls); 072 } 073 074 /** set the value value 075 * @param value value to set 076 **/ 077 public void setValue(Object value) { 078 item.setValue(value); 079 } 080 081 /** set the value maxlength 082 * Maximum length of the parameter. The default value is the length of the string specified in 083 * the value attribute. 084 * @param maxlength value to set 085 **/ 086 public void setMaxlength(double maxlength) { 087 this.maxlength=maxlength; 088 } 089 090 /** set the value separator 091 * Specifies the character that separates values in the list of parameter values in the value 092 * attribute. The default is a comma. If you specify a list of values for the value attribute, you must 093 * also specify the list attribute. 094 * @param separator value to set 095 **/ 096 public void setSeparator(String separator) { 097 this.separator=separator; 098 } 099 100 /** set the value scale 101 * Number of decimal places of the parameter. The default value is zero. 102 * @param scale value to set 103 **/ 104 public void setScale(double scale) { 105 item.setScale((int)scale); 106 } 107 108 /** set the value cfsqltype 109 * The SQL type that the parameter (any type) will be bound to. 110 * @param type value to set 111 * @throws DatabaseException 112 **/ 113 public void setCfsqltype(String type) throws DatabaseException { 114 item.setType(SQLCaster.toIntType(type)); 115 116 } 117 118 /** 119 * @see javax.servlet.jsp.tagext.Tag#doStartTag() 120 */ 121 public int doStartTag() throws PageException { 122 Tag parent = getParent(); 123 while(parent!=null && !(parent instanceof Query)) { 124 parent=parent.getParent(); 125 } 126 if(parent instanceof Query) { 127 Query query = (Query)parent; 128 if(!item.isNulls() && !item.isValueSet()) 129 throw new ApplicationException("attribute value from tag queryparam is required if attribute null is false"); 130 if(list) { 131 String v = Caster.toString(item.getValue()); 132 Array arr=null; 133 if(StringUtil.isEmpty(v)){ 134 arr=new ArrayImpl(); 135 arr.append(""); 136 } 137 else arr=List.listToArrayRemoveEmpty(v,separator); 138 139 int len=arr.size(); 140 StringBuffer sb=new StringBuffer(); 141 for(int i=1;i<=len;i++) { 142 query.setParam(item.clone(check(arr.getE(i)))); 143 if(i>1)sb.append(','); 144 sb.append('?'); 145 } 146 write(sb.toString()); 147 } 148 else { 149 check(item.getValue()); 150 query.setParam(item); 151 write("?"); 152 } 153 } 154 else { 155 throw new ApplicationException("Wrong Context, tag QueryParam must be inside a Query tag"); 156 } 157 return SKIP_BODY; 158 } 159 160 private Object check(Object value) throws PageException { 161 if(maxlength!=-1) { 162 String str = Caster.toString(value); 163 if(str.length()>maxlength) 164 throw new DatabaseException("value ["+value+"] is to large, defined maxlength is ["+Caster.toString(maxlength)+"] but length of value is ["+str.length()+"]",null,null,null); 165 } 166 return value; 167 } 168 169 private void write(String str) { 170 try { 171 pageContext.write(str); 172 } 173 catch (IOException e) {} 174 } 175 176 }