    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    }