001 package railo.transformer.cfml.evaluator.impl; 002 003 import railo.runtime.op.Caster; 004 import railo.transformer.bytecode.cast.CastString; 005 import railo.transformer.bytecode.expression.ExprString; 006 import railo.transformer.bytecode.expression.Expression; 007 import railo.transformer.bytecode.literal.LitBoolean; 008 import railo.transformer.bytecode.literal.LitDouble; 009 import railo.transformer.bytecode.literal.LitString; 010 import railo.transformer.bytecode.statement.tag.Attribute; 011 import railo.transformer.bytecode.statement.tag.Tag; 012 import railo.transformer.bytecode.util.ASMUtil; 013 import railo.transformer.cfml.evaluator.EvaluatorException; 014 import railo.transformer.cfml.evaluator.EvaluatorSupport; 015 import railo.transformer.library.tag.TagLibTag; 016 017 018 019 /** 020 * 021 * Prft den Kontext des Tag argument. 022 * Das Tag <code>argument</code> darf nur direkt innerhalb des Tag <code>function</code> liegen. 023 * Dem Tag <code>argument</code> muss als erstes im tag function vorkommen 024 */ 025 public final class Argument extends EvaluatorSupport { 026 //� 027 /** 028 * @see railo.transformer.cfml.evaluator.EvaluatorSupport#evaluate(org.w3c.dom.Element, railo.transformer.library.tag.TagLibTag) 029 */ 030 public void evaluate(Tag tag, TagLibTag libTag) throws EvaluatorException { 031 String ns=libTag.getTagLib().getNameSpaceAndSeparator(); 032 String functionName=ns+"function"; 033 034 ASMUtil.isLiteralAttribute(tag,"type",ASMUtil.TYPE_STRING,false,true); 035 ASMUtil.isLiteralAttribute(tag,"name",ASMUtil.TYPE_STRING,false,true); 036 //ASMUtil.isLiteralAttribute(tag,"hint",ASMUtil.TYPE_STRING,false,true); 037 //ASMUtil.isLiteralAttribute(tag,"displayname",ASMUtil.TYPE_STRING,false,true); 038 039 // check if default can be converted to a literal value that match the type declration. 040 checkDefaultValue(tag); 041 042 // check attribute passby 043 Attribute attrPassBy = tag.getAttribute("passby"); 044 if(attrPassBy!=null) { 045 ExprString expr = CastString.toExprString(attrPassBy.getValue()); 046 if(!(expr instanceof LitString)) 047 throw new EvaluatorException("Attribute passby of the Tag Argument, must be a literal string"); 048 LitString lit = (LitString)expr; 049 String passBy = lit.getString().toLowerCase().trim(); 050 if(!"value".equals(passBy) && !"ref".equals(passBy) && !"reference".equals(passBy)) 051 throw new EvaluatorException("Attribute passby of the Tag Argument has a invalid value ["+passBy+"], valid values are [reference,value]"); 052 } 053 054 // check if tag is direct inside function 055 if(!ASMUtil.isParentTag(tag,functionName)) { 056 Tag parent=ASMUtil.getParentTag(tag); 057 058 String addText=(parent!=null)? 059 "but tag "+libTag.getFullName()+" is inside tag "+parent.getFullname()+"": 060 "but tag "+libTag.getFullName()+" has no parent"; 061 062 throw new EvaluatorException("Wrong Context, tag "+libTag.getFullName() 063 +" must be direct inside a "+functionName+" tag, "+addText); 064 } 065 // TODO check if there is a tag other than argument and text before 066 067 } 068 069 public static void checkDefaultValue(Tag tag) { 070 Attribute _type = tag.getAttribute("type"); 071 if(_type!=null) { 072 ExprString typeValue = CastString.toExprString(_type.getValue()); 073 if(typeValue instanceof LitString) { 074 String strType=((LitString)typeValue).getString(); 075 Attribute _default = tag.getAttribute("default"); 076 if(_default!=null) { 077 Expression defaultValue = _default.getValue(); 078 if(defaultValue instanceof LitString) { 079 String strDefault=((LitString)defaultValue).getString(); 080 081 082 083 // check for boolean 084 if("boolean".equalsIgnoreCase(strType)) { 085 if("true".equalsIgnoreCase(strDefault) || "yes".equalsIgnoreCase(strDefault)) 086 tag.addAttribute(new Attribute(_default.isDynamicType(),_default.getName(), LitBoolean.TRUE, _default.getType())); 087 if("false".equalsIgnoreCase(strDefault) || "no".equalsIgnoreCase(strDefault)) 088 tag.addAttribute(new Attribute(_default.isDynamicType(),_default.getName(), LitBoolean.FALSE, _default.getType())); 089 } 090 091 // check for numbers 092 if("number".equalsIgnoreCase(strType) || "numeric".equalsIgnoreCase(strType)) { 093 Double dbl = Caster.toDouble(strDefault,null); 094 if(dbl!=null) { 095 tag.addAttribute(new Attribute(_default.isDynamicType(),_default.getName(), LitDouble.toExprDouble(dbl.doubleValue(), -1), _default.getType())); 096 } 097 } 098 } 099 } 100 } 101 } 102 } 103 104 }