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 **/
019/**
020 * Implements the CFML Function listsetat
021 */
022package lucee.runtime.functions.list;
023
024import lucee.runtime.PageContext;
025import lucee.runtime.exp.ExpressionException;
026import lucee.runtime.exp.FunctionException;
027import lucee.runtime.exp.PageException;
028import lucee.runtime.functions.BIF;
029import lucee.runtime.op.Caster;
030import lucee.runtime.type.Array;
031import lucee.runtime.type.util.ListUtil;
032
033public final class ListSetAt extends BIF {
034
035        private static final long serialVersionUID = -105782799713547552L;
036
037        public static String call(PageContext pc , String list, double posNumber, String value) throws ExpressionException {
038                return call(pc,list,posNumber,value,",",false);
039        }
040
041        public static String call(PageContext pc , String list, double posNumber, String value, String delimiter) throws ExpressionException {
042                return call(pc,list,posNumber,value,delimiter,false);
043        }
044        public static String call(PageContext pc , String list, double posNumber, String value, String delimiter, boolean includeEmptyFields) throws ExpressionException {
045                
046                if(list.length()==0)
047                        throw new FunctionException(pc,"listSetAt",1,"list","can't be empty");
048                
049                
050                int pos=((int) posNumber);
051                //int[] removedInfo=new int[2];
052                
053                Array arr = ListUtil.listToArray(list,delimiter);
054                int len=arr.size();
055                
056                // invalid index
057                if(pos<1)
058                        throw new FunctionException(pc,"listSetAt",2,"position","invalid string list index ["+(pos)+"]");
059                else if(len<pos) {
060                        throw new FunctionException(pc,"listSetAt",2,"position","invalid string list index ["+(pos)+"], indexes go from 1 to "+(len));
061                }
062                
063                StringBuilder sb=new StringBuilder();//RepeatString.call(new StringBuffer(),delimiter,removedInfo[0]);
064                boolean hasStart=false;
065                boolean hasSet=false;
066                String v;
067                int count=0;
068                for(int i=1;i<=len;i++) {
069                        v=(String)arr.get(i,"");
070                        if(hasStart) {
071                                sb.append(delimiter);
072                        }
073                        else hasStart=true;
074                        
075                        if(includeEmptyFields || v.length()>0)count++;
076                        if(!hasSet && pos==count) {
077                                sb.append(value);
078                                hasSet=true;
079                        }
080                        else sb.append(arr.get(i,""));
081                }
082                if(!hasSet){
083                        throw new FunctionException(pc,"listSetAt",2,"position","invalid string list index ["+(pos)+"]");
084                }
085                
086                
087                return sb.toString();
088        }
089
090    @Override
091        public Object invoke(PageContext pc, Object[] args) throws PageException {
092        if(args.length==3)
093                        return call(pc, Caster.toString(args[0]), Caster.toDoubleValue(args[1]), Caster.toString(args[2]));
094        if(args.length==4)
095                        return call(pc, Caster.toString(args[0]), Caster.toDoubleValue(args[1]), Caster.toString(args[2]), Caster.toString(args[3]));
096        if(args.length==5)
097                        return call(pc, Caster.toString(args[0]), Caster.toDoubleValue(args[1]), Caster.toString(args[2]), Caster.toString(args[3]), Caster.toBooleanValue(args[4]));
098        
099                throw new FunctionException(pc, "ListSetAt", 3, 5, args.length);
100        }
101}