001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.jexl2.internal;
018    
019    import java.lang.reflect.Array;
020    import java.util.AbstractList;
021    import java.util.Collection;
022    import java.util.Iterator;
023    import java.util.List;
024    import java.util.ListIterator;
025    
026    /**
027     * A class that wraps an array within an AbstractList.
028     * <p>
029     * It overrides all methods because introspection uses this class a a marker for wrapped arrays; the declared class
030     * for any method is thus always ArrayListWrapper.
031     * </p>
032     */
033    public class ArrayListWrapper extends AbstractList<Object> {
034        /** the array to wrap. */
035        private final Object array;
036    
037        /**
038         * Create the wrapper.
039         * @param anArray {@link #array}
040         */
041        public ArrayListWrapper(Object anArray) {
042            if (!anArray.getClass().isArray()) {
043                throw new IllegalArgumentException(anArray.getClass() + " is not an array");
044            }
045            this.array = anArray;
046        }
047    
048        /** {@inheritDoc} */
049        @Override
050        public Object get(int index) {
051            return Array.get(array, index);
052        }
053    
054        /** {@inheritDoc} */
055        @Override
056        public Object set(int index, Object element) {
057            Object old = get(index);
058            Array.set(array, index, element);
059            return old;
060        }
061    
062        /** {@inheritDoc} */
063        @Override
064        public int size() {
065            return Array.getLength(array);
066        }
067    
068        @Override
069        public Object[] toArray() {
070            final int size = size();
071            Object[] a = new Object[size];
072            for(int i = 0; i < size; ++i) {
073                a[i] = get(i);
074            }
075            return a;
076        }
077    
078        @Override
079        @SuppressWarnings("unchecked")
080        public <T> T[] toArray(T[] a) {
081            int size = size();
082            if (a.length < size) {
083                T[] x = (T[]) Array.newInstance(a.getClass().getComponentType(), size);
084                System.arraycopy(a, a.length, x, 0, a.length);
085            }
086            for(int i = 0; i < size; ++i) {
087                a[i] = (T) get(i);
088            }
089            if (a.length > size) {
090                a[size] = null;
091            }
092            return a;
093        }
094    
095        @Override
096        public int indexOf(Object o) {
097            final int size = size();
098            if (o == null) {
099                for (int i = 0; i < size; i++) {
100                    if (get(i) == null) {
101                        return i;
102                    }
103                }
104            } else {
105                for (int i = 0; i < size; i++) {
106                    if (o.equals(get(i))) {
107                        return i;
108                    }
109                }
110            }
111            return -1;
112        }
113    
114        @Override
115        public boolean contains(Object o) {
116            return indexOf(o) != -1;
117        }
118        
119        @Override
120        public boolean isEmpty() {
121            return super.isEmpty();
122        }
123    
124        @Override
125        public Iterator<Object> iterator() {
126            return super.iterator();
127        }
128        
129        @Override
130        public boolean containsAll(Collection<?> c) {
131            return super.containsAll(c);
132        }
133    
134        @Override
135        public int lastIndexOf(Object o) {
136            return super.lastIndexOf(o);
137        }
138    
139        @Override
140        public ListIterator<Object> listIterator() {
141            return super.listIterator();
142        }
143    
144        @Override
145        public ListIterator<Object> listIterator(int index) {
146            return super.listIterator(index);
147        }
148    
149        @Override
150        public List<Object> subList(int fromIndex, int toIndex) {
151            return super.subList(fromIndex, toIndex);
152        }
153        
154        @Override
155        public boolean add(Object o) {
156            throw new UnsupportedOperationException("Not supported.");
157        }
158    
159        @Override
160        public boolean remove(Object o) {
161            throw new UnsupportedOperationException("Not supported.");
162        }
163    
164        @Override
165        public boolean addAll(Collection<? extends Object> c) {
166            throw new UnsupportedOperationException("Not supported.");
167        }
168    
169        @Override
170        public boolean addAll(int index, Collection<? extends Object> c) {
171            throw new UnsupportedOperationException("Not supported.");
172        }
173    
174        @Override
175        public boolean removeAll(Collection<?> c) {
176            throw new UnsupportedOperationException("Not supported.");
177        }
178    
179        @Override
180        public boolean retainAll(Collection<?> c) {
181            throw new UnsupportedOperationException("Not supported.");
182        }
183    
184        @Override
185        public void clear() {
186            throw new UnsupportedOperationException("Not supported.");
187        }
188    
189        @Override
190        public void add(int index, Object element) {
191            throw new UnsupportedOperationException("Not supported.");
192        }
193    
194        @Override
195        public Object remove(int index) {
196            throw new UnsupportedOperationException("Not supported.");
197        }
198    
199    }