package org.magenta.generators; import org.magenta.DataKey; import org.magenta.DataSpecification; import org.magenta.Fixture; import org.magenta.GenerationStrategy; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; /** * Decorator of a {@link GenerationStrategy} that filters and transforms the output of the decorated generator. * * @author ngagnon * * @param <D> The type of data generated by this generator * @param <O> the type of data generated by the decorated generator * @param <S> The data specification type needed by the decorated strategy */ public class TransformedStrategy<D, O, S extends DataSpecification> implements GenerationStrategy<D, S> { private GenerationStrategy<? extends O, ? super S> strategy; private Predicate<? super O> filter; private Function<? super O, D> converter; /** * Default constructor. * * @param strategy the decorated strategy * @param filter the filter * @param converter a conversion function */ public TransformedStrategy(GenerationStrategy<? extends O, ? super S> strategy, Predicate<? super O> filter, Function<? super O, D> converter) { this.strategy = strategy; this.converter = converter; this.filter = filter; } @Override public Iterable<D> generate(Fixture<? extends S> dataDomain) { return FluentIterable.from(strategy.generate(dataDomain)).filter(filter).transform(converter); } @Override public Iterable<D> generate(int numberOfElements, Fixture<? extends S> dataDomain) { //the filter may reduce the number of elements returned return FluentIterable.from(strategy.generate(numberOfElements,dataDomain)).filter(filter).transform(converter); } @Override public Iterable<DataKey<?>> getModifiedDataSet() { return strategy.getModifiedDataSet(); } @Override public String toString() { StringBuilder sb = new StringBuilder(); if(this.filter != Predicates.alwaysTrue() || this.converter != Functions.identity()){ sb.append(TransformedStrategy.class.getSimpleName()).append(" using "); if(this.filter != Predicates.alwaysTrue()){ sb.append("filter [").append(this.filter).append(']'); if(this.converter != Functions.identity()){ sb.append(" and "); } } if(this.converter != Functions.identity()){ sb.append("converter [").append(this.converter).append(']'); } } sb.append(strategy.toString()); return sb.toString(); } }