Improvements for the updatable chart

This commit is contained in:
Lennart Hensler committed 2012-02-28 17:05:49 +01:00
1 parent 5f400bf95d
commit f43b50153b
10 files changed
+200 -103

No files matched your search

@@ -11,7 +11,7 @@ import com.sap.sailing.domain.swisstimingadapter.SailMasterMessage;
public class SailMasterLiveSimulatorConnectorImpl extends SailMasterConnectorImpl {
private final List<SailMasterMessage> bufferedMessageList;
private long messageDeliveryIntervalInMs = 250;
private long messageDeliveryIntervalInMs = 500;
public SailMasterLiveSimulatorConnectorImpl(String host, int port, RaceSpecificMessageLoader messageLoader, boolean canSendRequests) throws InterruptedException {
super(host, port, messageLoader, canSendRequests);
@@ -39,11 +39,13 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
Triple<String, Integer, RaceSpecificMessageLoader> key = new Triple<String, Integer, RaceSpecificMessageLoader>(host, port, messageLoader);
SailMasterConnector result = connectors.get(key);
if (result == null) {
result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
// result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
result = new SailMasterLiveSimulatorConnectorImpl(host, port, messageLoader, canSendRequests);
connectors.put(key, result);
// TODO how do connectors get stopped, terminated and removed from the connectors map again?
} else if (result.isStopped()) {
result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
// result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
result = new SailMasterLiveSimulatorConnectorImpl(host, port, messageLoader, canSendRequests);
connectors.put(key, result);
}
return result;
@@ -277,10 +277,11 @@ public interface SailingServiceAsync {
/**
* Returns the mark passings and the data for the given {@link DetailType} of all competitors in
* <code>competitorsQuery</code> in the <code>race</code>.<br />
* <code>competitorsQuery</code> in the <code>race</code>, including the first dates in the query.<br />
* The Long part in the <code>competitorsQuery</code> defines the time point, from which on the data should be
* returned. If this time point is lesser than the start of race, all available data for this competitor is
* returned.
* returned.<br />
* Returns <code>null</code>, if <code>race</code> isn't tracked.
*/
void getCompetitorsRaceData(RaceIdentifier race, List<Pair<Date,CompetitorDTO>> competitorsToLoad, long stepSize,
DetailType detailType, AsyncCallback<MultiCompetitorRaceDataDTO> callback);
@@ -45,7 +45,6 @@ import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.TimeListener;
import com.sap.sailing.gwt.ui.client.Timer;
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
import com.sap.sailing.gwt.ui.shared.CompetitorRaceDataDTO;
import com.sap.sailing.gwt.ui.shared.MultiCompetitorRaceDataDTO;
@@ -119,7 +118,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
List<RaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
if(!selectedRaces.isEmpty()) {
loadData();
loadData(true);
}
timer.addTimeListener(this);
}
@@ -176,20 +175,31 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
protected abstract Component<SettingsType> getComponent();
protected void loadData() {
if (competitorSelectionProvider.getSelectedCompetitors().iterator().hasNext()) {
setWidget(busyIndicatorPanel);
/**
* Loads the needed data (data which isn't in the {@link #chartData cache}) for the {@link #getVisibleCompetitors()
* visible competitors} via
* {@link SailingServiceAsync#getCompetitorsRaceData(RaceIdentifier, List, long, DetailType, AsyncCallback)}. After
* loading is the method {@link #drawChartData()} called.<br />
* If no competitor is visible, is the {@link #noCompetitorsSelectedLabel} displayed.
*
* @param showBusyIndicator If <code>true</code> is the busy indicator shown while loading the data from the server.
*/
protected void loadData(boolean showBusyIndicator) {
if (hasVisibleCompetitors()) {
if (showBusyIndicator) {
setWidget(busyIndicatorPanel);
}
if (chartData == null || chartData.getDetailType() != getDataToShow()) {
chartData = new MultiCompetitorRaceDataDTO(getDataToShow());
}
final ArrayList<Pair<Date, CompetitorDTO>> competitorsToLoad = new ArrayList<Pair<Date, CompetitorDTO>>();
for (CompetitorDTO competitor : competitorSelectionProvider.getSelectedCompetitors()) {
for (CompetitorDTO competitor : getVisibleCompetitors()) {
Date chartDataDateOfNewestData = chartData.getDateOfNewestData();
if (!chartData.contains(competitor)) {
competitorsToLoad.add(new Pair<Date, CompetitorDTO>(new Date(0), competitor));
} else if (chartData.getCompetitorRaceData(competitor).getDateOfNewestData().before(chartDataDateOfNewestData)) {
Date competitorDateOfNewestData = chartData.getCompetitorRaceData(competitor).getDateOfNewestData();
} else if (chartData.getCompetitorData(competitor).getDateOfNewestData().before(chartDataDateOfNewestData)) {
Date competitorDateOfNewestData = chartData.getCompetitorData(competitor).getDateOfNewestData();
competitorsToLoad.add(new Pair<Date, CompetitorDTO>(new Date(competitorDateOfNewestData.getTime() + getStepSize()), competitor));
}
}
@@ -207,7 +217,14 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
public void onSuccess(MultiCompetitorRaceDataDTO result) {
fireEvent(new DataLoadedEvent());
if (result != null) {
chartData.addAllRaceData(result);
for (CompetitorRaceDataDTO competitorData : result.getAllRaceData()) {
if (chartData.contains(competitorData.getCompetitor())) {
chartData.addCompetitorRaceData(competitorData);
chartData.setCompetitorMarkPassingsData(competitorData);
} else {
chartData.setCompetitorData(competitorData.getCompetitor(), competitorData);
}
}
}
drawChartData();
setWidget(chart);
@@ -229,7 +246,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
@Override
public void addedToSelection(CompetitorDTO competitor) {
loadData();
loadData(false);
}
@Override
@@ -242,7 +259,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
if (competitorMarkPassingSeries != null) {
chart.removeSeries(competitorMarkPassingSeries);
}
if (!competitorSelectionProvider.getSelectedCompetitors().iterator().hasNext()) {
if (!hasVisibleCompetitors()) {
setWidget(noCompetitorsSelectedLabel);
}
}
@@ -250,7 +267,9 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
/**
* Creates the series for all selected competitors if these aren't created yet.<br />
* Fills the series for the selected competitors with the data in {@link AbstractChartPanel#chartData}.<br />
* Removes series of competitors, which aren't selected and adds series for competitors, which are newly selected.
* Removes series of competitors, which aren't selected and adds series for competitors, which are newly selected.<br /><br />
*
* The data for all {@link #getVisibleCompetitors() visible competitors} needs to be filled before calling this method.
*/
private synchronized void drawChartData() {
//Make sure the busy indicator is removed at this point, or plotting the data results in an exception
@@ -262,8 +281,8 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
Series compSeries = getCompetitorSeries(competitor);
Series markSeries = getCompetitorMarkPassingSeries(competitor);
if (isCompetitorVisible(competitor)) {
CompetitorRaceDataDTO competitorData = chartData.getCompetitorRaceData(competitor);
if (competitorData != null) { //TODO Exception?
CompetitorRaceDataDTO competitorData = chartData.getCompetitorData(competitor);
if (competitorData != null) {
List<Triple<String, Date, Double>> markPassingsData = competitorData.getMarkPassingsData();
List<Point> markPassingPoints = new ArrayList<Point>();
for (Triple<String, Date, Double> markPassingData : markPassingsData) {
@@ -273,17 +292,17 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
markPassingPoints.add(markPassingPoint);
}
}
markSeries.setPoints(markPassingPoints.toArray(new Point[0]));
List<Pair<Date, Double>> raceData = competitorData.getRaceData();
List<Point> competitorPoints = new ArrayList<Point>();
Point[] compSeriesPoints = compSeries.getPoints();
Date dateOfNewestSeriesPoint = new Date(compSeriesPoints[compSeriesPoints.length - 1].getX().longValue());
List<Pair<Date, Double>> raceData = competitorData.getRaceDataAfterDate(dateOfNewestSeriesPoint);
for (Pair<Date, Double> data : raceData) {
if (data.getA() != null && data.getB() != null) {
Point competitorPoint = new Point(data.getA().getTime(), data.getB());
competitorPoints.add(competitorPoint);
compSeries.addPoint(competitorPoint);
}
}
compSeries.setPoints(competitorPoints.toArray(new Point[0]));
//Adding the series if chart doesn't contain it
if (!chartSeries.contains(compSeries)) {
@@ -329,6 +348,14 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
}
}
private Iterable<CompetitorDTO> getVisibleCompetitors() {
return competitorSelectionProvider.getSelectedCompetitors();
}
private boolean hasVisibleCompetitors() {
return getVisibleCompetitors().iterator().hasNext();
}
private boolean isCompetitorVisible(CompetitorDTO competitor) {
return competitorSelectionProvider.isSelected(competitor);
}
@@ -416,7 +443,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
/**
* Updates the settings known to be contained in {@link ChartSettings}. Subclasses have to update settings provided
* by subclasses thereof. Subclasses also need to call {@link #clearChart()} and {@link #loadData()}, if this method returns <code>true</code>;
* by subclasses thereof. Subclasses also need to call {@link #clearChart()} and {@link #loadData(boolean)}, if this method returns <code>true</code>;
*
* @return <code>true</code> if the settings had been changed and a clearing and loading is needed.
*/
@@ -447,7 +474,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
/**
* Updates the {@link #dataToShow} field, creates a new chart for the new <code>dataToShow</code> and clears the {@link #chartData}.<br />
* Doesn't {@link #loadData() load the data}.
* Doesn't {@link #loadData(boolean) load the data}.
*
* @return <code>true</code> if the data to show changed
*/
@@ -476,7 +503,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
setChartData(null);
clearChart();
loadData();
loadData(false);
}
/**
@@ -521,12 +548,11 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
@Override
public void timeChanged(Date date) {
//Load the new data only if the timer is in live mode and the data has been initialized by loadData()
if (timer.getPlayMode() == PlayModes.Live && getChartData() != null) {
Date newestEvent = getChartData().getDateOfNewestData();
if (competitorSelectionProvider.getSelectedCompetitors().iterator().hasNext() &&
newestEvent.before(date) && (date.getTime() - newestEvent.getTime()) >= getStepSize()) {
loadData();
if (getChartData() != null) {
Date newestEvent = getChartData().getOldestDateOfNewestData();
if (hasVisibleCompetitors()
&& ((newestEvent.before(date) && (date.getTime() - newestEvent.getTime()) >= getStepSize()) || newestEvent == null)) {
loadData(false);
}
}
}
@@ -44,7 +44,7 @@ public class ChartPanel extends AbstractChartPanel<ChartSettings> implements Com
public void updateSettings(ChartSettings newSettings) {
updateSettingsOnly(newSettings);
clearChart();
loadData();
loadData(false);
}
@Override
@@ -58,6 +58,7 @@ public class CompareCompetitorsChartDialog extends DialogBox {
multiChartPanel = new MultiChartPanel(sailingService, competitorSelectionProvider, raceSelectionProvider,
timer, stringConstants, errorReporter);
multiChartPanel.setSize("100%", "100%");
//TODO Delete DataLoadedHandler
multiChartPanel.addDataLoadedHandler(new DataLoadedHandler() {
@Override
public void onDataLoaded(DataLoadedEvent event) {
@@ -40,7 +40,7 @@ public class MultiChartPanel extends AbstractChartPanel<MultiChartSettings> impl
boolean dataToShowChanged = setDataToShow(newSettings.getDataToShow());
if (dataToShowChanged || settingsChanged) {
clearChart();
loadData();
loadData(false);
}
}
@@ -1347,43 +1347,36 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
MultiCompetitorRaceDataDTO data = null;
TrackedRace trackedRace = getExistingTrackedRace(race);
if (trackedRace != null) {
data = getMultiCompetitorRaceDataDTO(trackedRace, competitorsQuery, trackedRace.getStart().asDate(),
trackedRace.getTimePointOfNewestEvent().asDate(), stepSize, detailType);
data = getMultiCompetitorRaceDataDTO(trackedRace, competitorsQuery, trackedRace.getStart(),
trackedRace.getTimePointOfNewestEvent(), stepSize, detailType);
}
return data;
}
private MultiCompetitorRaceDataDTO getMultiCompetitorRaceDataDTO(TrackedRace race,
List<Pair<Date, CompetitorDTO>> competitorsQuery, Date startDate, Date endDate, long stepSize,
List<Pair<Date, CompetitorDTO>> competitorsQuery, TimePoint startTime, TimePoint endTime, long stepSize,
DetailType detailType) throws NoWindException {
MultiCompetitorRaceDataDTO data = new MultiCompetitorRaceDataDTO(detailType);
// Fetching the data from the TrackedRace
for (Pair<Date, CompetitorDTO> competitorQuery : competitorsQuery) {
List<Long> timePoints = new ArrayList<Long>();
for (long i = competitorQuery.getA().before(startDate) ? startDate.getTime() : competitorQuery.getA()
.getTime(); i <= endDate.getTime(); i += stepSize) {
timePoints.add(i);
}
Competitor competitor = getCompetitorById(race.getRace().getCompetitors(), competitorQuery.getB().id);
ArrayList<Triple<String, Date, Double>> markPassingsData = new ArrayList<Triple<String, Date, Double>>();
ArrayList<Pair<Date, Double>> raceData = new ArrayList<Pair<Date, Double>>();
// Filling the mark passings
for (MarkPassing markPassing : race.getMarkPassings(competitor)) {
MillisecondsTimePoint time = new MillisecondsTimePoint(markPassing.getTimePoint().asMillis());
if (time.asDate().after(competitorQuery.getA())) {
markPassingsData.add(new Triple<String, Date, Double>(markPassing.getWaypoint().getName(), time
.asDate(), getCompetitorRaceDataEntry(detailType, race, competitor, time)));
}
markPassingsData.add(new Triple<String, Date, Double>(markPassing.getWaypoint().getName(), time
.asDate(), getCompetitorRaceDataEntry(detailType, race, competitor, time)));
}
// Filling the race data
for (Long timePoint : timePoints) {
MillisecondsTimePoint time = new MillisecondsTimePoint(timePoint);
for (long i = competitorQuery.getA().before(startTime.asDate()) ? startTime.asMillis() : competitorQuery.getA()
.getTime(); i <= endTime.asMillis(); i += stepSize) {
MillisecondsTimePoint time = new MillisecondsTimePoint(i);
raceData.add(new Pair<Date, Double>(time.asDate(), getCompetitorRaceDataEntry(detailType, race, competitor,
time)));
}
// Adding fetched data to the container
data.setCompetitorRaceData(competitorQuery.getB(), new CompetitorRaceDataDTO(competitorQuery.getB(),
data.setCompetitorData(competitorQuery.getB(), new CompetitorRaceDataDTO(competitorQuery.getB(),
detailType, markPassingsData, raceData));
}
return data;
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.shared;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
@@ -15,13 +16,13 @@ public class CompetitorRaceDataDTO implements IsSerializable {
private CompetitorDTO competitor;
private DetailType detailType;
private Date dateOfNewestData; //TODO Javadoc
/**
* A: Bouy-Name; B: Data-Date; C: Data
* A: Bouy-Name; B: mark passing time; C: data as defined by {@link #detailType} for {@link #competitor} for time point B
*/
private List<Triple<String, Date, Double>> markPassingsData;
/**
* A: Data-Date; B: Data
* A: time for B; B: data as defined by {@link #detailType} for {@link #competitor} for time point A
*/
private List<Pair<Date, Double>> raceData;
@@ -45,48 +46,86 @@ public class CompetitorRaceDataDTO implements IsSerializable {
return detailType;
}
/**
* Takes the {@link Date} of the last elements in {@link #raceData} and {@link #markPassingsData} and returns the newer date.
*/
public Date getDateOfNewestData() {
return dateOfNewestData;
Date dateOfNewestRaceData = raceData.get(raceData.size() - 1).getA();
Date dateOfNewestMarkPassing = markPassingsData.get(markPassingsData.size() - 1).getB();
return dateOfNewestRaceData.after(dateOfNewestMarkPassing) ? dateOfNewestRaceData : dateOfNewestMarkPassing;
}
/**
* Clears the old {@link #markPassingsData} and {@link #addAllMarkPassingsData(Collection) adds} the data in <code>markPassingsData</code> afterwards.
* @param markPassingsData
*/
public void setMarkPassingsData(List<Triple<String, Date, Double>> markPassingsData) {
this.markPassingsData = new ArrayList<Triple<String,Date,Double>>();
addAllMarkPassingsData(markPassingsData);
}
/**
* @return An unmodifiable list of the {@link #markPassingsData}.
*/
public List<Triple<String, Date, Double>> getMarkPassingsData() {
return Collections.unmodifiableList(markPassingsData);
}
/**
* {@link #addMarkPassingsData(Triple) Adds} all elements in <code>markPassingsDataToAdd</code>. Just adds the data and doesn't do any
* checks, like if the data is already contained or if the detail types fit.
*
* @param markPassingsDataToAdd
*/
public void addAllMarkPassingsData(Collection<Triple<String, Date, Double>> markPassingsDataToAdd) {
for (Triple<String, Date, Double> data : markPassingsDataToAdd) {
addMarkPassingsData(data);
}
}
/**
* Adds the data <code>markPassingsDataToAdd</code> at the correct index (via binary search) to {@link #markPassingsData}.
* Just adds the data and doesn't do any checks, like if the data is already contained or if the detail types fit.
*
* @param markPassingsDataToAdd
*/
public void addMarkPassingsData(Triple<String, Date, Double> markPassingsDataToAdd) {
getMarkPassingsData().add(markPassingsDataToAdd);
//Updating the timePointOfNewestEvent
if (markPassingsDataToAdd.getB().after(dateOfNewestData)) {
dateOfNewestData = markPassingsDataToAdd.getB();
}
markPassingsData.add(Collections.binarySearch(markPassingsData, markPassingsDataToAdd, new MarkPassingsByTime()), markPassingsDataToAdd);
}
/**
* @return An unmodifiable list of the {@link #raceData}
*/
public List<Pair<Date, Double>> getRaceData() {
return Collections.unmodifiableList(raceData);
}
/**
* {@link #addRaceData(Pair) Adds} all elements in <code>raceDataToAdd</code>. Just adds the data and doesn't do any
* checks, like if the data is already contained or if the detail types fit.
*
* @param raceDataToAdd
*/
public void addAllRaceData(Collection<Pair<Date, Double>> raceDataToAdd) {
for (Pair<Date, Double> data : raceDataToAdd) {
addRaceData(data);
}
}
/**
* Adds the data <code>raceDataToAdd</code> at the correct index (via binary search) to {@link #raceData}.
* Just adds the data and doesn't do any checks, like if the data is already contained or if the detail types fit.
*
* @param raceDataToAdd
*/
public void addRaceData(Pair<Date, Double> raceDataToAdd) {
getRaceData().add(raceDataToAdd);
//Updating the timePointOfNewestEvent
if (raceDataToAdd.getA().after(dateOfNewestData)) {
dateOfNewestData = raceDataToAdd.getA();
}
raceData.add(Collections.binarySearch(raceData, raceDataToAdd, new RaceDataByTime()), raceDataToAdd);
}
/**
* Adds all data, if the detailTypes fit.
* Adds all data with {@link #addAllMarkPassingsData(Collection)} and {@link #addAllRaceData(Collection)}, if the
* detailTypes fit. Just adds the data and doesn't do any checks, like if the data is already contained.
*
* @param dataToAdd
*/
public void addAllData(CompetitorRaceDataDTO dataToAdd) {
@@ -96,4 +135,27 @@ public class CompetitorRaceDataDTO implements IsSerializable {
}
}
/**
* @param after The date, exclusive, from where the data should be returned
* @return An unmodifiable sublist of {@link #raceData}
*/
public List<Pair<Date, Double>> getRaceDataAfterDate(Date after) {
int from = Collections.binarySearch(raceData, new Pair<Date, Double>(after, 0.0), new RaceDataByTime());
return Collections.unmodifiableList(raceData.subList(from + 1, raceData.size()));
}
public class RaceDataByTime implements Comparator<Pair<Date, Double>> {
@Override
public int compare(Pair<Date, Double> d1, Pair<Date, Double> d2) {
return d1.getA().compareTo(d2.getA());
}
}
public class MarkPassingsByTime implements Comparator<Triple<String, Date, Double>> {
@Override
public int compare(Triple<String, Date, Double> m1, Triple<String, Date, Double> m2) {
return m1.getB().compareTo(m2.getB());
}
}
}
@@ -11,69 +11,68 @@ import com.sap.sailing.domain.common.DetailType;
public class MultiCompetitorRaceDataDTO implements IsSerializable {
private DetailType detailType;
private HashMap<CompetitorDTO, CompetitorRaceDataDTO> raceData;
private HashMap<CompetitorDTO, CompetitorRaceDataDTO> competitorsData;
MultiCompetitorRaceDataDTO() {}
public MultiCompetitorRaceDataDTO(DetailType detailType) {
this.detailType = detailType;
this.raceData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>();
this.competitorsData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>();
}
public MultiCompetitorRaceDataDTO(DetailType detailType, HashMap<CompetitorDTO, CompetitorRaceDataDTO> raceData) {
this.detailType = detailType;
this.raceData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>(raceData);
this.competitorsData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>(raceData);
}
public Set<CompetitorDTO> getCompetitors() {
return raceData.keySet();
return competitorsData.keySet();
}
public CompetitorRaceDataDTO getCompetitorRaceData(CompetitorDTO competitor) {
return raceData.get(competitor);
public CompetitorRaceDataDTO getCompetitorData(CompetitorDTO competitor) {
return competitorsData.get(competitor);
}
/**
* Sets the data for a competitor, if the <code>detailTypes</code> fit.<br />
* If the competitor is already contained, the data will be overwritten.
*/
public void setCompetitorRaceData(CompetitorDTO competitor, CompetitorRaceDataDTO raceData) {
if (detailType == raceData.getDetailType()) {
this.raceData.put(competitor, raceData);
public void setCompetitorData(CompetitorDTO competitor, CompetitorRaceDataDTO competitorData) {
if (detailType == competitorData.getDetailType()) {
this.competitorsData.put(competitor, competitorData);
}
}
/**
* Adds all data in <code>raceDataToAdd</code> to the existing data of the <code>competitor</code>, if the <code>detailTypes</code> fit.<br />
* If the <code>competitor</code> is not contained, the data will be
* {@link MultiCompetitorRaceDataDTO#setCompetitorRaceData(CompetitorDTO, CompetitorRaceDataDTO) set}.
* Replaces the {@link CompetitorRaceDataDTO#markPassingsData} from the {@link CompetitorRaceDataDTO data} of the
* {@link CompetitorDTO} in <code>competitorData</code> with the markPassingsData in <code>competitorData</code>.<br />
* If the competitor is not contained, nothing happens.
*
* @param competitorData
*/
public void addCompetitorRaceData(CompetitorDTO competitor, CompetitorRaceDataDTO raceDataToAdd) {
if (detailType == raceDataToAdd.getDetailType()) {
if (raceData.containsKey(competitor)) {
raceData.get(competitor).addAllData(raceDataToAdd);
} else {
raceData.put(competitor, raceDataToAdd);
public void setCompetitorMarkPassingsData(CompetitorRaceDataDTO competitorData) {
if (detailType == competitorData.getDetailType()) {
if (competitorsData.containsKey(competitorData.getCompetitor())) {
competitorsData.get(competitorData.getCompetitor()).setMarkPassingsData(competitorData.getMarkPassingsData());
}
}
}
/**
* Adds all {@link CompetitorRaceDataDTO#raceData} in <code>competitorDataToAdd</code> to the existing data of the
* {@link CompetitorDTO} in <code>competitorDataToAdd</code>, if the {@link DetailType DetailTypes} fit.<br />
* If the competitor is not contained, nothing happens.
*/
public void addCompetitorRaceData(CompetitorRaceDataDTO competitorDataToAdd) {
if (detailType == competitorDataToAdd.getDetailType()) {
if (competitorsData.containsKey(competitorDataToAdd.getCompetitor())) {
competitorsData.get(competitorDataToAdd.getCompetitor()).addAllRaceData(competitorDataToAdd.getRaceData());
}
}
}
public Collection<CompetitorRaceDataDTO> getAllRaceData() {
return raceData.values();
}
/**
* Adds all data in <code>dataToAdd</code>, if the <code>detailTypes</code> fit.<br />
* The data which are not contained, will be
* {@link MultiCompetitorRaceDataDTO#setCompetitorRaceData(CompetitorDTO, CompetitorRaceDataDTO) set}.
*
* @param dataToAdd
*/
public void addAllRaceData(MultiCompetitorRaceDataDTO dataToAdd) {
//The check if the detailType fits will be done by addCompetitorRaceDataDTO
for (CompetitorRaceDataDTO competitorDataToAdd : dataToAdd.getAllRaceData()) {
addCompetitorRaceData(competitorDataToAdd.getCompetitor(), competitorDataToAdd);
}
return competitorsData.values();
}
public DetailType getDetailType() {
@@ -82,7 +81,7 @@ public class MultiCompetitorRaceDataDTO implements IsSerializable {
public Date getDateOfNewestData() {
Date dateOfNewestData = null;
for (CompetitorRaceDataDTO competitorRaceData : raceData.values()) {
for (CompetitorRaceDataDTO competitorRaceData : competitorsData.values()) {
Date raceDateOfNewestData = competitorRaceData.getDateOfNewestData();
if (dateOfNewestData == null) {
dateOfNewestData = raceDateOfNewestData;
@@ -93,12 +92,25 @@ public class MultiCompetitorRaceDataDTO implements IsSerializable {
return dateOfNewestData;
}
public Date getOldestDateOfNewestData() {
Date dateOfNewestData = null;
for (CompetitorRaceDataDTO competitorRaceData : competitorsData.values()) {
Date raceDateOfNewestData = competitorRaceData.getDateOfNewestData();
if (dateOfNewestData == null) {
dateOfNewestData = raceDateOfNewestData;
} else {
dateOfNewestData = dateOfNewestData.before(raceDateOfNewestData) ? dateOfNewestData : raceDateOfNewestData;
}
}
return dateOfNewestData;
}
public boolean isEmpty() {
return raceData.isEmpty();
return competitorsData.isEmpty();
}
public boolean contains(CompetitorDTO competitor) {
return raceData.containsKey(competitor);
return competitorsData.containsKey(competitor);
}
}