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.runtime.functions.list;
020
021import lucee.commons.lang.StringUtil;
022import lucee.runtime.PageContext;
023import lucee.runtime.exp.FunctionException;
024import lucee.runtime.exp.PageException;
025import lucee.runtime.functions.BIF;
026import lucee.runtime.op.Caster;
027import lucee.runtime.op.Decision;
028import lucee.runtime.type.Array;
029import lucee.runtime.type.util.ListUtil;
030
031/**
032 * Implements the CFML Function listqualify
033 */
034public final class ListQualify extends BIF {
035        
036        private static final long serialVersionUID = -7450079285934992224L;
037        
038        public static String call(PageContext pc , String list, String qualifier) {
039                return call(pc,list,qualifier,",","all", false, false);
040        }
041
042        public static String call(PageContext pc , String list, String qualifier, String delimiter) {
043                return call(pc,list,qualifier,delimiter,"all", false, false);
044        }
045
046        public static String call(PageContext pc , String list, String qualifier, String delimiter, String elements) {
047                return call(pc, list, qualifier, delimiter, elements, false, false);
048        }
049        
050        public static String call(PageContext pc , String list, String qualifier, String delimiter, String elements, boolean includeEmptyFields) {
051                return call(pc, list, qualifier, delimiter, elements, includeEmptyFields, false);
052        }
053        
054        public static String call(PageContext pc , String list, String qualifier, String delimiter, String elements, boolean includeEmptyFields, 
055                        boolean psq // this is used only internally by lucee, search for "PSQ-BIF" in code
056                        ) {
057                
058                if(list.length()==0) return "";
059                if(psq)list=StringUtil.replace(list, "'", "''", false);
060                
061                Array arr=includeEmptyFields?ListUtil.listToArray(list,delimiter):ListUtil.listToArrayRemoveEmpty(list,delimiter);
062                
063                boolean isQChar=qualifier.length()==1;
064                boolean isDChar=delimiter.length()==1;
065                
066                if(isQChar && isDChar) return doIt(arr,qualifier.charAt(0),delimiter.charAt(0),elements);
067                else if(isQChar && !isDChar) return doIt(arr,qualifier.charAt(0),delimiter,elements);
068                else if(!isQChar && isDChar) return doIt(arr,qualifier,delimiter.charAt(0),elements);
069                else return doIt(arr,qualifier,delimiter,elements);
070                
071        }
072
073    private static String doIt(Array arr, char qualifier, char delimiter, String elements) {
074        StringBuilder rtn=new StringBuilder();
075        int len=arr.size();
076        
077                if(StringUtil.toLowerCase(elements).equals("all")) {
078                        rtn.append(qualifier);
079                        rtn.append(arr.get(1,""));
080                        rtn.append(qualifier);
081                        for(int i=2;i<=len;i++) {
082                                rtn.append(delimiter);
083                                rtn.append(qualifier);
084                                rtn.append(arr.get(i,""));
085                                rtn.append(qualifier);
086                        }
087                }
088                else {
089                        qualifyString(rtn,arr.get(1,"").toString(),qualifier);
090                        for(int i=2;i<=len;i++) {
091                                rtn.append(delimiter);
092                                qualifyString(rtn,arr.get(i,"").toString(),qualifier);
093                        }
094                }
095                return rtn.toString();
096    }
097    private static String doIt(Array arr, char qualifier, String delimiter, String scope) {
098        StringBuilder rtn=new StringBuilder();
099        int len=arr.size();
100        
101                if(StringUtil.toLowerCase(scope).equals("all")) {
102                        rtn.append(qualifier);
103                        rtn.append(arr.get(1,""));
104                        rtn.append(qualifier);
105                        for(int i=2;i<=len;i++) {
106                                rtn.append(delimiter);
107                                rtn.append(qualifier);
108                                rtn.append(arr.get(i,""));
109                                rtn.append(qualifier);
110                        }
111                }
112                else {
113                        qualifyString(rtn,arr.get(1,"").toString(),qualifier);
114                        for(int i=2;i<=len;i++) {
115                                rtn.append(delimiter);
116                                qualifyString(rtn,arr.get(i,"").toString(),qualifier);
117                        }
118                }
119                return rtn.toString();
120    }
121    private static String doIt(Array arr, String qualifier, char delimiter, String scope) {
122        StringBuilder rtn=new StringBuilder();
123        int len=arr.size();
124        
125                if(StringUtil.toLowerCase(scope).equals("all")) {
126                        rtn.append(qualifier);
127                        rtn.append(arr.get(1,""));
128                        rtn.append(qualifier);
129                        for(int i=2;i<=len;i++) {
130                                rtn.append(delimiter);
131                                rtn.append(qualifier);
132                                rtn.append(arr.get(i,""));
133                                rtn.append(qualifier);
134                        }
135                }
136                else {
137                        qualifyString(rtn,arr.get(1,"").toString(),qualifier);
138                        for(int i=2;i<=len;i++) {
139                                rtn.append(delimiter);
140                                qualifyString(rtn,arr.get(i,"").toString(),qualifier);
141                        }
142                }
143                return rtn.toString();
144    }
145    private static String doIt(Array arr, String qualifier, String delimiter, String scope) {
146        StringBuilder rtn=new StringBuilder();
147        int len=arr.size();
148        
149                if(StringUtil.toLowerCase(scope).equals("all")) {
150                        rtn.append(qualifier);
151                        rtn.append(arr.get(1,""));
152                        rtn.append(qualifier);
153                        for(int i=2;i<=len;i++) {
154                                rtn.append(delimiter);
155                                rtn.append(qualifier);
156                                rtn.append(arr.get(i,""));
157                                rtn.append(qualifier);
158                        }
159                }
160                else {
161                        qualifyString(rtn,arr.get(1,"").toString(),qualifier);
162                        for(int i=2;i<=len;i++) {
163                                rtn.append(delimiter);
164                                qualifyString(rtn,arr.get(i,"").toString(),qualifier);
165                        }
166                }
167                return rtn.toString();
168    }
169    
170    
171    private static void qualifyString(StringBuilder rtn,String value,String qualifier) {
172                if(Decision.isNumeric(value)) rtn.append(value);
173                else {
174                        rtn.append(qualifier);
175                        rtn.append(value);
176                        rtn.append(qualifier);
177                }
178        }
179        private static void qualifyString(StringBuilder rtn,String value,char qualifier) {
180                if(Decision.isNumeric(value)) rtn.append(value);
181                else {
182                        rtn.append(qualifier);
183                        rtn.append(value);
184                        rtn.append(qualifier);
185                }
186        }
187        
188    @Override
189        public Object invoke(PageContext pc, Object[] args) throws PageException {
190        if(args.length==2)
191                        return call(pc, Caster.toString(args[0]), Caster.toString(args[1]));
192        if(args.length==3)
193                        return call(pc, Caster.toString(args[0]), Caster.toString(args[1]), Caster.toString(args[2]));
194        if(args.length==4)
195                        return call(pc, Caster.toString(args[0]), Caster.toString(args[1]), Caster.toString(args[2]), Caster.toString(args[3]));
196        if(args.length==5)
197                        return call(pc, Caster.toString(args[0]), Caster.toString(args[1]), Caster.toString(args[2]), Caster.toString(args[3]), Caster.toBooleanValue(args[4]));
198        
199                throw new FunctionException(pc, "ListQualify", 2, 5, args.length);
200        }
201    
202    
203}