package jp.sourceforge.glad.collection.iteration;

import jp.sourceforge.glad.collection.closure.Closure;
import jp.sourceforge.glad.collection.exception.BreakException;
import jp.sourceforge.glad.collection.exception.ContinueException;

public class IterableIterationHandler<T>
        extends IterationHandlerSupport<T>
        implements IterationHandler<T> {

    final Object label;

    final Iterable<T> iterable;

    public IterableIterationHandler(Iterable<T> iterable) {
        this(null, iterable);
    }

    public IterableIterationHandler(Object label, Iterable<T> iterable) {
        this.label = label;
        this.iterable = iterable;
    }

    protected void doIterate(Closure<T> callback) throws Exception {
        for (T each : iterable) {
            try {
                callback.execute(each);
            } catch (ContinueException e) {
                checkRethrow(e);
                continue;
            } catch (BreakException e) {
                checkRethrow(e);
                break;
            }
        }
    }

    void checkRethrow(ContinueException e) {
        if (label != null && !label.equals(e.getLabel())) {
            throw e;
        }
    }

    void checkRethrow(BreakException e) {
        if (label != null && !label.equals(e.getLabel())) {
            throw e;
        }
    }

}
