prepared for score correction metadata (timestamp, comment)

This commit is contained in:
Axel Uhl committed 2012-07-20 15:04:43 +02:00
1 parent 60ce4d7097
commit 3616e09138
11 files changed
+156 -5

No files matched your search

@@ -51,4 +51,18 @@ public interface ScoreCorrection extends Serializable {
*/
boolean isScoreCorrected(Competitor competitor, RaceColumn raceColumn);
/**
* Tells when the score correction was last updated. This should usually be the "validity time" and not the
* "transaction time." In other words, if scores provided by the race committee are updated to this score correction
* at time X, and the race committee's scores are tagged with time Y, then this method should return Y, not X. If
* Y is not available for some reason, X may be used as a default.
*/
TimePoint getTimePointOfLastCorrectionsValidity();
/**
* A free-form comment to display to the viewers of the leaderboard that has these score corrections. It should make
* crystal clear if the scores are preliminary or not yet jury-finalized. If <code>null</code> is returned, this
* always has to be interpreted as "preliminary" because then no comment as to the correctness have been made.
*/
String getComment();
}
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.leaderboard;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.TimePoint;
public interface SettableScoreCorrection extends ScoreCorrection {
@@ -33,4 +34,7 @@ public interface SettableScoreCorrection extends ScoreCorrection {
boolean hasCorrectionFor(RaceColumn raceInLeaderboard);
void setLastCorrected(TimePoint timePointOfLastCorrectionsValidity);
void setComment(String scoreCorrectionComment);
}
@@ -132,11 +132,13 @@ public abstract class AbstractLeaderboardImpl implements Leaderboard, RaceColumn
}
/**
* @param scoreCorrection must not be <code>null</code>
* @param scoreComparator the comparator to use to compare basic scores, such as net points
* @param name must not be <code>null</code>
*/
public AbstractLeaderboardImpl(SettableScoreCorrection scoreCorrection,
ThresholdBasedResultDiscardingRule resultDiscardingRule, Comparator<Double> scoreComparator) {
assert scoreCorrection != null;
this.carriedPoints = new HashMap<Competitor, Double>();
this.scoreCorrection = scoreCorrection;
this.displayNames = new HashMap<Competitor, String>();
@@ -35,6 +35,20 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
*/
private final Map<Pair<Competitor, RaceColumn>, Double> correctedScores;
/**
* If <code>null</code>, despite a non-<code>null</code> {@link #timePointOfLastCorrectionsValidity} value the result have to be assumed
* to be preliminary and need to be displayed with a corresponding hint.
*/
private String comment;
/**
* Tells when the score correction was last updated. This should usually be the "validity time" and not the
* "transaction time." In other words, if scores provided by the race committee are updated to this score correction
* at time X, and the race committee's scores are tagged with time Y, then this method should return Y, not X. If
* Y is not available for some reason, X may be used as a default.
*/
private TimePoint timePointOfLastCorrectionsValidity;
public ScoreCorrectionImpl() {
this.maxPointsReasons = new HashMap<Util.Pair<Competitor,RaceColumn>, MaxPointsReason>();
this.correctedScores = new HashMap<Util.Pair<Competitor,RaceColumn>, Double>();
@@ -160,4 +174,24 @@ public class ScoreCorrectionImpl implements SettableScoreCorrection {
return false;
}
@Override
public TimePoint getTimePointOfLastCorrectionsValidity() {
return timePointOfLastCorrectionsValidity;
}
@Override
public String getComment() {
return comment;
}
@Override
public void setLastCorrected(TimePoint timePointOfLastCorrectionsValidity) {
this.timePointOfLastCorrectionsValidity = timePointOfLastCorrectionsValidity;
}
@Override
public void setComment(String scoreCorrectionComment) {
this.comment = scoreCorrectionComment;
}
}
@@ -51,7 +51,7 @@ public class TestColumnSwapping {
leaderboardCreationDate = new Date();
try {
// get Leaderboard with name and current date
leaderboardOriginalDTO = new LeaderboardDTO();
leaderboardOriginalDTO = new LeaderboardDTO(null, null);
leaderboardOriginalDTO.addRace("Race1", DEFAULT_FLEET, true, null, null);
leaderboardOriginalDTO.addRace("Race3", DEFAULT_FLEET, true, null, null);
leaderboardOriginalDTO.addRace("Race2", DEFAULT_FLEET, true, null, null);
@@ -101,7 +101,7 @@ public class TestColumnSwapping {
@Test
public void testLeaderBoardDTOMethods() {
lb = new LeaderboardDTO();
lb = new LeaderboardDTO(null, null);
assertNotNull("Leaderboard != NULL", lb);
lb.addRace("1", DEFAULT_FLEET, false, null, null);
lb.addRace("2", DEFAULT_FLEET, false, null, null);
@@ -252,4 +252,7 @@ public interface SailingService extends RemoteService {
void removeFregURLs(Set<String> toRemove) throws Exception;
void addFragUrl(String result) throws Exception;
Void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity,
String comment);
}
@@ -234,6 +234,9 @@ public interface SailingServiceAsync {
void updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString, String columnName,
Double correctedScore, Date date, AsyncCallback<Triple<Double, Double, Boolean>> asyncCallback);
void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity,
String comment, AsyncCallback<Void> callback);
void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates,
AsyncCallback<Void> callback);
@@ -566,8 +566,9 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
legColumns = new ArrayList<LegColumn>();
}
@Override
public String getValue(LeaderboardRowDTO object) {
// The following code exists only for robustness. This method should never be called because
// RaceColumn implements its own render(...) method which doesn't make use of getValue(...)
final double totalPoints = object.fieldsByRaceColumnName.get(getRaceColumnName()).totalPoints;
return "" + (totalPoints == 0 ? "" : scoreFormat.format(totalPoints));
}
@@ -206,6 +206,7 @@ import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardCarryVa
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardGroup;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardMaxPointsReason;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCorrection;
import com.sap.sailing.server.operationaltransformation.UpdateLeaderboardScoreCorrectionMetadata;
import com.sap.sailing.server.operationaltransformation.UpdateRaceDelayToLive;
import com.sap.sailing.server.replication.ReplicaDescriptor;
import com.sap.sailing.server.replication.ReplicationFactory;
@@ -418,7 +419,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
LeaderboardDTO result = null;
final Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
if (leaderboard != null) {
result = new LeaderboardDTO();
result = new LeaderboardDTO(leaderboard.getScoreCorrection()==null ?
null : leaderboard.getScoreCorrection().getTimePointOfLastCorrectionsValidity().asDate(),
leaderboard.getScoreCorrection()==null?null:leaderboard.getScoreCorrection().getComment());
final TimePoint timePoint = new MillisecondsTimePoint(date);
result.competitors = new ArrayList<CompetitorDTO>();
result.name = leaderboard.getName();
@@ -1964,6 +1967,12 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
new MillisecondsTimePoint(date)));
}
@Override
public Void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity, String comment) {
return getService().apply(
new UpdateLeaderboardScoreCorrectionMetadata(leaderboardName, new MillisecondsTimePoint(timePointOfLastCorrectionValidity), comment));
}
@Override
public void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) throws NoWindException {
Date dateForResults = new Date(); // we don't care about the result date/time here; use current date as default
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.shared;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -21,8 +22,14 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements IsSerializ
public List<CompetitorDTO> competitors;
private Map<RaceColumnDTO, List<CompetitorDTO>> competitorOrderingPerRace;
private Date timePointOfLastCorrectionsValidity;
private String comment;
public LeaderboardDTO() {
public LeaderboardDTO(Date timePointOfLastCorrectionsValidity, String comment) {
this.timePointOfLastCorrectionsValidity = timePointOfLastCorrectionsValidity;
this.comment = comment;
competitorOrderingPerRace = new HashMap<RaceColumnDTO, List<CompetitorDTO>>();
}
@@ -38,6 +45,25 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements IsSerializ
return competitors.indexOf(competitor) + 1;
};
/**
* A free-form comment to display to the viewers of the leaderboard that has these score corrections. It should make
* crystal clear if the scores are preliminary or not yet jury-finalized. If <code>null</code> is returned, this
* always has to be interpreted as "preliminary" because then no comment as to the correctness have been made.
*/
public String getComment() {
return comment;
}
/**
* Tells when the score correction was last updated. This should usually be the "validity time" and not the
* "transaction time." In other words, if scores provided by the race committee are updated to this score correction
* at time X, and the race committee's scores are tagged with time Y, then this method should return Y, not X. If
* Y is not available for some reason, X may be used as a default.
*/
public Date getTimePointOfLastCorrectionsValidity() {
return timePointOfLastCorrectionsValidity;
}
@Override
public int hashCode() {
return super.hashCode() ^ ((competitors == null) ? 0 : competitors.hashCode());
@@ -0,0 +1,55 @@
package com.sap.sailing.server.operationaltransformation;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.SettableScoreCorrection;
import com.sap.sailing.server.RacingEventService;
import com.sap.sailing.server.RacingEventServiceOperation;
public class UpdateLeaderboardScoreCorrectionMetadata extends AbstractLeaderboardOperation<Void> {
private static final long serialVersionUID = -977025759476022993L;
private final TimePoint timePointOfLastCorrectionValidity;
private final String comment;
/**
* @param timePoint the time point for which to deliver leaderboard results as the result of this operation
*/
public UpdateLeaderboardScoreCorrectionMetadata(String leaderboardName, TimePoint timePointOfLastCorrectionValidity, String comment) {
super(leaderboardName);
this.timePointOfLastCorrectionValidity = timePointOfLastCorrectionValidity;
this.comment = comment;
}
@Override
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
// TODO Auto-generated method stub
return null;
}
@Override
public Void internalApplyTo(RacingEventService toState) throws NoWindException {
Leaderboard leaderboard = toState.getLeaderboardByName(getLeaderboardName());
if (leaderboard != null) {
SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection();
if (scoreCorrection != null) {
scoreCorrection.setComment(comment);
scoreCorrection.setLastCorrected(timePointOfLastCorrectionValidity);
} else {
throw new IllegalArgumentException("Leaderboard "+getLeaderboardName()+" has no score corrections to which to apply metadata "+
timePointOfLastCorrectionValidity+"/"+comment);
}
} else {
throw new IllegalArgumentException("Didn't find leaderboard "+getLeaderboardName());
}
updateStoredLeaderboard(toState, leaderboard);
return null;
}
}