root/livinglogic.java.ul4/library/src/com/livinglogic/ul4/Utils.java @ 211:81ee70bb3e88

Revision 211:81ee70bb3e88, 36.5 KB (checked in by Walter Doerwald <walter@…>, 10 years ago)

Added reversed function (Java part of isssue #5).

Line 
1package com.livinglogic.ul4;
2
3import java.util.AbstractList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.Iterator;
7import java.util.LinkedList;
8import java.util.NoSuchElementException;
9import java.util.List;
10import java.util.Locale;
11import java.util.Map;
12import java.util.Vector;
13import java.util.Date;
14import java.text.SimpleDateFormat;
15import org.apache.commons.lang.StringUtils;
16import org.apache.commons.lang.StringEscapeUtils;
17
18class Range extends AbstractList
19{
20    int start;
21
22    int stop;
23
24    int step;
25
26    int length;
27
28    public Range(int start, int stop, int step)
29    {
30        if (0 == step)
31        {
32            throw new IllegalArgumentException("Step argument must be different from zero!");
33        }
34        else if (0 < step)
35        {
36            this.length = rangeLength(start, stop, step);
37        }
38        else
39        {
40            this.length = rangeLength(stop, start, -step);
41        }
42        this.start = start;
43        this.stop = stop;
44        this.step = step;
45    }
46
47    public Object get(int index)
48    {
49        if ((index < 0) || (index >= length))
50        {
51            throw new IndexOutOfBoundsException("Invalid index: " + index);
52        }
53        return new Integer(start + index * step);
54    }
55
56    protected int rangeLength(int lowerEnd, int higherEnd, int positiveStep)
57    {
58        int retVal = 0;
59        if (lowerEnd < higherEnd)
60        {
61            int diff = higherEnd - lowerEnd - 1;
62            retVal = diff/positiveStep + 1;
63        }
64        return retVal;
65    }
66
67    public int size()
68    {
69        return length;
70    }
71}
72
73class StringIterator implements Iterator
74{
75    String string;
76
77    int stringSize;
78
79    int index;
80
81    public StringIterator(String string)
82    {
83        this.string = string;
84        stringSize = string.length();
85        index = 0;
86    }
87
88    public boolean hasNext()
89    {
90        return index < stringSize;
91    }
92
93    public Object next()
94    {
95        if (index >= stringSize)
96        {
97            throw new NoSuchElementException("No more characters available!");
98        }
99        return String.valueOf(string.charAt(index++));
100    }
101
102    public void remove()
103    {
104        throw new UnsupportedOperationException("Strings don't support character removal!");
105    }
106}
107
108class StringReversedIterator implements Iterator
109{
110    String string;
111
112    int stringSize;
113
114    int index;
115
116    public StringReversedIterator(String string)
117    {
118        this.string = string;
119        stringSize = string.length();
120        index = stringSize - 1;
121    }
122
123    public boolean hasNext()
124    {
125        return index >= 0;
126    }
127
128    public Object next()
129    {
130        if (index < 0)
131        {
132            throw new NoSuchElementException("No more characters available!");
133        }
134        return String.valueOf(string.charAt(index--));
135    }
136
137    public void remove()
138    {
139        throw new UnsupportedOperationException("Strings don't support character removal!");
140    }
141}
142
143class ListReversedIterator implements Iterator
144{
145    List list;
146
147    int listSize;
148
149    int index;
150
151    public ListReversedIterator(List list)
152    {
153        this.list = list;
154        listSize = list.size();
155        index = listSize - 1;
156    }
157
158    public boolean hasNext()
159    {
160        return index >= 0;
161    }
162
163    public Object next()
164    {
165        if (index < 0)
166        {
167            throw new NoSuchElementException("No more items available!");
168        }
169        return list.get(index--);
170    }
171
172    public void remove()
173    {
174        list.remove(index);
175    }
176}
177
178class MapItemIterator implements Iterator
179{
180    Iterator iterator;
181
182    public MapItemIterator(Map map)
183    {
184        iterator = map.entrySet().iterator();
185    }
186
187    public boolean hasNext()
188    {
189        return iterator.hasNext();
190    }
191
192    public Object next()
193    {
194        Vector retVal = new Vector(2);
195        Map.Entry entry = (Map.Entry)iterator.next();
196        retVal.add(entry.getKey());
197        retVal.add(entry.getValue());
198        return retVal;
199    }
200
201    public void remove()
202    {
203        iterator.remove();
204    }
205}
206
207class ZipIterator implements Iterator
208{
209    Iterator iterator1;
210    Iterator iterator2;
211    Iterator iterator3;
212
213    public ZipIterator(Iterator iterator1, Iterator iterator2)
214    {
215        this.iterator1 = iterator1;
216        this.iterator2 = iterator2;
217        this.iterator3 = null;
218    }
219
220    public ZipIterator(Iterator iterator1, Iterator iterator2, Iterator iterator3)
221    {
222        this.iterator1 = iterator1;
223        this.iterator2 = iterator2;
224        this.iterator3 = iterator3;
225    }
226
227    public boolean hasNext()
228    {
229        return iterator1.hasNext() && iterator2.hasNext() && (iterator3 == null || iterator3.hasNext());
230    }
231
232    public Object next()
233    {
234        Vector retVal = new Vector(iterator3 != null ? 3 : 2);
235        retVal.add(iterator1.next());
236        retVal.add(iterator2.next());
237        if (iterator3 != null)
238            retVal.add(iterator3.next());
239        return retVal;
240    }
241
242    public void remove()
243    {
244        iterator1.remove();
245        iterator2.remove();
246        if (iterator3 != null)
247            iterator3.remove();
248    }
249}
250
251class SequenceEnumerator implements Iterator
252{
253    Iterator sequenceIterator;
254
255    int index = 0;
256
257    public SequenceEnumerator(Iterator sequenceIterator)
258    {
259        this.sequenceIterator = sequenceIterator;
260    }
261
262    public boolean hasNext()
263    {
264        return sequenceIterator.hasNext();
265    }
266
267    public Object next()
268    {
269        Vector retVal = new Vector(2);
270        retVal.add(new Integer(index++));
271        retVal.add(sequenceIterator.next());
272        return retVal;
273    }
274
275    public void remove()
276    {
277        sequenceIterator.remove();
278    }
279}
280
281public class Utils
282{
283    protected static final Integer INTEGER_TRUE = new Integer(1);
284
285    protected static final Integer INTEGER_FALSE = new Integer(0);
286
287    public static Object neg(Integer arg)
288    {
289        return new Integer(-arg.intValue());
290    }
291
292    public static Object neg(Number arg)
293    {
294        return new Double(-arg.doubleValue());
295    }
296
297    public static Object neg(Object arg)
298    {
299        if (arg instanceof Integer)
300            return neg((Integer)arg);
301        else if (arg instanceof Number)
302            return neg((Number)arg);
303        throw new UnsupportedOperationException("Can't negate instance of " + arg.getClass() + "!");
304    }
305
306    public static Object add(Integer arg1, Integer arg2)
307    {
308        return new Integer(arg1.intValue() + arg2.intValue());
309    }
310
311    public static Object add(Number arg1, Number arg2)
312    {
313        return new Double(arg1.doubleValue() + arg2.doubleValue());
314    }
315
316    public static Object add(String arg1, String arg2)
317    {
318        return arg1 + arg2;
319    }
320
321    public static Object add(Object arg1, Object arg2)
322    {
323        if (arg1 instanceof Integer && arg2 instanceof Integer)
324            return add((Integer)arg1, (Integer)arg2);
325        else if (arg1 instanceof Number && arg2 instanceof Number)
326            return add((Number)arg1, (Number)arg2);
327        else if (arg1 instanceof String && arg2 instanceof String)
328            return add((String)arg1, (String)arg2);
329        throw new UnsupportedOperationException("Can't add instances of " + arg1.getClass() + " and " + arg2.getClass() + "!");
330    }
331
332    public static Object sub(Integer arg1, Integer arg2)
333    {
334        return new Integer(arg1.intValue() - arg2.intValue());
335    }
336
337    public static Object sub(Number arg1, Number arg2)
338    {
339        return new Double(arg1.doubleValue() - arg2.doubleValue());
340    }
341
342    public static Object sub(Object arg1, Object arg2)
343    {
344        if (arg1 instanceof Integer && arg2 instanceof Integer)
345            return sub((Integer)arg1, (Integer)arg2);
346        else if (arg1 instanceof Number && arg2 instanceof Number)
347            return sub((Number)arg1, (Number)arg2);
348        else if (arg1 instanceof String && arg2 instanceof String)
349            return sub((String)arg1, (String)arg2);
350        throw new UnsupportedOperationException("Can't subtract instances of " + arg1.getClass() + " and " + arg2.getClass() + "!");
351    }
352
353    public static Object mul(String arg1, Integer arg2)
354    {
355        return StringUtils.repeat(arg1, arg2.intValue());
356    }
357
358    public static Object mul(Integer arg1, String arg2)
359    {
360        return StringUtils.repeat(arg2, arg1.intValue());
361    }
362
363    public static Object mul(Integer arg1, Integer arg2)
364    {
365        return new Integer(arg1.intValue() * arg2.intValue());
366    }
367
368    public static Object mul(Number arg1, Number arg2)
369    {
370        return new Double(arg1.doubleValue() * arg2.doubleValue());
371    }
372
373    public static Object mul(Object arg1, Object arg2)
374    {
375        if (arg1 instanceof String && arg2 instanceof Integer)
376            return mul((String)arg1, (Integer)arg2);
377        if (arg1 instanceof Integer && arg2 instanceof String)
378            return mul((Integer)arg1, (String)arg2);
379        if (arg1 instanceof Integer && arg2 instanceof Integer)
380            return mul((Integer)arg1, (Integer)arg2);
381        if (arg1 instanceof Number && arg2 instanceof Number)
382            return mul((Number)arg1, (Number)arg2);
383        throw new UnsupportedOperationException("Can't multiply instances of " + arg1.getClass() + " and " + arg2.getClass() + "!");
384    }
385
386    public static Object truediv(Number arg1, Number arg2)
387    {
388        return new Double(arg1.doubleValue() / arg2.doubleValue());
389    }
390
391    public static Object truediv(Object arg1, Object arg2)
392    {
393        throw new UnsupportedOperationException("Can't divide instances of " + arg1.getClass() + " and " + arg2.getClass() + "!");
394    }
395
396    public static Object floordiv(Integer arg1, Integer arg2)
397    {
398        return new Integer(arg1.intValue() / arg2.intValue());
399    }
400
401    public static Object floordiv(Number arg1, Number arg2)
402    {
403        return new Double((int)(arg1.doubleValue() / arg2.doubleValue()));
404    }
405
406    public static Object floordiv(Object arg1, Object arg2)
407    {
408        throw new UnsupportedOperationException("Can't divide instances of " + arg1.getClass() + " and " + arg2.getClass() + "!");
409    }
410
411    public static Object mod(Integer arg1, Integer arg2)
412    {
413        return new Integer(arg1.intValue() % arg2.intValue());
414    }
415
416    public static Object mod(Object arg1, Object arg2)
417    {
418        if (arg1 instanceof Integer && arg2 instanceof Integer)
419            return mod((Integer)arg1, (Integer)arg2);
420        else if (arg1 instanceof Color && arg2 instanceof Color)
421            return ((Color)arg1).blend((Color)arg2);
422        throw new UnsupportedOperationException("Can't apply the modulo operator to instances of " + arg1.getClass() + " and " + arg2.getClass() + "!");
423    }
424
425    public static Object getItem(String arg1, Integer arg2)
426    {
427        int index = arg2.intValue();
428        if (0 > index)
429        {
430            index += arg1.length();
431        }
432        return arg1.substring(index, index + 1);
433    }
434
435    public static Object getItem(List arg1, Integer arg2)
436    {
437        int index = arg2.intValue();
438        if (0 > index)
439        {
440            index += arg1.size();
441        }
442        return arg1.get(index);
443    }
444
445    public static Object getItem(Color arg1, Integer arg2)
446    {
447        int index = arg2.intValue();
448        switch (index)
449        {
450            case 0:
451                return new Integer(arg1.getR());
452            case 1:
453                return new Integer(arg1.getG());
454            case 2:
455                return new Integer(arg1.getB());
456            case 3:
457                return new Integer(arg1.getA());
458            default:
459                throw new ArrayIndexOutOfBoundsException();
460        }
461    }
462
463    public static Object getItem(Map arg1, Object arg2)
464    {
465        Object result = arg1.get(arg2);
466
467        if ((result == null) && !arg1.containsKey(arg2))
468            throw new KeyException(arg2);
469        return result;
470    }
471
472    public static Object getItem(Object arg1, Object arg2)
473    {
474        if (arg1 instanceof String && arg2 instanceof Integer)
475            return getItem((String)arg1, (Integer)arg2);
476        else if (arg1 instanceof List && arg2 instanceof Integer)
477            return getItem((List)arg1, (Integer)arg2);
478        else if (arg1 instanceof Color && arg2 instanceof Integer)
479            return getItem((Color)arg1, (Integer)arg2);
480        else if (arg1 instanceof Map)
481            return getItem((Map)arg1, arg2);
482        throw new UnsupportedOperationException("Instance of " + arg1.getClass() + " does not support getitem with argument of type " + arg2.getClass() + "!");
483    }
484
485    private static int getSliceStartPos(int sequenceSize, Integer virtualPos)
486    {
487        int retVal;
488        if (null == virtualPos)
489        {
490            retVal = 0;
491        }
492        else
493        {
494            retVal = virtualPos.intValue();
495            if (0 > retVal)
496            {
497                retVal += sequenceSize;
498            }
499            if (0 > retVal)
500            {
501                retVal = 0;
502            }
503            else if (sequenceSize < retVal)
504            {
505                retVal = sequenceSize;
506            }
507        }
508        return retVal;
509    }
510
511    private static int getSliceEndPos(int sequenceSize, Integer virtualPos)
512    {
513        int retVal;
514        if (null == virtualPos)
515        {
516            retVal = sequenceSize;
517        }
518        else
519        {
520            retVal = virtualPos.intValue();
521            if (0 > retVal)
522            {
523                retVal += sequenceSize;
524            }
525            if (0 > retVal)
526            {
527                retVal = 0;
528            }
529            else if (sequenceSize < retVal)
530            {
531                retVal = sequenceSize;
532            }
533        }
534        return retVal;
535    }
536
537    public static Object getSlice(List arg1, Integer arg2, Integer arg3)
538    {
539        int size = arg1.size();
540        int start = getSliceStartPos(size, arg2);
541        int end = getSliceEndPos(size, arg3);
542        if (end < start)
543            end = start;
544        return arg1.subList(start, end);
545    }
546
547    public static Object getSlice(String arg1, Integer arg2, Integer arg3)
548    {
549        int size = arg1.length();
550        int start = getSliceStartPos(size, arg2);
551        int end = getSliceEndPos(size, arg3);
552        if (end < start)
553            end = start;
554        return StringUtils.substring(arg1, start, end);
555    }
556
557    public static Object getSlice(Object arg1, Object arg2, Object arg3)
558    {
559        if (arg1 instanceof List)
560            return getSlice((List)arg1, (Integer)arg2, (Integer)arg3);
561        else if (arg1 instanceof String)
562            return getSlice((String)arg1, (Integer)arg2, (Integer)arg3);
563        throw new UnsupportedOperationException("Instance of " + arg1.getClass() + " does not support getslice with arguments of type " + arg2.getClass() + " and " + arg3.getClass() + "!");
564    }
565
566    public static boolean getBool(Boolean obj)
567    {
568        return obj.booleanValue();
569    }
570
571    public static boolean getBool(String obj)
572    {
573        return (obj.length() > 0);
574    }
575
576    public static boolean getBool(Integer obj)
577    {
578        return (obj.intValue() != 0);
579    }
580
581    public static boolean getBool(Long obj)
582    {
583        return (obj.longValue() != 0);
584    }
585
586    public static boolean getBool(Double obj)
587    {
588        return (obj.doubleValue() != 0.);
589    }
590
591    public static boolean getBool(Date obj)
592    {
593        return true;
594    }
595
596    public static boolean getBool(Collection obj)
597    {
598        return !obj.isEmpty();
599    }
600
601    public static boolean getBool(Map obj)
602    {
603        return !obj.isEmpty();
604    }
605
606    public static boolean getBool(Object obj)
607    {
608        if (null == obj)
609            return false;
610        else if (obj instanceof Boolean)
611            return getBool((Boolean)obj);
612        else if (obj instanceof String)
613            return getBool((String)obj);
614        else if (obj instanceof Integer)
615            return getBool((Integer)obj);
616        else if (obj instanceof Long)
617            return getBool((Long)obj);
618        else if (obj instanceof Double)
619            return getBool((Double)obj);
620        else if (obj instanceof Date)
621            return getBool((Date)obj);
622        else if (obj instanceof Collection)
623            return getBool((Collection)obj);
624        else if (obj instanceof Map)
625            return getBool((Map)obj);
626        return true;
627    }
628
629    public static boolean lt(Object obj1, Object obj2)
630    {
631        if (null != obj1)
632        {
633            if (null != obj2)
634                return ((Comparable)obj1).compareTo(obj2) < 0;
635        }
636        else if (null == obj2)
637            return false;
638        throw new RuntimeException("Can't compare object to null!");
639    }
640
641    public static boolean le(Object obj1, Object obj2)
642    {
643        if (null != obj1)
644        {
645            if (null != obj2)
646                return ((Comparable)obj1).compareTo(obj2) <= 0;
647        }
648        else if (null == obj2)
649            return true;
650        throw new RuntimeException("Can't compare object to null!");
651    }
652
653    public static boolean contains(String obj, String container)
654    {
655        return container.indexOf(obj) >= 0;
656    }
657
658    public static boolean contains(Object obj, Collection container)
659    {
660        return container.contains(obj);
661    }
662
663    public static boolean contains(Object obj, Map container)
664    {
665        return container.containsKey(obj);
666    }
667
668    public static boolean contains(Object obj, Object container)
669    {
670        if (container instanceof String)
671            return contains(obj, (String)container);
672        else if (container instanceof Collection)
673            return contains(obj, (Collection)container);
674        else if (container instanceof Map)
675            return contains(obj, (Map)container);
676        throw new RuntimeException("Can't determine presence for instance of " + obj.getClass() + " in container instance of class " + container.getClass() + "!");
677    }
678
679    public static String xmlescape(Object obj)
680    {
681        if (obj == null)
682            return "";
683
684        String str = obj.toString();
685        int length = str.length();
686        StringBuffer sb = new StringBuffer((int)(1.2 * length));
687        for (int offset = 0; offset < length; offset++)
688        {
689            char c = str.charAt(offset);
690            switch (c)
691            {
692                case '<':
693                    sb.append("&lt;");
694                    break;
695                case '>':
696                    sb.append("&gt;");
697                    break;
698                case '&':
699                    sb.append("&amp;");
700                    break;
701                case '\'':
702                    sb.append("&#39;");
703                    break;
704                case '"':
705                    sb.append("&quot;");
706                    break;
707                case '\t':
708                    sb.append(c);
709                    break;
710                case '\n':
711                    sb.append(c);
712                    break;
713                case '\r':
714                    sb.append(c);
715                    break;
716                case '\u0085':
717                    sb.append(c);
718                    break;
719                default:
720                    if ((('\u0020' <= c) && (c <= '\u007e')) || ('\u00A0' <= c))
721                        sb.append(c);
722                    else
723                        sb.append("&#").append((int)c).append(';');
724                    break;
725            }
726        }
727        return sb.toString();
728    }
729
730    public static String csv(Object obj)
731    {
732        if (obj == null)
733            return "";
734        if (!(obj instanceof String))
735            obj = repr(obj);
736        return StringEscapeUtils.escapeCsv((String)obj);
737    }
738
739    public static Object toInteger(String obj)
740    {
741        return Integer.valueOf(obj);
742    }
743
744    public static Object toInteger(Integer obj)
745    {
746        return obj;
747    }
748
749    public static Object toInteger(Long obj)
750    {
751        return obj;
752    }
753
754    public static Object toInteger(Number obj)
755    {
756        return new Integer(obj.intValue());
757    }
758
759    public static Object toInteger(Boolean obj)
760    {
761        return obj.booleanValue() ? INTEGER_TRUE : INTEGER_FALSE;
762    }
763
764    public static Object toInteger(Object obj)
765    {
766        if (obj instanceof String)
767            return toInteger((String)obj);
768        else if (obj instanceof Integer)
769            return toInteger((Integer)obj);
770        else if (obj instanceof Long)
771            return toInteger((Long)obj);
772        else if (obj instanceof Number)
773            return toInteger((Number)obj);
774        else if (obj instanceof Boolean)
775            return toInteger((Boolean)obj);
776        throw new UnsupportedOperationException("Can't convert instance of " + obj.getClass() + " to an integer!");
777    }
778
779    public static Object toInteger(String obj1, Integer obj2)
780    {
781        return Integer.valueOf(obj1, obj2.intValue());
782    }
783
784    public static Object toInteger(Object obj1, Object obj2)
785    {
786        if (obj1 instanceof String && obj2 instanceof Integer)
787        {
788            return toInteger((String)obj1, (Integer)obj2);
789        }
790        throw new UnsupportedOperationException("Can't convert instance of " + obj1.getClass() + " to an integer using " + obj2.getClass() + " as base!");
791    }
792
793    public static String repr(Object obj)
794    {
795        if (obj == null)
796            return "None";
797        else if (obj instanceof Boolean)
798            return ((Boolean)obj).booleanValue() ? "True" : "False";
799        else if (obj instanceof Integer)
800            return String.valueOf(((Integer)obj).intValue());
801        else if (obj instanceof Long)
802            return String.valueOf(((Long)obj).longValue());
803        else if (obj instanceof Double)
804            return String.valueOf(((Double)obj).doubleValue());
805        else if (obj instanceof String)
806            return new StringBuffer()
807                .append("\"")
808                .append(StringEscapeUtils.escapeJava(((String)obj)))
809                .append("\"")
810                .toString();
811        else if (obj instanceof Date)
812            return isoformat((Date)obj);
813        else if (obj instanceof Color)
814            return ((Color)obj).repr();
815        else if (obj instanceof Collection)
816        {
817            StringBuffer sb = new StringBuffer();
818            sb.append("[");
819            boolean first = true;
820            for (Iterator iter = ((Collection)obj).iterator(); iter.hasNext();)
821            {
822                if (first)
823                    first = false;
824                else
825                    sb.append(", ");
826                sb.append(repr(iter.next()));
827            }
828            sb.append("]");
829            return sb.toString();
830        }
831        else if (obj instanceof Map)
832        {
833            StringBuffer sb = new StringBuffer();
834            sb.append("{");
835            boolean first = true;
836            for (Iterator iter = ((Map)obj).entrySet().iterator(); iter.hasNext();)
837            {
838                if (first)
839                    first = false;
840                else
841                    sb.append(", ");
842                Map.Entry entry = (Map.Entry)iter.next();
843                sb.append(repr(entry.getKey()));
844                sb.append(": ");
845                sb.append(repr(entry.getValue()));
846            }
847            sb.append("}");
848            return sb.toString();
849        }
850        return null;
851    }
852   
853    public static String json(Object obj)
854    {
855        if (obj == null)
856            return "null";
857        else if (obj instanceof Boolean)
858            return ((Boolean)obj).booleanValue() ? "true" : "false";
859        else if (obj instanceof Integer)
860            return String.valueOf(((Integer)obj).intValue());
861        else if (obj instanceof Long)
862            return String.valueOf(((Long)obj).longValue());
863        else if (obj instanceof Double)
864            return String.valueOf(((Double)obj).doubleValue());
865        else if (obj instanceof String)
866            return new StringBuffer()
867                .append("\"")
868                .append(StringEscapeUtils.escapeJavaScript(((String)obj)))
869                .append("\"")
870                .toString();
871        else if (obj instanceof Date)
872            return json(isoformat((Date)obj));
873        else if (obj instanceof Collection)
874        {
875            StringBuffer sb = new StringBuffer();
876            sb.append("[");
877            boolean first = true;
878            for (Iterator iter = ((Collection)obj).iterator(); iter.hasNext();)
879            {
880                if (first)
881                    first = false;
882                else
883                    sb.append(", ");
884                sb.append(json(iter.next()));
885            }
886            sb.append("]");
887            return sb.toString();
888        }
889        else if (obj instanceof Map)
890        {
891            StringBuffer sb = new StringBuffer();
892            sb.append("{");
893            boolean first = true;
894            for (Iterator iter = ((Map)obj).entrySet().iterator(); iter.hasNext();)
895            {
896                if (first)
897                    first = false;
898                else
899                    sb.append(", ");
900                Map.Entry entry = (Map.Entry)iter.next();
901                sb.append(json(entry.getKey()));
902                sb.append(": ");
903                sb.append(json(entry.getValue()));
904            }
905            sb.append("}");
906            return sb.toString();
907        }
908        return null;
909    }
910   
911    public static Iterator reversed(Object obj)
912    {
913        if (obj instanceof String)
914            return new StringReversedIterator((String)obj);
915        else if (obj instanceof List)
916            return new ListReversedIterator((List)obj);
917        throw new UnsupportedOperationException("Can't created reversed iterator for instance of " + obj.getClass() + "!");
918    }
919   
920    public static Object length(String obj)
921    {
922        return new Integer(obj.length());
923    }
924
925    public static Object length(Collection obj)
926    {
927        return new Integer(obj.size());
928    }
929
930    public static Object length(Map obj)
931    {
932        return new Integer(obj.size());
933    }
934
935    public static Object length(Object obj)
936    {
937        if (obj instanceof String)
938            return length((String)obj);
939        else if (obj instanceof Collection)
940            return length((Collection)obj);
941        else if (obj instanceof Map)
942            return length((Map)obj);
943        throw new UnsupportedOperationException("Can't determine length for instance of " + obj.getClass() + "!");
944    }
945
946    public static Iterator iterator(String obj)
947    {
948        return new StringIterator(obj);
949    }
950
951    public static Iterator iterator(Collection obj)
952    {
953        return obj.iterator();
954    }
955
956    public static Iterator iterator(Map obj)
957    {
958        return obj.keySet().iterator();
959    }
960
961    public static Iterator iterator(Object obj)
962    {
963        if (obj instanceof String)
964            return iterator((String)obj);
965        else if (obj instanceof Collection)
966            return iterator((Collection)obj);
967        else if (obj instanceof Map)
968            return iterator((Map)obj);
969        else if (obj instanceof Iterator)
970            return (Iterator)obj;
971        throw new UnsupportedOperationException("Can't iterate instance of " + obj.getClass() + "!");
972    }
973
974    public static Object enumerate(Object obj)
975    {
976        return new SequenceEnumerator(iterator(obj));
977    }
978
979    public static Object chr(Integer obj)
980    {
981        int intValue = obj.intValue();
982        char charValue = (char)intValue;
983        if (intValue != (int)charValue)
984        {
985            throw new IndexOutOfBoundsException("Code point " + intValue + " is invalid!");
986        }
987        return String.valueOf(charValue);
988    }
989
990    public static Object chr(Object obj)
991    {
992        if (obj instanceof Integer)
993            return chr((Integer)obj);
994        throw new UnsupportedOperationException("Instance of " + obj.getClass() + " is no valid unicode codepoint!");
995    }
996
997    public static Object ord(String obj)
998    {
999        if (1 != obj.length())
1000        {
1001            throw new IllegalArgumentException("String " + obj + " contains more than one unicode character!");
1002        }
1003        return new Integer((int)obj.charAt(0));
1004    }
1005
1006    public static Object ord(Object obj)
1007    {
1008        if (obj instanceof String)
1009            return chr((String)obj);
1010        throw new UnsupportedOperationException("Can't determine unicode code point for instance of " + obj.getClass() + "!");
1011    }
1012
1013    public static Object hex(Integer obj)
1014    {
1015        return "0x" + Integer.toHexString(obj.intValue());
1016    }
1017
1018    public static Object hex(Object obj)
1019    {
1020        if (obj instanceof Integer)
1021            return hex((Integer)obj);
1022        throw new UnsupportedOperationException("Instance of " + obj.getClass() + " can't be represented as a hexadecimal string!");
1023    }
1024
1025    public static Object oct(Integer obj)
1026    {
1027        return "0o" + Integer.toOctalString(obj.intValue());
1028    }
1029
1030    public static Object oct(Object obj)
1031    {
1032        if (obj instanceof Integer)
1033            return oct((Integer)obj);
1034        throw new UnsupportedOperationException("Instance of " + obj.getClass() + " can't be represented as an octal string!");
1035    }
1036
1037    public static Object bin(Integer obj)
1038    {
1039        return "0b" + Integer.toBinaryString(obj.intValue());
1040    }
1041
1042    public static Object bin(Object obj)
1043    {
1044        if (obj instanceof Integer)
1045            return chr((Integer)obj);
1046        throw new UnsupportedOperationException("Instance of " + obj.getClass() + " can't be represented as a binary string!");
1047    }
1048
1049    public static Object sorted(String obj)
1050    {
1051        Vector retVal;
1052        int length = obj.length();
1053        retVal = new Vector(obj.length());
1054        for (int i = 0; i < length; i++)
1055        {
1056            retVal.add(String.valueOf(obj.charAt(i)));
1057        }
1058        Collections.sort(retVal);
1059        return retVal;
1060    }
1061
1062    public static Object sorted(Collection obj)
1063    {
1064        Vector retVal = new Vector(obj);
1065        Collections.sort(retVal);
1066        return retVal;
1067    }
1068
1069    public static Object sorted(Map obj)
1070    {
1071        Vector retVal = new Vector(obj.keySet());
1072        Collections.sort(retVal);
1073        return retVal;
1074    }
1075
1076    public static Object sorted(Object obj)
1077    {
1078        if (obj instanceof String)
1079            return sorted((String)obj);
1080        else if (obj instanceof Collection)
1081            return sorted((Collection)obj);
1082        else if (obj instanceof Map)
1083            return sorted((Map)obj);
1084        throw new RuntimeException("Can't sort instance of " + obj.getClass() + "!");
1085    }
1086
1087    public static Object range(Integer obj)
1088    {
1089        return new Range(0, obj.intValue(), 1);
1090    }
1091
1092    public static Object range(Object obj)
1093    {
1094        if (obj instanceof Integer)
1095            return range((Integer)obj);
1096        throw new UnsupportedOperationException("Can't build a range for parameter: instance of " + obj.getClass() + "!");
1097    }
1098
1099    public static Object range(Integer obj1, Integer obj2)
1100    {
1101        return new Range(obj1.intValue(), obj2.intValue(), 1);
1102    }
1103
1104    public static Object range(Object obj1, Object obj2)
1105    {
1106        if (obj1 instanceof Integer && obj2 instanceof Integer)
1107            return range((Integer)obj1, (Integer)obj2);
1108        throw new UnsupportedOperationException("Can't build a range for parameters: instances of " + obj1.getClass() + " and " + obj2.getClass() + "!");
1109    }
1110
1111    public static Object range(Integer obj1, Integer obj2, Integer obj3)
1112    {
1113        return new Range(obj1.intValue(), obj2.intValue(), obj3.intValue());
1114    }
1115
1116    public static Object range(Object obj1, Object obj2, Object obj3)
1117    {
1118        if (obj1 instanceof Integer && obj2 instanceof Integer && obj3 instanceof Integer)
1119            return range((Integer)obj1, (Integer)obj2, (Integer)obj3);
1120        throw new UnsupportedOperationException("Can't build a range for parameters: instances of " + obj1.getClass() + " and " + obj2.getClass() + " and " + obj3.getClass() + "!");
1121    }
1122
1123    public static Object zip(Object obj1, Object obj2)
1124    {
1125        return new ZipIterator(iterator(obj1), iterator(obj2));
1126    }
1127
1128    public static Object zip(Object obj1, Object obj2, Object obj3)
1129    {
1130        return new ZipIterator(iterator(obj1), iterator(obj2), iterator(obj3));
1131    }
1132
1133    public static Object split(String obj1, String obj2)
1134    {
1135        LinkedList retVal = new LinkedList();
1136        int length = obj1.length();
1137        int delimLength = obj2.length();
1138        int pos1 = 0;
1139        int pos2;
1140        while (pos1 < length)
1141        {
1142            while ((pos1 < length) && obj1.startsWith(obj2, pos1))
1143            {
1144                if (0 == pos1)
1145                {
1146                    retVal.add("");
1147                }
1148                pos1 += delimLength;
1149                retVal.add("");
1150            }
1151            if (pos1 < length)
1152            {
1153                pos2 = pos1 + 1;
1154                if (!retVal.isEmpty())
1155                {
1156                    retVal.removeLast();
1157                }
1158                while ((pos2 < length) && !obj1.startsWith(obj2, pos2))
1159                {
1160                    pos2++;
1161                }
1162                retVal.add(obj1.substring(pos1, pos2));
1163                pos1 = pos2;
1164            }
1165        }
1166        return retVal;
1167    }
1168
1169    public static Object split(Object obj)
1170    {
1171        if (obj instanceof String)
1172            return StringUtils.split((String)obj);
1173        throw new UnsupportedOperationException("Can't split instance of " + obj.getClass() + "!");
1174    }
1175
1176    public static Object split(Object obj1, Object obj2)
1177    {
1178        if ((obj1 instanceof String) && (obj2 instanceof String))
1179            return split((String)obj1, (String)obj2);
1180        throw new UnsupportedOperationException("Can't split instance of " + obj1.getClass() + " with delimiter instance of " + obj2.getClass() + "!");
1181    }
1182
1183    public static Object strip(Object obj)
1184    {
1185        if (obj instanceof String)
1186            return StringUtils.strip((String)obj);
1187        throw new UnsupportedOperationException("Can't strip instance of " + obj.getClass() + "!");
1188    }
1189
1190    public static Object lstrip(Object obj)
1191    {
1192        if (obj instanceof String)
1193            return StringUtils.stripStart((String)obj, null);
1194        throw new UnsupportedOperationException("Can't lstrip instance of " + obj.getClass() + "!");
1195    }
1196
1197    public static Object rstrip(Object obj)
1198    {
1199        if (obj instanceof String)
1200            return StringUtils.stripEnd((String)obj, null);
1201        throw new UnsupportedOperationException("Can't rstrip instance of " + obj.getClass() + "!");
1202    }
1203
1204    public static Object upper(String obj)
1205    {
1206        return obj.toUpperCase();
1207    }
1208
1209    public static Object upper(Object obj)
1210    {
1211        if (obj instanceof String)
1212            return upper((String)obj);
1213        throw new UnsupportedOperationException("Can't convert an instance of " + obj.getClass() + " to upper case!");
1214    }
1215
1216    public static Object lower(String obj)
1217    {
1218        return obj.toLowerCase();
1219    }
1220
1221    public static Object lower(Object obj)
1222    {
1223        if (obj instanceof String)
1224            return lower((String)obj);
1225        throw new UnsupportedOperationException("Can't convert an instance of " + obj.getClass() + " to lower case!");
1226    }
1227
1228    public static Object capitalize(String obj)
1229    {
1230        return String.valueOf(Character.toTitleCase(obj.charAt(0))) + obj.substring(1).toLowerCase();
1231    }
1232
1233    public static Object capitalize(Object obj)
1234    {
1235        if (obj instanceof String)
1236            return capitalize((String)obj);
1237        throw new UnsupportedOperationException("Can't convert an instance of " + obj.getClass() + " to capital case!");
1238    }
1239
1240    public static SimpleDateFormat isoDateFormatter = new SimpleDateFormat("yyyy.MM.dd'T'HH:mm:ss.SSS'000'");
1241
1242    public static String isoformat(Date obj)
1243    {
1244        return isoDateFormatter.format(obj);
1245    }
1246
1247    public static String isoformat(Object obj)
1248    {
1249        if (obj instanceof Date)
1250            return isoformat((Date)obj);
1251        throw new UnsupportedOperationException("Can't call isoformat on instance of " + obj.getClass() + "!");
1252    }
1253
1254    public static Object format(Date obj, String formatString, Locale locale)
1255    {
1256        StringBuffer javaFormatString = new StringBuffer();
1257        int formatStringLength = formatString.length();
1258        boolean escapeCharacterFound = false;
1259        boolean inLiteral = false;
1260        char formatChar;
1261        String javaFormatSequence;
1262        for (int i = 0; i < formatStringLength; i++)
1263        {
1264            formatChar = formatString.charAt(i);
1265            if (escapeCharacterFound)
1266            {
1267                switch (formatChar)
1268                {
1269                    case 'a':
1270                        javaFormatSequence = "EE";
1271                        break;
1272                    case 'A':
1273                        javaFormatSequence = "EEEE";
1274                        break;
1275                    case 'b':
1276                        javaFormatSequence = "MMM";
1277                        break;
1278                    case 'B':
1279                        javaFormatSequence = "MMMM";
1280                        break;
1281                    case 'c':
1282                        throw new UnsupportedOperationException("Unimplemented escape sequence %c");
1283                    case 'd':
1284                        javaFormatSequence = "dd";
1285                        break;
1286                    case 'f':
1287                        javaFormatSequence = "SSS'000";
1288                        break;
1289                    case 'H':
1290                        javaFormatSequence = "HH";
1291                        break;
1292                    case 'I':
1293                        javaFormatSequence = "hh";
1294                        break;
1295                    case 'j':
1296                        javaFormatSequence = "DDD";
1297                        break;
1298                    case 'm':
1299                        javaFormatSequence = "MM";
1300                        break;
1301                    case 'M':
1302                        javaFormatSequence = "mm";
1303                        break;
1304                    case 'p':
1305                        javaFormatSequence = "aa";
1306                        break;
1307                    case 'S':
1308                        javaFormatSequence = "ss";
1309                        break;
1310                    case 'U':
1311                        javaFormatSequence = "ww";
1312                        break;
1313                    case 'w':
1314                        throw new UnsupportedOperationException("Unimplemented escape sequence %w");
1315                    case 'W':
1316                        javaFormatSequence = "ww";
1317                        break;
1318                    case 'x':
1319                        throw new UnsupportedOperationException("Unimplemented escape sequence %x");
1320                    case 'X':
1321                        throw new UnsupportedOperationException("Unimplemented escape sequence %X");
1322                    case 'y':
1323                        javaFormatSequence = "yy";
1324                        break;
1325                    case 'Y':
1326                        javaFormatSequence = "yyyy";
1327                        break;
1328                    default:
1329                        javaFormatSequence = null;
1330                        break;
1331                }
1332                if (inLiteral != (null == javaFormatSequence))
1333                {
1334                    javaFormatString.append('\'');
1335                    inLiteral = !inLiteral;
1336                }
1337                if (null != javaFormatSequence)
1338                {
1339                    javaFormatString.append(javaFormatSequence);
1340                    if ('f' == formatChar)
1341                    {
1342                        inLiteral = true;
1343                    }
1344                }
1345                else
1346                {
1347                    javaFormatString.append(formatChar);
1348                }
1349                escapeCharacterFound = false;
1350            }
1351            else
1352            {
1353                escapeCharacterFound = ('%' == formatChar);
1354                if (!escapeCharacterFound)
1355                {
1356                    if (inLiteral = !inLiteral)
1357                    {
1358                        javaFormatString.append('\'');
1359                    }
1360                    javaFormatString.append(formatChar);
1361                    if ('\'' == formatChar)
1362                    {
1363                        javaFormatString.append(formatChar);
1364                    }
1365                }
1366            }
1367        }
1368        if (inLiteral)
1369        {
1370            javaFormatString.append('\'');
1371        }
1372        return new SimpleDateFormat(javaFormatString.toString(), locale).format(obj);
1373    }
1374
1375    public static Object format(Object obj, Object formatString, Locale locale)
1376    {
1377        if (formatString instanceof String)
1378        {
1379            if (obj instanceof Date)
1380            {
1381                return format((Date)obj, (String)formatString, locale);
1382            }
1383        }
1384        throw new UnsupportedOperationException("Can't call format on instance of " + obj.getClass() + " with format string instance of " + formatString.getClass() + "!");
1385    }
1386
1387    public static Object replace(Object obj, Object arg1, Object arg2)
1388    {
1389        if (obj instanceof String && arg1 instanceof String && arg2 instanceof String)
1390            return StringUtils.replace((String)obj, (String)arg1, (String)arg2);
1391        throw new UnsupportedOperationException("Can't call replace on instance of " + obj.getClass() + "!");
1392    }
1393
1394    public static Object find(Object obj, Object arg1)
1395    {
1396        if (obj instanceof String && arg1 instanceof String)
1397            return new Integer(((String)obj).indexOf((String)arg1));
1398        throw new UnsupportedOperationException("Can't call find on instance of " + obj.getClass() + "!");
1399    }
1400
1401    public static Object rfind(Object obj, Object arg1)
1402    {
1403        if (obj instanceof String && arg1 instanceof String)
1404            return new Integer(((String)obj).lastIndexOf((String)arg1));
1405        throw new UnsupportedOperationException("Can't call rfind on instance of " + obj.getClass() + "!");
1406    }
1407
1408    public static Object items(Map obj)
1409    {
1410        return new MapItemIterator(obj);
1411    }
1412
1413    public static Object items(Object obj)
1414    {
1415        if (obj instanceof Map)
1416            return items((Map)obj);
1417        throw new UnsupportedOperationException("Instance of " + obj.getClass() + " can't be iterated as a map!");
1418    }
1419
1420    public static String type(Object obj)
1421    {
1422        if (obj == null)
1423            return "none";
1424        else if (obj instanceof String)
1425            return "str";
1426        else if (obj instanceof Boolean)
1427            return "bool";
1428        else if (obj instanceof Integer || obj instanceof Long)
1429            return "int";
1430        else if (obj instanceof Double)
1431            return "float";
1432        else if (obj instanceof Date)
1433            return "date";
1434        else if (obj instanceof Color)
1435            return "color";
1436        else if (obj instanceof List)
1437            return "list";
1438        else if (obj instanceof Map)
1439            return "dict";
1440        else if (obj instanceof Template)
1441            return "template";
1442        else
1443            return null;
1444    }
1445
1446    private static double _getdouble(Object arg)
1447    {
1448        if (arg instanceof Integer)
1449            return ((Integer)arg).doubleValue();
1450        else if (arg instanceof Long)
1451            return ((Long)arg).doubleValue();
1452        else if (arg instanceof Double)
1453            return ((Double)arg).doubleValue();
1454        else
1455            throw new UnsupportedOperationException("can't convert " + arg.getClass() + " to float!");
1456    }
1457
1458    private static int _getint(Object arg)
1459    {
1460        if (arg instanceof Integer)
1461            return ((Integer)arg).intValue();
1462        else if (arg instanceof Long)
1463            return ((Long)arg).intValue();
1464        else if (arg instanceof Double)
1465            return ((Double)arg).intValue();
1466        else
1467            throw new UnsupportedOperationException("can't convert " + arg.getClass() + " to int!");
1468    }
1469
1470    public static Color rgb(Object arg1, Object arg2, Object arg3)
1471    {
1472        return Color.fromrgb(_getdouble(arg1), _getdouble(arg2), _getdouble(arg3));
1473    }
1474
1475    public static Color rgb(Object arg1, Object arg2, Object arg3, Object arg4)
1476    {
1477        return Color.fromrgb(_getdouble(arg1), _getdouble(arg2), _getdouble(arg3), _getdouble(arg4));
1478    }
1479
1480    public static Color hsv(Object arg1, Object arg2, Object arg3)
1481    {
1482        return Color.fromhsv(_getdouble(arg1), _getdouble(arg2), _getdouble(arg3));
1483    }
1484
1485    public static Color hsv(Object arg1, Object arg2, Object arg3, Object arg4)
1486    {
1487        return Color.fromhsv(_getdouble(arg1), _getdouble(arg2), _getdouble(arg3), _getdouble(arg4));
1488    }
1489
1490    public static Color hls(Object arg1, Object arg2, Object arg3)
1491    {
1492        return Color.fromhls(_getdouble(arg1), _getdouble(arg2), _getdouble(arg3));
1493    }
1494
1495    public static Color hls(Object arg1, Object arg2, Object arg3, Object arg4)
1496    {
1497        return Color.fromhls(_getdouble(arg1), _getdouble(arg2), _getdouble(arg3), _getdouble(arg4));
1498    }
1499
1500    public static Color withlum(Object arg1, Object arg2)
1501    {
1502        return ((Color)arg1).withlum(_getdouble(arg2));
1503    }
1504
1505    public static Color witha(Object arg1, Object arg2)
1506    {
1507        return ((Color)arg1).witha(_getint(arg2));
1508    }
1509
1510    public static void main(String[] args)
1511    {
1512        //System.out.println(split("\t\tgurk\t\t\t\t\t\thurz\t\tschwumpl\t\t\t\t", "\t\t"));
1513        System.out.println(split("gurk\t\t\t\t\t\thurz\t\tschwumpl", "\t\t"));
1514        //System.out.println(split("\t\tgurk\t\t\t\t\t\thurz\t\tschwumpl\t\t\t\t"));
1515        //System.out.println(split("gurk\t\t\t\t\t\thurz\t\tschwumpl"));
1516        //System.out.println(split("  gurk      hurz  schwumpl    "));
1517    }
1518}
Note: See TracBrowser for help on using the browser.