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