org.geoserver.catalog.util.CloseableIteratorAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.geoserver.catalog.util.CloseableIteratorAdapter.java

Source

/* Copyright (c) 2001 - 2013 OpenPlans - www.openplans.org. All rights reserved.
 * This code is licensed under the GPL 2.0 license, available at the root
 * application directory.
 */
package org.geoserver.catalog.util;

import java.io.Closeable;
import java.io.IOException;
import java.util.Iterator;
import java.util.logging.Logger;

import org.geotools.util.logging.Logging;
import org.opengis.filter.Filter;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import com.google.common.collect.UnmodifiableIterator;
import com.google.common.io.Closeables;

public class CloseableIteratorAdapter<T> implements CloseableIterator<T> {

    private static final Logger LOGGER = Logging.getLogger(CloseableIteratorAdapter.class);

    protected final Iterator<T> wrapped;

    protected Closeable whatToClose;

    public CloseableIteratorAdapter(Iterator<T> wrapped) {
        this.wrapped = wrapped;
        if (wrapped instanceof Closeable) {
            this.whatToClose = (Closeable) wrapped;
        } else {
            this.whatToClose = null;
        }
    }

    public CloseableIteratorAdapter(Iterator<T> filteredNotCloseable, Closeable closeMe) {
        this.wrapped = filteredNotCloseable;
        this.whatToClose = closeMe;
    }

    @Override
    public boolean hasNext() {
        boolean hasNext = wrapped.hasNext();
        if (!hasNext) {
            // auto close
            close();
        }
        return hasNext;
    }

    @Override
    public T next() {
        return wrapped.next();
    }

    @Override
    public void remove() {
        wrapped.remove();
    }

    /**
     * Closes the wrapped iterator if its an instance of {@code CloseableIterator}, does nothing
     * otherwise; override if needed.
     * 
     * @see java.io.Closeable#close()
     */
    @Override
    public void close() {
        try {
            Closeables.close(whatToClose, false);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            whatToClose = null;
        }
    }

    @Override
    protected void finalize() {
        if (whatToClose != null) {
            try {
                close();
            } finally {
                LOGGER.warning("There is code not closing CloseableIterator!!! Auto closing at finalize().");
            }
        }
    }

    public static <T> CloseableIterator<T> filter(final Iterator<T> iterator, final Filter filter) {

        Predicate<T> predicate = filterAdapter(filter);
        UnmodifiableIterator<T> filteredNotCloseable = Iterators.filter(iterator, predicate);
        Closeable closeable = iterator instanceof Closeable ? (Closeable) iterator : null;

        return new CloseableIteratorAdapter<T>(filteredNotCloseable, closeable);

    }

    public static <F, T> CloseableIterator<T> transform(Iterator<F> iterator,
            Function<? super F, ? extends T> function) {

        Iterator<T> transformedNotCloseable = Iterators.transform(iterator, function);
        Closeable closeable = (Closeable) (iterator instanceof CloseableIterator ? iterator : null);

        return new CloseableIteratorAdapter<T>(transformedNotCloseable, closeable);
    }

    public static <T> CloseableIterator<T> limit(final Iterator<T> iterator, int maxElements) {

        Iterator<T> limitedNotCloseable = Iterators.limit(iterator, maxElements);
        Closeable closeable = iterator instanceof Closeable ? (Closeable) iterator : null;

        return new CloseableIteratorAdapter<T>(limitedNotCloseable, closeable);

    }

    public static void close(Iterator<?> iterator) {
        if (iterator instanceof Closeable) {
            Closeables.closeQuietly((Closeable) iterator);
        }
    }

    public static <T> CloseableIterator<T> empty() {
        Iterator<T> empty = Iterators.emptyIterator();
        return new CloseableIteratorAdapter<T>(empty);
    }

    private static <T> com.google.common.base.Predicate<T> filterAdapter(final Filter catalogPredicate) {

        return new com.google.common.base.Predicate<T>() {

            @Override
            public boolean apply(T input) {
                return catalogPredicate.evaluate(input);
            }
        };
    }
}