Merge branch 'master' into racecommittee_integrated

Conflicts:
	java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRegattaImpl.java
	java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/TestColumnSwapping.java
	java/com.sap.sailing.gwt.ui/build.properties
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardDialog.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardDescriptor.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupDialog.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/AbstractLeaderboardDTO.java
	java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java
This commit is contained in:
Armin Zamani
2013-02-22 15:51:13 +01:00
30 changed files with 377 additions and 98 deletions
+1
View File
@@ -1,4 +1,5 @@
/target
build.log
.metadata
*.class
*.swp
+4 -1
View File
@@ -2,7 +2,10 @@
# this holds for default installation
USER_HOME=~
PROJECT_HOME=$USER_HOME/git
echo PROJECT_HOME is $PROJECT_HOME
if [ "$PROJECT_HOME" = "" ]; then
PROJECT_HOME=$USER_HOME/git
fi
SERVERS_HOME=$USER_HOME/servers
# x86 or x86_64 should work for most cases
+2 -1
View File
@@ -1,3 +1,4 @@
build.log
gwt-unitCache
bin/
log
log
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.persistence.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
@@ -52,7 +54,7 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
private final Set<Serializable> suppressedCompetitorIDs;
private final Leaderboard leaderboard;
private transient final Set<LeaderboardCorrectionsResolvedListener> listeners;
private transient Set<LeaderboardCorrectionsResolvedListener> listeners;
public DelayedLeaderboardCorrectionsImpl(Leaderboard leaderboard) {
listeners = new HashSet<>();
@@ -70,6 +72,11 @@ public class DelayedLeaderboardCorrectionsImpl implements DelayedLeaderboardCorr
leaderboard.addRaceColumnListener(this);
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
listeners = new HashSet<>();
}
@Override
public void addLeaderboardCorrectionsResolvedListener(LeaderboardCorrectionsResolvedListener listener) {
listeners.add(listener);
@@ -119,6 +119,35 @@ public class LeaderboardScoringAndRankingTest extends AbstractLeaderboardTest {
assertEquals(10-(i-1), leaderboard.getTotalPoints(competitors.get(i), f1Column, now), 0.000000001);
}
}
@Test
public void testColumnFactorInRegattaLeaderboard() throws NoWindException {
List<Competitor> competitors = createCompetitors(10);
Regatta regatta = createRegatta(/* qualifying */ 2, new String[] { "Default" }, /* final */0,
new String[] { "Default" },
/* medal */false, "testColumnFactorInRegattaLeaderboard",
DomainFactory.INSTANCE.getOrCreateBoatClass("49er", /* typicallyStartsUpwind */true),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.HIGH_POINT));
Leaderboard leaderboard = createLeaderboard(regatta, /* discarding thresholds */ new int[0]);
Series qualificationSeries;
Iterator<? extends Series> seriesIter = regatta.getSeries().iterator();
qualificationSeries = seriesIter.next();
RaceColumn q1Column = qualificationSeries.getRaceColumnByName("Q1");
RaceColumn q2Column = qualificationSeries.getRaceColumnByName("Q2");
final double factor = 2.0;
q2Column.setFactor(factor);
TimePoint now = MillisecondsTimePoint.now();
TimePoint later = new MillisecondsTimePoint(now.asMillis()+1000);
TrackedRace q1Default = new MockedTrackedRaceWithStartTimeAndRanks(now, competitors);
ArrayList<Competitor> reverseCompetitors = new ArrayList<Competitor>(competitors);
Collections.reverse(reverseCompetitors);
TrackedRace q2Default = new MockedTrackedRaceWithStartTimeAndRanks(now, reverseCompetitors);
q1Column.setTrackedRace(q1Column.getFleetByName("Default"), q1Default);
q2Column.setTrackedRace(q2Column.getFleetByName("Default"), q2Default);
assertEquals(Double.valueOf(competitors.size()), leaderboard.getTotalPoints(competitors.get(0), q1Column, later));
assertEquals(factor * Double.valueOf(1), leaderboard.getTotalPoints(competitors.get(0), q2Column, later), 0.000000001);
assertEquals(Double.valueOf(factor*1.0+competitors.size()), leaderboard.getTotalPoints(competitors.get(0), later), 0.000000001);
}
/**
* Regarding bug 961, test scoring in a leaderboard that has a qualification series with two unordered groups where for one
@@ -5,9 +5,9 @@ import java.util.Set;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
import com.sap.sailing.domain.tracking.RaceTracker;
import com.sap.sailing.domain.tracking.RacesHandle;
import com.sap.sailing.domain.tractracadapter.DomainFactory;
import com.sap.sailing.domain.tractracadapter.TracTracRaceTracker;
import com.tractrac.clientmodule.Event;
import com.tractrac.clientmodule.Race;
@@ -15,9 +15,9 @@ public class RaceHandleImpl implements RacesHandle {
private final Event tractracEvent;
private final DomainFactory domainFactory;
private final DynamicTrackedRegatta trackedRegatta;
private final TracTracRaceTracker raceTracker;
private final RaceTracker raceTracker;
public RaceHandleImpl(DomainFactory domainFactory, Event tractracEvent, DynamicTrackedRegatta trackedRegatta, TracTracRaceTracker raceTracker) {
public RaceHandleImpl(DomainFactory domainFactory, Event tractracEvent, DynamicTrackedRegatta trackedRegatta, RaceTracker raceTracker) {
this.domainFactory = domainFactory;
this.tractracEvent = tractracEvent;
this.trackedRegatta = trackedRegatta;
@@ -44,7 +44,7 @@ public class RaceHandleImpl implements RacesHandle {
}
@Override
public TracTracRaceTracker getRaceTracker() {
public RaceTracker getRaceTracker() {
return raceTracker;
}
@@ -52,13 +52,7 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
@Override
public String getName() {
String result;
if (getDisplayName() != null) {
result = getDisplayName();
} else {
result = getRegatta().getName();
}
return result;
return getRegatta().getName();
}
@Override
@@ -173,10 +173,12 @@ public class TrackedRegattaImpl implements TrackedRegatta {
logger.log(Level.INFO, "Creating DynamicTrackedRaceImpl for RaceDefinition " + raceDefinition.getName());
DynamicTrackedRaceImpl result = new DynamicTrackedRaceImpl(this, raceDefinition,
windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind, millisecondsOverWhichToAverageSpeed);
addTrackedRace(result);
// adding the raceDefinition to the raceDefinitionSetToUpdate BEFORE calling addTrackedRace helps those who
// are called back by RaceListener.raceAdded(TrackedRace) and who then expect the update to have happened
if (raceDefinitionSetToUpdate != null) {
raceDefinitionSetToUpdate.addRaceDefinition(raceDefinition);
}
addTrackedRace(result);
return result;
}
@@ -43,19 +43,11 @@ public class TestColumnSwapping {
int[] disc = { 5, 8, 9, 0, 7, 5, 43 };
service.createFlexibleLeaderboard(LEADERBOARDNAME, disc, ScoringSchemeType.LOW_POINT, null);
try {
service.addColumnToLeaderboard("Race1", LEADERBOARDNAME, true);
service.addColumnToLeaderboard("Race2", LEADERBOARDNAME, true);
service.addColumnToLeaderboard("Race3", LEADERBOARDNAME, true);
leglist = new ArrayList<String>();
leglist.add("Race1");
leglist.add("Race2");
leglist.add("Race3");
leaderboardCreationDate = new Date();
// get Leaderboard with name and current date
leaderboardOriginalDTO = new LeaderboardDTO(null, null, /* higherScoreIsBetter */ false);
leaderboardOriginalDTO.addRace("Race1", /* explicitFactor */ null, DEFAULT_FLEET, true, null, null);
leaderboardOriginalDTO.addRace("Race3", /* explicitFactor */ null, DEFAULT_FLEET, true, null, null);
leaderboardOriginalDTO.addRace("Race2", /* explicitFactor */ null, DEFAULT_FLEET, true, null, null);
// get Leaderboard with name and current date
leaderboardOriginalDTO = new LeaderboardDTO(null, null, /* higherScoreIsBetter */ false);
leaderboardOriginalDTO.addRace("Race1", /* explicitFactor */ null, 1., DEFAULT_FLEET, true, null, null);
leaderboardOriginalDTO.addRace("Race3", /* explicitFactor */ null, 1., DEFAULT_FLEET, true, null, null);
leaderboardOriginalDTO.addRace("Race2", /* explicitFactor */ null, 1., DEFAULT_FLEET, true, null, null);
} catch (Exception e) {
e.printStackTrace();
}
@@ -104,9 +96,9 @@ public class TestColumnSwapping {
public void testLeaderBoardDTOMethods() {
lb = new LeaderboardDTO(null, null, /* higherScoreIsBetter */ false);
assertNotNull("Leaderboard != NULL", lb);
lb.addRace("1", /* explicitFactor */ null, DEFAULT_FLEET, false, null, null);
lb.addRace("2", /* explicitFactor */ null, DEFAULT_FLEET, false, null, null);
lb.addRace("3", /* explicitFactor */ null, DEFAULT_FLEET, true, null, null);
lb.addRace("1", /* explicitFactor */ null, 1., DEFAULT_FLEET, false, null, null);
lb.addRace("2", /* explicitFactor */ null, 1., DEFAULT_FLEET, false, null, null);
lb.addRace("3", /* explicitFactor */ null, 1., DEFAULT_FLEET, true, null, null);
lb.moveRaceDown("1");
String[] s = new String[] { "2", "1", "3" };
for (int i = 0; i < lb.getRaceList().size(); i++)
+5 -1
View File
@@ -24,6 +24,7 @@ bin.includes = META-INF/,\
RaceBoard.html,\
Spectator.html,\
com.sap.sailing.gwt.ui.Spectator/,\
com.sap.sailing.gwt.ui.PolarSheets/,\
com.sap.sailing.gwt.ui.RaceBoard/,\
highcharts/,\
Spectator.css,\
@@ -37,5 +38,8 @@ bin.includes = META-INF/,\
com.sap.sailing.gwt.ui.YoutubePopup/,\
YoutubePopup.html,\
TvView.html,\
com.sap.sailing.gwt.ui.TvView/
com.sap.sailing.gwt.ui.TvView/,\
BrowserUnsupported.html,\
PolarSheets.css,\
PolarSheets.html
output.. = WEB-INF/classes/
@@ -36,7 +36,7 @@ public abstract class AbstractEventManagementPanel extends AbstractRegattaPanel
RegattaDTO selectedRegatta = getSelectedRegatta();
this.availableRegattas.clear();
this.availableRegattasListBox.clear();
this.availableRegattasListBox.addItem(this.stringMessages.noRegatta());
this.availableRegattasListBox.addItem(this.stringMessages.defaultRegatta());
List<RegattaDTO> regattasSortedByName = new ArrayList<RegattaDTO>(regattas);
Collections.sort(regattasSortedByName, new Comparator<RegattaDTO>() {
@Override
@@ -42,7 +42,7 @@ public abstract class AbstractLeaderboardDialog extends DataEntryDialog<Leaderbo
protected LeaderboardDescriptor getResult() {
int[] discardThresholdsBoxContents = getDiscardThresholds(discardThresholdBoxes);
leaderboard.setName(nameTextBox.getValue());
leaderboard.setDisplayName(displayNameTextBox.getValue());
leaderboard.setDisplayName(displayNameTextBox.getValue().trim().isEmpty() ? null : displayNameTextBox.getValue());
leaderboard.setDiscardThresholds(discardThresholdsBoxContents);
CourseAreaDTO courseArea = getSelectedCourseArea();
if (courseArea == null) {
@@ -174,6 +174,7 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = URLEncoder.encode("/gwt/Leaderboard.html?name=" + object.name
+ (showRaceDetails ? "&showRaceDetails=true" : "")
+ (object.displayName != null ? "&displayName="+object.displayName : "")
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
return ANCHORTEMPLATE.cell(link, object.name);
}
@@ -256,12 +257,38 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
Window.alert("This is a meta leaderboard. It can't be changed here.");
} else {
if (leaderboardDTO.isRegattaLeaderboard) {
// LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name,
// null, leaderboardDTO.discardThresholds, leaderboardDTO.regattaName, leaderboardDTO.courseAreaId);
openUpdateRegattaLeaderboardDialog(leaderboardDTO, otherExistingLeaderboard, oldLeaderboardName);
LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name,
leaderboardDTO.displayName, null, leaderboardDTO.discardThresholds, leaderboardDTO.regattaName, leaderboardDTO.courseAreaId);
AbstractLeaderboardDialog dialog = new RegattaLeaderboardEditDialog(Collections
.unmodifiableCollection(otherExistingLeaderboard), Collections.unmodifiableCollection(allRegattas),
descriptor, stringMessages, errorReporter,
new DialogCallback<LeaderboardDescriptor>() {
@Override
public void cancel() {
}
@Override
public void ok(LeaderboardDescriptor result) {
updateLeaderboard(oldLeaderboardName, result);
}
});
dialog.show();
} else {
LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name, leaderboardDTO.scoringScheme, leaderboardDTO.discardThresholds, leaderboardDTO.courseAreaId);
openUpdateFlexibleLeaderboardDialog(leaderboardDTO, otherExistingLeaderboard, oldLeaderboardName, descriptor);
LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name, leaderboardDTO.displayName, leaderboardDTO.scoringScheme, leaderboardDTO.discardThresholds, leaderboardDTO.courseAreaId);
FlexibleLeaderboardEditDialog dialog = new FlexibleLeaderboardEditDialog(Collections
.unmodifiableCollection(otherExistingLeaderboard),
descriptor, stringMessages, errorReporter,
new DialogCallback<LeaderboardDescriptor>() {
@Override
public void cancel() {
}
@Override
public void ok(LeaderboardDescriptor result) {
updateLeaderboard(oldLeaderboardName, result);
}
});
dialog.show();
}
}
} else if (LeaderboardConfigImagesBarCell.ACTION_EDIT_SCORES.equals(value)) {
@@ -1030,9 +1057,9 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
leaderboardSelectionChanged();
}
private void updateLeaderboard(final String oldLeaderboardName, final LeaderboardDescriptor leaderboardToUdate) {
sailingService.updateLeaderboard(oldLeaderboardName, leaderboardToUdate.getName(), leaderboardToUdate.getDisplayName(),
leaderboardToUdate.getDiscardThresholds(), new AsyncCallback<Void>() {
private void updateLeaderboard(final String oldLeaderboardName, final LeaderboardDescriptor leaderboardToUpdate) {
sailingService.updateLeaderboard(oldLeaderboardName, leaderboardToUpdate.getName(), leaderboardToUpdate.getDisplayName(),
leaderboardToUpdate.getDiscardThresholds(), new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to update leaderboard " + oldLeaderboardName + ": "
@@ -1044,9 +1071,9 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
for (int i = 0; i < leaderboardList.getList().size(); i++) {
StrippedLeaderboardDTO dao = leaderboardList.getList().get(i);
if (dao.name.equals(oldLeaderboardName)) {
dao.name = leaderboardToUdate.getName();
dao.displayName = leaderboardToUdate.getDisplayName();
dao.discardThresholds = leaderboardToUdate.getDiscardThresholds();
dao.name = leaderboardToUpdate.getName();
dao.displayName = leaderboardToUpdate.getDisplayName();
dao.discardThresholds = leaderboardToUpdate.getDiscardThresholds();
break;
}
}
@@ -25,17 +25,19 @@ public class LeaderboardDescriptor {
public LeaderboardDescriptor() {
}
public LeaderboardDescriptor(String name, ScoringSchemeType scoringScheme, int[] discardThresholds, String regattaName, String courseAreaId) {
public LeaderboardDescriptor(String name, String displayName, ScoringSchemeType scoringScheme, int[] discardThresholds, String regattaName, String courseAreaId) {
this.name = name;
this.displayName = displayName;
this.scoringScheme = scoringScheme;
this.discardThresholds = discardThresholds;
this.regattaName = regattaName;
this.courseAreaId = courseAreaId;
}
public LeaderboardDescriptor(String name, ScoringSchemeType scoringScheme, int[] discardThresholds, String courseAreaId) {
public LeaderboardDescriptor(String name, String displayName, ScoringSchemeType scoringScheme, int[] discardThresholds, String courseAreaId) {
this.name = name;
this.displayName = displayName;
this.scoringScheme = scoringScheme;
this.discardThresholds = discardThresholds;
this.courseAreaId = courseAreaId;
@@ -107,10 +107,10 @@ public class LeaderboardGroupDialog extends DataEntryDialog<LeaderboardGroupDial
final List<StrippedLeaderboardDTO> emptyStrippedLeaderboardDTOList = Collections.emptyList();
errorMessage = new FlexibleLeaderboardDialog.LeaderboardParameterValidator(stringMessages,
emptyStrippedLeaderboardDTOList).getErrorMessage(new LeaderboardDescriptor("Overall",
/* displayName */ null,
groupToValidate.getOverallLeaderboardScoringSchemeType(),
groupToValidate.getOverallLeaderboardDiscardThresholds(),
null));
;
}
return errorMessage;
}
@@ -372,7 +372,7 @@ public interface StringMessages extends Messages {
String createRegattaLeaderboard();
String editFlexibleLeaderboard();
String editRegattaLeaderboard();
String noRegatta();
String defaultRegatta();
String useOverallLeaderboard();
String overallStandings();
String scoringSchemeHighPointEssOverall();
@@ -400,7 +400,7 @@ createFlexibleLeaderboard=Create flexible leaderboard
createRegattaLeaderboard=Create regatta leaderboard
editFlexibleLeaderboard=Edit flexible leaderboard
editRegattaLeaderboard=Edit regatta leaderboard
noRegatta=No regatta
defaultRegatta=Default regatta
useOverallLeaderboard=Use Overall leaderboard
overallStandings=Overall Standings
type=Type
@@ -510,4 +510,4 @@ addCourseArea=Add course area
courseAreas=Course areas
courseArea=Course area
pleaseEnterNonEmptyCourseArea=Please enter a course area.
pleaseSelectACourseArea=Please select a course area.
pleaseSelectACourseArea=Please select a course area.
@@ -401,7 +401,7 @@ createFlexibleLeaderboard=Flexible Rangliste anlegen
createRegattaLeaderboard=Rangliste für Regatta anlegen
editFlexibleLeaderboard=Flexible Rangliste ändern
editRegattaLeaderboard=Rangliste für Regatta ändern
noRegatta=Keine Regatta
defaultRegatta=Regatta automatisch wählen/anlegen
useOverallLeaderboard=Overall-Ergebnisse anzeigen
overallStandings=Gesamtstand
type=Typ
@@ -510,4 +510,4 @@ addCourseArea=Kursbereich hinzufügen
courseAreas=Kursbereiche
courseArea=Kursbereich
pleaseEnterNonEmptyCourseArea=Bitte geben Sie einen Kursbereich ein.
pleaseSelectACourseArea=Bitte wählen Sie einen Kursbereich aus.
pleaseSelectACourseArea=Bitte wählen Sie einen Kursbereich aus.
@@ -274,8 +274,9 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
/**
* Assembles a URL for a leaderboard that displays with the <code>settings</code> and <code>embedded</code> mode
* as specified by the parameters.
* @param leaderboardDisplayName TODO
*/
public static String getUrl(String leaderboardName, LeaderboardUrlSettings settings) {
public static String getUrl(String leaderboardName, String leaderboardDisplayName, LeaderboardUrlSettings settings) {
StringBuilder overallDetails = new StringBuilder();
for (DetailType overallDetail : settings.getLeaderboardSettings().getOverallDetailsToShow()) {
overallDetails.append('&');
@@ -307,6 +308,7 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = URLEncoder.encode("/gwt/Leaderboard.html?name=" + leaderboardName
+ (settings.isShowRaceDetails() ? "&"+PARAM_SHOW_RACE_DETAILS+"=true" : "")
+ (leaderboardDisplayName != null ? "&displayName="+leaderboardDisplayName : "")
+ (settings.isEmbedded() ? "&"+PARAM_EMBEDDED+"=true" : "")
+ (settings.getLeaderboardSettings().isShowOverallLeaderboardsOnSamePage() ? "&"+PARAM_SHOW_OVERALL_LEADERBOARDS_ON_SAME_PAGE+"=true" : "")
+ (settings.getLeaderboardSettings().getDelayInMilliseconds() == null &&
@@ -80,10 +80,12 @@ public class LeaderboardUrlConfigurationDialog extends SettingsDialog<Leaderboar
private CheckBox autoRefreshCheckbox;
private Anchor resultingUrl;
private final String leaderboardName;
private final String leaderboardDisplayName;
public LeaderboardUrlConfigurationDialogComponent(AbstractLeaderboardDTO leaderboard, StringMessages stringMessages) {
this.stringMessages = stringMessages;
this.leaderboardName = leaderboard.name;
this.leaderboardDisplayName = leaderboard.displayName;
List<RaceColumnDTO> raceList = leaderboard.getRaceList();
List<String> namesOfRaceColumnsToShow = new ArrayList<String>();
for (RaceColumnDTO raceColumn : raceList) {
@@ -101,8 +103,8 @@ public class LeaderboardUrlConfigurationDialog extends SettingsDialog<Leaderboar
/* delayBetweenAutoAdvancesInMilliseconds */ 3000l, /* delayInMilliseconds */ 3000l, stringMessages);
}
private void updateURL(LeaderboardUrlSettings settings, String leaderboardName) {
resultingUrl.setHref(LeaderboardEntryPoint.getUrl(leaderboardName, settings));
private void updateURL(LeaderboardUrlSettings settings, String leaderboardName, String leaderboardDisplayName) {
resultingUrl.setHref(LeaderboardEntryPoint.getUrl(leaderboardName, leaderboardDisplayName, settings));
}
/**
@@ -123,7 +125,7 @@ public class LeaderboardUrlConfigurationDialog extends SettingsDialog<Leaderboar
public String getErrorMessage(LeaderboardUrlSettings settings) {
String errorMessage = superValidator.getErrorMessage(settings.getLeaderboardSettings());
if (errorMessage == null) {
updateURL(settings, leaderboardName);
updateURL(settings, leaderboardName, leaderboardDisplayName);
}
return errorMessage;
}
@@ -44,8 +44,6 @@ import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO.ScoreCorrectionEn
public class MatchAndApplyScoreCorrectionsDialog extends DataEntryDialog<BulkScoreCorrectionDTO> {
private static final RegExp p = RegExp.compile("^([A-Z][A-Z][A-Z])\\s*[^0-9]*([0-9]*)$");
private static final double MEDAL_RACE_FACTOR = 2;
private final LeaderboardDTO leaderboard;
private final Map<CompetitorDTO, String> defaultOfficialSailIDsForCompetitors;
private final Set<String> allOfficialSailIDs;
@@ -257,7 +255,7 @@ public class MatchAndApplyScoreCorrectionsDialog extends DataEntryDialog<BulkSco
officialCorrectionEntry.getMaxPointsReason());
if (officialCorrectionEntry.getScore() != null) {
double officialTotalPoints = officialCorrectionEntry.getScore().doubleValue();
double officialNetPoints = raceColumn.isMedalRace() ? officialTotalPoints / MEDAL_RACE_FACTOR : officialTotalPoints;
double officialNetPoints = officialTotalPoints / raceColumn.getEffectiveFactor();
result.addScoreUpdate(competitor, raceColumn, officialNetPoints);
}
}
@@ -312,7 +310,7 @@ public class MatchAndApplyScoreCorrectionsDialog extends DataEntryDialog<BulkSco
.get(raceNameOrNumber).get(officialSailID);
final Double officialTotalPoints = officialCorrectionEntry.isDiscarded() ? new Double(0) : officialCorrectionEntry.getScore();
final Double officialNetPoints = officialCorrectionEntry.getScore() == null ? null :
raceColumn.isMedalRace() ? officialCorrectionEntry.getScore() / MEDAL_RACE_FACTOR : officialCorrectionEntry.getScore();
officialCorrectionEntry.getScore() / raceColumn.getEffectiveFactor();
SafeHtmlBuilder sb = new SafeHtmlBuilder();
boolean entriesDiffer =
((officialNetPoints == null && entry.netPoints != null) || (officialNetPoints != null && entry.netPoints != null && !new Double(entry.netPoints).equals(officialNetPoints))) ||
@@ -524,8 +524,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
// Note: the RaceColumnDTO won't be created by the following addRace call because it has been created
// above by the result.createEmptyRaceColumn call
result.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), fleetDTO,
raceColumn.isMedalRace(), raceIdentifier, race);
result.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), raceColumn.getFactor(),
fleetDTO, raceColumn.isMedalRace(), raceIdentifier, race);
if (latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive != null) {
raceColumnDTO.setWhenLastTrackedRaceWasLive(fleetDTO, latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive.asDate());
}
@@ -2120,8 +2120,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
}
final FleetDTO fleetDTO = convertToFleetDTO(fleet);
RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), fleetDTO,
raceColumn.isMedalRace(), raceIdentifier, raceDTO);
RaceColumnDTO raceColumnDTO = leaderboardDTO.addRace(raceColumn.getName(), raceColumn.getExplicitFactor(), raceColumn.getFactor(),
fleetDTO, raceColumn.isMedalRace(), raceIdentifier, raceDTO);
if (latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive != null) {
raceColumnDTO.setWhenLastTrackedRaceWasLive(fleetDTO, latestTimePointAfterQueryTimePointWhenATrackedRaceWasLive.asDate());
}
@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Set;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.impl.Util.Pair;
@@ -148,13 +149,17 @@ public abstract class AbstractLeaderboardDTO implements IsSerializable {
* @param explicitFactor
* factor by which to multiply the race column's points for the overall score; if <code>null</code>, the
* default will be determined by whether or not the column is marked as medal race
* @param effectiveFactor
* is what you get when you call {@link RaceColumn#getFactor()} on the race column that the resulting
* {@link RaceColumnDTO} represents
* @param fleetDTO
* must not be null
*/
public RaceColumnDTO addRace(String raceColumnName, Double explicitFactor, FleetDTO fleetDTO,
boolean medalRace, RegattaAndRaceIdentifier trackedRaceIdentifier, RaceDTO race) {
public RaceColumnDTO addRace(String raceColumnName, Double explicitFactor, double effectiveFactor,
FleetDTO fleetDTO, boolean medalRace, RegattaAndRaceIdentifier trackedRaceIdentifier, RaceDTO race) {
assert fleetDTO != null;
RaceColumnDTO raceColumnDTO = getOrCreateRaceColumn(raceColumnName);
raceColumnDTO.setEffectiveFactor(effectiveFactor);
raceColumnDTO.setExplicitFactor(explicitFactor);
boolean contains = false;
for (FleetDTO fleet : raceColumnDTO.getFleets()) {
@@ -21,6 +21,7 @@ public class RaceColumnDTO extends NamedDTO implements IsSerializable {
private Map<FleetDTO, RaceDTO> racesPerFleet;
private Boolean isValidInTotalScore;
private Double explicitFactor;
private double effectiveFactor;
/**
* If the column has tracked races attached, this field tells the latest time point when one of those races was
@@ -234,4 +235,12 @@ public class RaceColumnDTO extends NamedDTO implements IsSerializable {
return false;
return true;
}
public void setEffectiveFactor(double effectiveFactor) {
this.effectiveFactor = effectiveFactor;
}
public double getEffectiveFactor() {
return effectiveFactor;
}
}
@@ -211,6 +211,7 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = URLEncoder.encode("/gwt/Leaderboard.html?name=" + leaderboard.name
+ (showRaceDetails ? "&showRaceDetails=true" : "")
+ (leaderboard.displayName != null ? "&displayName="+leaderboard.displayName : "")
+ (isEmbedded ? "&embedded=true" : "")
+ "&leaderboardGroupName=" + leaderboardGroup.name + "&root=" + root
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
@@ -308,11 +309,9 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
b.append(TEXTTEMPLATE.textWithClass(fleet.name, 50, STYLE_TABLE_TEXT));
} else {
String displayName = fleet.name;
if ("Default".equals(fleet.name)) {
b.append(TEXTTEMPLATE.textWithClass("", 70, STYLE_TABLE_TEXT));
} else {
if (! "Default".equals(fleet.name)) {
b.append(TEXTTEMPLATE.textWithClass(displayName, 50, STYLE_TABLE_TEXT));
}
}
}
renderRacesToHTml(leaderboard.name, raceColumns, fleet, b);
@@ -0,0 +1,102 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Extreme Sailing Series leaderboard</title>
<link rel="stylesheet" href="../css/leaderboard.css" type="text/css"/>
<link rel="stylesheet" href="../css/tablesorter.css" type="text/css"/>
<script type="text/javascript" src="jquery-latest.js"></script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.tablesorter.js"></script>
<script type="text/javascript">
$.getJSON('http://ess40-2012.sapsailing.com/sailingserver/leaderboard?leaderboardName=Extreme%2040%20Rio', function (data) {
var h1; h2;
var Header = new Array();
var Row = new Array();
var Values = new Array();
var Competitors = new Array();
var toWrite = '';
var imgFlagPath = '/gwt/images/flags/';
h1 = data.name.toString();
if(data.scoringComment) {
h2 = data.scoringComment.toString();
} else {
h2 = '';
}
Header.push("Rank");
Header.push("Team");
Header = $.merge(Header, data.columnNames);
Header.push("&sum;");
Competitors = data.competitors;
//create HTML Header
toWrite += '<thead><tr>';
for (var i = 0; i < Header.length; i++) {
toWrite += '<th>' + Header[i] + '</th>';
};
toWrite += '</tr></thead><tbody>';
//collect Row Data
$.each(Competitors, function (index, values) {
Row.push(values.rank.toString());
Row.push(values.name.toString());
Values = values.raceScores;
//get Competitor Points
$.each(Values, function (indexPoints, valuesPoints) {
if(valuesPoints.maxPointsReason.toString() != 'NONE') {
Row.push(valuesPoints.maxPointsReason.toString());
} else {
Row.push(valuesPoints.totalPoints.toString());
}
});
Row.push(values.totalPoints.toString());
//Row complete
//write Row
toWrite += '<tr>';
for (var j = 0; j < Header.length; j++) {
if (j < Row.length) {
if(j == 0) {
toWrite += '<td>' + Row[j] + '</td>';
} else if(j == 1) {
toWrite += '<td style="white-space:nowrap;">';
toWrite += '<img style="padding-right:8px;" src="' + imgFlagPath + values.countryCode.toString().toLowerCase() + '.png">';
toWrite += Row[j];
toWrite + '</td>';
} else if (j > 1 && j < (Row.length - 1)) {
toWrite += '<td class="leaderboard-points-TotalPoints-NotDiscarded">' + Row[j] + '</td>';
} else {
toWrite += '<td>' + Row[j] + '</td>';
}
} else {//fill rest of the Header row
toWrite += '<td>&nbsp;</td>';
}
};
toWrite += '</tr>';
//Row completed
//reset Row
Row = new Array();
});
toWrite += '</tbody>';
$('#h1').text(h1);
$('#h2').text(h2);
$('#leaderboardTable').html(toWrite);
$("#leaderboardTable").tablesorter();
});
</script>
</head>
<body>
<h1 id="h1"></h1>
<h2 id="h2"></h2>
<table id="leaderboardTable" class="tablesorter"></table>
</body>
</html>
@@ -0,0 +1,109 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Extreme Sailing Series leaderboard</title>
<link rel="stylesheet" href="../css/leaderboard.css" type="text/css"/>
<link rel="stylesheet" href="../css/tablesorter.css" type="text/css"/>
<script type="text/javascript" src="jquery-latest.js"></script>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.tablesorter.js"></script>
<script type="text/javascript">
String.prototype.startsWith = function(str)
{ return (this.match("^"+str)==str) }
$.getJSON('http://ess40-2012.sapsailing.com/sailingserver/leaderboard?leaderboardName=Extreme%20Sailing%20Series%202012%20Overall', function (data) {
var h1; h2;
var Header = new Array();
var Row = new Array();
var Values = new Array();
var Competitors = new Array();
var toWrite = '';
var imgFlagPath = '/gwt/images/flags/';
h1 = data.name.toString();
if(data.scoringComment) {
h2 = data.scoringComment.toString();
} else {
h2 = '';
}
Header.push("Rank");
Header.push("Team");
Header = $.merge(Header, data.columnNames);
Header.push("&sum;");
Competitors = data.competitors;
//create HTML Header
toWrite += '<thead><tr>';
for (var i = 0; i < Header.length; i++) {
var headerText = Header[i];
if(headerText.startsWith('Extreme 40 ')) {
headerText = headerText.substring(11, headerText.length);
}
toWrite += '<th>' + headerText + '</th>';
};
toWrite += '</tr></thead><tbody>';
//collect Row Data
$.each(Competitors, function (index, values) {
Row.push(values.rank.toString());
Row.push(values.name.toString());
Values = values.raceScores;
//get Competitor Points
$.each(Values, function (indexPoints, valuesPoints) {
if(valuesPoints.maxPointsReason.toString() != 'NONE') {
Row.push(valuesPoints.maxPointsReason.toString());
} else {
Row.push(valuesPoints.totalPoints.toString());
}
});
Row.push(values.totalPoints.toString());
//Row complete
//write Row
toWrite += '<tr>';
for (var j = 0; j < Header.length; j++) {
if (j < Row.length) {
if(j == 0) {
toWrite += '<td>' + Row[j] + '</td>';
} else if(j == 1) {
toWrite += '<td style="white-space:nowrap;">';
toWrite += '<img style="padding-right:8px;" src="' + imgFlagPath + values.countryCode.toString().toLowerCase() + '.png">';
toWrite += Row[j];
toWrite + '</td>';
} else if (j > 1 && j < (Row.length - 1)) {
toWrite += '<td class="leaderboard-points-TotalPoints-NotDiscarded">' + Row[j] + '</td>';
} else {
toWrite += '<td>' + Row[j] + '</td>';
}
} else {//fill rest of the Header row
toWrite += '<td>&nbsp;</td>';
}
};
toWrite += '</tr>';
//Row completed
//reset Row
Row = new Array();
});
toWrite += '</tbody>';
$('#h1').text(h1);
$('#h2').text(h2);
$('#leaderboardTable').html(toWrite);
$("#leaderboardTable").tablesorter();
});
</script>
</head>
<body>
<h1 id="h1"></h1>
<h2 id="h2"></h2>
<table id="leaderboardTable" class="tablesorter"></table>
</body>
</html>
@@ -82,6 +82,7 @@ public class ESS40ResultsAsCSVServlet extends AbstractCSVHttpServlet {
csvLine.add(competitor.getName());
csv.add(csvLine);
// TODO: we should only export complete races where all competitors have valid totalPoints for a race
for (RaceColumn raceColumn : raceColumns) {
List<Competitor> rankedCompetitorsForColumn = rankedCompetitorsPerColumn.get(raceColumn);
if (rankedCompetitorsForColumn == null) {
@@ -89,34 +90,18 @@ public class ESS40ResultsAsCSVServlet extends AbstractCSVHttpServlet {
timePoint);
rankedCompetitorsPerColumn.put(raceColumn, rankedCompetitorsForColumn);
}
Double netRacePoints = leaderboard.getNetPoints(competitor, raceColumn, timePoint);
// Double netRacePoints = leaderboard.getNetPoints(competitor, raceColumn, timePoint);
Double totalRacePoints = leaderboard.getTotalPoints(competitor, raceColumn, timePoint);
MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitor, raceColumn,
timePoint);
// int rank = rankedCompetitorsForColumn.indexOf(competitor)+1;
// TrackedRace trackedRace = raceColumn.getTrackedRace(competitor);
// if (trackedRace != null) {
// int raceRank = trackedRace.getRank(competitor, timePoint);
// }
// boolean isCorrected = leaderboard.getScoreCorrection().isScoreCorrected(competitor,
// raceColumn);
boolean isDiscarded = leaderboard.isDiscarded(competitor, raceColumn, timePoint);
MaxPointsReason maxPointsReason = leaderboard.getMaxPointsReason(competitor, raceColumn, timePoint);
int rank = rankedCompetitorsForColumn.indexOf(competitor)+1;
if(totalRacePoints != null) {
if (maxPointsReason == null || maxPointsReason == MaxPointsReason.NONE) {
csvLine.add(rank);
csvLine.add(totalRacePoints);
if (maxPointsReason == null || maxPointsReason == MaxPointsReason.NONE) {
if (!isDiscarded) {
if (totalRacePoints != null) {
csvLine.add(totalRacePoints);
}
} else {
if (netRacePoints != null) {
csvLine.add(netRacePoints);
}
}
} else {
if (!isDiscarded) {
csvLine.add(maxPointsReason.name());
} else {
csvLine.add(maxPointsReason.name());
csvLine.add(totalRacePoints);
}
}
}
@@ -1520,7 +1520,13 @@ public class RacingEventServiceImpl implements RacingEventService, RegattaListen
<T> void replicate(RacingEventServiceOperation<T> operation) {
for (OperationExecutionListener listener : operationExecutionListeners.keySet()) {
listener.executed(operation); // TODO consider exception handling
try {
listener.executed(operation);
} catch (Exception e) {
// don't risk the master's operation only because replication to a listener/replica doesn't work
logger.severe("Error replicating operation "+operation+" to replication listener "+listener);
logger.throwing(RacingEventServiceImpl.class.getName(), "replicate", e);
}
}
}
@@ -26,7 +26,7 @@
</p>
</div>
<div id='navigation'>
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=Extreme%20Sailing%20Series%202013%20Rio&showRaceDetails=true&leaderboardGroupName=Extreme%20Sailing%20Series%202013&root=leaderboardGroupPanel;refreshIntervalMillis=10000&amp;lastN=3'>
<a class='navButton event' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=Extreme%20Sailing%20Series%202013%20Muscat&displayName=Muscat&showRaceDetails=true&leaderboardGroupName=Extreme%20Sailing%20Series%202013&root=leaderboardGroupPanel;refreshIntervalMillis=10000&amp;lastN=3'>
Live Muscat Act Leaderboard
</a>
<a class='navButton overall' href='http://ess40-2013.sapsailing.com/gwt/Leaderboard.html?name=Extreme%20Sailing%20Series%202013%20Overall&amp;showRaceDetails=false&amp;refreshIntervalMillis=10000&amp;displayName=Overall%20Standings&amp;leaderboardGroupName=Extreme%20Sailing%20Series%202013&amp;root=leaderboardGroupPanel'>