package jp.sourceforge.glad.collection.iteration;

import jp.sourceforge.glad.collection.closure.Closure;
import jp.sourceforge.glad.collection.closure.PredicateClosure;
import jp.sourceforge.glad.collection.exception.CheckedException;
import jp.sourceforge.glad.collection.exception.ControlException;
import jp.sourceforge.glad.collection.exception.ReturnException;
import jp.sourceforge.glad.collection.predicate.Predicate;

public abstract class IterationHandlerSupport<T>
        implements IterationHandler<T> {

    public void iterate(Closure<T> callback) {
        boolean success = false;
        try {
            try {
                doIterate(callback);
                success = true;
            } catch (ReturnException e) {
                success = true;
                throw e;
            } finally {
                try {
                    close();
                } catch (Exception e) {
                    if (success) throw e;
                }
            }
        } catch (ControlException e) {
            throw e;
        } catch (RuntimeException e) {
            handleRuntimeException(e);
        } catch (Exception e) {
            handleCheckedException(e);
        }
    }

    public void iterate(Predicate<T> callback) {
        iterate(new PredicateClosure<T>(callback));
    }

    protected abstract void doIterate(Closure<T> callback) throws Exception;

    protected void close() throws Exception {
    }

    protected void handleRuntimeException(RuntimeException e) {
        throw e;
    }

    protected void handleCheckedException(Exception e) {
        throw new CheckedException(e);
    }

}
