package com.github.pfichtner.jrunalyser.base.datasource; import static com.google.common.base.Predicates.compose; import static com.google.common.base.Predicates.equalTo; import static com.google.common.base.Predicates.not; import java.io.IOException; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.github.pfichtner.jrunalyser.base.data.SegmentationUnit; import com.github.pfichtner.jrunalyser.base.data.WayPoint; import com.github.pfichtner.jrunalyser.base.data.stat.DefaultStatistics; import com.github.pfichtner.jrunalyser.base.data.stat.Functions; import com.github.pfichtner.jrunalyser.base.data.stat.Statistics; import com.github.pfichtner.jrunalyser.base.data.track.DefaultTrack; import com.github.pfichtner.jrunalyser.base.data.track.Id; import com.github.pfichtner.jrunalyser.base.data.track.Track; import com.github.pfichtner.jrunalyser.base.data.track.Tracks; import com.github.pfichtner.jrunalyser.base.data.track.comparator.TrackComparators; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.base.Throwables; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterables; public class StatCalculatorDatasourceFascade extends AbstractDatasourceFascade { private static final Logger log = LoggerFactory .getLogger(StatCalculatorDatasourceFascade.class); private final DatasourceFascade delegate; private final Function<Id, Track> loadTrack = new Function<Id, Track>() { @Override public Track apply(Id id) { try { return loadTrack(id); } catch (IOException e) { throw Throwables.propagate(e); } } }; public StatCalculatorDatasourceFascade(DatasourceFascade delegate) { this.delegate = delegate; } @Override public Set<Id> getTrackIds() throws IOException { return this.delegate.getTrackIds(); } @Override public Iterable<Id> getTrackIds(Date start, Date end) throws IOException { return this.delegate.getTrackIds(start, end); } @Override public Track loadTrack(Id id) throws IOException { return addStats(this.delegate.loadTrack(id)); } @Override public Iterable<Track> loadTracks(Iterable<Id> ids) throws IOException { return Iterables.transform(ids, this.loadTrack); } @Override public List<Id> listTracks(SegmentationUnit segmentationUnit) throws IOException { return this.delegate.listTracks(segmentationUnit); } @Override public Optional<Statistics> loadBestSegment(Id id, SegmentationUnit segmentationUnit) throws IOException { return this.delegate.loadBestSegment(id, segmentationUnit); } @Override public Set<Id> getSimilarTracks(final Id id) throws IOException { return FluentIterable.from(getTrackIds()).filter(not(equalTo(id))) .transform(this.loadTrack).filter(similarTo(id)) .transform(Functions.Tracks.id).toSet(); } @Override public boolean isAwayEqReturn(Id id) { try { return Tracks.isAwayEqReturn(loadTrack(id)); } catch (IOException e) { throw Throwables.propagate(e); } } private Predicate<Track> similarTo(final Id id) throws IOException { return compose(equalTo(Integer.valueOf(0)), compareTrack(id)); } private Function<Track, Integer> compareTrack(final Id id) throws IOException { return new Function<Track, Integer>() { Track ref = loadTrack(id); Comparator<Track> trackComparator = TrackComparators.byAttributes; @Override public Integer apply(Track track) { return Integer.valueOf(this.trackComparator.compare(this.ref, track)); } }; }; @Override public Track addTrack(Track track) throws IOException { return addStats(this.delegate.addTrack(track)); } @Override public Track removeTrack(Id id) throws IOException { return this.delegate.removeTrack(id); } @Override public Set<WayPoint> getCommonWaypoints() { return this.delegate.getCommonWaypoints(); } // ------------------------------------------------------------- private static Track addStats(Track track) { if (track.getStatistics() == null) { log.debug("Calculating Statistics for " + track); return new DefaultTrack(track.getId(), track.getMetadata(), track.getWaypoints(), track.getSegments(), DefaultStatistics.ofTrack(track)); } return track; } }