001/**
002 *
003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved.
004 *
005 * This library is free software; you can redistribute it and/or
006 * modify it under the terms of the GNU Lesser General Public
007 * License as published by the Free Software Foundation; either 
008 * version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013 * Lesser General Public License for more details.
014 * 
015 * You should have received a copy of the GNU Lesser General Public 
016 * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
017 * 
018 **/
019package lucee.runtime.type.wrap;
020
021import java.util.ArrayList;
022import java.util.Collection;
023import java.util.Iterator;
024import java.util.List;
025import java.util.ListIterator;
026
027import lucee.runtime.exp.PageException;
028import lucee.runtime.exp.PageRuntimeException;
029import lucee.runtime.type.Array;
030import lucee.runtime.type.it.ArrayListIteratorImpl;
031
032public class ArrayAsList implements List {
033
034        Array array;
035        
036        private ArrayAsList(Array array) {
037                this.array=array;
038        }
039        
040        public static List toList(Array array) {
041                if(array instanceof ListAsArray) return ((ListAsArray)array).list;
042                if(array instanceof List) return (List) array;
043                return new ArrayAsList(array);
044        }
045        
046        
047        @Override
048        public boolean add(Object o) {
049                try {
050                        array.append(o);
051                } 
052                catch (PageException e) {
053                        return false;
054                }
055                return true;
056        }
057
058        public void add(int index, Object element) {
059                try {
060                        array.insert(index+1, element);
061                } catch (PageException e) {
062                        throw new IndexOutOfBoundsException(e.getMessage());
063                }
064        }
065
066        @Override
067        public boolean addAll(Collection c) {
068                Iterator it = c.iterator();
069                while(it.hasNext()) {
070                        add(it.next());
071                }
072                return !c.isEmpty();
073        }
074
075        @Override
076        public boolean addAll(int index, Collection c) {
077                Iterator it = c.iterator();
078                while(it.hasNext()) {
079                        add(index++,it.next());
080                }
081                return !c.isEmpty();
082        }
083
084        @Override
085        public void clear() {
086                array.clear();
087        }
088
089        @Override
090        public boolean contains(Object o) {
091                return indexOf(o)!=-1;
092        }
093
094        @Override
095        public boolean containsAll(Collection c) {
096                Iterator it = c.iterator();
097                while(it.hasNext()) {
098                        if(!contains(it.next()))return false;
099                }
100                return true;
101        }
102
103        @Override
104        public Object get(int index) {
105                try {
106                        return array.getE(index+1);
107                } catch (PageException e) {
108                        throw new IndexOutOfBoundsException(e.getMessage());
109                }
110        }
111
112        public int indexOf(Object o) {
113                Iterator<Object> it=array.valueIterator();
114                int index=0;
115                while(it.hasNext()) {
116                        if(it.next().equals(o))return index;
117                        index++;
118                }
119                return -1;
120        }
121
122        @Override
123        public boolean isEmpty() {
124                return array.size()==0;
125        }
126
127        @Override
128        public Iterator iterator() {
129                return array.valueIterator();
130        }
131
132        public int lastIndexOf(Object o) {
133                Iterator<Object> it=array.valueIterator();
134                int index=0;
135                int rtn=-1;
136                while(it.hasNext()) {
137                        if(it.next().equals(o))rtn=index;
138                        index++;
139                }
140                return rtn;
141        }
142
143        @Override
144        public ListIterator listIterator() {
145                return listIterator(0);
146        }
147
148        @Override
149        public ListIterator listIterator(int index) {
150                return new ArrayListIteratorImpl(array,index);
151                //return array.toList().listIterator(index);
152        }
153        
154
155        @Override
156        public boolean remove(Object o) {
157                int index = indexOf(o);
158                if(index==-1) return false;
159                
160                try {
161                        array.removeE(index+1);
162                } catch (PageException e) {
163                        return false;
164                }
165                return true;
166        }
167
168        public Object remove(int index) {
169                try {
170                        return array.removeE(index+1);
171                } catch (PageException e) {
172                        throw new IndexOutOfBoundsException(e.getMessage());
173                }
174        }
175
176        public boolean removeAll(Collection c) {
177                Iterator it = c.iterator();
178                boolean rtn=false;
179                while(it.hasNext()) {
180                        if(remove(it.next()))rtn=true;
181                }
182                return rtn;
183        }
184
185        public boolean retainAll(Collection c) {new ArrayList().retainAll(c);
186                boolean modified = false;
187                Iterator it = iterator();
188                while (it.hasNext()) {
189                    if(!c.contains(it.next())) {
190                        it.remove();
191                        modified = true;
192                    }
193                }
194                return modified;
195        }
196
197        public Object set(int index, Object element) {
198                try {
199                        if(!array.containsKey(index+1)) throw new IndexOutOfBoundsException("Index: "+(index+1)+", Size: "+size());
200                        return array.setE(index+1,element);
201                } catch (PageException e) {
202                        throw new PageRuntimeException(e);
203                }
204        }
205
206        @Override
207        public int size() {
208                return array.size();
209        }
210
211        @Override
212        public List subList(int fromIndex, int toIndex) {
213                return array.toList().subList(fromIndex, toIndex);
214        }
215
216        @Override
217        public Object[] toArray() {
218                return array.toArray();
219        }
220
221        @Override
222        public Object[] toArray(Object[] a) {
223                return array.toArray();
224        }
225}