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 */
017package org.apache.commons.jexl2.internal;
018
019import java.lang.reflect.Array;
020import java.util.AbstractList;
021import java.util.Collection;
022import java.util.Iterator;
023import java.util.List;
024import 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 */
033public 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}