001 package railo.transformer.cfml.evaluator.impl; 002 003 004 import java.util.Iterator; 005 import java.util.List; 006 import java.util.Map; 007 008 import railo.runtime.functions.system.CFFunction; 009 import railo.transformer.bytecode.Body; 010 import railo.transformer.bytecode.BytecodeException; 011 import railo.transformer.bytecode.Literal; 012 import railo.transformer.bytecode.Statement; 013 import railo.transformer.bytecode.cast.CastBoolean; 014 import railo.transformer.bytecode.expression.Expression; 015 import railo.transformer.bytecode.literal.LitBoolean; 016 import railo.transformer.bytecode.literal.LitString; 017 import railo.transformer.bytecode.statement.PrintOut; 018 import railo.transformer.bytecode.statement.tag.Attribute; 019 import railo.transformer.bytecode.statement.tag.Tag; 020 import railo.transformer.bytecode.util.ASMUtil; 021 import railo.transformer.cfml.evaluator.EvaluatorException; 022 import railo.transformer.cfml.evaluator.EvaluatorSupport; 023 import railo.transformer.library.function.FunctionLib; 024 import railo.transformer.library.function.FunctionLibFunction; 025 import railo.transformer.library.tag.TagLibTag; 026 027 /** 028 * Pr�ft den Kontext des Tag function. 029 * Das Attribute <code>argument</code> darf nur direkt innerhalb des Tag <code>function</code> liegen. 030 * Dem Tag <code>argument</code> muss als erstes im tag function vorkommen 031 */ 032 public final class Function extends EvaluatorSupport { 033 034 //� 035 /** 036 * @see railo.transformer.cfml.evaluator.EvaluatorSupport#evaluate(org.w3c.dom.Element, railo.transformer.library.tag.TagLibTag) 037 */ 038 public void evaluate(Tag tag, TagLibTag libTag, FunctionLib[] flibs) throws EvaluatorException { 039 Body p=(Body) tag.getParent(); 040 Statement pp = p.getParent(); 041 042 boolean isCFC=true; 043 try { 044 isCFC = ASMUtil.getAncestorPage(tag).isComponent(); 045 } catch (BytecodeException e) {} 046 047 Attribute attrName = tag.getAttribute("name"); 048 if(attrName!=null) { 049 Expression expr = attrName.getValue(); 050 if(expr instanceof LitString && !isCFC){ 051 checkFunctionName(((LitString)expr).getString(),flibs); 052 } 053 054 } 055 // attribute abstract 056 Attribute attrAbstract = tag.getAttribute("abstract"); 057 if(attrAbstract!=null) { 058 Expression expr = CastBoolean.toExprBoolean(attrAbstract.getValue()); 059 if(!(expr instanceof LitBoolean)) 060 throw new EvaluatorException("Attribute abstract of the Tag Function, must be a literal boolean value (true or false, yes or no)"); 061 boolean abstr = ((LitBoolean)expr).getBooleanValue(); 062 if(abstr)throwIfNotEmpty(tag); 063 } 064 065 // Attribute Output 066 // "output=true" wird in "railo.transformer.cfml.attributes.impl.Function" geh�ndelt 067 Attribute attrOutput = tag.getAttribute("output"); 068 if(attrOutput!=null) { 069 Expression expr = CastBoolean.toExprBoolean(attrOutput.getValue()); 070 if(!(expr instanceof LitBoolean)) 071 throw new EvaluatorException("Attribute output of the Tag Function, must be a literal boolean value (true or false, yes or no)"); 072 boolean output = ((LitBoolean)expr).getBooleanValue(); 073 //if(!output) ASMUtil.removeLiterlChildren(tag, true); 074 } 075 076 077 //if(ASMUtil.isRoot(pp)) { 078 Map attrs = tag.getAttributes(); 079 Iterator it = attrs.keySet().iterator(); 080 Attribute attr; 081 while(it.hasNext()) { 082 attr=(Attribute) attrs.get(it.next()); 083 checkAttributeValue(tag,attr); 084 } 085 //} 086 087 } 088 089 090 public static void checkFunctionName(String name, FunctionLib[] flibs) throws EvaluatorException { 091 FunctionLibFunction flf; 092 for (int i = 0; i < flibs.length; i++) { 093 flf = flibs[i].getFunction(name); 094 if(flf!=null && flf.getCazz()!=CFFunction.class) { 095 throw new EvaluatorException("The name ["+name+"] is already used by a built in Function"); 096 } 097 } 098 } 099 100 101 public static void throwIfNotEmpty(Tag tag) throws EvaluatorException { 102 Body body = tag.getBody(); 103 List statments = body.getStatements(); 104 Statement stat; 105 Iterator it = statments.iterator(); 106 TagLibTag tlt; 107 108 while(it.hasNext()) { 109 stat=(Statement) it.next(); 110 if(stat instanceof PrintOut) { 111 //body.remove(stat); 112 } 113 else if(stat instanceof Tag) { 114 tlt = ((Tag)stat).getTagLibTag(); 115 if(!tlt.getTagClassName().equals("railo.runtime.tag.Argument")) 116 throw new EvaluatorException("tag "+tlt.getFullName()+" is not allowed inside a function declaration"); 117 } 118 } 119 } 120 121 private void checkAttributeValue(Tag tag, Attribute attr) throws EvaluatorException { 122 if(!(attr.getValue() instanceof Literal)) 123 throw new EvaluatorException("Attribute ["+attr.getName()+"] of the Tag ["+tag.getFullname()+"] must be a literal/constant value"); 124 125 } 126 }