001    /*
002     * Created on Nov 26, 2010
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     *
013     * Copyright @2010-2011 the original author or authors.
014     */
015    package org.fest.assertions.util;
016    
017    import java.lang.reflect.Array;
018    import java.util.AbstractList;
019    
020    import org.fest.util.VisibleForTesting;
021    
022    /**
023     * An list-like wrapper for arrays. This class does not provide type-safety in order to handle both arrays
024     * of objects and arrays of primitives.
025     *
026     * @author Alex Ruiz
027     * @author Yvonne Wang
028     */
029    public class ArrayWrapperList extends AbstractList<Object> {
030    
031      /**
032       * Wraps a given array with a <code>{@link ArrayWrapperList}</code>
033       * @param array the array to wrap.
034       * @return the wrapped array or {@code null} if the given array was already {@code null}.
035       * @throws IllegalArgumentException if the {@code array} is not an array.
036       */
037      public static ArrayWrapperList wrap(Object array) {
038        if (array == null) return null;
039        if (!array.getClass().isArray()) throw new IllegalArgumentException("The object to wrap should be an array");
040        return new ArrayWrapperList(array);
041      }
042    
043      private final Object array;
044    
045      @VisibleForTesting ArrayWrapperList(Object array) {
046        this.array = array;
047      }
048    
049      /**
050       * {@inheritDoc}
051       */
052      @Override public Object get(int index) {
053        checkIsInRange(index);
054        return Array.get(array, index);
055      }
056    
057      private void checkIsInRange(int index) {
058        int size = size();
059        if (index >= 0 && index < size()) return;
060        String message = String.format("Index should be between 0 and %d (inclusive,) but was %d", size - 1, index);
061        throw new IndexOutOfBoundsException(message);
062      }
063    
064      /**
065       * {@inheritDoc}
066       */
067      @Override public int size() {
068        return Array.getLength(array);
069      }
070    
071      /**
072       * Returns the component type of the wrapped array.
073       * @return the component type of the wrapped array.
074       */
075      public Class<?> getComponentType() {
076        return array.getClass().getComponentType();
077      }
078      
079      @VisibleForTesting Object array() { return array; }
080    }