001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.transformer.cfml.evaluator.impl;
020
021import java.util.ArrayList;
022import java.util.Iterator;
023import java.util.List;
024
025import lucee.runtime.functions.list.ListQualify;
026import lucee.runtime.functions.other.PreserveSingleQuotes;
027import lucee.runtime.functions.other.QuotedValueList;
028import lucee.runtime.functions.query.ValueList;
029import lucee.transformer.bytecode.Body;
030import lucee.transformer.bytecode.Literal;
031import lucee.transformer.bytecode.Statement;
032import lucee.transformer.bytecode.cast.CastOther;
033import lucee.transformer.bytecode.cast.CastString;
034import lucee.transformer.bytecode.expression.Expression;
035import lucee.transformer.bytecode.expression.var.Argument;
036import lucee.transformer.bytecode.expression.var.BIF;
037import lucee.transformer.bytecode.expression.var.Member;
038import lucee.transformer.bytecode.expression.var.UDF;
039import lucee.transformer.bytecode.expression.var.Variable;
040import lucee.transformer.bytecode.literal.LitBoolean;
041import lucee.transformer.bytecode.literal.LitString;
042import lucee.transformer.bytecode.statement.PrintOut;
043import lucee.transformer.bytecode.statement.tag.Tag;
044import lucee.transformer.cfml.evaluator.EvaluatorException;
045import lucee.transformer.cfml.evaluator.EvaluatorSupport;
046
047
048/**
049 * sign print outs for preserver
050*/
051public final class Query extends EvaluatorSupport {
052
053        /**
054         * @see lucee.transformer.cfml.evaluator.EvaluatorSupport#evaluate(org.w3c.dom.Element)
055         */
056        public void evaluate(Tag tag) throws EvaluatorException { 
057                translateChildren(tag.getBody().getStatements().iterator());
058        }
059        
060        private void translateChildren(Iterator it) {
061                Statement stat;
062                 
063                while(it.hasNext()) {
064                        stat=(Statement) it.next();
065                        if(stat instanceof PrintOut) {
066                                PrintOut printOut = ((PrintOut)stat);
067                                Expression e = printOut.getExpr();
068                                if(!(e instanceof Literal)) {
069                                        Expression expr=removeCastString(e);
070                                        
071                                        if(expr instanceof Variable) {
072                                                // do not preserve BIF PreserveSingleQuotes return value
073                                                Member member = ((Variable)expr).getFirstMember();
074                                                if(member instanceof BIF) {
075                                                        BIF bif=(BIF) member;
076
077                                                        if(bif.getClazz().getName().equals(PreserveSingleQuotes.class.getName())) {
078                                                                printOut.setExpr(bif.getArguments()[0].getValue());
079                                                                continue;
080                                                        }
081                                                        else if(bif.getClazz().getName().equals(ListQualify.class.getName())) {
082                                                                Argument[] args = bif.getArguments();
083                                                                List<Argument> arr=new ArrayList<Argument>();
084                                                                
085                                                                // first get existing arguments
086                                                                arr.add(args[0]);
087                                                                arr.add(args[1]);
088                                                                if(args.length>=3)arr.add(args[2]);
089                                                                else arr.add(new Argument(LitString.toExprString(","),"string"));
090                                                                if(args.length>=4)arr.add(args[3]);
091                                                                else arr.add(new Argument(LitString.toExprString("all"),"string"));
092                                                                if(args.length>=5)arr.add(args[4]);
093                                                                else arr.add(new Argument(LitBoolean.toExprBoolean(false),"boolean"));
094                                                                
095                                                                
096                                                                // PSQ-BIF DO NOT REMOVE THIS COMMENT
097                                                                arr.add(new Argument(LitBoolean.toExprBoolean(true),"boolean"));
098                                                                bif.setArguments(arr.toArray(new Argument[arr.size()]));
099                                                                continue;
100                                                        }
101                                                        else if(
102                                                                bif.getClazz().getName().equals(QuotedValueList.class.getName()) ||
103                                                                bif.getClazz().getName().equals(ValueList.class.getName())
104                                                                ) {
105                                                                //printOut.setPreserveSingleQuote(false);
106                                                                continue;
107                                                        }
108                                                }
109                                                
110                                                // do not preserve UDF return value
111                                                member= ((Variable)expr).getLastMember();
112                                                if(member instanceof UDF) continue;
113                                        }
114                                        printOut.setCheckPSQ(true);
115                                        if(e!=expr)printOut.setExpr(expr);
116                                }
117                        }
118                        else if(stat instanceof Tag){
119                                Body b=((Tag)stat).getBody();
120                                if(b!=null) 
121                                        translateChildren(b.getStatements().iterator());
122                        }
123                        else if(stat instanceof Body){
124                                translateChildren(((Body)stat).getStatements().iterator());
125                        }
126                }
127        }
128
129        private Expression removeCastString(Expression expr) {
130                while(true) {
131                        if(expr instanceof CastString){
132                                expr=((CastString)expr).getExpr();
133                                
134                        }
135                        else if(
136                                        expr instanceof CastOther && 
137                                        (
138                                                        ((CastOther) expr).getType().equalsIgnoreCase("String") || 
139                                                        ((CastOther) expr).getType().equalsIgnoreCase("java.lang.String")
140                                        )
141                                ){
142                                        expr=((CastOther) expr).getExpr();
143                        }
144                        else break;
145                }
146                return expr;
147        }
148}
149
150
151
152