001    package org.apache.tapestry.util;
002    
003    import org.apache.hivemind.util.Defense;
004    
005    import java.util.Iterator;
006    
007    /**
008     * <p>This class implements an {@link Iterator} which can only return a fixed
009     * number of items.</p>
010     *
011     */
012    public class SizeRestrictingIterator implements Iterator {
013    
014        private static final int DEFAULT_MAX_SIZE = 20;
015    
016        private final int _maxSize;
017        private final Iterator _iterator;
018        private int _currentIndex;
019    
020        /**
021         * Constructs an Iterator which will return at most {@link #DEFAULT_MAX_SIZE} items.
022         *
023         * @param iterator
024         *          The underlying iterator this object will defer to for actual
025         *          iteration.
026         */
027        public SizeRestrictingIterator(Iterator iterator)
028        {
029            this(iterator, DEFAULT_MAX_SIZE);
030        }
031    
032        /**
033         * Constructs an Iterator which will return at most as many
034         * items as defined by the user.
035         *
036         * @param iterator
037         *          The underlying iterator this object will defer to for actual
038         *          iteration.
039         * @param maxSize
040         *          How many items to return / filter the list by.
041         */
042        public SizeRestrictingIterator(Iterator iterator, int maxSize)
043        {
044            Defense.notNull(iterator, "Iterator source");
045            
046            _iterator = iterator;
047            _maxSize = maxSize;
048            
049            _currentIndex = 0;
050        }
051        
052        /**
053         * {@inheritDoc}
054         */
055        public boolean hasNext()
056        {
057            return _currentIndex < _maxSize && _iterator.hasNext();
058        }
059    
060        /**
061         * {@inheritDoc}
062         */
063        public Object next()
064        {
065            _currentIndex++;
066            return _iterator.next();
067        }
068    
069        /**
070         * {@inheritDoc}
071         */
072        public void remove()
073        {
074            _currentIndex--;
075            _iterator.remove();
076        }
077        
078        public String toString()
079        {
080            return "SizeRestrictingIterator[" +
081                   "_maxSize=" + _maxSize +
082                   '\n' +
083                   ", _current=" + _currentIndex +
084                   '\n' +
085                   ", _iterator=" + _iterator +
086                   '\n' +
087                   ']';
088        }
089    }