001    package railo.runtime.type.util;
002    
003    import java.util.Iterator;
004    import java.util.List;
005    import java.util.ListIterator;
006    
007    import railo.runtime.converter.LazyConverter;
008    import railo.runtime.exp.ExpressionException;
009    import railo.runtime.exp.PageException;
010    import railo.runtime.exp.PageRuntimeException;
011    import railo.runtime.op.Caster;
012    import railo.runtime.type.Array;
013    import railo.runtime.type.Collection;
014    import railo.runtime.type.KeyImpl;
015    import railo.runtime.type.Sizeable;
016    import railo.runtime.type.dt.DateTime;
017    
018    public abstract class ArraySupport implements Array,List,Sizeable {
019    
020            
021            /**
022             * @see java.util.List#add(int, E)
023             */
024            public final void add(int index, Object element) {
025                    try {
026                            insert(index+1, element);
027                    } catch (PageException e) {
028                            throw new IndexOutOfBoundsException("can't insert value to List at position "+index+", " +
029                                            "valid values are from 0 to "+(size()-1)+", size is "+size());
030                    }
031            }
032    
033            /**
034             * @see java.util.List#addAll(java.util.Collection)
035             */
036            public final boolean addAll(java.util.Collection c) {
037                    Iterator it = c.iterator();
038                    while(it.hasNext()) {
039                            add(it.next());
040                    }
041                    return true;
042            }
043    
044            /**
045             * @see java.util.List#addAll(int, java.util.Collection)
046             */
047            public final boolean addAll(int index, java.util.Collection c) {
048                    Iterator it = c.iterator();
049                    while(it.hasNext()) {
050                            add(index++,it.next());
051                    }
052                    return !c.isEmpty();
053            }
054            
055            /**
056         * adds a value and return this array
057         * @param o
058         * @return this Array
059         */
060        public synchronized boolean add(Object o) {
061            appendEL(o);
062            return true;
063        }
064    
065            /**
066             * @see java.util.List#contains(java.lang.Object)
067             */
068            public final boolean contains(Object o) {
069                    return indexOf(o)!=-1;
070            }
071    
072            /**
073             * @see java.util.List#containsAll(java.util.Collection)
074             */
075            public final boolean containsAll(java.util.Collection c) {
076                    Iterator it = c.iterator();
077                    while(it.hasNext()) {
078                            if(!contains(it.next()))return false;
079                    }
080                    return true;
081            }
082    
083            /**
084             * @see java.util.List#indexOf(java.lang.Object)
085             */
086            public final int indexOf(Object o) {
087                    Iterator it=iterator();
088                    int index=0;
089                    while(it.hasNext()) {
090                            if(it.next().equals(o))return index;
091                            index++;
092                    }
093                    return -1;
094            }
095    
096            /**
097             * @see java.util.List#isEmpty()
098             */
099            public final boolean isEmpty() {
100                    return size()==0;
101            }
102    
103            /**
104             * @see java.util.List#lastIndexOf(java.lang.Object)
105             */
106            public final int lastIndexOf(Object o) {
107                    Iterator it=iterator();
108                    int index=0;
109                    int rtn=-1;
110                    while(it.hasNext()) {
111                            if(it.next().equals(o))rtn=index;
112                            index++;
113                    }
114                    return rtn;
115            }
116    
117            /**
118             * @see java.util.List#listIterator()
119             */
120            public final ListIterator listIterator() {
121                    return new ListIteratorImpl(this,0);
122            }
123    
124            /**
125             * @see java.util.List#listIterator(int)
126             */
127            public final ListIterator listIterator(int index) {
128                    return new ListIteratorImpl(this,index);
129                    //return toArrayList().listIterator(index);
130            }
131    
132            /**
133             * @see java.util.List#remove(java.lang.Object)
134             */
135            public final boolean remove(Object o) {
136                    int index = indexOf(o);
137                    if(index==-1) return false;
138                    
139                    try {
140                            removeE(index+1);
141                    } catch (PageException e) {
142                            return false;
143                    }
144                    return true;
145            }
146    
147            /**
148             * @see java.util.List#removeAll(java.util.Collection)
149             */
150            public final boolean removeAll(java.util.Collection c) {
151                    Iterator it = c.iterator();
152                    boolean rtn=false;
153                    while(it.hasNext()) {
154                            if(remove(it.next()))rtn=true;
155                    }
156                    return rtn;
157            }
158    
159            /**
160             * @see java.util.List#retainAll(java.util.Collection)
161             */
162            public final boolean retainAll(java.util.Collection c) {
163                    boolean modified = false;
164                    Iterator it = iterator();
165                    while (it.hasNext()) {
166                        if(!c.contains(it.next())) {
167                            it.remove();
168                            modified = true;
169                        }
170                    }
171                    return modified;
172            }
173    
174            /**
175             * @see java.util.List#subList(int, int)
176             */
177            public final List subList(int fromIndex, int toIndex) {
178                    throw new RuntimeException("method subList is not supported");
179            }
180            
181    
182            public static final short TYPE_OBJECT = 0;
183            public static final short TYPE_BOOLEAN = 1;
184            public static final short TYPE_BYTE = 2;
185            public static final short TYPE_SHORT = 3;
186            public static final short TYPE_INT = 4;
187            public static final short TYPE_LONG = 5;
188            public static final short TYPE_FLOAT = 6;
189            public static final short TYPE_DOUBLE = 7;
190            public static final short TYPE_CHARACTER = 8;
191            public static final short TYPE_STRING = 9;
192    
193            /**
194             * @see java.util.List#toArray(T[])
195             */
196            public final Object[] toArray(Object[] a) {
197                    if(a==null) return toArray();
198                    
199                    
200                    Class trgClass=a.getClass().getComponentType();
201                    short type=TYPE_OBJECT;
202                    if(trgClass==Boolean.class) type=TYPE_BOOLEAN;
203                    else if(trgClass==Byte.class) type=TYPE_BYTE;
204                    else if(trgClass==Short.class) type=TYPE_SHORT;
205                    else if(trgClass==Integer.class) type=TYPE_INT;
206                    else if(trgClass==Long.class) type=TYPE_LONG;
207                    else if(trgClass==Float.class) type=TYPE_FLOAT;
208                    else if(trgClass==Double.class) type=TYPE_DOUBLE;
209                    else if(trgClass==Character.class) type=TYPE_CHARACTER;
210                    else if(trgClass==String.class) type=TYPE_STRING;
211                    
212                    
213                    Iterator it = iterator();
214                    int i=0;
215                    Object o;
216                    try {
217                            while(it.hasNext()) {
218                                    o=it.next();
219                                    switch(type){
220                                    case TYPE_BOOLEAN:
221                                            o=Caster.toBoolean(o);
222                                    break;
223                                    case TYPE_BYTE:
224                                            o=Caster.toByte(o);
225                                    break;
226                                    case TYPE_CHARACTER:
227                                            o=Caster.toCharacter(o);
228                                    break;
229                                    case TYPE_DOUBLE:
230                                            o=Caster.toDouble(o);
231                                    break;
232                                    case TYPE_FLOAT:
233                                            o=Caster.toFloat(o);
234                                    break;
235                                    case TYPE_INT:
236                                            o=Caster.toInteger(o);
237                                    break;
238                                    case TYPE_LONG:
239                                            o=Caster.toLong(o);
240                                    break;
241                                    case TYPE_SHORT:
242                                            o=Caster.toShort(o);
243                                    break;
244                                    case TYPE_STRING:
245                                            o=Caster.toString(o);
246                                    break;
247                                    }
248                                    a[i++]=o;
249                            }
250                    }
251                    catch(PageException pe){
252                            throw new PageRuntimeException(pe);
253                    }
254                    return a;
255            }
256    
257            /**
258             * @see java.util.List#get(int)
259             */
260            public final Object get(int index) {
261                    if(index<0)  
262                            throw new IndexOutOfBoundsException("invalid index defintion ["+index+"], " +
263                                            "index should be a number between [0 - "+(size()-1)+"], size is "+size());
264                    if(index>=size())
265                            throw new IndexOutOfBoundsException("invalid index ["+index+"] defintion, " +
266                                            "index should be a number between [0 - "+(size()-1)+"], size is "+size());
267                    
268                    return get(index+1, null); 
269            }
270    
271            /**
272             * @see java.util.List#remove(int)
273             */
274            public final Object remove(int index) {
275                    if(index<0)  
276                            throw new IndexOutOfBoundsException("invalid index defintion ["+index+"], " +
277                                            "index should be a number between [0 - "+(size()-1)+"], size is "+size());
278                    if(index>=size())
279                            throw new IndexOutOfBoundsException("invalid index ["+index+"] defintion, " +
280                                            "index should be a number between [0 - "+(size()-1)+"], size is "+size());
281                    
282                    return removeEL(index+1); 
283            }
284    
285            /**
286             * @see java.util.List#set(int, java.lang.Object)
287             */
288            public final Object set(int index, Object element) {
289                    Object o=get(index);
290                    setEL(index+1, element); 
291                    return o;
292            }
293            
294    
295        /**
296         * @see railo.runtime.type.Collection#containsKey(java.lang.String)
297         */
298        public boolean containsKey(String key) {
299            return get(KeyImpl.init(key),null)!=null;
300        }
301        
302        /**
303         * @see railo.runtime.type.Collection#_contains(java.lang.String)
304         */
305        public boolean containsKey(Collection.Key key) {
306            return get(key,null)!=null;
307        }
308    
309        /**
310         * @see railo.runtime.type.Array#containsKey(int)
311         */
312        public boolean containsKey(int key) {
313            return get(key,null)!=null;
314        }
315    
316    
317            /**
318             *
319             * @see java.lang.Object#toString()
320             */
321            public String toString() {
322                    return LazyConverter.serialize(this);
323            }
324            
325            /**
326             * @see java.lang.Object#clone()
327             */
328            public synchronized Object clone() {
329                    return duplicate(true);
330            }
331    
332        /**
333         * @see railo.runtime.op.Castable#castToString()
334         */
335        public String castToString() throws PageException {
336            throw new ExpressionException("Can't cast Complex Object Type Array to String",
337              "Use Build-In-Function \"serialize(Array):String\" to create a String from Array");
338        }
339    
340        /**
341         * @see railo.runtime.op.Castable#castToString(java.lang.String)
342         */
343        public String castToString(String defaultValue) {
344            return defaultValue;
345        }
346    
347    
348        /**
349         * @see railo.runtime.op.Castable#castToBooleanValue()
350         */
351        public boolean castToBooleanValue() throws PageException {
352            throw new ExpressionException("Can't cast Complex Object Type Array to a boolean value");
353        }
354        
355        /**
356         * @see railo.runtime.op.Castable#castToBoolean(java.lang.Boolean)
357         */
358        public Boolean castToBoolean(Boolean defaultValue) {
359            return defaultValue;
360        }
361        
362    
363    
364        /**
365         * @see railo.runtime.op.Castable#castToDoubleValue()
366         */
367        public double castToDoubleValue() throws PageException {
368            throw new ExpressionException("Can't cast Complex Object Type Array to a number value");
369        }
370        
371        /**
372         * @see railo.runtime.op.Castable#castToDoubleValue(double)
373         */
374        public double castToDoubleValue(double defaultValue) {
375            return defaultValue;
376        }
377        
378    
379    
380        /**
381         * @see railo.runtime.op.Castable#castToDateTime()
382         */
383        public DateTime castToDateTime() throws PageException {
384            throw new ExpressionException("Can't cast Complex Object Type Array to a Date");
385        }
386        
387        /**
388         * @see railo.runtime.op.Castable#castToDateTime(railo.runtime.type.dt.DateTime)
389         */
390        public DateTime castToDateTime(DateTime defaultValue) {
391            return defaultValue;
392        }
393    
394            /**
395             * @see railo.runtime.op.Castable#compare(boolean)
396             */
397            public int compareTo(boolean b) throws PageException {
398                    throw new ExpressionException("can't compare Complex Object Type Array with a boolean value");
399            }
400    
401            /**
402             * @see railo.runtime.op.Castable#compareTo(railo.runtime.type.dt.DateTime)
403             */
404            public int compareTo(DateTime dt) throws PageException {
405                    throw new ExpressionException("can't compare Complex Object Type Array with a DateTime Object");
406            }
407    
408            /**
409             * @see railo.runtime.op.Castable#compareTo(double)
410             */
411            public int compareTo(double d) throws PageException {
412                    throw new ExpressionException("can't compare Complex Object Type Array with a numeric value");
413            }
414    
415            /**
416             * @see railo.runtime.op.Castable#compareTo(java.lang.String)
417             */
418            public int compareTo(String str) throws PageException {
419                    throw new ExpressionException("can't compare Complex Object Type Array with a String");
420            }
421    
422            /**
423             * @see railo.runtime.type.Array#toList()
424             */
425            public List toList() {
426                    return this;
427            }
428            
429            /**
430             * @see railo.runtime.type.Iteratorable#valueIterator()
431             */
432            public Iterator valueIterator() {
433                    return iterator();
434            }
435            
436            public boolean equals(Object obj){
437                    if(!(obj instanceof Collection)) return false;
438                    return CollectionUtil.equals(this,(Collection)obj);
439            }
440            
441    }