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.logging.log4j.core.util;
018
019import java.util.Iterator;
020import java.util.NoSuchElementException;
021
022/**
023 * An {@link java.util.Iterator Iterator} over an array of objects.
024 * <p>
025 * This iterator does not support {@link #remove}, as the object array cannot be
026 * structurally modified.
027 * <p>
028 * The iterator implements a {@link #reset} method, allowing the reset of the iterator
029 * back to the start if required.
030 *
031 * @param <E> the type to iterate over
032 * @since 3.0
033 * @version $Id: ObjectArrayIterator.java 1734648 2016-03-11 23:51:22Z ggregory $
034 */
035public class ObjectArrayIterator<E> implements /*Resettable*/ Iterator<E> {
036
037    /** The array */
038    final E[] array;
039    /** The start index to loop from */
040    final int startIndex;
041    /** The end index to loop to */
042    final int endIndex;
043    /** The current iterator index */
044    int index = 0;
045
046    //-------------------------------------------------------------------------
047    /**
048     * Constructs an ObjectArrayIterator that will iterate over the values in the
049     * specified array.
050     *
051     * @param array the array to iterate over
052     * @throws NullPointerException if <code>array</code> is <code>null</code>
053     */
054    @SafeVarargs
055    public ObjectArrayIterator(final E... array) {
056        this(array, 0, array.length);
057    }
058
059    /**
060     * Constructs an ObjectArrayIterator that will iterate over the values in the
061     * specified array from a specific start index.
062     *
063     * @param array  the array to iterate over
064     * @param start  the index to start iterating at
065     * @throws NullPointerException if <code>array</code> is <code>null</code>
066     * @throws IndexOutOfBoundsException if the start index is out of bounds
067     */
068    public ObjectArrayIterator(final E array[], final int start) {
069        this(array, start, array.length);
070    }
071
072    /**
073     * Construct an ObjectArrayIterator that will iterate over a range of values
074     * in the specified array.
075     *
076     * @param array  the array to iterate over
077     * @param start  the index to start iterating at
078     * @param end  the index (exclusive) to finish iterating at
079     * @throws IndexOutOfBoundsException if the start or end index is out of bounds
080     * @throws IllegalArgumentException if end index is before the start
081     * @throws NullPointerException if <code>array</code> is <code>null</code>
082     */
083    public ObjectArrayIterator(final E array[], final int start, final int end) {
084        super();
085        if (start < 0) {
086            throw new ArrayIndexOutOfBoundsException("Start index must not be less than zero");
087        }
088        if (end > array.length) {
089            throw new ArrayIndexOutOfBoundsException("End index must not be greater than the array length");
090        }
091        if (start > array.length) {
092            throw new ArrayIndexOutOfBoundsException("Start index must not be greater than the array length");
093        }
094        if (end < start) {
095            throw new IllegalArgumentException("End index must not be less than start index");
096        }
097        this.array = array;
098        this.startIndex = start;
099        this.endIndex = end;
100        this.index = start;
101    }
102
103    // Iterator interface
104    //-------------------------------------------------------------------------
105
106    /**
107     * Returns true if there are more elements to return from the array.
108     *
109     * @return true if there is a next element to return
110     */
111    @Override
112    public boolean hasNext() {
113        return this.index < this.endIndex;
114    }
115
116    /**
117     * Returns the next element in the array.
118     *
119     * @return the next element in the array
120     * @throws NoSuchElementException if all the elements in the array
121     *    have already been returned
122     */
123    @Override
124    public E next() {
125        if (hasNext() == false) {
126            throw new NoSuchElementException();
127        }
128        return this.array[this.index++];
129    }
130
131    /**
132     * Throws {@link UnsupportedOperationException}.
133     *
134     * @throws UnsupportedOperationException always
135     */
136    @Override
137    public void remove() {
138        throw new UnsupportedOperationException("remove() method is not supported for an ObjectArrayIterator");
139    }
140
141    // Properties
142    //-------------------------------------------------------------------------
143
144    /**
145     * Gets the array that this iterator is iterating over.
146     *
147     * @return the array this iterator iterates over
148     */
149    public E[] getArray() {
150        return this.array;
151    }
152
153    /**
154     * Gets the start index to loop from.
155     *
156     * @return the start index
157     */
158    public int getStartIndex() {
159        return this.startIndex;
160    }
161
162    /**
163     * Gets the end index to loop to.
164     *
165     * @return the end index
166     */
167    public int getEndIndex() {
168        return this.endIndex;
169    }
170
171    /**
172     * Resets the iterator back to the start index.
173     */
174    //@Override
175    public void reset() {
176        this.index = this.startIndex;
177    }
178
179}