001    /**
002     * Implements the CFML Function listdeleteat
003     */
004    package railo.runtime.functions.list;
005    
006    import railo.runtime.PageContext;
007    import railo.runtime.exp.ExpressionException;
008    import railo.runtime.exp.FunctionException;
009    import railo.runtime.ext.function.Function;
010    
011    public final class ListDeleteAt implements Function {
012            
013            private static char[] DEFAULT_DELIMITER=new char[]{','};
014            
015            public static String call(PageContext pc , String list, double posNumber) throws ExpressionException {
016                    return _call(pc,list,(int)posNumber,DEFAULT_DELIMITER,false);
017            }
018            
019            public static String call(PageContext pc, String list, double posNumber, String del) throws ExpressionException {
020                    return _call(pc, list, (int)posNumber, del.toCharArray(),false);
021            }
022            
023            public static String call(PageContext pc, String list, double posNumber, String del, boolean includeEmptyFields) throws ExpressionException {
024                    return _call(pc, list, (int)posNumber, del.toCharArray(),includeEmptyFields);
025            }
026            
027            
028    
029            
030    
031            public static String _call(PageContext pc, String list, int pos, char[] del, boolean includeEmptyFields) throws ExpressionException {
032            
033            StringBuilder sb = new StringBuilder();
034            int len=list.length();
035            int index=0;
036            char last=0,c;
037            
038            if(pos<1) throw new FunctionException(pc,"ListDeleteAt",2,"index","index must be greater than 0");
039            
040            pos--;
041            
042            int i=0;
043            
044            // ignore all delimiter at start
045            if(!includeEmptyFields)for(;i<len;i++){
046                    c=list.charAt(i);
047                    if(!equal(del,c)) break;
048                    sb.append(c);
049            }
050            
051            // before
052            for(;i<len;i++){
053                    
054                    c=list.charAt(i);
055                    if(index==pos && !equal(del,c)) break;
056                    if(equal(del,c)) {
057                            if(includeEmptyFields || !equal(del,last))
058                                    index++;
059                    }
060                    sb.append(c);
061                    last=c;
062            }
063            
064            
065            // suppress item
066            for(;i<len;i++){
067                    if(equal(del,list.charAt(i))) break;
068            }
069            
070            // ignore following delimiter
071            for(;i<len;i++){
072                    if(!equal(del,list.charAt(i))) break;
073            }
074            
075            if(i==len){
076                    
077                    while(sb.length()>0 && equal(del,sb.charAt(sb.length()-1))) {
078                            sb.delete(sb.length()-1, sb.length());
079                    }
080                    if(pos>index) throw new FunctionException(pc,"ListDeleteAt",2,"index","index must be a integer between 1 and "+index);
081                    
082                    return sb.toString();
083            }
084            
085            
086            // fill the rest
087            for(;i<len;i++){
088                    sb.append(list.charAt(i));
089            }
090            
091            return sb.toString();
092        }
093            
094            
095        private static boolean equal(char[] del, char c) {
096            for(int i=0;i<del.length;i++){
097                    if(del[i]==c) return true;
098            }
099                    return false;
100            }
101    
102    
103            
104            
105    }