package org.magenta.core; import static com.google.common.base.Predicates.in; import static com.google.common.base.Predicates.not; import java.util.Arrays; import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.magenta.DataSet; import org.magenta.random.FluentRandom; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * Implementation of a {@link DataSet} based on a guava {@link Supplier} of * Iterable. * * @author ngagnon * * @param <D> * the data type */ public abstract class AbstractDataSet<D> implements DataSet<D> { private final Map<Object, D> links; private final Class<D> type; private final FluentRandom randomizer; /** * Construct a new dataset using the provided supplier as source. * * @param type * the type of data * @param randomizer * the java random to use for shuffling and by the "any()" method */ public AbstractDataSet(Class<D> type, FluentRandom randomizer) { this.links = new LinkedHashMap<Object, D>(); this.type = type; this.randomizer = randomizer; } @Override public boolean isEmpty() { return Iterables.isEmpty(get()); } @Override public DataSet<D> toTransient() { return this; } @Override public DataSet<D> subset(int size) { return new GenericDataSet<D>(Iterables.limit(get(), size), this.type, getRandomizer()); } @Override public DataSet<D> filter(Predicate<? super D> filter) { return new GenericDataSet<D>(Iterables.filter(get(), filter), this.type, getRandomizer()); } @Override public <X> DataSet<X> transform(Function<? super D, X> function, Class<X> newType) { return new GenericDataSet<X>(Iterables.transform(get(), function), newType, getRandomizer()); } @Override public <X> DataSet<X> cast(final Class<X> type) { return transform( new Function<D,X>(){ @Override public X apply(D input) { return type.cast(input); } }, type); } /* * (non-Javadoc) * * @see * org.magenta.DataSet#process(org.magenta * .Processor) */ /* * @Override public DataSet<D> process(final Function<? super D, Void> * processor) { return new GenericDataSet<D>(Iterables.transform(get(), new * Function<D, D>() { * * @Override public D apply(D input) { processor.apply(input); return input; } * * }), this.type, getRandomizer()); } */ @Override @SafeVarargs public final DataSet<D> without(D... items) { return filter(not(in(Arrays.asList(items)))); } @Override public DataSet<D> without(Collection<D> items) { return filter(not(in(items))); } @Override public abstract Iterable<D> get(); @Override public D[] array() { return Iterables.toArray(get(), this.type); } @Override public D[] array(int size) { return Iterables.toArray(list(size), this.type); } @Override public D[] randomArray() { return Iterables.toArray(randomList(), this.type); } @Override public D[] randomArray(int size) { return Iterables.toArray(randomList(size), this.type); } @Override public List<D> list() { Iterable<D> i = get(); return (i instanceof List)?(List<D>)i :Lists.newArrayList(i); } @Override public List<D> list(int size) { Iterable<D> i = Iterables.limit(get(), size); return i instanceof List? (List<D>)i:Lists.newArrayList(i); } @Override public List<D> randomList() { return getRandomizer().iterable(get()).shuffle().list(); } @Override public List<D> randomList(int size) { return Lists.newArrayList(Iterables.limit(getRandomizer().iterable(get()).shuffle().list(), size)); } @Override public Set<D> set() { return Sets.newLinkedHashSet(get()); } @Override public Set<D> set(int size) { return Sets.newLinkedHashSet(Iterables.limit(get(), size)); } @Override public D any() { return getRandomizer().iterable(get()).any(); } @Override public D any(Predicate<? super D> filter) { return getRandomizer().iterable(Iterables.filter(get(), filter)).any(); } @Override public DataSet<D> load(){ for(D data:get()){ } return this; } @Override public DataSet<D> persist() { throw new UnsupportedOperationException("This dataset is not persistent:"+toString()); } @Override public D link(Object o) { D referred = links.get(o); if (referred == null) { referred = any(); links.put(o, referred); } return referred; } @SuppressWarnings("unchecked") @Override public <L> Iterable<L> reverseLink(Class<L> type, D referred) { List<L> linkedObjects = Lists.newArrayList(); for (Map.Entry<Object, D> entry : links.entrySet()) { if (entry.getValue().equals(referred)) { linkedObjects.add((L) entry.getKey()); } } return linkedObjects; } @Override public Class<D> getType() { return this.type; } /** * @return this data set randomizer */ protected FluentRandom getRandomizer() { return randomizer; } @Override public int hashCode() { return !this.isGenerated() && !this.isPersistent() ? get().hashCode() : super.hashCode(); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof DataSet) { @SuppressWarnings("unchecked") DataSet<D> other = (DataSet<D>) obj; return !this.isGenerated() && !other.isGenerated() && !this.isPersistent() && !other.isPersistent() && Iterables.elementsEqual(this.get(), other.get()); } return false; } }