001    package railo.runtime.type.util;
002    
003    import java.util.Arrays;
004    import java.util.HashSet;
005    import java.util.Iterator;
006    import java.util.Set;
007    
008    import railo.commons.lang.StringList;
009    import railo.commons.lang.StringUtil;
010    import railo.runtime.exp.ExpressionException;
011    import railo.runtime.exp.PageException;
012    import railo.runtime.op.Caster;
013    import railo.runtime.type.Array;
014    import railo.runtime.type.ArrayImpl;
015    import railo.runtime.type.Collection;
016    import railo.runtime.type.Collection.Key;
017    
018    /**
019     * List is not a type, only some static method to manipulate String lists
020     */
021    public final class ListUtil {
022    
023            /**
024             * casts a list to Array object, the list can be have quoted (",') arguments and delimter in this arguments are ignored. quotes are not removed
025             * example:
026             *  listWithQuotesToArray("aab,a'a,b',a\"a,b\"",",","\"'") will be translated to ["aab","a'a,b'","a\"a,b\""]
027             * 
028             * 
029             * 
030             * @param list list to cast
031             * @param delimiter delimter of the list
032             * @param quotes quotes of the list
033             * @return Array Object
034             */
035            public static Array listWithQuotesToArray(String list, String delimiter,String quotes) {
036                    if(list.length()==0) return new ArrayImpl();
037                    
038                    int len=list.length();
039                    int last=0;
040                    char[] del=delimiter.toCharArray();
041                    char[] quo=quotes.toCharArray();
042                    char c;
043                    char inside=0;
044                    
045                    ArrayImpl array=new ArrayImpl();
046                    try{
047                            for(int i=0;i<len;i++) {
048                                c=list.charAt(i);
049                                for(int y=0;y<quo.length;y++){
050                                    if(c==quo[y]) {
051                                                    if(c==inside)inside=0;
052                                                    else if(inside==0)inside=c;
053                                                    continue;
054                                            }
055                                }
056                                
057                                for(int y=0;y<del.length;y++) {
058                                            if(inside==0 && c==del[y]) {
059                                                    array._append(list.substring(last,i));
060                                                    last=i+1;
061                                            }
062                                }
063                            }
064                            if(last<=len)array.append(list.substring(last));
065                    }
066                    catch(ExpressionException e){}
067                    return array;
068            }
069            
070            /**
071             * casts a list to Array object
072             * @param list list to cast
073             * @param delimiter delimter of the list
074             * @return Array Object
075             */
076            public static Array listToArray(String list, String delimiter) {
077                if(delimiter.length()==1)return listToArray(list, delimiter.charAt(0));
078                if(list.length()==0) return new ArrayImpl();
079                if(delimiter.length()==0) {
080                    int len = list.length();
081                    ArrayImpl array=new ArrayImpl();
082                    array.appendEL("");// ACF compatibility
083                            for(int i=0;i<len;i++){
084                            array.appendEL(list.charAt(i));
085                    }
086                            array.appendEL("");// ACF compatibility
087                            return array;
088                }
089                    
090                int len=list.length();
091                    int last=0;
092                    char[] del=delimiter.toCharArray();
093                    char c;
094                    
095                    ArrayImpl array=new ArrayImpl();
096                    try{
097                            for(int i=0;i<len;i++) {
098                                c=list.charAt(i);
099                                for(int y=0;y<del.length;y++) {
100                                            if(c==del[y]) {
101                                                    array.appendEL(list.substring(last,i));
102                                                    last=i+1;
103                                            }
104                                }
105                            }
106                            if(last<=len)array.append(list.substring(last));
107                    }
108                    catch(ExpressionException e){}
109                    return array;
110            }
111            
112            public static Array listToArray(String list, String delimiter, boolean multiCharDelim) {
113                    if(!multiCharDelim || delimiter.length()==0) return listToArray(list, delimiter);
114                    if(delimiter.length()==1)return listToArray(list, delimiter.charAt(0));
115                    int len=list.length();
116                    if(len==0) return new ArrayImpl();
117                     
118                    Array array=new ArrayImpl();
119                    int from=0;
120                    int index;
121                    int dl=delimiter.length();
122                    while((index=list.indexOf(delimiter,from))!=-1){
123                            array.appendEL(list.substring(from,index));
124                            from=index+dl;
125                    }
126                    array.appendEL(list.substring(from,len));
127                    
128                    return array;
129            }
130    
131            /**
132             * casts a list to Array object
133             * @param list list to cast
134             * @param delimiter delimter of the list
135             * @return Array Object
136             */
137            public static Array listToArray(String list, char delimiter) {
138                    if(list.length()==0) return new ArrayImpl();
139                    int len=list.length();
140                    int last=0;
141                    
142                    Array array=new ArrayImpl();
143                    try{
144                            for(int i=0;i<len;i++) {
145                                    if(list.charAt(i)==delimiter) {
146                                            array.append(list.substring(last,i));
147                                            last=i+1;
148                                    }
149                            }
150                            if(last<=len)array.append(list.substring(last));
151                    }
152                    catch(PageException e){}
153                    return array;
154            }
155            
156            /**
157             * casts a list to Array object remove Empty Elements
158             * @param list list to cast
159             * @param delimiter delimter of the list
160             * @return Array Object
161             */
162            public static Array listToArrayRemoveEmpty(String list, String delimiter, boolean multiCharDelim) {
163                    if(!multiCharDelim || delimiter.length()==0) return listToArrayRemoveEmpty(list, delimiter);
164                    
165                if(delimiter.length()==1)return listToArrayRemoveEmpty(list, delimiter.charAt(0));
166                    
167                int len=list.length();
168                    if(len==0)  return new ArrayImpl();
169                    
170                    
171                    Array array=new ArrayImpl();
172                    int from=0;
173                    int index;
174                    int dl=delimiter.length();
175                    while((index=list.indexOf(delimiter,from))!=-1){
176                            if(from<index)array.appendEL(list.substring(from,index));
177                            from=index+dl;
178                    }
179                    if(from<len)array.appendEL(list.substring(from,len));
180                    return array;
181                    
182            }
183            
184            
185            
186            
187            public static Array listToArrayRemoveEmpty(String list, String delimiter) {
188                if(delimiter.length()==1)return listToArrayRemoveEmpty(list, delimiter.charAt(0));
189                    int len=list.length();
190                    ArrayImpl array=new ArrayImpl();
191                    if(len==0) return array;
192                    if(delimiter.length()==0) {
193                    for(int i=0;i<len;i++){
194                            array.appendEL(list.charAt(i));
195                    }
196                            return array;
197                }
198                    int last=0;
199                    
200                    char[] del = delimiter.toCharArray();
201                    char c;
202                    for(int i=0;i<len;i++) {
203                        c=list.charAt(i);
204                        for(int y=0;y<del.length;y++) {
205                                    if(c==del[y]) {
206                                            if(last<i)array._append(list.substring(last,i));
207                                            last=i+1;
208                                    }
209                        }
210                    }
211                    if(last<len)array._append(list.substring(last));
212    
213                    return array;
214            }
215            
216        /**
217         * casts a list to Array object remove Empty Elements
218         * @param list list to cast
219         * @param delimiter delimter of the list
220         * @return Array Object
221         */
222        public static Array listToArrayRemoveEmpty(String list, char delimiter) {
223            int len=list.length();
224            ArrayImpl array=new ArrayImpl();
225            if(len==0) return array;
226            int last=0;
227            
228            for(int i=0;i<len;i++) {
229                if(list.charAt(i)==delimiter) {
230                    if(last<i)array._append(list.substring(last,i));
231                    last=i+1;
232                }
233            }
234            if(last<len)array._append(list.substring(last));
235    
236            return array;
237        }
238            
239            /**
240             * casts a list to Array object remove Empty Elements
241             * @param list list to cast
242             * @param delimiter delimter of the list
243             * @return Array Object
244             */
245            public static String rest(String list, String delimiter, boolean ignoreEmpty) {
246                //if(delimiter.length()==1)return rest(list, delimiter.charAt(0));
247                    int len=list.length();
248                    if(len==0) return "";
249                    //int last=-1;
250                    
251                    char[] del = delimiter.toCharArray();
252                    char c;
253                    
254                    if(ignoreEmpty)list=ltrim(list,del);
255                    len=list.length();
256                    
257                    
258                    for(int i=0;i<len;i++) {
259                        c=list.charAt(i);
260                        for(int y=0;y<del.length;y++) {
261                                    if(c==del[y]) {
262                                            return ignoreEmpty?ltrim(list.substring(i+1),del):list.substring(i+1);
263                                    }
264                        }
265                    }
266                    return "";
267            }
268            
269            private static String ltrim(String list,char[] del) {
270                    int len=list.length();
271                    char c;
272                    //               remove at start
273                    outer:while(len>0) {
274                        c=list.charAt(0);
275                        for(int i=0;i<del.length;i++) {
276                            if(c==del[i]) {
277                                list=list.substring(1);
278                                len=list.length();
279                                continue outer;
280                            }
281                        }
282                        break;
283                    }
284                    return list;
285            }
286        
287        /**
288         * casts a list to Array object remove Empty Elements
289         * @param list list to cast
290         * @param delimiter delimter of the list
291         * @return Array Object
292         */
293        public static StringList listToStringListRemoveEmpty(String list, char delimiter) {
294            int len=list.length();
295            StringList rtn=new StringList();
296            if(len==0) return rtn.reset();
297            int last=0;
298            
299            for(int i=0;i<len;i++) {
300                if(list.charAt(i)==delimiter) {
301                    if(last<i)rtn.add(list.substring(last,i));
302                    last=i+1;
303                }
304            }
305            if(last<len)rtn.add(list.substring(last));
306    
307            return rtn.reset();
308        }
309            
310            /**
311             * casts a list to Array object, remove all empty items at start and end of the list
312             * @param list list to cast
313             * @param delimiter delimter of the list
314             * @return Array Object
315             */
316            public static Array listToArrayTrim(String list, String delimiter) {
317                if(delimiter.length()==1)return listToArrayTrim(list, delimiter.charAt(0));
318                    if(list.length()==0) return new ArrayImpl();
319                    char[] del = delimiter.toCharArray();
320                    char c;
321                    
322                    // remove at start
323                    outer:while(list.length()>0) {
324                        c=list.charAt(0);
325                        for(int i=0;i<del.length;i++) {
326                            if(c==del[i]) {
327                                list=list.substring(1);
328                                continue outer;
329                            }
330                        }
331                        break;
332                    }
333                    
334                    int len;
335                    outer:while(list.length()>0) {
336                        c=list.charAt(list.length()-1);
337                        for(int i=0;i<del.length;i++) {
338                            if(c==del[i]) {
339                                len=list.length();
340                                list=list.substring(0,len-1<0?0:len-1);
341                                continue outer;
342                            }
343                        }
344                        break;
345                    }
346                    return listToArray(list, delimiter);
347            }
348            
349            /**
350             * casts a list to Array object, remove all empty items at start and end of the list and store count to info
351             * @param list list to cast
352             * @param delimiter delimter of the list
353             * @param info
354             * @return Array Object
355             */
356            public static Array listToArrayTrim(String list, String delimiter, int[] info) {
357                if(delimiter.length()==1)return listToArrayTrim(list, delimiter.charAt(0),info);
358                    if(list.length()==0) return new ArrayImpl();
359                    char[] del = delimiter.toCharArray();
360                    char c;
361                    
362                    // remove at start
363                    outer:while(list.length()>0) {
364                        c=list.charAt(0);
365                        for(int i=0;i<del.length;i++) {
366                            if(c==del[i]) {
367                                            info[0]++;
368                                list=list.substring(1);
369                                continue outer;
370                            }
371                        }
372                        break;
373                    }
374                    
375                    int len;
376                    outer:while(list.length()>0) {
377                        c=list.charAt(list.length()-1);
378                        for(int i=0;i<del.length;i++) {
379                            if(c==del[i]) {
380                                            info[1]++;
381                                len=list.length();
382                                list=list.substring(0,len-1<0?0:len-1);
383                                continue outer;
384                            }
385                        }
386                        break;
387                    }
388                    return listToArray(list, delimiter);
389            }
390        
391        /**
392         * casts a list to Array object, remove all empty items at start and end of the list and store count to info
393         * @param list list to cast
394         * @param delimiter delimter of the list
395         * @param info
396         * @return Array Object
397         * @throws ExpressionException 
398         */
399        public static String listInsertAt(String list, int pos, String value, String delimiter, boolean ignoreEmpty) throws ExpressionException {
400            if(pos<1)
401                throw new ExpressionException("invalid string list index ["+(pos)+"]");
402       
403            char[] del = delimiter.toCharArray();
404            char c;
405            StringBuilder result=new StringBuilder();
406            String end="";
407            int len;
408            
409            // remove at start
410            if(ignoreEmpty){
411                    outer:while(list.length()>0) {
412                        c=list.charAt(0);
413                        for(int i=0;i<del.length;i++) {
414                            if(c==del[i]) {
415                                list=list.substring(1);
416                                result.append(c);
417                                continue outer;
418                            }
419                        }
420                        break;
421                    }
422            }
423            
424            // remove at end
425            if(ignoreEmpty){
426                    outer:while(list.length()>0) {
427                        c=list.charAt(list.length()-1);
428                        for(int i=0;i<del.length;i++) {
429                            if(c==del[i]) {
430                                len=list.length();
431                                list=list.substring(0,len-1<0?0:len-1);
432                                end=c+end;
433                                continue outer;
434                            }
435                     
436                        }
437                        break;
438                    }
439            }
440            
441            len=list.length();
442            int last=0;
443            
444            int count=0;
445            outer:for(int i=0;i<len;i++) {
446                c=list.charAt(i);
447                for(int y=0;y<del.length;y++) {
448                    if(c==del[y]) {
449                        
450                            if(!ignoreEmpty || last<i) {
451                                    if(pos==++count){
452                                result.append(value);
453                                result.append(del[0]);
454                            }
455                                            }
456                        result.append(list.substring(last,i));
457                        result.append(c);
458                        last=i+1;
459                        continue outer;
460                    }
461                }
462            }
463            count++;
464            if(last<=len){
465                if(pos==count) {
466                    result.append(value);
467                    result.append(del[0]);
468                }
469                
470                result.append(list.substring(last));
471            }
472            if(pos>count) {
473                throw new ExpressionException("invalid string list index ["+(pos)+"], indexes go from 1 to "+(count));
474                
475            }
476            
477            return result+end;
478            
479            
480        }
481            
482            /**
483             * casts a list to Array object, remove all empty items at start and end of the list
484             * @param list list to cast
485             * @param delimiter delimter of the list
486             * @return Array Object
487             */
488        public static Array listToArrayTrim(String list, char delimiter) {
489            if(list.length()==0) return new ArrayImpl();
490            // remove at start
491            while(list.indexOf(delimiter)==0) {
492                list=list.substring(1);
493            }
494            int len=list.length();
495            if(len==0) return new ArrayImpl();
496            while(list.lastIndexOf(delimiter)==len-1) {
497                list=list.substring(0,len-1<0?0:len-1);
498                len=list.length();
499            }
500            return listToArray(list, delimiter);
501        }
502    
503        /**
504         * @param list
505         * @param delimiter
506         * @return trimmed list
507         */
508        public static StringList toListTrim(String list, char delimiter) {
509            if(list.length()==0) return new StringList();
510            // remove at start
511            while(list.indexOf(delimiter)==0) {
512                list=list.substring(1);
513            }
514            int len=list.length();
515            if(len==0) return new StringList();
516            while(list.lastIndexOf(delimiter)==len-1) {
517                list=list.substring(0,len-1<0?0:len-1);
518                len=list.length();
519            }
520            
521            return toList(list, delimiter);
522        }
523        
524        /**
525         * @param list
526         * @param delimiter
527         * @return list
528         */
529        public static StringList toList(String list, char delimiter) {
530            if(list.length()==0) return new StringList();
531            int len=list.length();
532            int last=0;
533            
534            StringList rtn=new StringList();
535           
536            for(int i=0;i<len;i++) {
537                if(list.charAt(i)==delimiter) {
538                    rtn.add(list.substring(last,i));
539                    last=i+1;
540                }
541            }
542            if(last<=len)rtn.add(list.substring(last));
543            rtn.reset();
544            return rtn;
545        }
546        
547        public static StringList toWordList(String list) {
548            if(list.length()==0) return new StringList();
549            int len=list.length();
550            int last=0;
551            char c,l=0;
552            StringList rtn=new StringList();
553           
554            for(int i=0;i<len;i++) {
555                if(StringUtil.isWhiteSpace(c=list.charAt(i))) {
556                    rtn.add(list.substring(last,i),l);
557                    l=c;
558                    last=i+1;
559                }
560            }
561            if(last<=len)rtn.add(list.substring(last),l);
562            rtn.reset();
563            return rtn;
564        }
565        
566            /**
567             * casts a list to Array object, remove all empty items at start and end of the list
568             * @param list list to cast
569             * @param delimiter delimter of the list
570             * @param info
571             * @return Array Object
572             */
573            public static Array listToArrayTrim(String list, char delimiter, int[] info) {
574                    if(list.length()==0) return new ArrayImpl();
575                    // remove at start
576                    while(list.indexOf(delimiter)==0) {
577                            info[0]++;
578                            list=list.substring(1);
579                    }
580                    int len=list.length();
581                    if(len==0) return new ArrayImpl();
582                    while(list.lastIndexOf(delimiter)==len-1) {
583                            info[1]++;
584                            list=list.substring(0,len-1<0?0:len-1);
585                            len=list.length();
586                    }
587                    return listToArray(list, delimiter);
588            }
589        
590    
591            /**
592             * finds a value inside a list, ignore case
593             * @param list list to search
594             * @param value value to find
595             * @return position in list (0-n) or -1
596             */
597            public static int listFindNoCase(String list, String value) {
598                    return listFindNoCase(list, value, ",", true);
599            }       
600    
601            /**
602             * finds a value inside a list, do not ignore case
603             * @param list list to search
604             * @param value value to find
605             * @param delimiter delimiter of the list
606             * @return position in list (0-n) or -1
607             */
608            public static int listFindNoCase(String list, String value, String delimiter) {
609                    return listFindNoCase(list, value, delimiter, true);
610            }       
611    
612            
613            /**
614             * finds a value inside a list, do not ignore case
615             * @param list list to search
616             * @param value value to find
617             * @param delimiter delimiter of the list
618             * @param trim trim the list or not
619             * @return position in list (0-n) or -1
620             */
621            public static int listFindNoCase(String list, String value, String delimiter,boolean trim) {
622                    Array arr = trim?listToArrayTrim(list,delimiter):listToArray(list,delimiter);
623                    int len=arr.size();
624                    for(int i=1;i<=len;i++) {
625                            if(((String)arr.get(i,"")).equalsIgnoreCase(value)) return i-1;
626                    }
627                    return -1;
628            }
629    
630            public static int listFindForSwitch(String list, String value, String delimiter) {
631                    if(list.indexOf(delimiter)==-1 && list.equalsIgnoreCase(value)) return 1;
632                    
633                    Array arr = listToArray(list,delimiter);
634                    int len=arr.size();
635                    for(int i=1;i<=len;i++) {
636                            if(((String)arr.get(i,"")).equalsIgnoreCase(value)) return i;
637                    }
638                    return -1;
639            }
640            
641            /**
642             * finds a value inside a list, ignore case, ignore empty items
643             * @param list list to search
644             * @param value value to find
645             * @param delimiter delimiter of the list
646             * @return position in list or 0
647             */
648            public static int listFindNoCaseIgnoreEmpty(String list, String value, String delimiter) {
649                if(delimiter.length()==1)return listFindNoCaseIgnoreEmpty(list, value, delimiter.charAt(0));
650                if(list==null) return -1;
651                    int len=list.length();
652                    if(len==0) return -1;
653                    int last=0;
654                    int count=0;
655                    char[] del = delimiter.toCharArray();
656                    char c;
657                    
658                    for(int i=0;i<len;i++) {
659                            c=list.charAt(i);
660                            for(int y=0;y<del.length;y++) {
661                                    if(c==del[y]) {
662                                            if(last<i) {
663                                                    if(list.substring(last,i).equalsIgnoreCase(value)) return count;
664                                                    count++;
665                                            }
666                                            last=i+1;
667                                            
668                                    }
669                        }
670                    }
671                    if(last<len) {
672                            if(list.substring(last).equalsIgnoreCase(value)) return count;
673                    }
674                    return -1;
675            }
676            
677            /**
678             * finds a value inside a list, ignore case, ignore empty items
679             * @param list list to search
680             * @param value value to find
681             * @param delimiter delimiter of the list
682             * @return position in list or 0
683             */
684            public static int listFindNoCaseIgnoreEmpty(String list, String value, char delimiter) {
685                    if(list==null) return -1;
686                    int len=list.length();
687                    if(len==0) return -1;
688                    int last=0;
689                    int count=0;
690                    
691                    for(int i=0;i<len;i++) {
692                            if(list.charAt(i)==delimiter) {
693                                    if(last<i) {
694                                            if(list.substring(last,i).equalsIgnoreCase(value)) return count;
695                                            count++;
696                                    }
697                                    last=i+1;
698                            }
699                    }
700                    if(last<len) {
701                            if(list.substring(last).equalsIgnoreCase(value)) return count;
702                    }
703                    return -1;
704            }
705            
706    
707            
708            
709            /**
710             * finds a value inside a list, case sensitive
711             * @param list list to search
712             * @param value value to find
713             * @return position in list or 0
714             */
715            public static int listFind(String list, String value) {
716                    return listFind(list, value, ",");
717            }
718            
719            /**
720             * finds a value inside a list, do not case sensitive
721             * @param list list to search
722             * @param value value to find
723             * @param delimiter delimiter of the list
724             * @return position in list or 0
725             */
726            public static int listFind(String list, String value, String delimiter) {
727                    Array arr = listToArrayTrim(list,delimiter);
728                    int len=arr.size();
729                    for(int i=1;i<=len;i++) {
730                            if(arr.get(i,"").equals(value)) return i-1;
731                    }
732    
733                    return -1;
734            }
735            
736            /**
737             * finds a value inside a list, case sensitive, ignore empty items
738             * @param list list to search
739             * @param value value to find
740             * @param delimiter delimiter of the list
741             * @return position in list or 0
742             */
743            public static int listFindIgnoreEmpty(String list, String value, String delimiter) {
744                if(delimiter.length()==1)return listFindIgnoreEmpty(list, value, delimiter.charAt(0));
745                    if(list==null) return -1;
746                    int len=list.length();
747                    if(len==0) return -1;
748                    int last=0;
749                    int count=0;
750                    char[] del = delimiter.toCharArray();
751                    char c;
752                    
753                    for(int i=0;i<len;i++) {
754                            c=list.charAt(i);
755                            for(int y=0;y<del.length;y++) {
756                                    if(c==del[y]) {
757                                            if(last<i) {
758                                                    if(list.substring(last,i).equals(value)) return count;
759                                                    count++;
760                                            }
761                                            last=i+1;
762                                            
763                                    }
764                        }
765                    }
766                    if(last<len) {
767                            if(list.substring(last).equals(value)) return count;
768                    }
769                    return -1;
770            }
771    
772            /**
773             * finds a value inside a list, case sensitive, ignore empty items
774             * @param list list to search
775             * @param value value to find
776             * @param delimiter delimiter of the list
777             * @return position in list or 0
778             */
779            public static int listFindIgnoreEmpty(String list, String value, char delimiter) {
780                    if(list==null) return -1;
781                    int len=list.length();
782                    if(len==0) return -1;
783                    int last=0;
784                    int count=0;
785                    
786                    for(int i=0;i<len;i++) {
787                            if(list.charAt(i)==delimiter) {
788                                    if(last<i) {
789                                            if(list.substring(last,i).equals(value)) return count;
790                                            count++;
791                                    }
792                                    last=i+1;
793                            }
794                    }
795                    if(last<len) {
796                            if(list.substring(last).equals(value)) return count;
797                    }
798                    return -1;
799            }
800            
801            /**
802             * returns if a value of the list contains given value, ignore case
803             * @param list list to search in
804             * @param value value to serach
805             * @param delimiter delimiter of the list
806             * @return position in list or 0
807             */
808            public static int listContainsNoCase(String list, String value, String delimiter) {
809                    if(StringUtil.isEmpty(value)) return -1;
810                    
811                    Array arr=listToArray(list,delimiter);
812                    int len=arr.size();
813                    
814                    for(int i=1;i<=len;i++) {
815                            if(StringUtil.indexOfIgnoreCase(arr.get(i,"").toString(), value)!=-1) return i-1;
816                    }
817                    return -1;
818            }
819            
820            /**
821             * returns if a value of the list contains given value, ignore case, ignore empty values
822             * @param list list to search in
823             * @param value value to serach
824             * @param delimiter delimiter of the list
825             * @return position in list or 0
826             */
827            public static int listContainsIgnoreEmptyNoCase(String list, String value, String delimiter) {
828                    if(StringUtil.isEmpty(value)) return -1;
829                    Array arr=listToArrayRemoveEmpty(list,delimiter);
830                    int count=0;
831                    int len=arr.size();
832                    
833                    for(int i=1;i<=len;i++) {
834                            String item=arr.get(i,"").toString();
835                            if(StringUtil.indexOfIgnoreCase(item, value)!=-1) return count;
836                            count++;
837                    }
838                    return -1;
839            }
840    
841            /**
842             * returns if a value of the list contains given value, case sensitive
843             * @param list list to search in
844             * @param value value to serach
845             * @param delimiter delimiter of the list
846             * @return position in list or 0
847             */
848            public static int listContains(String list, String value, String delimiter) {
849                    if(StringUtil.isEmpty(value)) return -1;
850                    
851                            Array arr=listToArray(list,delimiter);
852                            int len=arr.size();
853                            
854                            for(int i=1;i<=len;i++) {
855                                    if(arr.get(i,"").toString().indexOf(value)!=-1) return i-1;
856                            }
857                    return -1;
858                    
859            }
860            
861            /**
862             * returns if a value of the list contains given value, case sensitive, ignore empty positions
863             * @param list list to search in
864             * @param value value to serach
865             * @param delimiter delimiter of the list
866             * @return position in list or 0
867             */
868            public static int listContainsIgnoreEmpty(String list, String value, String delimiter) {
869                    if(StringUtil.isEmpty(value)) return -1;
870                    Array arr=listToArrayRemoveEmpty(list,delimiter);
871                    int count=0;
872                    int len=arr.size();
873                    
874                    for(int i=1;i<=len;i++) {
875                            String item=arr.get(i,"").toString();
876                            if(item.indexOf(value)!=-1) return count;
877                            count++;
878                    }
879                    return -1;
880            }
881    
882            /**
883             * convert a string array to string list, removes empty values at begin and end of the list
884             * @param array array to convert
885             * @param delimiter delimiter for the new list
886             * @return list generated from string array
887             */
888            public static String arrayToListTrim(String[] array, String delimiter) {
889                    return trim(arrayToList(array,delimiter),delimiter);
890            }
891            
892            /**
893             * convert a string array to string list
894             * @param array array to convert
895             * @param delimiter delimiter for the new list
896             * @return list generated from string array
897             */
898            public static String arrayToList(String[] array, String delimiter) {
899                    if(ArrayUtil.isEmpty(array)) return "";
900                    StringBuilder sb=new StringBuilder(array[0]);
901                    
902                    if(delimiter.length()==1) {
903                            char c=delimiter.charAt(0);
904                            for(int i=1;i<array.length;i++) {
905                                    sb.append(c);
906                                    sb.append(array[i]);
907                            }
908                    }
909                    else {
910                            for(int i=1;i<array.length;i++) {
911                                    sb.append(delimiter);
912                                    sb.append(array[i]);
913                            }
914                    }
915                    
916    
917                    return sb.toString();
918            }
919            
920            public static String arrayToList(Collection.Key[] array, String delimiter) {
921                    if(array.length==0) return "";
922                    StringBuilder sb=new StringBuilder(array[0].getString());
923                    
924                    if(delimiter.length()==1) {
925                            char c=delimiter.charAt(0);
926                            for(int i=1;i<array.length;i++) {
927                                    sb.append(c);
928                                    sb.append(array[i].getString());
929                            }
930                    }
931                    else {
932                            for(int i=1;i<array.length;i++) {
933                                    sb.append(delimiter);
934                                    sb.append(array[i].getString());
935                            }
936                    }
937                    
938    
939                    return sb.toString();
940            }
941            
942            /**
943             * convert Array Object to string list
944             * @param array array to convert
945             * @param delimiter delimiter for the new list
946             * @return list generated from string array
947             * @throws PageException
948             */
949            public static String arrayToList(Array array, String delimiter) throws PageException {
950                    if(array.size()==0) return "";
951                    StringBuilder sb=new StringBuilder(Caster.toString(array.getE(1)));
952                    int len=array.size();
953                    
954                    for(int i=2;i<=len;i++) {
955                            sb.append(delimiter);
956                            sb.append(array.get(i,""));
957                    }
958                    return sb.toString();
959            }
960            
961            public static String listToList(java.util.List list, String delimiter) throws PageException {
962                    if(list.size()==0) return "";
963                    StringBuilder sb=new StringBuilder();
964                    Iterator it = list.iterator();
965                    
966                    if(it.hasNext()) sb.append(Caster.toString(it.next()));
967                            
968                    while(it.hasNext()) {
969                            sb.append(delimiter);
970                            sb.append(Caster.toString(it.next()));
971                    }
972                    return sb.toString();
973            }
974            
975            
976            /**
977             * trims a string array, removes all empty array positions at the start and the end of the array
978             * @param array array to remove elements
979             * @return cleared array
980             */
981            public static String[] trim(String[] array) {
982                    int from=0;
983                    int to=0;
984    
985                    // test start
986                    for(int i=0;i<array.length;i++) {
987                            from=i;
988                            if(array[i].length()!=0)break;
989                    }
990                    
991                    // test end
992                    for(int i=array.length-1;i>=0;i--) {
993                            to=i;
994                            if(array[i].length()!=0)break;
995                    }
996                    
997                    int newLen=to-from+1;
998                    
999                    if(newLen<array.length) {
1000                            String[] rtn=new String[newLen];
1001                            System.arraycopy(array,from,rtn,0,newLen);
1002                            return rtn;
1003                    }
1004                    return array;
1005            }
1006    
1007            /**
1008             * trims a string list, remove all empty delimiter at start and the end
1009             * @param list list to trim
1010             * @param delimiter delimiter of the list
1011             * @return trimed list
1012             */
1013            public static String trim(String list, String delimiter) {
1014                    return trim(list,delimiter,new int[2]);
1015            }
1016            
1017            /**
1018             * trims a string list, remove all empty delimiter at start and the end
1019             * @param list list to trim
1020             * @param delimiter delimiter of the list
1021             * @param removeInfo int array contain count of removed values (removeInfo[0]=at the begin;removeInfo[1]=at the end)
1022             * @return trimed list
1023             */
1024            public static String trim(String list, String delimiter,int[] removeInfo) {
1025    
1026                    if(list.length()==0)return "";
1027                    int from=0;
1028                    int to=list.length();
1029                    //int len=delimiter.length();
1030                    char[] del=delimiter.toCharArray();
1031                    char c;
1032                    
1033                    // remove at start
1034                    outer:while(list.length()>from) {
1035                        c=list.charAt(from);
1036                        for(int i=0;i<del.length;i++) {
1037                            if(c==del[i]) {
1038                                from++;
1039                                removeInfo[0]++;
1040                                //list=list.substring(from);
1041                                continue outer;
1042                            }
1043                        }
1044                        break;
1045                    }
1046                    
1047                    //int len;
1048                    outer:while(to>from) {
1049                        c=list.charAt(to-1);
1050                        for(int i=0;i<del.length;i++) {
1051                            if(c==del[i]) {
1052                                to--;
1053                                            removeInfo[1]++;
1054                                continue outer;
1055                            }
1056                        }
1057                        break;
1058                    }
1059                    int newLen=to-from;
1060                    
1061                    if(newLen<list.length()) {
1062                            return list.substring(from,to);
1063                    }
1064                    return list;
1065                    
1066            }       
1067            /**
1068             * sorts a string list
1069             * @param list list to sort
1070             * @param sortType sort type (numeric,text,textnocase)
1071             * @param sortOrder sort order (asc,desc)
1072             * @param delimiter list delimiter
1073             * @return sorted list
1074             * @throws PageException
1075             */
1076            public static String sortIgnoreEmpty(String list, String sortType, String sortOrder, String delimiter) throws PageException {
1077                    return _sort(toStringArray(listToArrayRemoveEmpty(list,delimiter)),sortType, sortOrder, delimiter);
1078            }
1079    
1080            /**
1081             * sorts a string list
1082             * @param list list to sort
1083             * @param sortType sort type (numeric,text,textnocase)
1084             * @param sortOrder sort order (asc,desc)
1085             * @param delimiter list delimiter
1086             * @return sorted list
1087             * @throws PageException
1088             */
1089            public static String sort(String list, String sortType, String sortOrder, String delimiter) throws PageException {
1090                    return _sort(toStringArray(listToArray(list,delimiter)),sortType, sortOrder, delimiter);
1091            }
1092            private static String _sort(Object[] arr, String sortType, String sortOrder, String delimiter) throws PageException {
1093    
1094                    Arrays.sort(arr,ArrayUtil.toComparator(null, sortType, sortOrder, false));
1095                    
1096                    StringBuilder sb=new StringBuilder();
1097                    for(int i=0;i<arr.length;i++) {
1098                            if(i!=0)sb.append(delimiter);
1099                            sb.append(arr[i]);
1100                    }
1101                    return sb.toString();
1102            }
1103    
1104    
1105            /**
1106             * cast a Object Array to a String Array
1107             * @param array
1108             * @return String Array
1109             */
1110            public  static String[] toStringArrayEL(Array array) {
1111                    String[] arr=new String[array.size()];
1112                    for(int i=0;i<arr.length;i++) {
1113                            arr[i]=Caster.toString(array.get(i+1,null),null);
1114                    }
1115                    
1116                    return arr;
1117            }
1118            
1119            /**
1120             * cast a Object Array to a String Array
1121             * @param array
1122             * @return String Array
1123             * @throws PageException
1124             */
1125        public static String[] toStringArray(Array array) throws PageException {
1126            String[] arr=new String[array.size()];
1127            for(int i=0;i<arr.length;i++) {
1128                arr[i]=Caster.toString(array.get(i+1,null));
1129            }
1130            return arr;
1131        }
1132        
1133        /**
1134         * cast a Object Array to a String Array
1135         * @param array
1136         * @param defaultValue 
1137         * @return String Array
1138         */
1139        public  static String[] toStringArray(Array array,String defaultValue) {
1140            String[] arr=new String[array.size()];
1141            for(int i=0;i<arr.length;i++) {
1142                arr[i]=Caster.toString(array.get(i+1,defaultValue),defaultValue);
1143            }
1144            
1145            return arr;
1146        }
1147            
1148            /**
1149             * cast a Object Array to a String Array and trim all values
1150             * @param array
1151             * @return String Array
1152             * @throws PageException
1153             */
1154        public  static String[] toStringArrayTrim(Array array) throws PageException {
1155                    String[] arr=new String[array.size()];
1156                    for(int i=0;i<arr.length;i++) {
1157                            arr[i]=Caster.toString(array.get(i+1,"")).trim();
1158                    }
1159                    
1160                    return arr;
1161            }
1162    
1163            /**
1164             * return first element of the list
1165             * @param list
1166             * @param delimiter
1167             * @return returns the first element of the list
1168             * @deprecated use instead  first(String list, String delimiter, boolean ignoreEmpty)
1169             */
1170            public static String first(String list, String delimiter) {
1171                    return first(list, delimiter,true);
1172            }
1173            
1174            /**
1175             * return first element of the list
1176             * @param list
1177             * @param delimiter
1178             * @param ignoreEmpty
1179             * @return returns the first element of the list
1180             */
1181            public static String first(String list, String delimiter, boolean ignoreEmpty) {
1182                    
1183                    if(StringUtil.isEmpty(list)) return "";
1184                    
1185                    char[] del;
1186                    if(StringUtil.isEmpty(delimiter)) {
1187                        del=new char[]{','};
1188                    }
1189                    else {
1190                            del=delimiter.toCharArray();
1191                    }
1192                    
1193                    int offset=0;
1194                    int index;
1195                    int x;
1196                    while(true) {
1197                        index=-1;
1198                        
1199                        for(int i=0;i<del.length;i++) {
1200                            x=list.indexOf(del[i],offset);
1201                            if(x!=-1 && (x<index || index==-1))index=x;
1202                        }
1203                            //index=list.indexOf(index,offset);
1204                        if(index==-1) {
1205                                    if(offset>0) return list.substring(offset);
1206                                    return list;
1207                            }
1208                        if(!ignoreEmpty && index==0) {
1209                                    return "";
1210                            }
1211                            else if(index==offset) {
1212                                    offset++;
1213                            }
1214                            else {
1215                                    if(offset>0)return list.substring(offset,index);
1216                                    return list.substring(0,index);
1217                            }
1218                       
1219                    }
1220            }
1221    
1222            /**
1223             * return last element of the list
1224             * @param list
1225             * @param delimiter
1226             * @return returns the last Element of a list
1227             * @deprecated use instead last(String list, String delimiter, boolean ignoreEmpty)
1228             */
1229            public static String last(String list, String delimiter) {
1230                    return last(list, delimiter, true);
1231            }
1232            
1233            /**
1234             * return last element of the list
1235             * @param list
1236             * @param delimiter
1237             * @param ignoreEmpty
1238             * @return returns the last Element of a list
1239             */
1240            public static String last(String list, String delimiter, boolean ignoreEmpty) {
1241    
1242                    if(StringUtil.isEmpty(list)) return "";
1243                    int len=list.length();
1244                    
1245                    char[] del;
1246                    if(StringUtil.isEmpty(delimiter)) {
1247                        del=new char[]{','};
1248                    }
1249                    else del=delimiter.toCharArray();
1250                    
1251                    int index;
1252                    int x;
1253                    while(true) {
1254                        index=-1;
1255                        
1256                        for(int i=0;i<del.length;i++) {
1257                            x=list.lastIndexOf(del[i]);
1258                            if(x>index)index=x;
1259                        }
1260    
1261                            if(index==-1) {
1262                                    return list;
1263                            }
1264                            
1265                            else if(index+1==len) {
1266                                    if(!ignoreEmpty) return"";
1267                                    list=list.substring(0,len-1);
1268                                    len--;
1269                            }
1270                            else {
1271                                    return list.substring(index+1);
1272                            }
1273                    }
1274            }
1275            
1276        /**
1277         * return last element of the list
1278         * @param list
1279         * @param delimiter
1280         * @return returns the last Element of a list
1281         */
1282            
1283            
1284        public static String last(String list, char delimiter) {
1285    
1286            int len=list.length();
1287            if(len==0) return "";
1288            int index=0;
1289            
1290            while(true) {
1291                index=list.lastIndexOf(delimiter);
1292                if(index==-1) {
1293                    return list;
1294                }
1295                else if(index+1==len) {
1296                    list=list.substring(0,len-1);
1297                    len--;
1298                }
1299                else {
1300                    return list.substring(index+1);
1301                }
1302            }
1303        }
1304    
1305            /**
1306             * returns count of items in the list
1307             * @param list
1308             * @param delimiter
1309             * @return list len
1310             */
1311            public static int len(String list, char delimiter,boolean ignoreEmpty) {
1312                    int len=StringUtil.length(list);
1313                    if(len==0) return 0;
1314    
1315                    int count=0;
1316                    int last=0;
1317                    
1318                    for(int i=0;i<len;i++) {
1319                            if(list.charAt(i)==delimiter) {
1320                                    if(!ignoreEmpty || last<i)count++;
1321                                    last=i+1;
1322                            }
1323                    }
1324                    if(!ignoreEmpty || last<len)count++;
1325                    return count;
1326            }
1327    
1328            /**
1329             * returns count of items in the list
1330             * @param list
1331             * @param delimiter
1332             * @return list len
1333             */
1334            public static int len(String list, String delimiter, boolean ignoreEmpty) {
1335                if(delimiter.length()==1)return len(list, delimiter.charAt(0),ignoreEmpty);
1336                    char[] del=delimiter.toCharArray();
1337                int len=StringUtil.length(list);
1338                    if(len==0) return 0;
1339                    
1340                    int count=0;
1341                    int last=0;
1342                    char c;
1343                    
1344                    for(int i=0;i<len;i++) {
1345                        c=list.charAt(i);
1346                        for(int y=0;y<del.length;y++) {
1347                                    if(c==del[y]) {
1348                                        if(!ignoreEmpty || last<i)count++;
1349                                            last=i+1;
1350                                    }
1351                        }
1352                    }
1353                    if(!ignoreEmpty || last<len)count++;
1354                    return count;
1355            }
1356            
1357            /* *
1358             * cast a int into a char
1359             * @param i int to cast
1360             * @return int as char
1361             * /
1362            private char c(int i) {
1363                return (char)i;
1364            }*/
1365            
1366            /**
1367             * gets a value from list
1368             * @param list list to cast
1369             * @param delimiter delimter of the list
1370             * @param position
1371             * @return Array Object
1372             */
1373            public static String getAt(String list, String delimiter, int position, boolean ignoreEmpty) {
1374                if(delimiter.length()==1)return getAt(list, delimiter.charAt(0), position,ignoreEmpty);
1375                    int len=list.length();
1376                    
1377                    if(len==0) return null;
1378                    int last=0;
1379                    int count=0;
1380                    
1381                    char[] del = delimiter.toCharArray();
1382                    char c;
1383                    for(int i=0;i<len;i++) {
1384                        c=list.charAt(i);
1385                        for(int y=0;y<del.length;y++) {
1386                                    if(c==del[y]) {
1387                                            if(!ignoreEmpty || last<i) {
1388                                                if(count++==position) {
1389                                                    return list.substring(last,i);
1390                                                }
1391                                            }
1392                                            last=i+1;
1393                                    }
1394                        }
1395                    }
1396                    if(last<len && position==count) return (list.substring(last));
1397    
1398                    return null;
1399            }
1400            
1401            /**
1402             * get a elemnt at a specified position in list
1403             * @param list list to cast
1404             * @param delimiter delimter of the list
1405             * @param position
1406             * @return Array Object
1407             */
1408            public static String getAt(String list, char delimiter, int position, boolean ignoreEmpty) {
1409                    int len=list.length();
1410                    if(len==0) return null;
1411                    int last=0;
1412                    int count=0;
1413                    
1414                    for(int i=0;i<len;i++) {
1415                            if(list.charAt(i)==delimiter) {
1416                                    if(!ignoreEmpty || last<i) {
1417                                        if(count++==position) {
1418                                            return list.substring(last,i);
1419                                        }
1420                                    }
1421                                    last=i+1;
1422                            }
1423                    }
1424                    if(last<len && position==count) return (list.substring(last));
1425    
1426                    return null;
1427            }
1428    
1429            public static String[] listToStringArray(String list, char delimiter) {
1430                    Array array = ListUtil.listToArrayRemoveEmpty(list,delimiter);
1431                    String[] arr=new String[array.size()];
1432            for(int i=0;i<arr.length;i++) {
1433                arr[i]=Caster.toString(array.get(i+1,""),"");
1434            }
1435            return arr;
1436            }
1437    
1438            /**
1439             * trim every single item of the array
1440             * @param arr
1441             * @return
1442             */
1443            public static String[] trimItems(String[] arr) {
1444                    for(int i=0;i<arr.length;i++) {
1445                            arr[i]=arr[i].trim();
1446                    }
1447                    return arr;
1448            }
1449    
1450            /**
1451             * trim every single item of the array
1452             * @param arr
1453             * @return
1454             * @throws PageException 
1455             */
1456            public static Array trimItems(Array arr) throws PageException {
1457                    Key[] keys = CollectionUtil.keys(arr);
1458                    
1459                    for(int i=0;i<keys.length;i++) {
1460                            arr.setEL(keys[i], Caster.toString(arr.get(keys[i],null)).trim());
1461                    }
1462                    return arr;
1463            }
1464    
1465            public static Set<String> listToSet(String list, String delimiter,boolean trim) {
1466                if(list.length()==0) return new HashSet<String>();
1467                    int len=list.length();
1468                    int last=0;
1469                    char[] del=delimiter.toCharArray();
1470                    char c;
1471                    
1472                    HashSet<String> set=new HashSet<String>();
1473                    for(int i=0;i<len;i++) {
1474                        c=list.charAt(i);
1475                        for(int y=0;y<del.length;y++) {
1476                                    if(c==del[y]) {
1477                                            set.add(trim?list.substring(last,i).trim():list.substring(last,i));
1478                                            last=i+1;
1479                                    }
1480                        }
1481                    }
1482                    if(last<=len)set.add(list.substring(last));
1483                    return set;
1484            }
1485    
1486            public static Set<String> listToSet(String list, char delimiter,boolean trim) {
1487                if(list.length()==0) return new HashSet<String>();
1488                    int len=list.length();
1489                    int last=0;
1490                    char c;
1491                    
1492                    HashSet<String> set=new HashSet<String>();
1493                    for(int i=0;i<len;i++) {
1494                        c=list.charAt(i);
1495                                    if(c==delimiter) {
1496                                            set.add(trim?list.substring(last,i).trim():list.substring(last,i));
1497                                            last=i+1;
1498                                    }
1499                    }
1500                    if(last<=len)set.add(list.substring(last));
1501                    return set;
1502            }
1503    
1504            
1505            public static Set<String> toSet(String[] arr) {
1506                    Set<String> set=new HashSet<String>();
1507                    
1508                    for(int i=0;i<arr.length;i++){
1509                            set.add(arr[i]);
1510                    }
1511                    return set;
1512            }
1513    }