Merge remote-tracking branch 'origin/racecommittee_app' into racecommittee_app

This commit is contained in:
Jan Broß committed 2013-07-25 09:56:19 +02:00
commit f97ffe4ffc
59 files changed
+517 -408

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
Kieler Woche 2012
Move wind data from test to prod
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: /TW 2013.*/}" > /tmp/windtracks-TW2013.json
/opt/mongodb/bin/mongoimport --upsert --port 10202 -d winddb -c WIND_TRACKS /tmp/windtracks-TW2013.json
@@ -32,7 +32,7 @@ public enum DetailType implements Serializable {
MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS(1, DESCENDING),
TOTAL_DISTANCE_TRAVELED(0, ASCENDING), TOTAL_AVERAGE_SPEED_OVER_GROUND(2, DESCENDING),
TOTAL_TIME_SAILED_IN_SECONDS(1, ASCENDING), RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING),
RACE_TIME_SINCE_LAST_POSITION_FIX_IN_SECONDS(1 , ASCENDING),
RACE_TIME_SINCE_LAST_POSITION_FIX_IN_SECONDS(0 , ASCENDING),
RACE_TRACKING_QUALITY(0 , ASCENDING);
private int precision;
@@ -13,6 +13,6 @@ public abstract class AbstractClientParamsPHPTest {
public void setUp(String resourceName) throws IOException {
InputStream is = getClass().getResourceAsStream(resourceName);
Reader r = new InputStreamReader(is);
clientParams = new ClientParamsPHP(r);
clientParams = new ClientParamsPHP(getClass().getResource(resourceName), r);
}
}
@@ -5,6 +5,7 @@ import java.io.IOException;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -67,6 +68,11 @@ public class ClientParamsPHP {
* keys for {@link #properties}.
*/
private final Map<UUID, String> propertiesByID;
/**
* The URL the document object was created from
*/
private final URL paramsUrl;
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
@@ -416,7 +422,8 @@ public class ClientParamsPHP {
}
}
public ClientParamsPHP(Reader r) throws IOException {
public ClientParamsPHP(URL paramsUrl, Reader r) throws IOException {
this.paramsUrl = paramsUrl;
BufferedReader br = new BufferedReader(r);
properties = new LinkedHashMap<>();
propertiesByID = new HashMap<>();
@@ -442,6 +449,10 @@ public class ClientParamsPHP {
}
}
public URL getParamsUrl() {
return paramsUrl;
}
public URI getLiveUri() throws URISyntaxException {
return new URI(properties.get("live-uri"));
}
@@ -1,7 +1,6 @@
package com.sap.sailing.domain.tractracadapter.impl;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.MalformedURLException;
@@ -277,7 +276,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
logger.fine("Fetching paramURL "+paramURL+" to check for updates for race(s) "+getRaces());
final ClientParamsPHP clientParams;
try {
clientParams = new ClientParamsPHP(new InputStreamReader(paramURL.openStream()));
clientParams = new ClientParamsPHP(paramURL, new InputStreamReader(paramURL.openStream()));
List<Pair<com.sap.sailing.domain.base.ControlPoint, NauticalSide>> newCourseControlPointsWithPassingSide = getControlPointsWithPassingSide(clientParams,
new ControlPointProducer<com.sap.sailing.domain.base.ControlPoint>() {
@Override
@@ -285,11 +284,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
return domainFactory.getOrCreateControlPoint(ttControlPoint);
}
});
if (getRaces() != null && !getRaces().isEmpty()) {
compareAndUpdateCourseIfNecessary(newCourseControlPointsWithPassingSide);
updateStartStopTimesAndLiveDelay(clientParams, simulator);
updateMarkPositionsIfNoPositionsReceivedYet(clientParams);
} else {
if (getRaces() == null || getRaces().isEmpty()) {
// create race definition / tracked race and add to event
final String raceName = clientParams.getRace().getName();
logger.log(Level.INFO, "Found data for non-existing race "+raceName+" in "+paramURL+". Creating RaceDefinition.");
@@ -314,9 +309,11 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
simulator.setTrackedRace(trackedRace);
}
}
} catch (IOException e) {
logger.info("Exception " + e.getMessage() + " while trying to read clientparams.php for races "
+ getRaces());
compareAndUpdateCourseIfNecessary(newCourseControlPointsWithPassingSide);
updateStartStopTimesAndLiveDelay(clientParams, simulator);
updateMarkPositionsIfNoPositionsReceivedYet(clientParams);
} catch (Exception e) {
logger.info("Exception " + e.getMessage() + " while trying to read clientparams.php for races " + getRaces());
logger.log(Level.SEVERE, "scheduleClientParamsPHPPoller.run", e);
}
}
@@ -361,9 +358,10 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
if (trackedRace != null) {
DynamicGPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
if (markTrack.getFirstRawFix() == null) {
final Position position = first ? controlPoint.getMark1Position() : controlPoint
.getMark2Position();
final Position position = first ? controlPoint.getMark1Position() : controlPoint.getMark2Position();
if (position != null) {
logger.info("Adding fix "+position+" from "+clientParams.getParamsUrl()+" for control point "+controlPoint.getName()+
" in race "+raceDefinition.getName());
markTrack.addGPSFix(new GPSFixImpl(position, MillisecondsTimePoint.now()));
}
}
@@ -1128,7 +1128,6 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
if (windSource.getType() == WindSourceType.COMBINED) {
if (combinedWindTrack == null) {
combinedWindTrack = new CombinedWindTrackImpl(this, WindSourceType.COMBINED.getBaseConfidence());
;
}
result = combinedWindTrack;
} else {
@@ -53,8 +53,9 @@ public class ExportPopup extends DialogBox {
ListBox lbData = new ListBox(true);
lbData.setName(TrackFilesExportParameters.DATA);
for (TrackFilesDataSource dataSource : TrackFilesDataSource.values())
for (TrackFilesDataSource dataSource : TrackFilesDataSource.values()) {
lbData.addItem(dataSource.name());
}
lbData.setVisibleItemCount(lbData.getItemCount());
lbData.setItemSelected(0, true);
mainPanel.add(lbData);
@@ -8,8 +8,6 @@ import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -21,16 +19,15 @@ import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable.ColumnFormatter;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
@@ -77,12 +74,6 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
private ListBox connectionsHistoryListBox;
private TextBox eventNameTextBox;
private TextBox hostnameTextBox;
private IntegerBox storedDataPortIntegerBox;
private IntegerBox liveDataPortIntegerBox;
private TextBox storedURITextBox;
private TextBox liveURITextBox;
private TextBox jsonURLTextBox;
@@ -109,8 +100,6 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
mainPanel.setWidth("100%");
CaptionPanel connectionsPanel = createConnectionsPanel();
//connectionsPanel.setWidth("100%");
mainPanel.add(connectionsPanel);
HorizontalPanel racesPanel = createRacesPanel();
@@ -119,37 +108,30 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
mainPanel.add(racesPanel);
fillConfigurations();
synchURIs();
return mainPanel;
}
protected CaptionPanel createConnectionsPanel() {
CaptionPanel connectionsPanel = new CaptionPanel(this.stringMessages.connections());
CaptionPanel connectionsPanel = new CaptionPanel("TracTrac " + stringMessages.connections());
connectionsPanel.ensureDebugId("ConnectionsSection");
connectionsPanel.setStyleName("bold");
FlexTable layoutTable = new FlexTable();
layoutTable.setWidth("100%");
Grid grid = new Grid(10, 3);
connectionsPanel.setContentWidget(grid);
// Existing TracTrac connections
Label connectionsHistoryLabel = new Label("TracTrac " + stringMessages.connections() + ":");
ColumnFormatter columnFormatter = layoutTable.getColumnFormatter();
FlexCellFormatter cellFormatter = layoutTable.getFlexCellFormatter();
columnFormatter.setWidth(0, "130px");
//columnFormatter.setWidth(1, "90%");
// History of connections
Label connectionsHistoryLabel = new Label(this.stringMessages.historyOfConnections() + ":");
this.connectionsHistoryListBox = new ListBox();
this.connectionsHistoryListBox.ensureDebugId("ConnectionHistory");
this.connectionsHistoryListBox.addChangeHandler(new ChangeHandler() {
connectionsHistoryListBox = new ListBox();
connectionsHistoryListBox.ensureDebugId("ConnectionHistory");
connectionsHistoryListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
updatePanelFromSelectedStoredConfiguration();
}
});
this.connectionsHistoryListBox.addClickHandler(new ClickHandler() {
connectionsHistoryListBox.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
// TODO: This leads to a strange behavior (values are updated by opening the drop down) but at the
@@ -159,184 +141,88 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
});
layoutTable.setWidget(0, 0, connectionsHistoryLabel);
layoutTable.setWidget(0, 1, this.connectionsHistoryListBox);
// Definition of new connection
Label defineNewConnectionLabel = new Label(this.stringMessages.defineNewConnection());
Element defineNewConnectionElement = defineNewConnectionLabel.getElement();
Style defineNewConnectionStyle = defineNewConnectionElement.getStyle();
defineNewConnectionStyle.setPaddingTop(30, Unit.PX);
defineNewConnectionStyle.setPaddingBottom(10, Unit.PX);
layoutTable.setWidget(1, 0, defineNewConnectionLabel);
cellFormatter.setColSpan(1, 0, 2);
// Host name
Label hostnameLabel = new Label(this.stringMessages.hostname() + ":");
this.hostnameTextBox = new TextBox();
this.hostnameTextBox.ensureDebugId("HostName");
this.hostnameTextBox.setText("germanmaster.traclive.dk");
this.hostnameTextBox.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
synchURIs();
}
});
layoutTable.setWidget(2, 0, hostnameLabel);
layoutTable.setWidget(2, 1, this.hostnameTextBox);
// Event name
Label eventNameLabel = new Label(this.stringMessages.eventName() + ":");
this.eventNameTextBox = new TextBox();
this.eventNameTextBox.ensureDebugId("RegattaName");
this.eventNameTextBox.setText("event_2011...");
this.eventNameTextBox.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
synchURIs();
}
});
layoutTable.setWidget(3, 0, eventNameLabel);
layoutTable.setWidget(3, 1, this.eventNameTextBox);
// Ports (Live and Stored)
Label portsLabel = new Label(this.stringMessages.ports() + ":");
layoutTable.setWidget(4, 0, portsLabel);
Label liveDataPortLabel = new Label(this.stringMessages.liveData());
Element liveDataPortElement = liveDataPortLabel.getElement();
Style liveDataPortStyle = liveDataPortElement.getStyle();
liveDataPortStyle.setProperty("paddingLeft", "30px");
this.liveDataPortIntegerBox = new IntegerBox();
this.liveDataPortIntegerBox.ensureDebugId("LiveDataPort");
this.liveDataPortIntegerBox.setText(Integer.toString(4400));
this.liveDataPortIntegerBox.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
updateStoredDataPort();
synchURIs();
}
});
layoutTable.setWidget(5, 0, liveDataPortLabel);
layoutTable.setWidget(5, 1, this.liveDataPortIntegerBox);
Label storedDataPortLabel = new Label(this.stringMessages.storedData());
Element storedDataPortElement = storedDataPortLabel.getElement();
Style storedDataPortStyle = storedDataPortElement.getStyle();
storedDataPortStyle.setProperty("paddingLeft", "30px");
this.storedDataPortIntegerBox = new IntegerBox();
this.storedDataPortIntegerBox.ensureDebugId("StoredDataPort");
this.storedDataPortIntegerBox.setText(Integer.toString(4401));
this.storedDataPortIntegerBox.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
synchURIs();
}
});
layoutTable.setWidget(6, 0, storedDataPortLabel);
layoutTable.setWidget(6, 1, this.storedDataPortIntegerBox);
grid.setWidget(0, 0, connectionsHistoryLabel);
grid.setWidget(0, 1, connectionsHistoryListBox);
// URIs (Live and Stored)
Label urisLabel = new Label(this.stringMessages.uris() + ":");
urisLabel.setTitle(this.stringMessages.leaveEmptyForDefault());
grid.setWidget(1, 0, new Label(stringMessages.details() + ":"));
layoutTable.setWidget(7, 0, urisLabel);
Label liveURILabel = new Label(stringMessages.liveUri() + ":");
liveURILabel.setTitle(stringMessages.leaveEmptyForDefault());
Label liveURILabel = new Label(this.stringMessages.liveUri());
liveURILabel.setTitle(this.stringMessages.leaveEmptyForDefault());
Element liveURIElement = liveURILabel.getElement();
Style liveURIStyle = liveURIElement.getStyle();
liveURIStyle.setProperty("paddingLeft", "30px");
liveURITextBox = new TextBox();
liveURITextBox.ensureDebugId("LiveURI");
liveURITextBox.setVisibleLength(40);
liveURITextBox.setTitle(stringMessages.leaveEmptyForDefault());
this.liveURITextBox = new TextBox();
this.liveURITextBox.ensureDebugId("LiveURI");
this.liveURITextBox.setVisibleLength(40);
this.liveURITextBox.setTitle(this.stringMessages.leaveEmptyForDefault());
grid.setWidget(2, 0, liveURILabel);
grid.setWidget(2, 1, liveURITextBox);
layoutTable.setWidget(8, 0, liveURILabel);
layoutTable.setWidget(8, 1, this.liveURITextBox);
Label storedURILabel = new Label(stringMessages.storedUri() + ":");
storedURILabel.setTitle(stringMessages.leaveEmptyForDefault());
Label storedURILabel = new Label(this.stringMessages.storedUri());
storedURILabel.setTitle(this.stringMessages.leaveEmptyForDefault());
Element storedURIElement = storedURILabel.getElement();
Style storedURIStyle = storedURIElement.getStyle();
storedURIStyle.setProperty("paddingLeft", "30px");
storedURITextBox = new TextBox();
storedURITextBox.ensureDebugId("StoredURI");
storedURITextBox.setVisibleLength(40);
storedURITextBox.setTitle(stringMessages.leaveEmptyForDefault());
this.storedURITextBox = new TextBox();
this.storedURITextBox.ensureDebugId("StoredURI");
this.storedURITextBox.setVisibleLength(40);
this.storedURITextBox.setTitle(this.stringMessages.leaveEmptyForDefault());
layoutTable.setWidget(9, 0, storedURILabel);
layoutTable.setWidget(9, 1, this.storedURITextBox);
grid.setWidget(3, 0, storedURILabel);
grid.setWidget(3, 1, storedURITextBox);
// JSON URL
Label jsonURLLabel = new Label(this.stringMessages.jsonUrl() + ":");
Label jsonURLLabel = new Label(stringMessages.jsonUrl() + ":");
this.jsonURLTextBox = new TextBox();
this.jsonURLTextBox.ensureDebugId("JSONURL");
this.jsonURLTextBox.setVisibleLength(100);
jsonURLTextBox = new TextBox();
jsonURLTextBox.ensureDebugId("JSONURL");
jsonURLTextBox.setVisibleLength(100);
layoutTable.setWidget(10, 0, jsonURLLabel);
layoutTable.setWidget(10, 1, this.jsonURLTextBox);
grid.setWidget(4, 0, jsonURLLabel);
grid.setWidget(4, 1, jsonURLTextBox);
// Course design Update URL
Label courseDesignUpdateURLLabel = new Label(this.stringMessages.courseDesignUpdateUrl() + ":");
Label courseDesignUpdateURLLabel = new Label(stringMessages.courseDesignUpdateUrl() + ":");
this.courseDesignUpdateURITextBox = new TextBox();
this.courseDesignUpdateURITextBox.ensureDebugId("COURSEDESIGNUPDATEURI");
this.courseDesignUpdateURITextBox.setVisibleLength(100);
courseDesignUpdateURITextBox = new TextBox();
courseDesignUpdateURITextBox.ensureDebugId("COURSEDESIGNUPDATEURI");
courseDesignUpdateURITextBox.setVisibleLength(100);
layoutTable.setWidget(11, 0, courseDesignUpdateURLLabel);
layoutTable.setWidget(11, 1, this.courseDesignUpdateURITextBox);
grid.setWidget(5, 0, courseDesignUpdateURLLabel);
grid.setWidget(5, 1, courseDesignUpdateURITextBox);
// TracTrac Username
Label tractracUsernameLabel = new Label(this.stringMessages.tractracUsername() + ":");
tractracUsernameTextBox = new TextBox();
tractracUsernameTextBox.ensureDebugId("tractracUsername");
tractracUsernameTextBox.setVisibleLength(40);
this.tractracUsernameTextBox = new TextBox();
this.tractracUsernameTextBox.ensureDebugId("tractracUsername");
this.tractracUsernameTextBox.setVisibleLength(40);
layoutTable.setWidget(12, 0, tractracUsernameLabel);
layoutTable.setWidget(12, 1, this.tractracUsernameTextBox);
grid.setWidget(6, 0, new Label(stringMessages.tractracUsername() + ":"));
grid.setWidget(6, 1, tractracUsernameTextBox);
// TracTrac Password
Label tractracPasswordLabel = new Label(this.stringMessages.tractracPassword() + ":");
tractracPasswordTextBox = new TextBox();
tractracPasswordTextBox.ensureDebugId("tractracPassword");
tractracPasswordTextBox.setVisibleLength(40);
this.tractracPasswordTextBox = new TextBox();
this.tractracPasswordTextBox.ensureDebugId("tractracPassword");
this.tractracPasswordTextBox.setVisibleLength(40);
grid.setWidget(7, 0, new Label(stringMessages.tractracPassword() + ":"));
grid.setWidget(7, 1, tractracPasswordTextBox);
layoutTable.setWidget(13, 0, tractracPasswordLabel);
layoutTable.setWidget(13, 1, this.tractracPasswordTextBox);
final CheckBox listHiddenRaces = new CheckBox(stringMessages.showHiddenRaces());
layoutTable.setWidget(14, 0, listHiddenRaces);
grid.setWidget(8, 0, new Label(stringMessages.racesWithHiddenState() + ":"));
final CheckBox showHiddenRacesCheckbox = new CheckBox(stringMessages.show());
grid.setWidget(8, 1, showHiddenRacesCheckbox);
// List Races
Button listRacesButton = new Button(this.stringMessages.listRaces());
Button listRacesButton = new Button(stringMessages.listRaces());
listRacesButton.ensureDebugId("ListRaces");
listRacesButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
loadingMessageLabel.setText(stringMessages.loading());
fillRaces(sailingService, listHiddenRaces.getValue());
fillRaces(sailingService, showHiddenRacesCheckbox.getValue());
}
});
layoutTable.setWidget(14, 1, listRacesButton);
grid.setWidget(9, 1, listRacesButton);
loadingMessageLabel = new Label();
layoutTable.setWidget(14, 2, loadingMessageLabel);
connectionsPanel.setContentWidget(layoutTable);
grid.setWidget(9, 2, loadingMessageLabel);
return connectionsPanel;
}
@@ -345,13 +231,11 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
HorizontalPanel racesPanel = new HorizontalPanel();
CaptionPanel trackableRacesPanel = createTrackableRacesPanel();
//trackableRacesPanel.setWidth("100%");
racesPanel.add(trackableRacesPanel);
racesPanel.setCellWidth(trackableRacesPanel, "50%");
CaptionPanel trackedRacesPanel = createTrackedRacesPanel();
//trackedRacesPanel.setWidth("100%");
racesPanel.add(trackedRacesPanel);
racesPanel.setCellWidth(trackedRacesPanel, "50%");
@@ -360,7 +244,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
protected CaptionPanel createTrackableRacesPanel() {
CaptionPanel trackableRacesPanel = new CaptionPanel(this.stringMessages.trackableRaces());
CaptionPanel trackableRacesPanel = new CaptionPanel(stringMessages.trackableRaces());
trackableRacesPanel.ensureDebugId("TrackableRacesSection");
trackableRacesPanel.setStyleName("bold");
@@ -380,19 +264,19 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
layoutTable.setWidget(0, 1, getAvailableRegattasListBox());
// Track settings (wind)
Label trackSettingsLabel = new Label(this.stringMessages.trackSettings() + ":");
Label trackSettingsLabel = new Label(stringMessages.trackSettings() + ":");
final CheckBox trackWindCheckBox = new CheckBox(this.stringMessages.trackWind());
final CheckBox trackWindCheckBox = new CheckBox(stringMessages.trackWind());
trackWindCheckBox.ensureDebugId("TrackWind");
trackWindCheckBox.setWordWrap(false);
trackWindCheckBox.setValue(Boolean.TRUE);
final CheckBox correctWindCheckBox = new CheckBox(this.stringMessages.declinationCheckbox());
final CheckBox correctWindCheckBox = new CheckBox(stringMessages.declinationCheckbox());
correctWindCheckBox.ensureDebugId("CorrectWind");
correctWindCheckBox.setWordWrap(false);
correctWindCheckBox.setValue(Boolean.TRUE);
final CheckBox simulateWithStartTimeNowCheckBox = new CheckBox(this.stringMessages.simulateWithStartTimeNow());
final CheckBox simulateWithStartTimeNowCheckBox = new CheckBox(stringMessages.simulateWithStartTimeNow());
simulateWithStartTimeNowCheckBox.ensureDebugId("SimulateWithStartTimeNow");
simulateWithStartTimeNowCheckBox.setWordWrap(false);
simulateWithStartTimeNowCheckBox.setValue(Boolean.FALSE);
@@ -403,7 +287,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
layoutTable.setWidget(3, 1, simulateWithStartTimeNowCheckBox);
// Filter
Label racesFilterLabel = new Label(this.stringMessages.filterRacesByName() + ":");
Label racesFilterLabel = new Label(stringMessages.filterRacesByName() + ":");
this.racesFilterTextBox = new TextBox();
this.racesFilterTextBox.ensureDebugId("FilterRaces");
@@ -415,7 +299,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
});
layoutTable.setWidget(4, 0, racesFilterLabel);
layoutTable.setWidget(4, 1, this.racesFilterTextBox);
layoutTable.setWidget(4, 1, racesFilterTextBox);
// Races
TextColumn<TracTracRaceRecordDTO> regattaNameColumn = new TextColumn<TracTracRaceRecordDTO>() {
@@ -456,24 +340,24 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
raceStatusColumn.setSortable(true);
AdminConsoleTableResources tableResources = GWT.create(AdminConsoleTableResources.class);
this.racesTable = new CellTable<TracTracRaceRecordDTO>(10000, tableResources);
this.racesTable.ensureDebugId("RacesTable");
this.racesTable.addColumn(regattaNameColumn, this.stringMessages.event());
this.racesTable.addColumn(raceNameColumn, this.stringMessages.race());
this.racesTable.addColumn(boatClassColumn, this.stringMessages.boatClass());
this.racesTable.addColumn(raceStartTrackingColumn, this.stringMessages.startTime());
this.racesTable.addColumn(raceStatusColumn, this.stringMessages.raceStatusColumn());
this.racesTable.addColumnSortHandler(getRaceTableColumnSortHandler(this.raceList.getList(), raceNameColumn,
racesTable = new CellTable<TracTracRaceRecordDTO>(10000, tableResources);
racesTable.ensureDebugId("RacesTable");
racesTable.addColumn(regattaNameColumn, stringMessages.event());
racesTable.addColumn(raceNameColumn, stringMessages.race());
racesTable.addColumn(boatClassColumn, stringMessages.boatClass());
racesTable.addColumn(raceStartTrackingColumn, stringMessages.startTime());
racesTable.addColumn(raceStatusColumn, stringMessages.raceStatusColumn());
racesTable.addColumnSortHandler(getRaceTableColumnSortHandler(this.raceList.getList(), raceNameColumn,
boatClassColumn, raceStartTrackingColumn, raceStatusColumn));
this.racesTable.setSelectionModel(new MultiSelectionModel<TracTracRaceRecordDTO>());
this.racesTable.setWidth("100%");
racesTable.setSelectionModel(new MultiSelectionModel<TracTracRaceRecordDTO>());
racesTable.setWidth("100%");
this.raceList.addDataDisplay(this.racesTable);
raceList.addDataDisplay(racesTable);
layoutTable.setWidget(5, 0, this.racesTable);
layoutTable.setWidget(5, 0, racesTable);
cellFormatter.setColSpan(5, 0, 2);
Button startTrackingButton = new Button(this.stringMessages.startTracking());
Button startTrackingButton = new Button(stringMessages.startTracking());
startTrackingButton.ensureDebugId("StartTracking");
startTrackingButton.addClickHandler(new ClickHandler() {
@Override
@@ -491,7 +375,7 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
protected CaptionPanel createTrackedRacesPanel() {
CaptionPanel trackedRacesPanel = new CaptionPanel(this.stringMessages.trackedRaces());
CaptionPanel trackedRacesPanel = new CaptionPanel(stringMessages.trackedRaces());
trackedRacesPanel.ensureDebugId("TrackedRacesSection");
trackedRacesPanel.setStyleName("bold");
@@ -548,24 +432,6 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
return boatClassNames.substring(0, boatClassNames.length() - 2);
}
private void synchURIs() {
String hostName = this.hostnameTextBox.getValue();
String regattaName = this.eventNameTextBox.getValue();
Integer liveDataPort = this.liveDataPortIntegerBox.getValue();
Integer storedDataPort = this.storedDataPortIntegerBox.getValue();
this.liveURITextBox.setValue("tcp://" + hostName + (liveDataPort != null ? ":" + liveDataPort : ""));
this.storedURITextBox.setValue("tcp://" + hostName + (storedDataPort != null ? ":" + storedDataPort : ""));
this.jsonURLTextBox.setValue("http://" + hostName + "/events/" + regattaName + "/jsonservice.php");
}
private void updateStoredDataPort() {
Integer liveDataPort = this.liveDataPortIntegerBox.getValue();
if(liveDataPort != null)
this.storedDataPortIntegerBox.setValue(Integer.valueOf(liveDataPort.intValue() + 1));
}
private void fillConfigurations() {
this.sailingService.getPreviousTracTracConfigurations(new MarkedAsyncCallback<List<TracTracConfigurationDTO>>() {
@Override
@@ -592,12 +458,12 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
private void fillRaces(final SailingServiceAsync sailingService, boolean listHiddenRaces) {
final String jsonURL = this.jsonURLTextBox.getValue();
final String liveDataURI = this.liveURITextBox.getValue();
final String storedDataURI = this.storedURITextBox.getValue();
final String courseDesignUpdateURI = this.courseDesignUpdateURITextBox.getValue();
final String tractracUsername = this.tractracUsernameTextBox.getValue();
final String tractracPassword = this.tractracPasswordTextBox.getValue();
final String jsonURL = jsonURLTextBox.getValue();
final String liveDataURI = liveURITextBox.getValue();
final String storedDataURI = storedURITextBox.getValue();
final String courseDesignUpdateURI = courseDesignUpdateURITextBox.getValue();
final String tractracUsername = tractracUsernameTextBox.getValue();
final String tractracPassword = tractracPasswordTextBox.getValue();
sailingService.listTracTracRacesInEvent(jsonURL, listHiddenRaces, new MarkedAsyncCallback<Pair<String, List<TracTracRaceRecordDTO>>>() {
@Override
@@ -672,20 +538,20 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
private void trackSelectedRaces(boolean trackWind, boolean correctWind, final boolean simulateWithStartTimeNow) {
String liveURI = this.liveURITextBox.getValue();
String storedURI = this.storedURITextBox.getValue();
String courseDesignUpdateURI = this.courseDesignUpdateURITextBox.getValue();
String tractracUsername = this.tractracUsernameTextBox.getValue();
String tractracPassword = this.tractracPasswordTextBox.getValue();
String liveURI = liveURITextBox.getValue();
String storedURI = storedURITextBox.getValue();
String courseDesignUpdateURI = courseDesignUpdateURITextBox.getValue();
String tractracUsername = tractracUsernameTextBox.getValue();
String tractracPassword = tractracPasswordTextBox.getValue();
RegattaDTO selectedRegatta = getSelectedRegatta();
RegattaIdentifier regattaIdentifier = null;
if (selectedRegatta != null) {
regattaIdentifier = new RegattaName(selectedRegatta.getName());
}
// Check if the assigned regatta makes sense
List<TracTracRaceRecordDTO> allRaces = this.raceList.getList();
List<TracTracRaceRecordDTO> allRaces = raceList.getList();
List<TracTracRaceRecordDTO> racesWithNotMatchingBoatClasses = new ArrayList<TracTracRaceRecordDTO>();
SelectionModel<? super TracTracRaceRecordDTO> selectionModel = this.racesTable.getSelectionModel();
SelectionModel<? super TracTracRaceRecordDTO> selectionModel = racesTable.getSelectionModel();
for (TracTracRaceRecordDTO race : allRaces) {
if (selectionModel.isSelected(race)) {
@@ -697,14 +563,14 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
StringBuilder builder = new StringBuilder(100 + racesWithNotMatchingBoatClasses.size() * 30);
builder.append("WARNING\n");
if (selectedRegatta != null) {
builder.append(this.stringMessages.boatClassDoesNotMatchSelectedRegatta(
builder.append(stringMessages.boatClassDoesNotMatchSelectedRegatta(
selectedRegatta.boatClass==null?"":selectedRegatta.boatClass.getName(),
selectedRegatta.getName()));
} else {
builder.append(this.stringMessages.regattaExistForSelectedBoatClass());
builder.append(stringMessages.regattaExistForSelectedBoatClass());
}
builder.append("\n\n");
builder.append(this.stringMessages.races());
builder.append(stringMessages.races());
builder.append("\n");
for (TracTracRaceRecordDTO record: racesWithNotMatchingBoatClasses) {
builder.append(record.name);
@@ -716,12 +582,12 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
final List<TracTracRaceRecordDTO> selectedRaces = new ArrayList<TracTracRaceRecordDTO>();
for (final TracTracRaceRecordDTO race : this.raceList.getList()) {
for (final TracTracRaceRecordDTO race : raceList.getList()) {
if (selectionModel.isSelected(race)) {
selectedRaces.add(race);
}
}
this.sailingService.trackWithTracTrac(regattaIdentifier, selectedRaces, liveURI, storedURI, courseDesignUpdateURI, trackWind, correctWind,
sailingService.trackWithTracTrac(regattaIdentifier, selectedRaces, liveURI, storedURI, courseDesignUpdateURI, trackWind, correctWind,
simulateWithStartTimeNow, tractracUsername, tractracPassword, new MarkedAsyncCallback<Void>() {
@Override
public void handleFailure(Throwable caught) {
@@ -737,39 +603,35 @@ public class TracTracEventManagementPanel extends AbstractEventManagementPanel {
}
private void updatePanelFromSelectedStoredConfiguration() {
int index = this.connectionsHistoryListBox.getSelectedIndex();
int index = connectionsHistoryListBox.getSelectedIndex();
if (index == -1)
return;
String configurationKey = this.connectionsHistoryListBox.getItemText(index);
TracTracConfigurationDTO config = this.previousConfigurations.get(configurationKey);
String configurationKey = connectionsHistoryListBox.getItemText(index);
TracTracConfigurationDTO config = previousConfigurations.get(configurationKey);
this.hostnameTextBox.setValue("");
this.eventNameTextBox.setValue("");
this.liveDataPortIntegerBox.setText("");
this.storedDataPortIntegerBox.setText("");
this.jsonURLTextBox.setValue(config.jsonURL);
this.liveURITextBox.setValue(config.liveDataURI);
this.storedURITextBox.setValue(config.storedDataURI);
this.courseDesignUpdateURITextBox.setValue(config.courseDesignUpdateURI);
this.tractracUsernameTextBox.setValue(config.tractracUsername);
this.tractracPasswordTextBox.setValue(config.tractracPassword);
jsonURLTextBox.setValue(config.jsonURL);
liveURITextBox.setValue(config.liveDataURI);
storedURITextBox.setValue(config.storedDataURI);
courseDesignUpdateURITextBox.setValue(config.courseDesignUpdateURI);
tractracUsernameTextBox.setValue(config.tractracUsername);
tractracPasswordTextBox.setValue(config.tractracPassword);
}
private void fillRaceListFromAvailableRacesApplyingFilter(String text) {
List<String> wordsToFilter = Arrays.asList(text.split(" "));
List<TracTracRaceRecordDTO> races = this.raceList.getList();
List<TracTracRaceRecordDTO> races = raceList.getList();
races.clear();
for (TracTracRaceRecordDTO race : this.availableTracTracRaces) {
for (TracTracRaceRecordDTO race : availableTracTracRaces) {
if (textContainsStringsToCheck(wordsToFilter, race.regattaName, race.name)) {
races.add(race);
}
}
// now sort again according to selected criterion
ColumnSortEvent.fire(this.racesTable, this.racesTable.getColumnSortList());
ColumnSortEvent.fire(racesTable, racesTable.getColumnSortList());
}
}
@@ -275,7 +275,7 @@ public class DetailTypeFormatter {
case RACE_TIME_SINCE_LAST_POSITION_FIX_IN_SECONDS:
return stringMessages.timeSinceLastPositionFixTooltip();
case RACE_TRACKING_QUALITY:
return "Tracking Quality";
return stringMessages.trackingQuality();
}
return "";
@@ -585,7 +585,7 @@ public interface StringMessages extends Messages {
String enableRaceFilter();
String raceStatusColumn();
String loading();
String showHiddenRaces();
String racesWithHiddenState();
String selectedCompetitors();
String mediaDateFormatError(String expectedTimeFormat);
String filterNothing();
@@ -745,4 +745,5 @@ public interface StringMessages extends Messages {
String polarDiagramButton();
String timeSinceLastPositionFix();
String timeSinceLastPositionFixTooltip();
String trackingQuality();
}
@@ -587,7 +587,7 @@ disableRaceFilter=Disable filter
enableRaceFilter=Enable filter
raceStatusColumn=Race Status
loading=Loading (on a slow internet connection this can take some minutes)...
showHiddenRaces=Show HIDDEN races
racesWithHiddenState=Races with state HIDDEN
mediaDateFormatError=Invalid date format. Use: {0}
selectedCompetitors=Selected competitors
filterNothing=Filter nothing
@@ -739,3 +739,4 @@ deselectAll=Deselect all
polarDiagramButton=Polar Diagram
timeSinceLastPositionFix=Last GPS
timeSinceLastPositionFixTooltip=Time since last received GPS position
trackingQuality=Tracking quality
@@ -586,7 +586,7 @@ disableRaceFilter=Deaktiviere Filter
enableRaceFilter=Aktiviere Filter
raceStatusColumn=Renn-Status
loading=Lade...
showHiddenRaces=Rennen im Status HIDDEN anzeigen
racesWithHiddenState=Rennen mit Status HIDDEN
selectedCompetitors=Ausgewählte Teilnehmer
filterNothing=Nichts filtern
topNCompetitorsByRaceRank=Wettfahrt Top {0}
@@ -735,3 +735,4 @@ deselectAll=Alle deselektieren
polarDiagramButton=Polardiagramm
timeSinceLastPositionFix=Letztes GPS
timeSinceLastPositionFixTooltip=Zeit seit der letzten empfangenen GPS-Position
trackingQuality=Tracking-Qualität
@@ -867,7 +867,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
result.put(DetailType.RACE_TIME_SINCE_LAST_POSITION_FIX_IN_SECONDS,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_TIME_SINCE_LAST_POSITION_FIX_IN_SECONDS,
new RaceTimeSinceLastPositionFixInSeconds(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
result.put(DetailType.RACE_TRACKING_QUALITY, new TrackingQualityColumn(stringMessages.rankGain(), new RaceTrackingQuality(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
result.put(DetailType.RACE_TRACKING_QUALITY, new TrackingQualityColumn(stringMessages.trackingQuality(), new RaceTrackingQuality(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE));
result.put(DetailType.RACE_DISTANCE_TRAVELED,
new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TRAVELED, new RaceDistanceTraveledInMeters(),
@@ -58,7 +58,6 @@ public class LeaderboardSettingsFactory {
legDetails.add(DetailType.ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS);
legDetails.add(DetailType.RANK_GAIN);
List<DetailType> raceDetails = new ArrayList<DetailType>();
raceDetails.add(DetailType.RACE_TIME_SINCE_LAST_POSITION_FIX_IN_SECONDS);
raceDetails.add(DetailType.RACE_DISTANCE_TRAVELED);
raceDetails.add(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
raceDetails.add(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS);
@@ -41,7 +41,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO;
import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO.ScoreCorrectionEntryDTO;
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 RegExp sailIdPattern = RegExp.compile("^([A-Z][A-Z][A-Z])\\s*[^0-9]*([0-9]*)$");
private final LeaderboardDTO leaderboard;
private final Map<CompetitorDTO, String> defaultOfficialSailIDsForCompetitors;
@@ -208,11 +208,14 @@ public class MatchAndApplyScoreCorrectionsDialog extends DataEntryDialog<BulkSco
*/
private String canonicalizeSailID(String sailID, String defaultNationality) {
String result = null;
MatchResult m = p.exec(sailID.trim());
if (p.test(sailID.trim())) {
MatchResult m = sailIdPattern.exec(sailID.trim());
if (sailIdPattern.test(sailID.trim())) {
String iocCode = m.getGroup(1);
if (iocCode != null) {
iocCode = iocCode.toUpperCase();
}
if (defaultNationality != null && (iocCode == null || iocCode.trim().length() == 0)) {
iocCode = defaultNationality;
iocCode = defaultNationality.toUpperCase();
}
if (iocCode != null && iocCode.trim().length() > 0) {
String number = m.getGroup(2);
@@ -73,8 +73,13 @@ public class ResultSelectionAndApplyDialog extends DataEntryDialog<Triple<String
}
});
scoreCorrectionProviderListBox.addItem("Please select a result import provider...");
List<String> sortedProviderNames = new ArrayList<String>();
for(String providerName: scoreCorrectionProviderNames) {
sortedProviderNames.add(providerName);
}
Collections.sort(sortedProviderNames);
scoreCorrectionProviderListBox.addItem("Please select a result import provider...");
for(String providerName: sortedProviderNames) {
scoreCorrectionProviderListBox.addItem(providerName);
}
}
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.ui.regattaoverview;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
@@ -45,6 +46,7 @@ import com.sap.sailing.domain.common.NauticalSide;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.domain.common.impl.NaturalComparator;
import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.gwt.ui.client.AnchorCell;
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
@@ -251,7 +253,16 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
}
};
circleColumn.setSortable(true);
final List<RaceLogRaceStatus> raceLogStatusList = Arrays.asList(RaceLogRaceStatus.values());
regattaOverviewListHandler.setComparator(circleColumn, new Comparator<RegattaOverviewEntryDTO>() {
@Override
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return raceLogStatusList.indexOf(left.raceInfo.lastStatus) -
raceLogStatusList.indexOf(right.raceInfo.lastStatus);
}
});
TextColumn<RegattaOverviewEntryDTO> courseAreaColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
@@ -327,6 +338,13 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
return result;
}
};
raceNameColumn.setSortable(true);
regattaOverviewListHandler.setComparator(raceNameColumn, new Comparator<RegattaOverviewEntryDTO>() {
@Override
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return new NaturalComparator().compare(left.raceInfo.raceName, right.raceInfo.raceName);
}
});
TextColumn<RegattaOverviewEntryDTO> raceStartTimeColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@Override
@@ -441,6 +459,13 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
return lastUpdateTime;
}
};
lastUpdateColumn.setSortable(true);
regattaOverviewListHandler.setComparator(lastUpdateColumn, new Comparator<RegattaOverviewEntryDTO>() {
@Override
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
return left.raceInfo.lastUpdateTime.compareTo(right.raceInfo.lastUpdateTime);
}
});
lastUpdateColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
TextColumn<RegattaOverviewEntryDTO> raceAdditionalInformationColumn = new TextColumn<RegattaOverviewEntryDTO>() {
@@ -53,4 +53,5 @@
<source path='shared'/>
<source path='test'/>
<source path='actions'/>
<source path='simulator'/>
</module>
@@ -37,4 +37,5 @@
<source path='shared'/>
<source path='common'/>
<source path='actions'/>
<source path='simulator'/>
</module>
@@ -37,4 +37,5 @@
<source path='shared'/>
<source path='actions'/>
<source path='masterdataimport'/>
<source path='simulator'/>
</module>
@@ -17,6 +17,7 @@
<source path='common' />
<source path='actions' />
<source path='masterdataimport'/>
<source path='simulator'/>
<entry-point class="com.sap.sailing.gwt.ui.polarsheets.PolarSheetsEntryPoint">
</entry-point>
@@ -37,4 +37,5 @@
<source path='shared'/>
<source path='actions'/>
<source path='masterdataimport'/>
<source path='simulator'/>
</module>
@@ -48,4 +48,5 @@
<source path='shared'/>
<source path='test'/>
<source path='actions'/>
<source path='simulator'/>
</module>
@@ -41,4 +41,5 @@
<source path='test'/>
<source path='actions'/>
<source path='masterdataimport'/>
<source path='simulator'/>
</module>
@@ -39,4 +39,5 @@
<source path='common'/>
<source path='actions'/>
<source path='masterdataimport'/>
<source path='simulator'/>
</module>
@@ -32,4 +32,5 @@
<source path='usermanagement'/>
<source path='shared'/>
<source path='actions'/>
<source path='simulator'/>
</module>
@@ -25,7 +25,7 @@ public class Manage2SailEventResultsParser {
public EventResultDescriptor getEventResult(InputStream is) throws IOException {
EventResultDescriptor result = null;
try {
JSONObject jsonRoot = (JSONObject) new JSONParser().parse(new InputStreamReader(is));
JSONObject jsonRoot = (JSONObject) new JSONParser().parse(new InputStreamReader(is, "UTF-8"));
result = new EventResultDescriptor();
result.setId((String) jsonRoot.get("Id"));
result.setIsafId((String) jsonRoot.get("IsafId"));
@@ -58,10 +58,14 @@ public class SeriesJsonSerializer implements JsonSerializer<Series> {
raceColumnJson.put("isLive", trackedRace.isLive(MillisecondsTimePoint.now()));
raceColumnJson.put("isTracked", true);
raceColumnJson.put("trackedRaceName", trackedRace.getRace().getName());
raceColumnJson.put("hasGpsData", trackedRace.hasGPSData());
raceColumnJson.put("hasWindData", trackedRace.hasWindData());
} else {
raceColumnJson.put("isLive", false);
raceColumnJson.put("isTracked", false);
raceColumnJson.put("trackedRaceName", null);
raceColumnJson.put("hasGpsData", false);
raceColumnJson.put("hasWindData", false);
}
racesPerFleetJson.add(raceColumnJson);
}
@@ -137,11 +137,13 @@ public class LeaderboardMasterDataJsonSerializer implements JsonSerializer<Leade
private JSONArray createRaceLogEventsForFleet(RaceColumn raceColumn, Fleet fleet) {
JSONArray array = new JSONArray();
RaceLog raceLog = raceColumn.getRaceLog(fleet);
raceLog.lockForRead();
for (RaceLogEvent event : raceLog.getFixes()) {
array.add(raceLogEventSerializer.serialize(event));
if (raceLog != null) {
raceLog.lockForRead();
for (RaceLogEvent event : raceLog.getFixes()) {
array.add(raceLogEventSerializer.serialize(event));
}
raceLog.unlockAfterRead();
}
raceLog.unlockAfterRead();
return array;
}
@@ -57,7 +57,7 @@ public class LeaderboardGroupJsonGetServlet extends AbstractJsonHttpServlet {
jsonLeaderboardEntries.add(jsonLeaderboard);
SettableScoreCorrection scoreCorrection = leaderboard.getScoreCorrection();
if(scoreCorrection != null) {
if (scoreCorrection != null) {
jsonLeaderboard.put("scoringComment", scoreCorrection.getComment());
TimePoint lastUpdateTimepoint = scoreCorrection.getTimePointOfLastCorrectionsValidity();
jsonLeaderboard.put("lastScoringUpdate", lastUpdateTimepoint != null ? lastUpdateTimepoint.asDate().toString(): null);
@@ -66,16 +66,14 @@ public class LeaderboardGroupJsonGetServlet extends AbstractJsonHttpServlet {
jsonLeaderboard.put("lastScoringUpdate", null);
}
if(isRegattaLeaderboard) {
if (isRegattaLeaderboard) {
RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard;
Regatta regatta = regattaLeaderboard.getRegatta();
jsonLeaderboard.put("scoringScheme", leaderboard.getScoringScheme().getType());
jsonLeaderboard.put("regattaName", regatta.getName());
} else {
jsonLeaderboard.put("scoringScheme", leaderboard.getScoringScheme().getType());
jsonLeaderboard.put("regattaName", null);
JSONArray jsonSeriesEntries = new JSONArray();
jsonLeaderboard.put("series", jsonSeriesEntries);
@@ -84,32 +82,32 @@ public class LeaderboardGroupJsonGetServlet extends AbstractJsonHttpServlet {
jsonSeriesEntries.add(jsonSeries);
jsonSeries.put("name", LeaderboardNameConstants.DEFAULT_SERIES_NAME);
jsonSeries.put("isMedalSeries", null);
JSONArray jsonFleetsEntries = new JSONArray();
jsonSeries.put("fleets", jsonFleetsEntries);
Fleet fleet = leaderboard.getFleet(LeaderboardNameConstants.DEFAULT_FLEET_NAME);
if(fleet != null) {
if (fleet != null) {
JSONObject jsonFleet = new JSONObject();
jsonFleet.put("name", fleet.getName());
jsonFleet.put("color", fleet.getColor() != null ? fleet.getColor().getAsHtml() : null);
jsonFleet.put("ordering", fleet.getOrdering());
jsonFleetsEntries.add(jsonFleet);
JSONArray jsonRacesEntries = new JSONArray();
jsonFleet.put("races", jsonRacesEntries);
for(RaceColumn raceColumn: leaderboard.getRaceColumns()) {
for (RaceColumn raceColumn: leaderboard.getRaceColumns()) {
JSONObject jsonRaceColumn = new JSONObject();
jsonRaceColumn.put("name", raceColumn.getName());
jsonRaceColumn.put("isMedalRace" , raceColumn.isMedalRace());
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
if(trackedRace != null) {
if (trackedRace != null) {
jsonRaceColumn.put("isTracked", true);
jsonRaceColumn.put("trackedRaceName", trackedRace.getRace().getName());
jsonRaceColumn.put("hasGpsData", trackedRace.hasGPSData());
jsonRaceColumn.put("hasWindData", trackedRace.hasWindData());
} else {
jsonRaceColumn.put("isTracked", false);
jsonRaceColumn.put("trackedRaceName", null);
jsonRaceColumn.put("hasGpsData", false);
jsonRaceColumn.put("hasWindData", false);
}
jsonRacesEntries.add(jsonRaceColumn);
}
@@ -203,12 +203,13 @@ public class LeaderboardJsonGetServlet extends AbstractJsonHttpServlet implement
TimePoint resultTimePoint = calculateTimePointForResultState(leaderboard, resultState);
StringBuffer jsonLeaderboardAsString;
if (resultTimePoint != null) {
Triple<TimePoint, ResultStates, Integer> resultStateAndTimePoint = new Triple<>(resultTimePoint, resultState, maxCompetitorsCount);
Triple<TimePoint, ResultStates, Integer> resultStateAndTimePointAndMaxCompetitorsCount =
new Triple<>(resultTimePoint, resultState, maxCompetitorsCount);
if (useCache) {
jsonLeaderboardAsString = getLeaderboardJsonFromCacheOrCompute(leaderboard, resultStateAndTimePoint, requestTimePoint);
jsonLeaderboardAsString = getLeaderboardJsonFromCacheOrCompute(leaderboard, resultStateAndTimePointAndMaxCompetitorsCount);
} else {
StringWriter sw = new StringWriter();
computeLeaderboardJson(leaderboard, resultStateAndTimePoint).writeJSONString(sw);
computeLeaderboardJson(leaderboard, resultStateAndTimePointAndMaxCompetitorsCount).writeJSONString(sw);
jsonLeaderboardAsString = sw.getBuffer();
}
} else {
@@ -236,22 +237,24 @@ public class LeaderboardJsonGetServlet extends AbstractJsonHttpServlet implement
}
private StringBuffer getLeaderboardJsonFromCacheOrCompute(Leaderboard leaderboard,
Triple<TimePoint, ResultStates, Integer> timePointAndResultStateAndMaxCompetitorsCount, final TimePoint requestTimePoint) throws NoWindException {
Triple<TimePoint, ResultStates, Integer> timePointAndResultStateAndMaxCompetitorsCount) throws NoWindException {
final StringBuffer result;
Map<Triple<TimePoint, ResultStates, Integer>, StringBuffer> cacheEntry = cache.get(leaderboard, /* waitForLatest */ false);
if (cacheEntry == null || !cacheEntry.containsKey(timePointAndResultStateAndMaxCompetitorsCount)) {
cacheMisses++;
LinkedHashSet<Triple<TimePoint, ResultStates, Integer>> timePointsAndResultStates = new LinkedHashSet<>();
timePointsAndResultStates.add(timePointAndResultStateAndMaxCompetitorsCount);
cache.triggerUpdate(leaderboard, new LeaderboardJsonCacheUpdateInterval(timePointsAndResultStates));
LinkedHashSet<Triple<TimePoint, ResultStates, Integer>> timePointsAndResultStatesAndMaxCompetitorsCount = new LinkedHashSet<>();
timePointsAndResultStatesAndMaxCompetitorsCount.add(timePointAndResultStateAndMaxCompetitorsCount);
cache.triggerUpdate(leaderboard, new LeaderboardJsonCacheUpdateInterval(timePointsAndResultStatesAndMaxCompetitorsCount));
// now wait for this entry to be computed
cacheEntry = cache.get(leaderboard, /* waitForLatest */ true);
StringBuffer jsonObjectAsString = cacheEntry.get(timePointAndResultStateAndMaxCompetitorsCount);
return jsonObjectAsString;
result = jsonObjectAsString;
} else {
cacheHits++;
result = cacheEntry.get(timePointAndResultStateAndMaxCompetitorsCount);
}
logger.finest(this+" cache hits/misses: "+cacheHits+"/"+cacheMisses);
return cacheEntry.get(timePointAndResultStateAndMaxCompetitorsCount);
return result;
}
private JSONObject computeLeaderboardJson(Leaderboard leaderboard,
@@ -41,7 +41,7 @@
</tr>
<tr>
<td>Example:</td>
<td>http://www.sapsailing.com/sailingserver/leaderboardgroup?leaderboardGroupName=ESS</td>
<td>http://tw2013.sapsailing.com/sailingserver/leaderboardgroup?leaderboardGroupName=Travem%C3%BCnder%20Woche%202013</td>
</tr>
</table>
@@ -1 +1 @@
{"name":"Extreme Sailing Series","description":"Extreme Sailing Series 2012","timepoint":"2013-03-22T11:35:59.772+0100","leaderboards":[{"name":"Extreme 40 Rio","scoringComment":null,"lastScoringUpdate":null,"scoringScheme":"HIGH_POINT","seriesName":"Default","fleets":[{"name":"Default","color":null,"ordering":0,"races":[{"name":"R1","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R2","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R3","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R4","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R5","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R6","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R7","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R8","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R9","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R10","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R11","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R12","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R13","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R14","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R15","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R16","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R17","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R18","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R19","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R20","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R21","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R22","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R23","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R24","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R25","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R26","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R27","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R28","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R29","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R30","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null}]}]},{"name":"Extreme 40 Muscat","scoringComment":null,"lastScoringUpdate":null,"scoringScheme":"HIGH_POINT_ESS_OVERALL","seriesName":"Default","fleets":[{"name":"Default","color":null,"ordering":0,"races":[{"name":"R1","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R2","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R3","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R4","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R5","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R6","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R7","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R8","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R9","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R10","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R11","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R12","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R13","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R14","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R15","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R16","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R17","isMedalRace":false,"isTracked":false,"trackedRaceName":null,"regattaName":null},{"name":"R18","isMedalRLine truncated
{"name":"Travemünder Woche 2013","description":"Travemünder Woche 2013 - All tracked classes","timepoint":"2013-07-24T16:08:54.823+0200","leaderboards":[{"name":"TW 2013 (Finn)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":"Preliminary results after race 8; protests may be pending","lastScoringUpdate":"Tue Jul 23 16:20:16 CEST 2013","scoringScheme":"LOW_POINT","regattaName":"TW 2013 (Finn)"},{"name":"TW 2013 (Formula 16)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":"Preliminary results after R11; protests may be pending","lastScoringUpdate":"Wed Jul 24 14:57:17 CEST 2013","scoringScheme":"LOW_POINT","regattaName":"TW 2013 (Formula 16)"},{"name":"TW 2013 (Hobie Tiger)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":"Preliminary results after race 7; tracking results for race 8","lastScoringUpdate":"Wed Jul 24 15:02:01 CEST 2013","scoringScheme":"LOW_POINT","regattaName":"TW 2013 (Hobie Tiger)"},{"name":"TW 2013 (Hobie Wild Cat)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":null,"lastScoringUpdate":null,"scoringScheme":"LOW_POINT","regattaName":"TW 2013 (Hobie Wild Cat)"},{"name":"TW 2013 (Tornado)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":null,"lastScoringUpdate":null,"scoringScheme":"LOW_POINT","regattaName":"TW 2013 (Tornado)"},{"name":"TW 2013 (505)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":null,"lastScoringUpdate":null,"scoringScheme":"LOW_POINT","regattaName":"TW 2013 (505)"},{"name":"TW 2013 (A-Catamaran)","displayName":null,"isMetaLeaderboard":false,"isRegattaLeaderboard":true,"scoringComment":null,"lastScoringUpdate":null,"scoringScheme":"LOW_POINT","regattaName":"TW 2013 (A-Catamaran)"}]}
@@ -41,7 +41,7 @@
</tr>
<tr>
<td>Example:</td>
<td>http://www.sapsailing.com/sailingserver/regatta?name=Extreme40%20Rio</td>
<td>http://tw2013.sapsailing.com/sailingserver/regatta?name=TW%202013%20%28Hobie%20Tiger%29</td>
</tr>
</table>
@@ -1 +1 @@
{"name":"KW 2013 49er (49er)","scoringSystem":"LOW_POINT","boatclass":"49er","series":[{"name":"Qualification","fleets":[{"name":"Blue","ordering":0,"color":{"r":39,"g":140,"b":194}},{"name":"Red","ordering":0,"color":{"r":232,"g":74,"b":26}}],"races":["Q1","Q2","Q3"]},{"name":"Finals","fleets":[{"name":"Gold","ordering":1,"color":{"r":222,"g":138,"b":46}},{"name":"Silver","ordering":2,"color":{"r":192,"g":192,"b":192}}],"races":["F1","F2"]},{"name":"Medal","fleets":[{"name":"Default","ordering":0}],"races":["M"]}]}
{"name":"TW 2013 (Hobie Tiger)","scoringSystem":"LOW_POINT","boatclass":"Hobie Tiger","series":[{"name":"Default","isMedalSeries":false,"startsWithZeroScore":false,"fleets":[{"name":"Default","ordering":0}],"races":["R1","R2","R3","R4","R5","R6","R7","R8","R9","R10","R11","R12","R13","R14","R15","R16","R17","R18"],"trackedRaces":{"fleets":[{"name":"Default","races":[{"name":"R1","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R2","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R3","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R4","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R5","isMedalRace":false,"isLive":false,"isTracked":true,"trackedRaceName":"Hobie Tiger - Race 5","hasGpsData":true,"hasWindData":true},{"name":"R6","isMedalRace":false,"isLive":false,"isTracked":true,"trackedRaceName":"Hobie Tiger - Race 6","hasGpsData":true,"hasWindData":true},{"name":"R7","isMedalRace":false,"isLive":true,"isTracked":true,"trackedRaceName":"Hobie Tiger - Race 7","hasGpsData":true,"hasWindData":true},{"name":"R8","isMedalRace":false,"isLive":false,"isTracked":true,"trackedRaceName":"Hobie Tiger - Race 8","hasGpsData":false,"hasWindData":false},{"name":"R9","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R10","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R11","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R12","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R13","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R14","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R15","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R16","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R17","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false},{"name":"R18","isMedalRace":false,"isLive":false,"isTracked":false,"trackedRaceName":null,"hasGpsData":false,"hasWindData":false}]}]}}]}
@@ -168,8 +168,7 @@ public abstract class AbstractDataRetriever implements DataRetriever {
Collections.<String> emptyList(),
new ArrayList<GpxPosition>());
TrackReader<E, F> trackReader = trackRetriever
.retrieveTrackReader(element);
TrackReader<E, F> trackReader = trackRetriever.retrieveTrackReader(element);
trackReader.getLocker().lock();
try {
Iterable<F> fixesIter = rawFixes ? trackReader
@@ -21,7 +21,7 @@ public class BouyDataRetriever extends AbstractDataRetriever {
TrackReaderRetriever<Mark, GPSFix> retriever = new TrackReaderRetriever<Mark, GPSFix>() {
@Override
public TrackReader<Mark, GPSFix> retrieveTrackReader(Mark e) {
return new GPSFixTrackReader<Mark, GPSFix>(
return new TrackReaderImpl<Mark, GPSFix>(
race.getOrCreateTrack(e));
}
};
@@ -22,7 +22,7 @@ public class CompetitorDataRetriever extends AbstractDataRetriever {
@Override
public TrackReader<Competitor, GPSFixMoving> retrieveTrackReader(
Competitor e) {
return new GPSFixTrackReader<Competitor, GPSFixMoving>(
return new TrackReaderImpl<Competitor, GPSFixMoving>(
race.getTrack(e));
}
};
@@ -1,48 +0,0 @@
package com.sap.sailing.server.trackfiles.impl;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.tracking.Track;
class GPSFixTrackReader<E, T extends Timed> implements
TrackReader<E, T>, IterableLocker {
private final Track<T> track;
GPSFixTrackReader(Track<T> track) {
this.track = track;
}
@Override
public void lock() {
track.lockForRead();
}
@Override
public void unlock() {
track.unlockAfterRead();
}
@Override
public Iterable<T> getTrack(E e) {
return track.getFixes();
}
@Override
public Iterable<T> getRawTrack(E e) {
return track.getRawFixes();
}
@Override
public IterableLocker getLocker() {
return new IterableLocker() {
@Override
public void lock() {
track.lockForRead();
}
@Override
public void unlock() {
track.unlockAfterRead();
}
};
}
}
@@ -4,9 +4,9 @@ import com.sap.sailing.domain.base.Timed;
interface TrackReader<E, T extends Timed> {
Iterable<T> getRawTrack(E e);
Iterable<T> getRawTrack(E e);
Iterable<T> getTrack(E e);
Iterable<T> getTrack(E e);
IterableLocker getLocker();
IterableLocker getLocker();
}
@@ -0,0 +1,47 @@
package com.sap.sailing.server.trackfiles.impl;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.tracking.Track;
class TrackReaderImpl<E, T extends Timed> implements TrackReader<E, T>, IterableLocker {
private final Track<T> track;
TrackReaderImpl(Track<T> track) {
this.track = track;
}
@Override
public void lock() {
track.lockForRead();
}
@Override
public void unlock() {
track.unlockAfterRead();
}
@Override
public Iterable<T> getTrack(E e) {
return track.getFixes();
}
@Override
public Iterable<T> getRawTrack(E e) {
return track.getRawFixes();
}
@Override
public IterableLocker getLocker() {
return new IterableLocker() {
@Override
public void lock() {
track.lockForRead();
}
@Override
public void unlock() {
track.unlockAfterRead();
}
};
}
}
@@ -3,5 +3,5 @@ package com.sap.sailing.server.trackfiles.impl;
import com.sap.sailing.domain.base.Timed;
interface TrackReaderRetriever<E, T extends Timed> {
TrackReader<E, T> retrieveTrackReader(E e);
TrackReader<E, T> retrieveTrackReader(E e);
}
@@ -2,11 +2,13 @@ package com.sap.sailing.server.trackfiles.impl;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import slash.navigation.gpx.GpxRoute;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.impl.WindSourceImpl;
import com.sap.sailing.domain.common.trackfiles.TrackFilesFormat;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind;
@@ -20,16 +22,14 @@ public class WindDataRetriever extends AbstractDataRetriever {
TrackReaderRetriever<WindSource, Wind> retriever = new TrackReaderRetriever<WindSource, Wind>() {
@Override
public TrackReader<WindSource, Wind> retrieveTrackReader(
WindSource e) {
return new GPSFixTrackReader<WindSource, Wind>(
race.getOrCreateWindTrack(e));
public TrackReader<WindSource, Wind> retrieveTrackReader(WindSource e) {
return new TrackReaderImpl<WindSource, Wind>(race.getOrCreateWindTrack(e));
}
};
return getRoutes(race, dataBeforeAfter, rawFixes,
WindToGpxPosition.INSTANCE,
race.getWindSources(WindSourceType.TRACK_BASED_ESTIMATION),
Collections.<WindSource> singleton(new WindSourceImpl(WindSourceType.COMBINED)),
new NameReader<WindSource>() {
@Override
public String getName(WindSource s) {
+9 -6
View File
@@ -39,7 +39,15 @@
-->
<!-- Uncomment the following in case there are upcoming and add the timeBar plus raceSection -->
<!--
<h2 class='articleSubheadline'>Upcoming</h2>
<div class="timeBar">
</div>
<br/>
-->
<h2 class='articleSubheadline'>2013</h2>
<div class="timeBar">
<div class='raceSection'>
<h5 class='date'>
@@ -62,12 +70,7 @@
<a href='http://www.travemuender-woche.com/' target='_blank'>Official website</a>
</div>
</div>
</div>
<br/>
<h2 class='articleSubheadline'>2013</h2>
<div class="timeBar">
<div class='raceSection'>
<h5 class='date'>
July 3 - 7
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sap.sailing.racecommittee.app"
android:versionCode="1"
android:versionName="1.0" >
android:versionCode="2"
android:versionName="2.1 - Kulig" >
<uses-sdk
android:maxSdkVersion="17"
@@ -67,6 +67,10 @@
android:name=".ui.activities.SettingsActivity"
android:screenOrientation="landscape" >
</activity>
<activity
android:name=".ui.activities.SystemInformationActivity"
android:screenOrientation="landscape" >
</activity>
<service
android:name="com.sap.sailing.racecommittee.app.services.RaceStateService"
@@ -41,31 +41,42 @@
android:layout_height="wrap_content"
android:text="FooRace"
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabel" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/courseInfoHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:text="FooRaceInfo"
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabelLink" />
<TextView
android:id="@+id/courseInfoHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:text="FooRaceInfo"
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabelLink" />
<TextView
android:id="@+id/windInfoHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:text="WindInfo"
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabelLink" />
<TextView
android:id="@+id/windInfoHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:text="WindInfo"
android:textAppearance="@style/TextAppearance.Welter.BigTitleLabelLink" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="horizontal" >
<Button
android:id="@+id/btnResetRace"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/reset_race" />
</LinearLayout>
<LinearLayout
@@ -75,12 +86,7 @@
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:orientation="horizontal" >
<Button
android:id="@+id/btnResetRace"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/reset_race" />
<TextView
android:id="@+id/currentTimeLabel"
android:layout_width="wrap_content"
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp" >
<TextView
android:id="@+id/system_information_application_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/application_information"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/system_information_application_version_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="@string/application_version"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/system_information_application_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/empty" />
<TextView
android:id="@+id/system_information_application_install_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="@string/application_install_date"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/system_information_application_install"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/empty" />
<TextView
android:id="@+id/system_information_persistence_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:text="@string/persistence_information"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/system_information_persistence_status_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:text="@string/empty"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/system_information_persistence_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/empty" />
</LinearLayout>
@@ -12,4 +12,8 @@
android:icon="@drawable/settings_grey"
android:title="@string/options_menu_settings"
android:showAsAction="" />
<item android:id="@+id/options_menu_info"
android:icon="@drawable/ic_menu_info_details"
android:title="@string/options_menu_info"
android:showAsAction="" />
</menu>
@@ -173,6 +173,7 @@
<string name="settings_advanced_min_rounds_description">Select the minimum number of rounds per course</string>
<string name="settings_advanced_min_rounds_header">Minimum rounds per course</string>
<string name="options_menu_live">Connection Information</string>
<string name="options_menu_info">Expert</string>
<string name="options_menu_wind">Enter Wind Data</string>
<string name="options_menu_reload">Reload</string>
<string name="options_menu_settings">Settings</string>
@@ -231,4 +232,11 @@
<string name="login_onto_course_area">Login onto course area</string>
<string name="please_select_a_login_type">Please select a login type.</string>
<string name="application_information">Application Information</string>
<string name="application_version">Version</string>
<string name="application_install_date">Install Date</string>
<string name="persistence_information">Persistence Status</string>
<string name="generic_error">Error</string>
</resources>
@@ -7,8 +7,6 @@ public class AppConstants {
public static final boolean IS_DATA_OFFLINE = false;
public final static String ApplicationVersion = "2.0 Beta 1 - Jumbotron";
// Intent extra fields
public final static String COURSE_AREA_UUID_KEY = "courseUuid";
public final static String RACE_ID_KEY = "raceUuid";
@@ -8,6 +8,7 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import com.sap.sailing.domain.common.racelog.StartProcedureType;
import com.sap.sailing.racecommittee.app.domain.coursedesign.BoatClassType;
import com.sap.sailing.racecommittee.app.domain.coursedesign.CourseLayouts;
import com.sap.sailing.racecommittee.app.domain.coursedesign.NumberOfRounds;
@@ -32,6 +33,7 @@ public class AppPreferences {
private final static String PREFERENCE_MANAGED_COURSE_AREAS = "courseAreasPref";
private final static String PREFERENCE_MIN_ROUNDS = "minRoundsPreference";
private final static String PREFERENCE_MAX_ROUNDS = "maxRoundsPreference";
private final static String PREFERENCE_DEFAULT_START_PROCEDURE_TYPE = "defaultStartProcedureType";
public static BoatClassType getBoatClass(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
@@ -176,4 +178,11 @@ public class AppPreferences {
}
return minRounds;
}
public static StartProcedureType getDefaultStartProcedureType(Context context) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
String defaultStartProcedureType = sp.getString(PREFERENCE_DEFAULT_START_PROCEDURE_TYPE, "RRS26");
StartProcedureType type = StartProcedureType.valueOf(defaultStartProcedureType);
return type;
}
}
@@ -141,7 +141,7 @@ public class OnlineDataManager extends DataManager {
}
SharedDomainFactory domainFactory = DomainFactoryImpl.INSTANCE;
JsonDeserializer<BoatClass> boatClassDeserializer = new BoatClassJsonDeserializer(domainFactory);
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(new RaceGroupDeserializer(
DataParser<Collection<ManagedRace>> parser = new ManagedRacesDataParser(context, new RaceGroupDeserializer(
boatClassDeserializer, new SeriesWithRowsDeserializer(new RaceRowDeserializer(new FleetDeserializer(
new ColorDeserializer()), new RaceCellDeserializer(
new RaceLogDeserializer(RaceLogEventDeserializer.create(domainFactory)))))));
@@ -8,6 +8,8 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import android.content.Context;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.SeriesBase;
import com.sap.sailing.domain.base.racegroup.RaceCell;
@@ -16,6 +18,7 @@ import com.sap.sailing.domain.base.racegroup.RaceRow;
import com.sap.sailing.domain.base.racegroup.SeriesWithRows;
import com.sap.sailing.domain.common.racelog.StartProcedureType;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.racecommittee.app.AppPreferences;
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
import com.sap.sailing.racecommittee.app.domain.impl.FleetIdentifierImpl;
import com.sap.sailing.racecommittee.app.domain.impl.ManagedRaceIdentifierImpl;
@@ -27,9 +30,11 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
// private static final String TAG = ManagedRacesDataParser.class.getName();
private JsonDeserializer<RaceGroup> deserializer;
private Context context;
public ManagedRacesDataParser(JsonDeserializer<RaceGroup> deserializer) {
public ManagedRacesDataParser(Context context, JsonDeserializer<RaceGroup> deserializer) {
this.deserializer = deserializer;
this.context = context;
}
public Collection<ManagedRace> parse(Reader reader) throws Exception {
@@ -61,8 +66,9 @@ public class ManagedRacesDataParser implements DataParser<Collection<ManagedRace
private ManagedRace createManagedRace(RaceGroup raceGroup, SeriesBase series, Fleet fleet, String name,
RaceLog raceLog) {
StartProcedureType startType = AppPreferences.getDefaultStartProcedureType(context);
return new ManagedRaceImpl(new ManagedRaceIdentifierImpl(name,
new FleetIdentifierImpl(fleet, series, raceGroup)), StartProcedureType.RRS26, raceLog);
new FleetIdentifierImpl(fleet, series, raceGroup)), startType, raceLog);
}
@@ -93,6 +93,10 @@ public abstract class BaseActivity extends Activity {
ExLog.i(TAG, "Clicked LIVE.");
Toast.makeText(this, getLiveIconText(), Toast.LENGTH_LONG).show();
return true;
case R.id.options_menu_info:
ExLog.i(TAG, "Clicked INFO.");
fadeActivity(SystemInformationActivity.class, false);
return true;
case android.R.id.home:
ExLog.i(TAG, "Clicked HOME.");
return onHomeClicked();
@@ -0,0 +1,54 @@
package com.sap.sailing.racecommittee.app.ui.activities;
import java.util.Date;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.widget.TextView;
import com.sap.sailing.racecommittee.app.R;
public class SystemInformationActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.system_information_view);
setupVersionView();
setupInstalledView();
}
private void setupVersionView() {
TextView versionView = (TextView) findViewById(R.id.system_information_application_version);
PackageInfo info = getPackageInfo();
if (info == null) {
versionView.setText(getString(R.string.generic_error));
} else {
versionView.setText(String.format("%s (Code %s)", info.versionName, info.versionCode));
}
}
private void setupInstalledView() {
TextView installView = (TextView) findViewById(R.id.system_information_application_install);
PackageInfo info = getPackageInfo();
if (info == null) {
installView.setText(getString(R.string.generic_error));
} else {
Date installDate = new Date(info.lastUpdateTime);
installView.setText(String.format("%s - %s", DateFormat.getLongDateFormat(this).format(installDate),
DateFormat.getTimeFormat(this).format(installDate)));
}
}
private PackageInfo getPackageInfo() {
try {
return getPackageManager().getPackageInfo(getPackageName(), 0);
} catch (NameNotFoundException e) {
return null;
}
}
}
@@ -20,8 +20,8 @@ public class CourseAreaArrayAdapter extends NamedArrayAdapter<CourseArea> {
return true;
} else if (AppPreferences.getManagedCourseAreaNames(getContext()).contains("*")) {
return true;
} else
} else {
return false;
}
}
}
@@ -94,7 +94,7 @@ public class RaceInfoFragment extends RaceFragment implements RaceStateChangedLi
});
Button resetButton = ((Button) getView().findViewById(R.id.btnResetRace));
Button resetButton = (Button) getView().findViewById(R.id.btnResetRace);
resetButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
ExLog.i(TAG, "Reset race button pressed");
@@ -202,11 +202,9 @@ public class RaceInfoFragment extends RaceFragment implements RaceStateChangedLi
if (getRace().getState().getCourseDesign() != null) {
CourseBase courseDesign = getRace().getState().getCourseDesign();
if (courseDesign.getName() != null) {
if (Util.isEmpty(courseDesign.getWaypoints())) {
String courseName = courseDesign.getName();
courseInfoHeader.setText(String.format(getString(R.string.running_on_course), courseName));
} else if (Util.isEmpty(courseDesign.getWaypoints())) {
courseInfoHeader.setText(getString(R.string.running_on_unknown));
} else {
courseInfoHeader.setText(String.format(getString(R.string.course_design_number_waypoints),
Util.size(courseDesign.getWaypoints())));
@@ -1,9 +1,13 @@
package com.sap.sailing.racecommittee.app.ui.fragments.raceinfo;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.racecommittee.app.R;
import com.sap.sailing.racecommittee.app.logging.ExLog;
import com.sap.sailing.racecommittee.app.ui.fragments.dialogs.PositioningFragment;
public class EssFinishingRaceFragment extends FinishingRaceFragment {
@@ -36,4 +40,24 @@ public class EssFinishingRaceFragment extends FinishingRaceFragment {
}
return getString(R.string.empty);
}
protected void showRemoveBlueFlagDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(getActivity().getResources().getString(R.string.confirmation_blue_flag_remove))
.setCancelable(true)
.setPositiveButton(getActivity().getResources().getString(R.string.yes), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ExLog.i(ExLog.FLAG_BLUE_REMOVE, getRace().getId().toString(), getActivity());
getRace().getState().getStartProcedure().setFinished(MillisecondsTimePoint.now());
}
})
.setNegativeButton(getActivity().getResources().getString(R.string.no), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ExLog.i(ExLog.FLAG_BLUE_REMOVE_NO, getRace().getId().toString(), getActivity());
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
@@ -106,7 +106,7 @@ public class FinishingRaceFragment extends RaceFragment {
fragment.show(fragmentManager, "dialogNovemberMode");
}
private void showRemoveBlueFlagDialog() {
protected void showRemoveBlueFlagDialog() {
FragmentManager fragmentManager = getFragmentManager();
RaceDialogFragment fragment = new RaceFinishedTimeDialog();