001package com.identityworksllc.iiq.common.iterators;
002
003import sailpoint.tools.CloseableIterator;
004
005import java.util.Iterator;
006
007/**
008 * A wrapper class for IIQ's CloseableIterator that still implements CloseableIterator,
009 * but also implement the broader Iterator and AutoClosable interfaces to allow regular
010 * Java stuff to interact with it.
011 *
012 * @param <T> The type being iterated (usually ResourceObject)
013 */
014public class CloseableIteratorAdapter<T> implements Iterator<T>, CloseableIterator<T>, AutoCloseable {
015
016    /**
017     * The internally wrapped iterator
018     */
019    private final CloseableIterator<T> iterator;
020
021    /**
022     * Construct a new iterator wrapper.
023     *
024     * @param iterator The iterator to wrap. If null is provided, a {@link NullCloseableIterator} is substituted
025     */
026    public CloseableIteratorAdapter(CloseableIterator<T> iterator) {
027        if (iterator == null) {
028            this.iterator = new NullCloseableIterator<>();
029        } else {
030            this.iterator = iterator;
031        }
032    }
033
034    /**
035     * Invokes close on the wrapped iterator
036     */
037    @Override
038    public void close() {
039        this.iterator.close();
040    }
041
042    /**
043     * Returns true if the wrapped iterator's hasNext() returns true
044     * @return True if the iterator has more elements
045     */
046    @Override
047    public boolean hasNext() {
048        return this.iterator.hasNext();
049    }
050
051    /**
052     * Returns the next element from the iterator
053     * @return The next element from the iterator
054     * @throws java.util.NoSuchElementException if the wrapped iterator was null or is exhausted
055     */
056    @Override
057    public T next() {
058        return this.iterator.next();
059    }
060}