package org.magenta.core;
import org.magenta.Fixture;
import org.magenta.DataKey;
import org.magenta.DataSet;
import org.magenta.DataSpecification;
import org.magenta.GenerationStrategy;
import org.magenta.events.PostDataSetGenerated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.eventbus.EventBus;
/**
* A {@linkplain DataSet} implementation that relies on a
* {@link GenerationStrategy} to build its set of data.
*
* @author ngagnon
*
* @param <D>
* the type of data
*/
public class GeneratedDataSet<D, S extends DataSpecification> extends AbstractDataSet<D> {
private static final Logger LOG = LoggerFactory.getLogger(GeneratedDataSet.class);
private Supplier<Iterable<D>> supplier;
private Fixture<S> domain;
private GenerationStrategy<D, S> strategy;
private DataKey<D> key;
private EventBus eventBus;
private boolean postProcessing;
/**
* Default constructor.
*
* @param domain
* the domain that the strategy will use to generate data
* @param strategy
* the generation strategy
* @param type
* the type of data
* @param <S>
* the data specification type
*/
public GeneratedDataSet(final Fixture<S> domain, final GenerationStrategy<D, ? super S> strategy, final DataKey<D> key, EventBus eventBus) {
super(key.getType(), domain.getRandomizer());
this.strategy = (GenerationStrategy)strategy;
this.domain = domain;
this.key = key;
this.eventBus = eventBus;
this.supplier = Suppliers.memoize(new Supplier<Iterable<D>>() {
@Override
public Iterable<D> get() {
LOG.trace("Generating [{}] for {}.", GeneratedDataSet.this.key, GeneratedDataSet.this);
Iterable<D> result = strategy.generate(domain);
return result;
}
});
}
@Override
public Iterable<D> get() {
Iterable<D> data = this.supplier.get();
//This has to be called after the supplier is initialized, since the loading of the triggered data key may
//indirectly call this dataset again, in which case the initialized data will be returned and the relationProcessed
//flag will be true
if (!postProcessing) {
postProcessing = true;
this.eventBus.post(new PostDataSetGenerated(this.key,this.domain));
LOG.trace("GENERATION COMPETED for [{}]", GeneratedDataSet.this.key);
}
return data;
}
@Override
public boolean isGenerated() {
return true;
}
@Override
public boolean isPersistent() {
return false;
}
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(GeneratedDataSet.class.getSimpleName()).append(" using a [")
.append(this.strategy.toString()).append(']');
return sb.toString();
}
}