package jp.sourceforge.glad.collection.iteration;

import jp.sourceforge.glad.collection.closure.Closure;
import jp.sourceforge.glad.collection.closure.ClosureAdapter;
import jp.sourceforge.glad.collection.function.Function;
import jp.sourceforge.glad.collection.predicate.Predicate;
import jp.sourceforge.glad.collection.predicate.PredicateAdapter;

public class IterationHandlerAdapter<S, T> implements IterationHandler<T> {

    private final IterationHandler<S> handler;

    private final Function<S, T> converter;

    public IterationHandlerAdapter(
            IterationHandler<S> handler, Function<S, T> converter) {
        this.handler = handler;
        this.converter = converter;
    }

    /**
     * このコンストラクタを使用する場合は、convert(S) メソッドをオーバライドしてください。
     * 
     * @param handler IterationHandler
     */
    protected IterationHandlerAdapter(IterationHandler<S> handler) {
        this(handler, null);
    }

    public void iterate(Closure<T> callback) {
        handler.iterate(new ClosureAdapter<S, T>(callback) {
            @Override
            protected T convert(S source) throws Exception {
                return IterationHandlerAdapter.this.convert(source);
            }
        });
    }

    public void iterate(Predicate<T> callback) {
        handler.iterate(new PredicateAdapter<S, T>(callback) {
            @Override
            protected T convert(S source) throws Exception {
                return IterationHandlerAdapter.this.convert(source);
            }
        });
    }

    protected T convert(S source) throws Exception {
        return converter.apply(source);
    }

}
