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    }