001    package railo.runtime.type.wrap;
002    
003    import java.util.ArrayList;
004    import java.util.Collections;
005    import java.util.Comparator;
006    import java.util.Iterator;
007    import java.util.List;
008    import java.util.ListIterator;
009    import java.util.Map.Entry;
010    
011    import railo.commons.lang.CFTypes;
012    import railo.runtime.PageContext;
013    import railo.runtime.converter.LazyConverter;
014    import railo.runtime.dump.DumpData;
015    import railo.runtime.dump.DumpProperties;
016    import railo.runtime.dump.DumpUtil;
017    import railo.runtime.exp.ExpressionException;
018    import railo.runtime.exp.PageException;
019    import railo.runtime.op.Caster;
020    import railo.runtime.op.Duplicator;
021    import railo.runtime.type.Array;
022    import railo.runtime.type.ArrayImpl;
023    import railo.runtime.type.Collection;
024    import railo.runtime.type.KeyImpl;
025    import railo.runtime.type.Sizeable;
026    import railo.runtime.type.Struct;
027    import railo.runtime.type.dt.DateTime;
028    import railo.runtime.type.it.EntryIterator;
029    import railo.runtime.type.it.KeyIterator;
030    import railo.runtime.type.it.StringIterator;
031    import railo.runtime.type.util.ArrayUtil;
032    import railo.runtime.type.util.MemberUtil;
033    
034    /**
035     * 
036     */
037    public class ListAsArray implements Array,List,Sizeable {
038    
039            protected List list;
040            
041            private ListAsArray(List list) {
042                    this.list=list;
043            }
044            
045            public static Array toArray(List list) {
046                    if(list instanceof ArrayAsList) return ((ArrayAsList)list).array;
047                    if(list instanceof Array) return (Array) list;
048                    return new ListAsArray(list);
049            }
050            
051            
052            @Override
053            public Object append(Object o) throws PageException {
054                    list.add(o);
055                    return o;
056            }
057            
058            
059            @Override
060            public Object appendEL(Object o) {
061                    list.add(o);
062                    return o;
063            }
064    
065            @Override
066            public boolean containsKey(int index) {
067                    return get(index-1,null)!=null;
068            }
069    
070            @Override
071            public Object get(int key, Object defaultValue) {
072                    try {
073                            Object rtn = list.get(key-1);
074                            if(rtn==null) return defaultValue;
075                            return rtn;
076                    }
077                    catch(Throwable t) {
078                            return defaultValue;
079                    }
080            }
081    
082            @Override
083            public Object getE(int key) throws PageException {
084                    try {
085                            Object rtn = list.get(key-1);
086                            if(rtn==null) throw new ExpressionException("Element at position ["+key+"] does not exist in list");
087                            return rtn;
088                    }
089                    catch(Throwable t) {
090                            throw new ExpressionException("Element at position ["+key+"] does not exist in list",t.getMessage());
091                    }
092            }
093    
094            @Override
095            public int getDimension() {
096                    return 1;
097            }
098    
099            public boolean insert(int key, Object value) throws PageException {
100                    try {
101                    list.add(key-1, value);
102                    }
103                    catch(Throwable t) {
104                            throw new ExpressionException("can't insert value to array at position "+key+", array goes from 1 to "+size());
105                    }
106                    return true;
107            }
108    
109            public int[] intKeys() {
110                    ListIterator lit = list.listIterator();
111                    ArrayList keys = new ArrayList();
112                    int index=0;
113                    Object v;
114                    while(lit.hasNext()) {
115                            index=lit.nextIndex()+1;
116                            v=lit.next();
117                            if(v!=null)keys.add(Integer.valueOf(index));
118                    }
119                    int[] intKeys = new int[keys.size()];
120                    Iterator it = keys.iterator();
121                    index=0;
122                    while(it.hasNext()) {
123                            intKeys[index++]=((Integer)it.next()).intValue();
124                    }
125                    
126                    return intKeys;
127            }
128    
129            @Override
130            public Object prepend(Object o) throws PageException {
131                    list.add(0,o);
132                    return o;
133            }
134    
135            public Object removeE(int key) throws PageException {
136                    try {
137                    return list.remove(key-1);
138                    }
139                    catch(Throwable t) {
140                            throw new ExpressionException("can not remove Element at position ["+key+"]",t.getMessage());
141                    }
142            }
143    
144            @Override
145            public Object removeEL(int key) {
146                    try {
147                            return removeE(key);
148                    } catch (PageException e) {
149                            return null;
150                    }
151            }
152    
153            public void resize(int to) throws PageException {
154                    while(size()<to)list.add(null);
155            }
156    
157            @Override
158            public Object setE(int key, Object value) throws PageException {
159                    if(key<=size()) {
160                            try {
161                            list.set(key-1, value);
162                            }
163                            catch(Throwable t) {
164                                    throw new ExpressionException("can not set Element at position ["+key+"]",t.getMessage());
165                            }
166                            
167                    }
168                    else {
169                            while(size()<key-1)list.add(null);
170                            list.add(value);
171                    }
172                    return value;
173            }
174    
175            @Override
176            public Object setEL(int key, Object value) {
177                    try {
178                            return setE(key, value);
179                    } catch (Throwable t) {}
180                    return value;
181            }
182    
183            @Override
184            public void sort(String sortType, String sortOrder) throws PageException {
185                    sort(ArrayUtil.toComparator(null, sortType, sortOrder, false));
186            }
187    
188            @Override
189            public synchronized void sort(Comparator comp) throws PageException {
190                    if(getDimension()>1)
191                            throw new ExpressionException("only 1 dimensional arrays can be sorted");
192                    Collections.sort(list,comp);
193            }
194    
195            @Override
196            public Object[] toArray() {
197                    return list.toArray();
198            }
199    
200            public ArrayList toArrayList() {
201                    return new ArrayList(list);
202            }
203    
204            @Override
205            public void clear() {
206                    list.clear();
207            }
208    
209            @Override
210            public boolean containsKey(String key) {
211                    return get(key,null)!=null;
212            }
213    
214            @Override
215            public boolean containsKey(Key key) {
216                    return get(key,null)!=null;
217            }
218    
219            @Override
220            public Collection duplicate(boolean deepCopy) {new ArrayImpl().duplicate(deepCopy);
221                    return new ListAsArray((List)Duplicator.duplicate(list,deepCopy));
222            }
223    
224            
225    
226            @Override
227            public Object get(String key) throws PageException {
228                    return getE(Caster.toIntValue(key));
229            }
230    
231            @Override
232            public Object get(Key key) throws PageException {
233                    return get(key.getString());
234            }
235    
236            @Override
237            public Object get(String key, Object defaultValue) {
238                    double index=Caster.toIntValue(key,Integer.MIN_VALUE);
239                    if(index==Integer.MIN_VALUE) return defaultValue;
240                return get((int)index,defaultValue);
241            }
242    
243            @Override
244            public Object get(Key key, Object defaultValue) {
245                    return get(key.getString(),defaultValue);
246            }
247    
248            @Override
249            public Key[] keys() {
250                    int[] intKeys = intKeys();
251                    Collection.Key[] keys = new Collection.Key[intKeys.length];
252                    for(int i=0;i<intKeys.length;i++) {
253                            keys[i]=KeyImpl.init(Caster.toString(intKeys[i]));
254                    }
255                    return keys;
256            }
257    
258            @Override
259            public Object remove(Key key) throws PageException {
260                    return removeE(Caster.toIntValue(key.getString()));
261            }
262    
263            @Override
264            public Object removeEL(Key key) {
265                    double index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
266                    if(index==Integer.MIN_VALUE) return null;
267                return removeEL((int)index);
268            }
269    
270            @Override
271            public Object set(String key, Object value) throws PageException {
272                    return setE(Caster.toIntValue(key),value);
273            }
274    
275            @Override
276            public Object set(Key key, Object value) throws PageException {
277                    return set(key.getString(),value);
278            }
279    
280            @Override
281            public Object setEL(String key, Object value) {
282                    double index=Caster.toIntValue(key,Integer.MIN_VALUE);
283                    if(index==Integer.MIN_VALUE) return value;
284                return setEL((int)index,value);
285            }
286    
287            @Override
288            public Object setEL(Key key, Object value) {
289                    return setEL(key.getString(), value);
290            }
291    
292            @Override
293            public int size() {
294                    return list.size();
295            }
296    
297            public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
298                    return DumpUtil.toDumpData(list, pageContext,maxlevel,dp);
299            }
300    
301            @Override
302            public Iterator iterator() {
303                    return list.iterator();
304            }
305    
306            @Override
307            public Iterator<Collection.Key> keyIterator() {
308                    return new KeyIterator(keys());
309            }
310        
311        @Override
312            public Iterator<String> keysAsStringIterator() {
313            return new StringIterator(keys());
314        }
315            
316            @Override
317            public Iterator<Entry<Key, Object>> entryIterator() {
318                    return new EntryIterator(this,keys());
319            }
320    
321            @Override
322        public String castToString() throws PageException {
323            throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to String",
324              "Use Built-In-Function \"serialize(Array):String\" to create a String from Array");
325        }
326    
327            @Override
328            public String castToString(String defaultValue) {
329                    return defaultValue;
330            }
331    
332    
333        @Override
334        public boolean castToBooleanValue() throws PageException {
335            throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to a boolean value");
336        }
337        
338        @Override
339        public Boolean castToBoolean(Boolean defaultValue) {
340            return defaultValue;
341        }
342    
343    
344        @Override
345        public double castToDoubleValue() throws PageException {
346            throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to a number value");
347        }
348        
349        @Override
350        public double castToDoubleValue(double defaultValue) {
351            return defaultValue;
352        }
353    
354    
355        @Override
356        public DateTime castToDateTime() throws PageException {
357            throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to a Date");
358        }
359        
360        @Override
361        public DateTime castToDateTime(DateTime defaultValue) {
362            return defaultValue;
363        }
364    
365            @Override
366            public int compareTo(boolean b) throws PageException {
367                    throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a boolean value");
368            }
369    
370            @Override
371            public int compareTo(DateTime dt) throws PageException {
372                    throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a DateTime Object");
373            }
374    
375            @Override
376            public int compareTo(double d) throws PageException {
377                    throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a numeric value");
378            }
379    
380            @Override
381            public int compareTo(String str) throws PageException {
382                    throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a String");
383            }
384    
385            @Override
386            public String toString() {
387                    return LazyConverter.serialize(this);
388            }
389            
390            @Override
391            public Object clone() {
392                    return duplicate(true);
393            }
394    
395            @Override
396            public boolean add(Object o) {
397                    return list.add(o);
398            }
399    
400            @Override
401            public void add(int index, Object element) {
402                    list.add(index, element);
403            }
404    
405            @Override
406            public boolean addAll(java.util.Collection c) {
407                    return list.addAll(c);
408            }
409    
410            @Override
411            public boolean addAll(int index, java.util.Collection c) {
412                    return list.addAll(index, c);
413            }
414    
415            @Override
416            public boolean contains(Object o) {
417                    return list.contains(o);
418            }
419    
420            @Override
421            public boolean containsAll(java.util.Collection c) {
422                    return list.contains(c);
423            }
424    
425            @Override
426            public Object get(int index) {
427                    return list.get(index);
428            }
429    
430            @Override
431            public int indexOf(Object o) {
432                    return list.indexOf(o);
433            }
434    
435            @Override
436            public boolean isEmpty() {
437                    return list.isEmpty();
438            }
439    
440            @Override
441            public int lastIndexOf(Object o) {
442                    return list.lastIndexOf(o);
443            }
444    
445            @Override
446            public ListIterator listIterator() {
447                    return list.listIterator();
448            }
449    
450            @Override
451            public ListIterator listIterator(int index) {
452                    return list.listIterator(index);
453            }
454    
455            @Override
456            public boolean remove(Object o) {
457                    return list.remove(o);
458            }
459    
460            @Override
461            public Object remove(int index) {
462                    return list.remove(index);
463            }
464    
465            @Override
466            public boolean removeAll(java.util.Collection c) {
467                    return list.removeAll(c);
468            }
469    
470            @Override
471            public boolean retainAll(java.util.Collection c) {
472                    return list.retainAll(c);
473            }
474    
475            @Override
476            public Object set(int index, Object element) {
477                    return list.set(index, element);
478            }
479    
480            @Override
481            public List subList(int fromIndex, int toIndex) {
482                    return list.subList(fromIndex, toIndex);
483            }
484    
485            @Override
486            public Object[] toArray(Object[] a) {
487                    return list.toArray(a);
488            }
489    
490    
491            @Override
492            public List toList() {
493                    return this;
494            }
495    
496            public Iterator valueIterator() {
497                    return list.iterator();
498            }
499    
500            @Override
501            public long sizeOf() {
502                    return ArrayUtil.sizeOf(list);
503            }
504    
505            @Override
506            public Object get(PageContext pc, Key key, Object defaultValue) {
507                    return get(key, defaultValue);
508            }
509    
510            @Override
511            public Object get(PageContext pc, Key key) throws PageException {
512                    return get(key);
513            }
514    
515            @Override
516            public Object set(PageContext pc, Key propertyName, Object value) throws PageException {
517                    return set(propertyName, value);
518            }
519    
520            @Override
521            public Object setEL(PageContext pc, Key propertyName, Object value) {
522                    return setEL(propertyName, value);
523            }
524    
525            @Override
526            public Object call(PageContext pc, Key methodName, Object[] args) throws PageException {
527                    return MemberUtil.call(pc, this, methodName, args, CFTypes.TYPE_ARRAY, "array");
528            }
529    
530            @Override
531            public Object callWithNamedValues(PageContext pc, Key methodName, Struct args) throws PageException {
532                    return MemberUtil.callWithNamedValues(pc,this,methodName,args, CFTypes.TYPE_ARRAY, "array");
533            }
534    
535            @Override
536            public java.util.Iterator<Object> getIterator() {
537            return valueIterator();
538        } 
539    }