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     * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
040     * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
041     * @version $Id: ArrayIterator.java 889223 2009-12-10 12:05:22Z henrib $
042     */
043    public class ArrayIterator implements Iterator<Object> {
044        /** The objects to iterate over. */
045        private final Object array;
046        /** The size of the array. */
047        private final int size;
048        /** The current position and size in the array. */
049        private int pos;
050    
051        /**
052         * Creates a new iterator instance for the specified array.
053         * @param arr The array for which an iterator is desired.
054         */
055        public ArrayIterator(Object arr) {
056            if (arr == null) {
057                array = null;
058                pos = 0;
059                size = 0;
060            } else if (!arr.getClass().isArray()) {
061                throw new IllegalArgumentException(arr.getClass() + " is not an array");
062            } else {
063                array = arr;
064                pos = 0;
065                size = Array.getLength(array);
066            }
067        }
068    
069        /**
070         * Move to next element in the array.
071         *
072         * @return The next object in the array.
073         */
074        public Object next() {
075            if (pos < size) {
076                return Array.get(array, pos++);
077            }    
078            // we screwed up...
079            throw new NoSuchElementException("No more elements: " + pos
080                                             + " / " + size);
081        }
082        
083        /**
084         * Check to see if there is another element in the array.
085         *
086         * @return Whether there is another element.
087         */
088        public boolean hasNext() {
089            return (pos < size);
090        }
091    
092        /**
093         * No op--merely added to satify the <code>Iterator</code> interface.
094         */
095        public void remove() {
096            throw new UnsupportedOperationException();
097        }
098    }