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    
018    package org.apache.commons.jexl2.internal;
019    
020    import java.util.Iterator;
021    import java.util.NoSuchElementException;
022    import java.lang.reflect.Array;
023    
024    /**
025     *  <p>
026     *  An Iterator wrapper for an Object[]. This will
027     *  allow us to deal with all array like structures
028     *  in a consistent manner.
029     *  </p>
030     *  <p>
031     *  WARNING : this class's operations are NOT synchronized.
032     *  It is meant to be used in a single thread, newly created
033     *  for each use in the #foreach() directive.
034     *  If this is used or shared, synchronize in the
035     *  next() method.
036     *  </p>
037     *
038     * @since 1.0
039     */
040    public class ArrayIterator implements Iterator<Object> {
041        /** The objects to iterate over. */
042        private final Object array;
043        /** The size of the array. */
044        private final int size;
045        /** The current position and size in the array. */
046        private int pos;
047    
048        /**
049         * Creates a new iterator instance for the specified array.
050         * @param arr The array for which an iterator is desired.
051         */
052        public ArrayIterator(Object arr) {
053            if (arr == null) {
054                array = null;
055                pos = 0;
056                size = 0;
057            } else if (!arr.getClass().isArray()) {
058                throw new IllegalArgumentException(arr.getClass() + " is not an array");
059            } else {
060                array = arr;
061                pos = 0;
062                size = Array.getLength(array);
063            }
064        }
065    
066        /**
067         * Move to next element in the array.
068         *
069         * @return The next object in the array.
070         */
071        public Object next() {
072            if (pos < size) {
073                return Array.get(array, pos++);
074            }    
075            // we screwed up...
076            throw new NoSuchElementException("No more elements: " + pos
077                                             + " / " + size);
078        }
079        
080        /**
081         * Check to see if there is another element in the array.
082         *
083         * @return Whether there is another element.
084         */
085        public boolean hasNext() {
086            return (pos < size);
087        }
088    
089        /**
090         * No op--merely added to satify the <code>Iterator</code> interface.
091         */
092        public void remove() {
093            throw new UnsupportedOperationException();
094        }
095    }