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