package railo.transformer.cfml.evaluator.impl; import railo.runtime.op.Caster; import railo.transformer.bytecode.cast.CastString; import railo.transformer.bytecode.expression.ExprString; import railo.transformer.bytecode.expression.Expression; import railo.transformer.bytecode.literal.LitBoolean; import railo.transformer.bytecode.literal.LitDouble; import railo.transformer.bytecode.literal.LitString; import railo.transformer.bytecode.statement.tag.Attribute; import railo.transformer.bytecode.statement.tag.Tag; import railo.transformer.bytecode.util.ASMUtil; import railo.transformer.cfml.evaluator.EvaluatorException; import railo.transformer.cfml.evaluator.EvaluatorSupport; import railo.transformer.library.tag.TagLibTag; /** * * Prft den Kontext des Tag argument. * Das Tag <code>argument</code> darf nur direkt innerhalb des Tag <code>function</code> liegen. * Dem Tag <code>argument</code> muss als erstes im tag function vorkommen */ public final class Argument extends EvaluatorSupport { //� /** * @see railo.transformer.cfml.evaluator.EvaluatorSupport#evaluate(org.w3c.dom.Element, railo.transformer.library.tag.TagLibTag) */ public void evaluate(Tag tag, TagLibTag libTag) throws EvaluatorException { String ns=libTag.getTagLib().getNameSpaceAndSeparator(); String functionName=ns+"function"; ASMUtil.isLiteralAttribute(tag,"type",ASMUtil.TYPE_STRING,false,true); ASMUtil.isLiteralAttribute(tag,"name",ASMUtil.TYPE_STRING,false,true); //ASMUtil.isLiteralAttribute(tag,"hint",ASMUtil.TYPE_STRING,false,true); //ASMUtil.isLiteralAttribute(tag,"displayname",ASMUtil.TYPE_STRING,false,true); // check if default can be converted to a literal value that match the type declration. checkDefaultValue(tag); // check attribute passby Attribute attrPassBy = tag.getAttribute("passby"); if(attrPassBy!=null) { ExprString expr = CastString.toExprString(attrPassBy.getValue()); if(!(expr instanceof LitString)) throw new EvaluatorException("Attribute passby of the Tag Argument, must be a literal string"); LitString lit = (LitString)expr; String passBy = lit.getString().toLowerCase().trim(); if(!"value".equals(passBy) && !"ref".equals(passBy) && !"reference".equals(passBy)) throw new EvaluatorException("Attribute passby of the Tag Argument has an invalid value ["+passBy+"], valid values are [reference,value]"); } // check if tag is direct inside function if(!ASMUtil.isParentTag(tag,functionName)) { Tag parent=ASMUtil.getParentTag(tag); String addText=(parent!=null)? "but tag "+libTag.getFullName()+" is inside tag "+parent.getFullname()+"": "but tag "+libTag.getFullName()+" has no parent"; throw new EvaluatorException("Wrong Context, tag "+libTag.getFullName() +" must be direct inside a "+functionName+" tag, "+addText); } // TODO check if there is a tag other than argument and text before } public static void checkDefaultValue(Tag tag) { Attribute _type = tag.getAttribute("type"); if(_type!=null) { ExprString typeValue = CastString.toExprString(_type.getValue()); if(typeValue instanceof LitString) { String strType=((LitString)typeValue).getString(); Attribute _default = tag.getAttribute("default"); if(_default!=null) { Expression defaultValue = _default.getValue(); if(defaultValue instanceof LitString) { String strDefault=((LitString)defaultValue).getString(); // check for boolean if("boolean".equalsIgnoreCase(strType)) { if("true".equalsIgnoreCase(strDefault) || "yes".equalsIgnoreCase(strDefault)) tag.addAttribute(new Attribute(_default.isDynamicType(),_default.getName(), LitBoolean.TRUE, _default.getType())); if("false".equalsIgnoreCase(strDefault) || "no".equalsIgnoreCase(strDefault)) tag.addAttribute(new Attribute(_default.isDynamicType(),_default.getName(), LitBoolean.FALSE, _default.getType())); } // check for numbers if("number".equalsIgnoreCase(strType) || "numeric".equalsIgnoreCase(strType)) { Double dbl = Caster.toDouble(strDefault,null); if(dbl!=null) { tag.addAttribute(new Attribute(_default.isDynamicType(),_default.getName(), LitDouble.toExprDouble(dbl.doubleValue()), _default.getType())); } } } } } } } }