package railo.runtime.tag;
import java.io.IOException;
import javax.servlet.jsp.tagext.Tag;
import railo.commons.lang.StringUtil;
import railo.runtime.db.SQLCaster;
import railo.runtime.db.SQLItemImpl;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.DatabaseException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.TagImpl;
import railo.runtime.op.Caster;
import railo.runtime.type.Array;
import railo.runtime.type.ArrayImpl;
import railo.runtime.type.util.ListUtil;
/**
* Checks the data type of a query parameter. The cfqueryparam tag is nested within a cfquery tag.
* It is embedded within the query SQL statement. If you specify its optional parameters, cfqueryparam
* also performs data validation.
*
*
*
**/
public final class QueryParam extends TagImpl {
private SQLItemImpl item=new SQLItemImpl();
/** Specifies the character that separates values in the list of parameter values in the value
** attribute. The default is a comma. If you specify a list of values for the value attribute, you must
** also specify the list attribute. */
private String separator=",";
/** Yes or No. Indicates that the parameter value of the value attribute is a list of values,
** separated by a separator character. The default is No */
private boolean list;
/** Maximum length of the parameter. The default value is the length of the string specified in
** the value attribute. */
private double maxlength=-1;
@Override
public void release() {
separator=",";
list=false;
maxlength=-1;
item=new SQLItemImpl();
}
/** set the value list
* Yes or No. Indicates that the parameter value of the value attribute is a list of values,
* separated by a separator character. The default is No
* @param list value to set
**/
public void setList(boolean list) {
this.list=list;
}
/** set the value null
* Yes or No. Indicates whether the parameter is passed as a null. If Yes, the tag ignores the
* value attribute. The default is No.
* @param nulls value to set
**/
public void setNull(boolean nulls) {
item.setNulls(nulls);
}
/** set the value value
* @param value value to set
**/
public void setValue(Object value) {
item.setValue(value);
}
/** set the value maxlength
* Maximum length of the parameter. The default value is the length of the string specified in
* the value attribute.
* @param maxlength value to set
**/
public void setMaxlength(double maxlength) {
this.maxlength=maxlength;
}
/** set the value separator
* Specifies the character that separates values in the list of parameter values in the value
* attribute. The default is a comma. If you specify a list of values for the value attribute, you must
* also specify the list attribute.
* @param separator value to set
**/
public void setSeparator(String separator) {
this.separator=separator;
}
/** set the value scale
* Number of decimal places of the parameter. The default value is zero.
* @param scale value to set
**/
public void setScale(double scale) {
item.setScale((int)scale);
}
/** set the value cfsqltype
* The SQL type that the parameter (any type) will be bound to.
* @param type value to set
* @throws DatabaseException
**/
public void setCfsqltype(String type) throws DatabaseException {
item.setType(SQLCaster.toIntType(type));
}
public void setSqltype(String type) throws DatabaseException {
item.setType(SQLCaster.toIntType(type));
}
@Override
public int doStartTag() throws PageException {
Tag parent = getParent();
while(parent!=null && !(parent instanceof Query)) {
parent=parent.getParent();
}
if(parent instanceof Query) {
Query query = (Query)parent;
if(!item.isNulls() && !item.isValueSet())
throw new ApplicationException("attribute value from tag queryparam is required if attribute null is false");
if(list) {
String v = Caster.toString(item.getValue());
Array arr=null;
if(StringUtil.isEmpty(v)){
arr=new ArrayImpl();
arr.append("");
}
else arr=ListUtil.listToArrayRemoveEmpty(v,separator);
int len=arr.size();
StringBuffer sb=new StringBuffer();
for(int i=1;i<=len;i++) {
query.setParam(item.clone(check(arr.getE(i))));
if(i>1)sb.append(',');
sb.append('?');
}
write(sb.toString());
}
else {
check(item.getValue());
query.setParam(item);
write("?");
}
}
else {
throw new ApplicationException("Wrong Context, tag QueryParam must be inside a Query tag");
}
return SKIP_BODY;
}
private Object check(Object value) throws PageException {
if(maxlength!=-1) {
String str = Caster.toString(value);
if(str.length()>maxlength)
throw new DatabaseException("value ["+value+"] is to large, defined maxlength is ["+Caster.toString(maxlength)+"] but length of value is ["+str.length()+"]",null,null,null);
}
return value;
}
private void write(String str) {
try {
pageContext.write(str);
}
catch (IOException e) {}
}
}