    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    }