Merge branch 'master' into bug3493

This commit is contained in:
Peter Siegmund committed 2016-03-09 12:18:22 +01:00
commit 6d6e4e23c9
71 files changed
+596 -322

No files matched your search

+3 -1
View File
@@ -36,8 +36,10 @@ start_servers() {
echo "Starting Java server \"$conf\"" >>/var/log/sailing.out
su - sailing -c "cd $SERVERS_DIR/$conf && ./start" 2>>/var/log/sailing.err >>/var/log/sailing.out
server_name="`echo $SERVER_NAME | tr [A-Z] [a-z]`"
echo "Appending macro invocation to $APACHE_CONFIG_DIR/001-events.conf to map internal IP $INSTANCE_INTERNAL_IP4 to plain server running $SERVER_PORT..." >>/var/log/sailing.out
echo "Use Plain-SSL ${INSTANCE_INTERNAL_IP4} 127.0.0.1 $SERVER_PORT" >>$APACHE_CONFIG_DIR/001-events.conf
echo "Appending macro invocation to $APACHE_CONFIG_DIR/001-events.conf to map ${server_name}.sapsailing.com to event with ID $EVENT_ID with server running on local port $SERVER_PORT..." >>/var/log/sailing.out
echo "Use Event ${server_name}.sapsailing.com \"$EVENT_ID\" 127.0.0.1 $SERVER_PORT" >>$APACHE_CONFIG_DIR/001-events.conf
echo "Use Event-SSL ${server_name}.sapsailing.com \"$EVENT_ID\" 127.0.0.1 $SERVER_PORT" >>$APACHE_CONFIG_DIR/001-events.conf
HTTP_LOGROTATE=/etc/logrotate.d/httpd
echo "Patching $HTTP_LOGROTATE so that old logs go to /var/log/old/$SERVER_NAME/$INSTANCE_IP4" >>/var/log/sailing.out
sed -i -e "s/\/var\/log\/old\/\([^/]*\)\/\([^/ ]*\)/\/var\/log\/old\/$SERVER_NAME\/$INSTANCE_IP4/" $HTTP_LOGROTATE
Binary file not shown.
@@ -27,6 +27,8 @@ import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
*/
public interface Series extends SeriesBase {
static public final String DEFAULT_NAME = "Default";
/**
* A series consists of one or more "race columns." Some people would just say "race," but we use the term "race" for
* something that has a single start time and start line; so if each fleet in a series gets their own start for
@@ -647,6 +647,9 @@ public class CandidateFinderImpl implements CandidateFinder {
}
pos.add(po);
}
if (pos.size() != 2){
return true;
}
Bearing diff1 = pos.get(0).getBearingGreatCircle(p)
.getDifferenceTo(pos.get(0).getBearingGreatCircle(pos.get(1)));
Bearing diff2 = pos.get(1).getBearingGreatCircle(p)
@@ -757,9 +760,7 @@ public class CandidateFinderImpl implements CandidateFinder {
Position portLinePosition = race.getOrCreateTrack(posLine.getA()).getEstimatedPosition(t, false);
Position starboardLinePosition = race.getOrCreateTrack(posLine.getB()).getEstimatedPosition(t, false);
distances.add((portLinePosition != null && starboardLinePosition != null) ? p.getDistanceToLine(
portLinePosition, starboardLinePosition) : portLinePosition != null ? p
.getDistance(portLinePosition) : starboardLinePosition != null ? p
.getDistance(portLinePosition) : null);
portLinePosition, starboardLinePosition) : null);
}
break;
case Offset:
@@ -863,6 +864,9 @@ public class CandidateFinderImpl implements CandidateFinder {
}
markPositions.add(estimatedMarkPosition);
}
if (markPositions.size() != 2){
return new Util.Pair<Mark, Mark>(null, null);
}
final List<Leg> legs = race.getRace().getCourse().getLegs();
final int indexOfWaypoint = race.getRace().getCourse().getIndexOfWaypoint(w);
if (indexOfWaypoint < 0) {
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.adminconsole;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -32,9 +33,8 @@ public abstract class AbstractLeaderboardDialog extends DataEntryDialog<Leaderbo
}
@Override
public void show() {
super.show();
nameTextBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return nameTextBox;
}
protected static ListBox createScoringSchemeListBox(DataEntryDialog<?> dialog, StringMessages stringMessages) {
@@ -55,12 +55,14 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
private final ListBox rankingMetricListBox;
protected final List<EventDTO> existingEvents;
private EventDTO defaultEvent;
public AbstractRegattaWithSeriesAndFleetsDialog(RegattaDTO regatta, Iterable<SeriesDTO> series, List<EventDTO> existingEvents,
public AbstractRegattaWithSeriesAndFleetsDialog(RegattaDTO regatta, Iterable<SeriesDTO> series, List<EventDTO> existingEvents, EventDTO correspondingEvent,
String title, String okButton, StringMessages stringMessages, Validator<T> validator, DialogCallback<T> callback) {
super(title, null, okButton, stringMessages.cancel(), validator, callback);
this.stringMessages = stringMessages;
this.regatta = regatta;
this.defaultEvent = correspondingEvent;
this.existingEvents = existingEvents;
rankingMetricListBox = createListBox(/* isMultipleSelect */ false);
for (RankingMetrics rankingMetricType : RankingMetrics.values()) {
@@ -198,9 +200,20 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
});
for (EventDTO event : sortedEvents) {
sailingEventsListBox.addItem(event.getName());
if (isCourseAreaInEvent(event, regatta.defaultCourseAreaUuid)) {
sailingEventsListBox.setSelectedIndex(sailingEventsListBox.getItemCount() - 1);
fillCourseAreaListBox(event);
if(defaultEvent != null){
if (defaultEvent.getName().equals(event.getName())){
sailingEventsListBox.setSelectedIndex(sailingEventsListBox.getItemCount() - 1);
fillCourseAreaListBox(event);
//select default course area, 2 elements as first is please select course area string
if (courseAreaListBox.getItemCount() == 2){
courseAreaListBox.setSelectedIndex(1);
}
}
} else {
if (isCourseAreaInEvent(event, regatta.defaultCourseAreaUuid)) {
sailingEventsListBox.setSelectedIndex(sailingEventsListBox.getItemCount() - 1);
fillCourseAreaListBox(event);
}
}
}
sailingEventsListBox.addChangeHandler(new ChangeHandler() {
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.adminconsole;
import java.util.Date;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
@@ -115,8 +116,7 @@ public class AddWindFixDialog extends DataEntryDialog<WindDTO> {
}
@Override
public void show() {
super.show();
speedInKnotsBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return speedInKnotsBox;
}
}
@@ -92,7 +92,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
leaderboardsDisplayers = new HashSet<>();
leaderboardGroupsDisplayers = new HashSet<>();
final EventManagementPanel eventManagementPanel = new EventManagementPanel(sailingService, this, getStringMessages());
final EventManagementPanel eventManagementPanel = new EventManagementPanel(sailingService, this, this, getStringMessages());
panel.addToVerticalTabPanel(new DefaultRefreshableAdminConsolePanel<EventManagementPanel>(eventManagementPanel) {
@Override
public void refreshAfterBecomingVisible() {
@@ -103,7 +103,7 @@ public class AdminConsoleEntryPoint extends AbstractSailingEntryPoint implements
leaderboardGroupsDisplayers.add(eventManagementPanel);
RegattaManagementPanel regattaManagementPanel = new RegattaManagementPanel(
sailingService, this, getStringMessages(), this);
sailingService, this, getStringMessages(), this, eventManagementPanel);
regattaManagementPanel.ensureDebugId("RegattaStructureManagement");
panel.addToVerticalTabPanel(new DefaultRefreshableAdminConsolePanel<RegattaManagementPanel>(regattaManagementPanel) {
@Override
@@ -6,6 +6,7 @@ import java.util.Comparator;
import java.util.List;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
@@ -142,11 +143,10 @@ public class CompetitorEditDialog extends DataEntryDialog<CompetitorDTO> {
}
@Override
public void show() {
super.show();
name.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return name;
}
/**
* Encodes an invalid color; can be used
* @author Axel Uhl (D043530)
@@ -0,0 +1,19 @@
package com.sap.sailing.gwt.ui.adminconsole;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
public class CreateDefaultRegattaDialog extends DataEntryDialog<Void> {
public CreateDefaultRegattaDialog(SailingServiceAsync sailingService, StringMessages stringMessages,
ErrorReporter errorReporter, com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback<Void> callback) {
super(stringMessages.createDefaultRegatta(), /*message*/ stringMessages.doYouWantToCreateADefaultRegatta(), stringMessages.yes(), stringMessages.no(), /*validator*/ null, callback);
}
@Override
protected Void getResult() {
return null;
}
}
@@ -0,0 +1,218 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.domain.common.dto.RaceColumnInSeriesDTO;
import com.sap.sailing.domain.common.dto.RegattaCreationParametersDTO;
import com.sap.sailing.domain.common.dto.SeriesCreationParametersDTO;
import com.sap.sailing.gwt.ui.client.EventsRefresher;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
public class CreateRegattaCallback implements DialogCallback<RegattaDTO>{
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final EventsRefresher eventsRefresher;
private final RegattaRefresher regattaRefresher;
private final StringMessages stringMessages;
private final List<EventDTO> existingEvents;
public CreateRegattaCallback(SailingServiceAsync sailingService, StringMessages stringMessages, ErrorReporter errorReporter, RegattaRefresher regattaRefresher, EventsRefresher eventsRefresher, List<EventDTO> existingEvents) {
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.regattaRefresher = regattaRefresher;
this.eventsRefresher = eventsRefresher;
this.stringMessages = stringMessages;
this.existingEvents = existingEvents;
}
@Override
public void ok(RegattaDTO newRegatta) {
createNewRegatta(newRegatta, existingEvents);
}
@Override
public void cancel() {
}
private void createNewRegatta(final RegattaDTO newRegatta, final List<EventDTO> existingEvents) {
LinkedHashMap<String, SeriesCreationParametersDTO> seriesStructure = new LinkedHashMap<String, SeriesCreationParametersDTO>();
for (SeriesDTO seriesDTO : newRegatta.series) {
SeriesCreationParametersDTO seriesPair = new SeriesCreationParametersDTO(seriesDTO.getFleets(),
seriesDTO.isMedal(), seriesDTO.isStartsWithZeroScore(),
seriesDTO.isFirstColumnIsNonDiscardableCarryForward(), seriesDTO.getDiscardThresholds(),
seriesDTO.hasSplitFleetContiguousScoring());
seriesStructure.put(seriesDTO.getName(), seriesPair);
}
sailingService.createRegatta(newRegatta.getName(), newRegatta.boatClass==null?null:newRegatta.boatClass.getName(),
newRegatta.startDate, newRegatta.endDate,
new RegattaCreationParametersDTO(seriesStructure), true,
newRegatta.scoringScheme, newRegatta.defaultCourseAreaUuid, newRegatta.useStartTimeInference,
newRegatta.rankingMetricType, new AsyncCallback<RegattaDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to create new regatta " + newRegatta.getName() + ": " + t.getMessage());
}
@Override
public void onSuccess(RegattaDTO regatta) {
// if regatta creation was successful, add race columns as modeled in the creation dialog;
// note that the SeriesCreationParametersDTO don't describe race columns.
createDefaultRacesIfDefaultSeriesIsPresent(newRegatta);
fillRegattas();
fillEvents(); // events have their associated regattas
openCreateDefaultRegattaLeaderboardDialog(regatta, existingEvents);
}
});
}
private void createDefaultRacesIfDefaultSeriesIsPresent(final RegattaDTO newRegatta) {
for (final SeriesDTO series: newRegatta.series) {
if (series.getName().equals(Series.DEFAULT_NAME) && !series.getRaceColumns().isEmpty()) {
final List<Pair<String, Integer>> raceColumnNamesToAddWithInsertIndex = new ArrayList<>();
for (RaceColumnDTO newRaceColumn : series.getRaceColumns()) {
// We could use an index counter here because we're assuming that we're creating
// races starting at index 0. However, to make things concurrency-safe, we have to
// assume that while the regatta already exists on the server, some other activity
// may already have started to create races for it. Better safe than sorry, append
// at the end, using -1 as "insertIndex."
raceColumnNamesToAddWithInsertIndex.add(new Pair<>(newRaceColumn.getName(), -1));
}
sailingService.addRaceColumnsToSeries(newRegatta.getRegattaIdentifier(), series.getName(), raceColumnNamesToAddWithInsertIndex,
new AsyncCallback<List<RaceColumnInSeriesDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to add race columns " + raceColumnNamesToAddWithInsertIndex
+ " to series " + series.getName() + ": " + caught.getMessage());
}
@Override
public void onSuccess(List<RaceColumnInSeriesDTO> raceColumns) {
fillRegattas();
}
});
}
}
}
private void fillRegattas() {
if (regattaRefresher != null){
regattaRefresher.fillRegattas();
}
}
private void fillEvents() {
if (eventsRefresher != null) {
eventsRefresher.fillEvents();
}
}
private void openCreateDefaultRegattaLeaderboardDialog(final RegattaDTO newRegatta, final List<EventDTO> existingEvents) {
CreateDefaultRegattaLeaderboardDialog dialog = new CreateDefaultRegattaLeaderboardDialog(sailingService, stringMessages, errorReporter, newRegatta, new DialogCallback<RegattaIdentifier>() {
@Override
public void ok(RegattaIdentifier regattaIdentifier) {
sailingService.createRegattaLeaderboard(regattaIdentifier, /* displayName */ null, new int[]{},
new AsyncCallback<StrippedLeaderboardDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to create default regatta leaderboard for " + newRegatta.getName()
+ ": " + t.getMessage());
}
@Override
public void onSuccess(StrippedLeaderboardDTO result) {
if (newRegatta.defaultCourseAreaUuid != null) {
// Show the event's leaderboard groups and allow the user to pick one to assign the regatta leaderboard to
final EventDTO event = getEventForCourseArea(existingEvents, newRegatta.defaultCourseAreaUuid);
if (!event.getLeaderboardGroups().isEmpty()) {
openRegattaLeaderboardToLeaderboardGroupOfEventLinkingDialog(result, event);
}
}
}
});
}
@Override
public void cancel() {
}
});
dialog.ensureDebugId("CreateDefaultRegattaDialog");
dialog.show();
}
/**
* When a new regatta with a new regatta leaderboard has been created, the user will now be given the chance to link
* the regatta leaderboard into a leaderboard group of the event out of which the regatta chose its default course area.
*
* @param newRegattaLeaderboard the new regatta leaderboard that the user may link now to a leaderboard group of an event
* @param eventToLinkRegattaTo an event that has at least one {@link EventDTO#getLeaderboardGroups() leaderboard group}
*/
private void openRegattaLeaderboardToLeaderboardGroupOfEventLinkingDialog(final StrippedLeaderboardDTO newRegattaLeaderboard, EventDTO eventToLinkRegattaTo) {
LinkRegattaLeaderboardToLeaderboardGroupOfEventDialog dialog = new LinkRegattaLeaderboardToLeaderboardGroupOfEventDialog(sailingService, stringMessages, errorReporter, newRegattaLeaderboard, eventToLinkRegattaTo,
new DialogCallback<LeaderboardGroupDTO>() {
@Override
public void ok(final LeaderboardGroupDTO selectedLeaderboardGroup) {
final List<String> leaderboardNames = new ArrayList<>();
for (StrippedLeaderboardDTO leaderboard : selectedLeaderboardGroup.getLeaderboards()) {
leaderboardNames.add(leaderboard.name);
}
leaderboardNames.add(newRegattaLeaderboard.name);
sailingService.updateLeaderboardGroup(selectedLeaderboardGroup.getName(), selectedLeaderboardGroup.getName(), selectedLeaderboardGroup.description,
selectedLeaderboardGroup.getDisplayName(), leaderboardNames, selectedLeaderboardGroup.getOverallLeaderboardDiscardThresholds(),
selectedLeaderboardGroup.getOverallLeaderboardScoringSchemeType(), new MarkedAsyncCallback<Void>(new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.failedToLinkLeaderboardToLeaderboardGroup(newRegattaLeaderboard.name, selectedLeaderboardGroup.getName()));
}
@Override
public void onSuccess(Void result) {
}
}));
}
@Override
public void cancel() {
}
});
dialog.ensureDebugId("LinkRegattaLeaderboardToLeaderboardGroupOfEventDialog");
dialog.show();
}
private EventDTO getEventForCourseArea(final List<EventDTO> existingEvents, final UUID courseAreaId) {
EventDTO result = null;
eventLoop:
for (final EventDTO event : existingEvents) {
if (event.venue != null) {
for (CourseAreaDTO courseArea : event.venue.getCourseAreas()) {
if (courseArea.id.equals(courseAreaId)) {
result = event;
break eventLoop;
}
}
}
}
return result;
}
}
@@ -19,7 +19,7 @@ public class DefaultRegattaCreateDialog extends AbstractRegattaWithSeriesAndFlee
public DefaultRegattaCreateDialog(List<EventDTO> existingEvents, RegattaDTO selectedRegatta,
SailingServiceAsync sailingService, ErrorReporter errorReporter, StringMessages stringMessages,
com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback<EventAndRegattaDTO> callback) {
super(selectedRegatta, selectedRegatta.series, existingEvents, stringMessages.createDefaultSettingsForAllRegattas(),
super(selectedRegatta, selectedRegatta.series, existingEvents, null, stringMessages.createDefaultSettingsForAllRegattas(),
stringMessages.ok(), stringMessages, null /* RegattaParameterValidator */, callback);
if (existingEvents != null && !existingEvents.isEmpty()) {
sailingEventsListBox.addItem((existingEvents.get(0)).getName());
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.adminconsole;
import java.util.Arrays;
import java.util.List;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
@@ -57,11 +58,9 @@ public class DeviceConfigurationCreateSingleMatcherDialog extends DataEntryDialo
return grid;
}
@Override
public void show() {
super.show();
identifierBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return identifierBox;
}
@Override
@@ -10,12 +10,11 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
@@ -240,9 +239,8 @@ public abstract class EventDialog extends DataEntryDialogWithBootstrap<EventDTO>
}
@Override
public void show() {
super.show();
Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { nameEntryField.setFocus(true); }});
protected FocusWidget getInitialFocusWidget() {
return nameEntryField;
}
protected Map<String, TextBox> createTextBoxesForLocalesAndDefault(Map<String, String> initialValues) {
@@ -36,6 +36,7 @@ import com.sap.sailing.gwt.ui.adminconsole.LeaderboardGroupDialog.LeaderboardGro
import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
import com.sap.sailing.gwt.ui.client.EventsRefresher;
import com.sap.sailing.gwt.ui.client.LeaderboardGroupsDisplayer;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.controls.FlushableCellTable;
@@ -94,12 +95,17 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
private static AnchorTemplates ANCHORTEMPLATE = GWT.create(AnchorTemplates.class);
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
private final RegattaRefresher regattaRefresher;
private final EventsRefresher eventsRefresher;
@SuppressWarnings("unchecked")
public EventListComposite(final SailingServiceAsync sailingService, final ErrorReporter errorReporter, final StringMessages stringMessages) {
public EventListComposite(final SailingServiceAsync sailingService, final ErrorReporter errorReporter,
RegattaRefresher regattaRefresher, EventsRefresher eventsRefresher, final StringMessages stringMessages) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.errorReporter = errorReporter;
this.regattaRefresher = regattaRefresher;
this.eventsRefresher = eventsRefresher;
availableLeaderboardGroups = Collections.emptyList();
allEvents = new ArrayList<EventDTO>();
@@ -452,6 +458,62 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
dialog.show();
}
private void openCreateDefaultRegattaDialog(final EventDTO createdEvent) {
CreateDefaultRegattaDialog dialog = new CreateDefaultRegattaDialog(sailingService, stringMessages, errorReporter, new DialogCallback<Void>() {
@Override
public void cancel() {
}
@Override
public void ok(Void editedObject) {
sailingService.getRegattas(new AsyncCallback<List<RegattaDTO>>() {
@Override
public void onFailure(Throwable caught) {
sailingService.getEvents(new AsyncCallback<List<EventDTO>>() {
@Override
public void onFailure(Throwable caught) {
openCreateRegattaDialog(Collections.<RegattaDTO>emptyList(), Collections.<EventDTO>emptyList(), createdEvent);
}
@Override
public void onSuccess(List<EventDTO> result) {
openCreateRegattaDialog(Collections.<RegattaDTO>emptyList(), Collections.unmodifiableList(result), createdEvent);
}
});
}
@Override
public void onSuccess(final List<RegattaDTO> existingRegattas) {
sailingService.getEvents(new AsyncCallback<List<EventDTO>>() {
@Override
public void onFailure(Throwable caught) {
openCreateRegattaDialog(existingRegattas, Collections.<EventDTO>emptyList(), createdEvent);
}
@Override
public void onSuccess(List<EventDTO> result) {
openCreateRegattaDialog(existingRegattas, Collections.unmodifiableList(result), createdEvent);
}
});
}
});
}
});
dialog.ensureDebugId("CreateDefaultRegattaDialog");
dialog.show();
}
private void openCreateRegattaDialog(List<RegattaDTO> existingRegattas,
List<EventDTO> existingEvents, EventDTO createdEvent) {
RegattaWithSeriesAndFleetsCreateDialog dialog = new RegattaWithSeriesAndFleetsCreateDialog(existingRegattas, existingEvents, createdEvent, stringMessages,
new CreateRegattaCallback(sailingService, stringMessages, errorReporter, regattaRefresher, eventsRefresher, existingEvents));
dialog.ensureDebugId("RegattaCreateDialog");
dialog.show();
}
/**
* @param newEvent the new event as created by the server, already including a valid {@link EventBaseDTO#id} value.
*/
@@ -485,6 +547,7 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
} else {
errorReporter.reportError("Could not find the event with name "+newEvent.getName()+" to which the leaderboardgroup should be added");
}
openCreateDefaultRegattaDialog(newEvent);
}
}));
}
@@ -625,6 +688,8 @@ public class EventListComposite extends Composite implements EventsRefresher, Le
public void cancel() {
}
}).show();
} else {
openCreateDefaultRegattaDialog(newEvent);
}
}
});
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.Set;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
@@ -8,6 +9,7 @@ import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.sap.sailing.gwt.ui.client.EventsRefresher;
import com.sap.sailing.gwt.ui.client.LeaderboardGroupsDisplayer;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.EventDTO;
@@ -28,7 +30,7 @@ public class EventManagementPanel extends SimplePanel implements EventsRefresher
private final RefreshableMultiSelectionModel<EventDTO> refreshableEventSelectionModel;
public EventManagementPanel(final SailingServiceAsync sailingService, final ErrorReporter errorReporter,
final StringMessages stringMessages) {
RegattaRefresher regattaRefresher, final StringMessages stringMessages) {
VerticalPanel mainPanel = new VerticalPanel();
setWidget(mainPanel);
mainPanel.setWidth("100%");
@@ -38,7 +40,7 @@ public class EventManagementPanel extends SimplePanel implements EventsRefresher
VerticalPanel eventsContentPanel = new VerticalPanel();
eventsPanel.setContentWidget(eventsContentPanel);
eventListComposite = new EventListComposite(sailingService, errorReporter, stringMessages);
eventListComposite = new EventListComposite(sailingService, errorReporter, regattaRefresher, this, stringMessages);
eventListComposite.ensureDebugId("EventListComposite");
eventsContentPanel.add(eventListComposite);
@@ -20,6 +20,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
@@ -243,11 +244,10 @@ public class IgtimiAccountsPanel extends FlowPanel {
}
@Override
public void show() {
super.show();
eMail.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return eMail;
}
@Override
protected UserData getResult() {
return new UserData(eMail.getText(), password.getText());
@@ -8,6 +8,7 @@ import java.util.List;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
@@ -199,8 +200,7 @@ public abstract class ImageDialog extends DataEntryDialog<ImageDTO> {
}
@Override
public void show() {
super.show();
imageURLAndUploadComposite.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return imageURLAndUploadComposite.getInitialFocusWidget();
}
}
@@ -9,6 +9,7 @@ import java.util.List;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
@@ -212,9 +213,7 @@ public class LeaderboardGroupDialog extends DataEntryDialog<LeaderboardGroupDial
}
@Override
public void show() {
super.show();
nameEntryField.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return nameEntryField;
}
}
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
@@ -77,11 +78,9 @@ public class MarkEditDialog extends DataEntryDialog<MarkDTO> {
return result;
}
@Override
public void show() {
super.show();
name.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return name;
}
@Override
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.ui.adminconsole;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
@@ -133,14 +134,22 @@ public class RaceColumnInLeaderboardDialog extends DataEntryDialog<RaceColumnInL
return mainPanel;
}
@Override
protected FocusWidget getInitialFocusWidget() {
final FocusWidget result;
if (isRegattaLeaderboard) {
result = explicitFactorBox;
} else {
result = raceNameBox;
}
return result;
}
@Override
public void show() {
super.show();
if (isRegattaLeaderboard) {
explicitFactorBox.setFocus(true);
explicitFactorBox.selectAll();
} else {
raceNameBox.setFocus(true);
}
}
}
@@ -189,9 +189,4 @@ public class RaceColumnsInLeaderboardDialog extends DataEntryDialog<List<RaceCol
}
parentPanel.insert(raceColumnsGrid, widgetIndex);
}
@Override
public void show() {
super.show();
}
}
@@ -272,7 +272,7 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
private void openEditRegattaDialog(RegattaDTO regatta, Collection<RegattaDTO> existingRegattas,
List<EventDTO> existingEvents) {
RegattaWithSeriesAndFleetsDialog dialog = new RegattaWithSeriesAndFleetsEditDialog(regatta, existingRegattas,
existingEvents, stringMessages, new DialogCallback<RegattaDTO>() {
existingEvents, /*correspondingEvent*/ null, stringMessages, new DialogCallback<RegattaDTO>() {
@Override
public void cancel() {
}
@@ -4,9 +4,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -20,22 +18,15 @@ import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
import com.sap.sailing.domain.common.RegattaIdentifier;
import com.sap.sailing.domain.common.dto.RegattaCreationParametersDTO;
import com.sap.sailing.domain.common.dto.SeriesCreationParametersDTO;
import com.sap.sailing.gwt.ui.client.EventsRefresher;
import com.sap.sailing.gwt.ui.client.RegattaRefresher;
import com.sap.sailing.gwt.ui.client.RegattasDisplayer;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sse.gwt.client.ErrorReporter;
import com.sap.sse.gwt.client.async.MarkedAsyncCallback;
import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
/**
* Allows administrators to manage the structure of a regatta. Each regatta consists of several substructures like
@@ -50,6 +41,7 @@ public class RegattaManagementPanel extends SimplePanel implements RegattasDispl
private final StringMessages stringMessages;
private final RegattaRefresher regattaRefresher;
private final EventsRefresher eventsRefresher;
private final RefreshableMultiSelectionModel<RegattaDTO> refreshableRegattaMultiSelectionModel;
private Button removeRegattaButton;
@@ -59,11 +51,12 @@ public class RegattaManagementPanel extends SimplePanel implements RegattasDispl
private final CaptionPanel regattasPanel;
public RegattaManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages, RegattaRefresher regattaRefresher) {
StringMessages stringMessages, RegattaRefresher regattaRefresher, EventsRefresher eventsRefresher) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.errorReporter = errorReporter;
this.regattaRefresher = regattaRefresher;
this.eventsRefresher = eventsRefresher;
VerticalPanel mainPanel = new VerticalPanel();
setWidget(mainPanel);
@@ -172,136 +165,11 @@ public class RegattaManagementPanel extends SimplePanel implements RegattasDispl
}
private void openCreateRegattaDialog(Collection<RegattaDTO> existingRegattas, final List<EventDTO> existingEvents) {
RegattaWithSeriesAndFleetsCreateDialog dialog = new RegattaWithSeriesAndFleetsCreateDialog(existingRegattas, existingEvents, stringMessages,
new DialogCallback<RegattaDTO>() {
@Override
public void cancel() {
}
@Override
public void ok(RegattaDTO newRegatta) {
createNewRegatta(newRegatta, existingEvents);
}
});
RegattaWithSeriesAndFleetsCreateDialog dialog = new RegattaWithSeriesAndFleetsCreateDialog(existingRegattas, existingEvents, /*eventToSelect*/ null, stringMessages,
new CreateRegattaCallback(sailingService, stringMessages, errorReporter, regattaRefresher, eventsRefresher, existingEvents));
dialog.ensureDebugId("RegattaCreateDialog");
dialog.show();
}
private void openCreateDefaultRegattaLeaderboardDialog(final RegattaDTO newRegatta, final List<EventDTO> existingEvents) {
CreateDefaultRegattaLeaderboardDialog dialog = new CreateDefaultRegattaLeaderboardDialog(sailingService, stringMessages, errorReporter, newRegatta, new DialogCallback<RegattaIdentifier>() {
@Override
public void ok(RegattaIdentifier regattaIdentifier) {
sailingService.createRegattaLeaderboard(regattaIdentifier, /* displayName */ null, new int[]{},
new AsyncCallback<StrippedLeaderboardDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to create default regatta leaderboard for " + newRegatta.getName()
+ ": " + t.getMessage());
}
@Override
public void onSuccess(StrippedLeaderboardDTO result) {
if (newRegatta.defaultCourseAreaUuid != null) {
// Show the event's leaderboard groups and allow the user to pick one to assign the regatta leaderboard to
final EventDTO event = getEventForCourseArea(existingEvents, newRegatta.defaultCourseAreaUuid);
if (!event.getLeaderboardGroups().isEmpty()) {
openRegattaLeaderboardToLeaderboardGroupOfEventLinkingDialog(result, event);
}
}
}
});
}
@Override
public void cancel() {
}
});
dialog.ensureDebugId("CreateDefaultRegattaDialog");
dialog.show();
}
/**
* When a new regatta with a new regatta leaderboard has been created, the user will now be given the chance to link
* the regatta leaderboard into a leaderboard group of the event out of which the regatta chose its default course area.
*
* @param newRegattaLeaderboard the new regatta leaderboard that the user may link now to a leaderboard group of an event
* @param eventToLinkRegattaTo an event that has at least one {@link EventDTO#getLeaderboardGroups() leaderboard group}
*/
private void openRegattaLeaderboardToLeaderboardGroupOfEventLinkingDialog(final StrippedLeaderboardDTO newRegattaLeaderboard, EventDTO eventToLinkRegattaTo) {
LinkRegattaLeaderboardToLeaderboardGroupOfEventDialog dialog = new LinkRegattaLeaderboardToLeaderboardGroupOfEventDialog(sailingService, stringMessages, errorReporter, newRegattaLeaderboard, eventToLinkRegattaTo,
new DialogCallback<LeaderboardGroupDTO>() {
@Override
public void ok(final LeaderboardGroupDTO selectedLeaderboardGroup) {
final List<String> leaderboardNames = new ArrayList<>();
for (StrippedLeaderboardDTO leaderboard : selectedLeaderboardGroup.getLeaderboards()) {
leaderboardNames.add(leaderboard.name);
}
leaderboardNames.add(newRegattaLeaderboard.name);
sailingService.updateLeaderboardGroup(selectedLeaderboardGroup.getName(), selectedLeaderboardGroup.getName(), selectedLeaderboardGroup.description,
selectedLeaderboardGroup.getDisplayName(), leaderboardNames, selectedLeaderboardGroup.getOverallLeaderboardDiscardThresholds(),
selectedLeaderboardGroup.getOverallLeaderboardScoringSchemeType(), new MarkedAsyncCallback<Void>(new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.failedToLinkLeaderboardToLeaderboardGroup(newRegattaLeaderboard.name, selectedLeaderboardGroup.getName()));
}
@Override
public void onSuccess(Void result) {
}
}));
}
@Override
public void cancel() {
}
});
dialog.ensureDebugId("LinkRegattaLeaderboardToLeaderboardGroupOfEventDialog");
dialog.show();
}
private EventDTO getEventForCourseArea(final List<EventDTO> existingEvents, final UUID courseAreaId) {
EventDTO result = null;
eventLoop:
for (final EventDTO event : existingEvents) {
if (event.venue != null) {
for (CourseAreaDTO courseArea : event.venue.getCourseAreas()) {
if (courseArea.id.equals(courseAreaId)) {
result = event;
break eventLoop;
}
}
}
}
return result;
}
private void createNewRegatta(final RegattaDTO newRegatta, final List<EventDTO> existingEvents) {
LinkedHashMap<String, SeriesCreationParametersDTO> seriesStructure = new LinkedHashMap<String, SeriesCreationParametersDTO>();
for (SeriesDTO seriesDTO : newRegatta.series) {
SeriesCreationParametersDTO seriesPair = new SeriesCreationParametersDTO(seriesDTO.getFleets(),
seriesDTO.isMedal(), seriesDTO.isStartsWithZeroScore(),
seriesDTO.isFirstColumnIsNonDiscardableCarryForward(), seriesDTO.getDiscardThresholds(),
seriesDTO.hasSplitFleetContiguousScoring());
seriesStructure.put(seriesDTO.getName(), seriesPair);
}
sailingService.createRegatta(newRegatta.getName(), newRegatta.boatClass==null?null:newRegatta.boatClass.getName(),
newRegatta.startDate, newRegatta.endDate,
new RegattaCreationParametersDTO(seriesStructure), true,
newRegatta.scoringScheme, newRegatta.defaultCourseAreaUuid, newRegatta.useStartTimeInference,
newRegatta.rankingMetricType, new AsyncCallback<RegattaDTO>() {
@Override
public void onFailure(Throwable t) {
errorReporter.reportError("Error trying to create new regatta " + newRegatta.getName() + ": " + t.getMessage());
}
@Override
public void onSuccess(RegattaDTO regatta) {
regattaRefresher.fillRegattas();
openCreateDefaultRegattaLeaderboardDialog(regatta, existingEvents);
}
});
}
@Override
public void fillRegattas(Iterable<RegattaDTO> regattas) {
@@ -8,11 +8,15 @@ import java.util.HashSet;
import java.util.List;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
import com.sap.sailing.domain.common.dto.RaceColumnInSeriesDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.EventDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
@@ -102,11 +106,11 @@ public class RegattaWithSeriesAndFleetsCreateDialog extends RegattaWithSeriesAnd
}
public RegattaWithSeriesAndFleetsCreateDialog(Collection<RegattaDTO> existingRegattas,
List<EventDTO> existingEvents, StringMessages stringMessages, DialogCallback<RegattaDTO> callback) {
super(new RegattaDTO(), Collections.<SeriesDTO>emptySet(), existingEvents, stringMessages.addRegatta(), stringMessages.ok(),
List<EventDTO> existingEvents, EventDTO correspondingEvent, StringMessages stringMessages, DialogCallback<RegattaDTO> callback) {
super(new RegattaDTO(), Collections.<SeriesDTO>emptySet(), existingEvents, correspondingEvent, stringMessages.addRegatta(), stringMessages.ok(),
stringMessages, new RegattaParameterValidator(stringMessages, existingRegattas), callback);
SeriesDTO series = new SeriesDTO();
series.setName("Default");
series.setName(Series.DEFAULT_NAME);
series.setMedal(false);
series.setStartsWithZeroScore(false);
series.setSplitFleetContiguousScoring(false);
@@ -132,14 +136,27 @@ public class RegattaWithSeriesAndFleetsCreateDialog extends RegattaWithSeriesAnd
}
@Override
public void show() {
super.show();
nameEntryField.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return nameEntryField;
}
@Override
protected RegattaDTO getResult() {
protected RegattaDTO getResult() {
RegattaDTO dto = super.getResult();
List<SeriesDTO> seriesList = getSeriesEditor().getValue();
for (SeriesDTO series : seriesList) {
// generate 3 Default Races if default series is still present
if (series.getName().equals(Series.DEFAULT_NAME)) {
List<RaceColumnDTO> races = new ArrayList<RaceColumnDTO>();
for (int i = 1; i <= 3; i++) {
RaceColumnDTO raceColumnDTO = new RaceColumnInSeriesDTO(series.getName(), dto.getName());
raceColumnDTO.setName("R"+i);
races.add(raceColumnDTO);
}
series.setRaceColumns(races);
}
}
dto.series = seriesList;
setRankingMetrics(dto);
return dto;
}
@@ -20,10 +20,10 @@ public abstract class RegattaWithSeriesAndFleetsDialog extends AbstractRegattaWi
protected TextBox nameEntryField;
protected SuggestBox boatClassEntryField;
public RegattaWithSeriesAndFleetsDialog(RegattaDTO regatta, Iterable<SeriesDTO> series, List<EventDTO> existingEvents,
public RegattaWithSeriesAndFleetsDialog(RegattaDTO regatta, Iterable<SeriesDTO> series, List<EventDTO> existingEvents, EventDTO defaultEvent,
String title, String okButton, StringMessages stringMessages,
Validator<RegattaDTO> validator, DialogCallback<RegattaDTO> callback) {
super(regatta, series, existingEvents, title, okButton, stringMessages, validator, callback);
super(regatta, series, existingEvents, defaultEvent, title, okButton, stringMessages, validator, callback);
this.stringMessages = stringMessages;
nameEntryField = createTextBox(null);
nameEntryField.ensureDebugId("NameTextBox");
@@ -9,6 +9,7 @@ import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
@@ -25,8 +26,8 @@ public class RegattaWithSeriesAndFleetsEditDialog extends RegattaWithSeriesAndFl
private RegattaConfigurationDTO currentRegattaConfiguration;
public RegattaWithSeriesAndFleetsEditDialog(RegattaDTO regatta, Collection<RegattaDTO> existingRegattas,
List<EventDTO> existingEvents, final StringMessages stringMessages, DialogCallback<RegattaDTO> callback) {
super(regatta, regatta.series, existingEvents, stringMessages.editRegatta(), stringMessages.ok(), stringMessages,
List<EventDTO> existingEvents, EventDTO correspondingEvent, final StringMessages stringMessages, DialogCallback<RegattaDTO> callback) {
super(regatta, regatta.series, existingEvents, correspondingEvent, stringMessages.editRegatta(), stringMessages.ok(), stringMessages,
null, callback);
ensureDebugId("RegattaWithSeriesAndFleetsEditDialog");
currentRegattaConfiguration = regatta.configuration;
@@ -74,9 +75,8 @@ public class RegattaWithSeriesAndFleetsEditDialog extends RegattaWithSeriesAndFl
}
@Override
public void show() {
super.show();
courseAreaListBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return courseAreaListBox;
}
@Override
@@ -8,6 +8,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
@@ -352,9 +353,8 @@ public class ReplicationPanel extends FlowPanel {
}
@Override
public void show() {
super.show();
hostnameEntryField.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return hostnameEntryField;
}
@Override
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.adminconsole;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
@@ -94,9 +95,7 @@ public class SailingServerCreateOrEditDialog extends DataEntryDialog<RemoteSaili
}
@Override
public void show() {
super.show();
nameTextBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return nameTextBox;
}
}
@@ -10,6 +10,7 @@ import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TabPanel;
@@ -196,9 +197,7 @@ public class SeriesWithFleetsCreateDialog extends DataEntryDialog<SeriesDTO> {
}
@Override
public void show() {
super.show();
nameEntryField.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return nameEntryField;
}
}
@@ -7,6 +7,7 @@ import java.util.List;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
@@ -180,8 +181,7 @@ public abstract class VideoDialog extends DataEntryDialog<VideoDTO> {
}
@Override
public void show() {
super.show();
videoURLAndUploadComposite.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return videoURLAndUploadComposite.getInitialFocusWidget();
}
}
@@ -1483,6 +1483,8 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c
String linkLeaderboardToLeaderboardGroupOfEvent();
String doYouWantToLinkLeaderboardToLeaderboardGroupOfEvent(String leaderboardName, String eventName);
String failedToLinkLeaderboardToLeaderboardGroup(String leaderboardName, String leaderboardGroupName);
String createDefaultRegatta();
String doYouWantToCreateADefaultRegatta();
String defaultLocale();
String defaultSailorsInfoLinkInfoText();
String qrSync();
@@ -1451,6 +1451,8 @@ pleaseSelectALeaderboardGroup=Please select a leaderboard group
linkLeaderboardToLeaderboardGroupOfEvent=Link Leaderboard to Leaderboard Group of Event
doYouWantToLinkLeaderboardToLeaderboardGroupOfEvent=Link leaderboard {0} to a leaderboard group of event {1}
failedToLinkLeaderboardToLeaderboardGroup=Failed to link leaderboard {0} to leaderboard group {1}
createDefaultRegatta=Create default regatta
doYouWantToCreateADefaultRegatta=Do you want to create a default Regatta?
defaultLocale=Default
defaultSailorsInfoLinkInfoText=The default link is used unless a language specific overwrite exists. If no default exists, there will be no link for languages that do not explicitly have one set.
qrSync=QR-Sync
@@ -1441,6 +1441,8 @@ pleaseSelectALeaderboardGroup=Bitte eine Ranglisten-Gruppe auswählen
linkLeaderboardToLeaderboardGroupOfEvent=Ergebnisliste einer Ranglisten-Gruppe einer Veranstaltung hinzufügen
doYouWantToLinkLeaderboardToLeaderboardGroupOfEvent=Ergebnisliste {0} zu einer Ranglisten-Gruppe der Veranstaltung {1} hinzufügen
failedToLinkLeaderboardToLeaderboardGroup=Ergebnisliste {0} konnte nicht in Ranglisten-Gruppe {1} eingefügt werden
createDefaultRegatta=Standardregatta anlegen
doYouWantToCreateADefaultRegatta=Möchten Sie eine Standardregatta für das Event anlegen?
defaultLocale=Standard
defaultSailorsInfoLinkInfoText=Der Standardwert wird verwendet, sofern kein Sprach-abhängiger Selglerinfo-Link hinterlegt wurde. Wenn kein Standardwert angegeben ist, so erscheint kein Selgerinfo-Link bei Sprachen, welche keinen Sprach-spezifischen Link definiert haben.
qrSync=QR-Sync
@@ -1373,6 +1373,8 @@ pleaseSelectALeaderboardGroup=Please select a leaderboard group
linkLeaderboardToLeaderboardGroupOfEvent=Link Leaderboard to Leaderboard Group of Event
doYouWantToLinkLeaderboardToLeaderboardGroupOfEvent=Link leaderboard {0} to a leaderboard group of event {1}
failedToLinkLeaderboardToLeaderboardGroup=Failed to link leaderboard {0} to leaderboard group {1}
createDefaultRegatta=Create default regatta
doYouWantToCreateADefaultRegatta=Do you want to create a default Regatta?
defaultLocale=Default
defaultSailorsInfoLinkInfoText=The default link is used unless a language specific overwrite exists. If no default exists, there will be no link for languages that do not explicitly have one set.
qrSync=QR-Sync
@@ -1388,6 +1388,8 @@ pleaseSelectALeaderboardGroup=Please select a leaderboard group
linkLeaderboardToLeaderboardGroupOfEvent=Link Leaderboard to Leaderboard Group of Event
doYouWantToLinkLeaderboardToLeaderboardGroupOfEvent=Link leaderboard {0} to a leaderboard group of event {1}
failedToLinkLeaderboardToLeaderboardGroup=Failed to link leaderboard {0} to leaderboard group {1}
createDefaultRegatta=Create default regatta
doYouWantToCreateADefaultRegatta=Do you want to create a default Regatta?
defaultLocale=Default
defaultSailorsInfoLinkInfoText=The default link is used unless a language specific overwrite exists. If no default exists, there will be no link for languages that do not explicitly have one set.
qrSync=QR-Sync
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.client;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
@@ -30,9 +31,8 @@ public class TextfieldEntryDialog extends DataEntryDialog<String> {
}
@Override
public void show() {
super.show();
entryField.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return entryField;
}
@Override
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.ui.client;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -36,8 +37,7 @@ public class TextfieldEntryDialogWithCheckbox extends DataEntryDialog<Util.Pair<
}
@Override
public void show() {
super.show();
entryField.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return entryField;
}
}
@@ -10,6 +10,7 @@ import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.media.client.Audio;
import com.google.gwt.media.client.MediaBase;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
@@ -293,8 +294,7 @@ public class NewMediaDialog extends DataEntryDialog<MediaTrack> {
}
@Override
public void show() {
super.show();
urlBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return urlBox;
}
}
@@ -8,6 +8,7 @@ import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
@@ -272,8 +273,7 @@ public abstract class AbstractCompetitorsFilterSetDialog extends DataEntryDialog
}
@Override
public void show() {
super.show();
filterSetNameTextBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return filterSetNameTextBox;
}
}
@@ -275,10 +275,4 @@ public class CompetitorsFilterSetsDialog extends DataEntryDialog<CompetitorsFilt
}
parentPanel.insert(competitorsFilterSetsGrid, widgetIndex);
}
@Override
public void show() {
super.show();
getOkButton().setFocus(true);
}
}
@@ -1,6 +1,7 @@
package com.sap.sailing.gwt.ui.leaderboardedit;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
@@ -35,10 +36,14 @@ public class EditCarryValueDialog extends DataEntryDialog<Double> {
return grid;
}
@Override
protected FocusWidget getInitialFocusWidget() {
return carriedPointsBox;
}
@Override
public void show() {
super.show();
carriedPointsBox.setFocus(true);
carriedPointsBox.selectAll();
}
}
@@ -32,9 +32,4 @@ public class EditCompetitorNameDialog extends DataEntryDialog<String> {
grid.setWidget(0, 1, competitorNameBox);
return grid;
}
@Override
public void show() {
super.show();
}
}
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.leaderboardedit;
import java.util.Arrays;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
@@ -61,10 +62,14 @@ public class EditScoreDialog extends DataEntryDialog<Util.Pair<MaxPointsReason,
return grid;
}
@Override
protected FocusWidget getInitialFocusWidget() {
return netPointsBox;
}
@Override
public void show() {
super.show();
netPointsBox.setFocus(true);
netPointsBox.selectAll();
}
}
@@ -13,6 +13,7 @@ import java.util.Set;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
@@ -244,12 +245,11 @@ public class ResultSelectionAndApplyDialog extends DataEntryDialog<Util.Triple<S
}
@Override
public void show() {
super.show();
scoreCorrectionProviderListBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return scoreCorrectionProviderListBox;
}
@Override
@Override
protected Util.Triple<String, String, Util.Pair<String, Date>> getResult() {
Util.Triple<String, String, Util.Pair<String, Date>> result = null;
@@ -47,4 +47,4 @@ customGwt = com.sap.sse.security.CustomFilter
# If no such bearer token is provided, the filter falls back to basic HTTP
# authentication ("Authentication: Basic ...") and then regular form-based
# authentication with POST parameters "username" and "password".
bearerToken = com.sap.sse.security.BearerTokenOrBasicOrFormAuthenticationFilter
bearerToken = com.sap.sailing.server.security.BearerTokenOrBasicOrFormAuthenticationFilterSAPSailing
@@ -67,7 +67,7 @@ public class RegattaDetailsCompositePO extends PageArea {
if (entry != null) {
WebElement removeAction = ActionsHelper.findRemoveAction(entry.getWebElement());
removeAction.click();
ActionsHelper.acceptAlert(this.driver);
// ActionsHelper.acceptAlert(this.driver);
// waitForAjaxRequests();
}
}
@@ -193,6 +193,8 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest {
seriesDialog.addRaces(1, 5);
seriesDialog.pressOk();
regattaDetails.deleteSeries("Default");
LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration();
leaderboardConfiguration.createRegattaLeaderboard(this.regatta);
}
@@ -124,6 +124,7 @@ public class TestColumnsInLeaderboard extends AbstractSeleniumTest {
SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME);
seriesDialog.addRaces(1, 1);
seriesDialog.pressOk();
regattaDetails.deleteSeries("Default");
// Start the tracking for the races and wait until they are ready to use
startTrackingRaceAndStopWhenFinished(adminConsole);
LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration();
@@ -199,6 +199,8 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest {
seriesDialog.addRaces(1, 5);
seriesDialog.pressOk();
regattaDetails.deleteSeries("Default");
LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration();
leaderboardConfiguration.createRegattaLeaderboard(this.regatta);
@@ -101,6 +101,7 @@ public class TestSwitchingOffStartOfRaceInference extends AbstractSeleniumTest {
SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME);
seriesDialog.addRaces(3, 3);
seriesDialog.pressOk();
regattaDetails.deleteSeries("Default");
// Start the tracking for the races and wait until they are ready to use
TracTracEventManagementPanelPO tracTracEvents = adminConsole.goToTracTracEvents();
tracTracEvents.listTrackableRaces(BMW_CUP_JSON_URL);
@@ -57,7 +57,8 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sailing.polars,
com.sap.sse.datamining;bundle-version="1.0.0",
com.sap.sse.datamining.shared;bundle-version="1.0.0",
com.sap.sailing.datamining
com.sap.sailing.datamining,
com.sap.sailing.server
Bundle-ClassPath: .
Web-ContextPath: /sailingserver
Export-Package: com.sap.sailing.server.gateway,
@@ -55,7 +55,7 @@ authc.successUrl = /api/restsecurity/hello
# If no such bearer token is provided, the filter falls back to basic HTTP
# authentication ("Authentication: Basic ...") and then regular form-based
# authentication with POST parameters "username" and "password".
bearerToken = com.sap.sse.security.BearerTokenOrBasicOrFormAuthenticationFilter
bearerToken = com.sap.sailing.server.security.BearerTokenOrBasicOrFormAuthenticationFilterSAPSailing
# Specifying filter chains for URL patterns
@@ -29,7 +29,11 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sailing.server.gateway.serialization.shared.android,
com.sap.sse.shared.android,
com.sap.sse.filestorage,
com.sap.sailing.simulator;bundle-version="1.0.0"
com.sap.sailing.simulator,
com.sap.sse.security,
org.apache.shiro.web;bundle-version="1.2.2",
org.apache.shiro.core;bundle-version="1.2.2",
javax.servlet;bundle-version="3.1.0"
Bundle-ClassPath: .
Export-Package: com.sap.sailing.server,
com.sap.sailing.server.impl;
@@ -42,5 +46,6 @@ Export-Package: com.sap.sailing.server,
com.sap.sailing.domain.racelogtrackingadapter.test",
com.sap.sailing.server.masterdata,
com.sap.sailing.server.operationaltransformation,
com.sap.sailing.server.operationaltransformation.racelog,
com.sap.sailing.server.security,
com.sap.sailing.server.simulation
@@ -0,0 +1,10 @@
package com.sap.sailing.server.security;
import com.sap.sse.security.BearerTokenOrBasicOrFormAuthenticationFilter;
public class BearerTokenOrBasicOrFormAuthenticationFilterSAPSailing extends
BearerTokenOrBasicOrFormAuthenticationFilter {
public BearerTokenOrBasicOrFormAuthenticationFilterSAPSailing() {
super(/* application name */ System.getProperty("com.sap.sailing.server.name", "SAP Sailing Analytics"));
}
}
@@ -16,6 +16,7 @@ import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
@@ -148,8 +149,8 @@ public class URLFieldWithFileUpload extends Composite implements HasValue<String
}
}
public void setFocus(boolean focused) {
urlTextBox.setFocus(focused);
public FocusWidget getInitialFocusWidget() {
return urlTextBox;
}
private HandlerRegistration addChangeHandler(ChangeHandler handler) {
@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.FontWeight;
@@ -22,6 +24,7 @@ import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.IsWidget;
@@ -45,7 +48,10 @@ import com.sap.sse.gwt.client.controls.IntegerBox;
* An abstract data entry dialog class, capturing data of type <code>T</code>, with generic OK/Cancel buttons, title and
* message. Subclasses may override the {@link #show()} method to set the focus on their favorable initial entry field.
* Subclasses can specify a widget to show in the dialog to capture properties specific to the result type <code>T</code> by
* overriding the {@link #getAdditionalWidget()} method.
* overriding the {@link #getAdditionalWidget()} method.<p>
*
* Subclasses can override which elements initially gets the focus by redefining the {@link #getInitialFocusWidget} method.
* By default, the OK button will have the focus.
*
* @author Axel Uhl (d043530)
*/
@@ -529,6 +535,18 @@ public abstract class DataEntryDialog<T> {
}
validate();
dateEntryDialog.center();
final FocusWidget focusWidget = getInitialFocusWidget();
if (focusWidget != null) {
Scheduler.get().scheduleFinally(new ScheduledCommand() { @Override public void execute() { focusWidget.setFocus(true); }});
}
}
/**
* Defines the {@link #okButton} as the default initial focus widget. Subclasses may redefine. Return
* {@code null} to not set the focus on any widget.
*/
protected FocusWidget getInitialFocusWidget() {
return okButton;
}
protected DialogBox getDialogBox() {
@@ -74,12 +74,7 @@ public class SettingsDialog<SettingsType extends Settings> extends DataEntryDial
}
@Override
public void show() {
super.show();
FocusWidget focusWidget = settingsDialogComponent.getFocusWidget();
if (focusWidget != null) {
focusWidget.setFocus(true);
}
protected FocusWidget getInitialFocusWidget() {
return settingsDialogComponent.getFocusWidget();
}
}
@@ -1,5 +1,6 @@
package com.sap.sse.security.ui.client.component;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
@@ -117,11 +118,9 @@ public class AbstractUserDialog extends DataEntryDialog<UserData> {
}
@Override
public void show() {
super.show();
nameBox.setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return nameBox;
}
protected StringMessages getStringMessages() {
return stringMessages;
}
@@ -47,10 +47,4 @@ public class CreateUserDialog extends AbstractUserDialog {
}
});
}
@Override
public void show() {
super.show();
getNameBox().setFocus(true);
}
}
@@ -1,5 +1,6 @@
package com.sap.sse.security.ui.client.component;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
@@ -25,8 +26,7 @@ public class EditEmailDialog extends AbstractUserDialog {
}
@Override
public void show() {
super.show();
getEmailBox().setFocus(true);
protected FocusWidget getInitialFocusWidget() {
return getEmailBox();
}
}
@@ -38,9 +38,14 @@ public class BearerTokenOrBasicOrFormAuthenticationFilter extends BasicHttpAuthe
private final FormAuthenticationFilterWithPublicCreateToken formAuthenticationFilter;
public BearerTokenOrBasicOrFormAuthenticationFilter() {
formAuthenticationFilter = new FormAuthenticationFilterWithPublicCreateToken();
this(/* application name */ "SAP");
}
protected BearerTokenOrBasicOrFormAuthenticationFilter(String applicationName) {
formAuthenticationFilter = new FormAuthenticationFilterWithPublicCreateToken();
setApplicationName(applicationName);
}
@Override
protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
String authorizationHeader = getAuthzHeader(request);
+1
View File
@@ -108,6 +108,7 @@ append_user_data_to_envsh ()
echo "# User-Data: START ($DATE_OF_EXECUTION)" >> $SERVER_HOME/env.sh
echo "INSTANCE_NAME=`ec2-metadata -i | cut -f2 -d \" \"`" >> $SERVER_HOME/env.sh
echo "INSTANCE_IP4=`ec2-metadata -v | cut -f2 -d \" \"`" >> $SERVER_HOME/env.sh
echo "INSTANCE_INTERNAL_IP4=`ec2-metadata -o | cut -f2 -d \" \"`" >> $SERVER_HOME/env.sh
echo "INSTANCE_DNS=`ec2-metadata -p | cut -f2 -d \" \"`" >> $SERVER_HOME/env.sh
for var in `cat "$ec2EnvVars_tmpFile"`; do
@@ -28,7 +28,7 @@
<string name="add_photo_select">Photo</string>
<string name="checking_in">Checking in&#8230;</string>
<string name="checking_out">Checking out&#8230;</string>
<string name="getting_event">Getting event informatiopn&#8230;</string>
<string name="getting_event">Getting event information&#8230;</string>
<string name="getting_leaderboard">Getting leaderboard information&#8230;</string>
<string name="getting_competitor">Getting competitor information&#8230;</string>
<string name="error">Error</string>
@@ -1,5 +1,17 @@
package com.sap.sailing.android.tracking.app.utils;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.net.Uri;
@@ -13,21 +25,22 @@ import com.sap.sailing.android.shared.util.NetworkHelper;
import com.sap.sailing.android.shared.util.UniqueDeviceUuid;
import com.sap.sailing.android.tracking.app.R;
import com.sap.sailing.android.tracking.app.valueobjects.CheckinData;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.SimpleRaceLogIdentifier;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.impl.SharedDomainFactoryImpl;
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
import com.sap.sailing.domain.common.tracking.impl.CompetitorJsonConstants;
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDIdentifierImpl;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
import com.sap.sailing.server.gateway.deserialization.impl.CourseAreaJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.LeaderboardGroupBaseJsonDeserializer;
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
import com.sap.sse.common.Util;
import com.sap.sse.shared.media.ImageDescriptor;
public class CheckinManager {
@@ -71,9 +84,8 @@ public class CheckinManager {
URLData urlData = new URLData();
urlData.uriStr = uri.toString();
urlData.server = scheme + "://" + uri.getHost();
urlData.port = (uri.getPort() == -1) ? 80 : uri.getPort();
urlData.hostWithPort = urlData.server + ":" + urlData.port;
urlData.port = uri.getPort();
urlData.hostWithPort = urlData.server + (urlData.port == -1 ? "" : (":" + urlData.port));
Exception exception = null;
try {
String leaderboardNameFromQR = URLEncoder.encode(uri.getQueryParameter(DeviceMappingConstants.URL_LEADERBOARD_NAME), "UTF-8")
@@ -82,9 +94,7 @@ public class CheckinManager {
urlData.checkinURLStr = urlData.hostWithPort + prefs.getServerCheckinPath().replace("{leaderboard-name}", leaderboardNameFromQR);
urlData.eventId = uri.getQueryParameter(DeviceMappingConstants.URL_EVENT_ID);
urlData.leaderboardName = leaderboardNameFromQR;
urlData.deviceUuid = new SmartphoneUUIDIdentifierImpl(UUID.fromString(UniqueDeviceUuid.getUniqueId(activity)));
urlData.eventUrl = urlData.hostWithPort + prefs.getServerEventPath(urlData.eventId);
urlData.leaderboardUrl = urlData.hostWithPort + prefs.getServerLeaderboardPath(urlData.leaderboardName);
urlData.competitorUrl = urlData.hostWithPort + prefs.getServerCompetitorPath(urlData.competitorId);
@@ -106,7 +116,6 @@ public class CheckinManager {
private void getLeaderBoardFromServer(final URLData urlData, HttpGetRequest getLeaderboardRequest) {
NetworkHelper.getInstance(activity)
.executeHttpJsonRequestAsync(getLeaderboardRequest, new NetworkHelper.NetworkHelperSuccessListener() {
@Override
public void performAction(JSONObject response) {
@@ -145,28 +154,31 @@ public class CheckinManager {
@Override
public void performAction(JSONObject response) {
EventBaseJsonDeserializer deserializer = new EventBaseJsonDeserializer(
new VenueJsonDeserializer(new CourseAreaJsonDeserializer(new SharedDomainFactoryImpl(
new RaceLogResolver() {
@Override
public RaceLog resolve(SimpleRaceLogIdentifier identifier) {
return null;
}
}))), new LeaderboardGroupBaseJsonDeserializer());
try {
//TODO use constants
urlData.eventId = response.getString("id");
urlData.eventName = response.getString("name");
urlData.eventStartDateStr = response.getString("startDate");
urlData.eventEndDateStr = response.getString("endDate");
JSONArray imageUrls = response.getJSONArray("imageURLs");
if (imageUrls.length() > 0) {
urlData.eventFirstImageUrl = imageUrls.getString(0);
final EventBase event = deserializer.deserialize((org.json.simple.JSONObject) new JSONParser().parse(response.toString()));
urlData.eventId = event.getId().toString();
urlData.eventName = event.getName();
urlData.eventStartDateStr = ""+event.getStartDate().asMillis();
urlData.eventEndDateStr = ""+event.getEndDate().asMillis();
Iterable<ImageDescriptor> imageUrls = event.getImages();
if (!Util.isEmpty(imageUrls)) {
urlData.eventFirstImageUrl = imageUrls.iterator().next().getURL().toString();
} else {
urlData.eventFirstImageUrl = null;
}
} catch (JSONException e) {
} catch (JsonDeserializationException | ParseException e) {
ExLog.e(activity, TAG, "Error getting data from call on URL: " + urlData.eventUrl + ", Error: " + e.getMessage());
handleApiError();
return;
}
HttpGetRequest getCompetitorRequest;
try {
getCompetitorRequest = new HttpGetRequest(new URL(urlData.competitorUrl), activity);
@@ -84,9 +84,8 @@ public class CheckinManager {
URLData urlData = new URLData();
urlData.uriStr = uri.toString();
urlData.server = scheme + "://" + uri.getHost();
urlData.port = (uri.getPort() == -1) ? 80 : uri.getPort();
urlData.hostWithPort = urlData.server + ":" + urlData.port;
urlData.port = uri.getPort();
urlData.hostWithPort = urlData.server + (urlData.port == -1 ? "" : (":" + urlData.port));
String leaderboardNameFromQR = "";
try {
leaderboardNameFromQR = URLEncoder.encode(
+2 -2
View File
@@ -271,8 +271,8 @@ Here are the steps to create a load balanced setup:
- Create a master instance holding all data (see http://wiki.sapsailing.com/wiki/amazon-ec2#Setting-up-Master-and-Replica)
- When using the Race Committee App (RCApp), try to make sure the app is configured to send its data to the master instance and not the ELB (otherwise, write requests may end up at replicas which then have to reverse-replicate these to the master which is as of this writing (2014-12-18) an EXPERIMENTAL feature). You may want to configure a separate URL for the master server for this purpose, so you don't have to re-configure the RCApp devices when switching to a different master server.
- Create `n` instances that are configured to connect to the master server, automatically launching replication by using one of the `*...-replica-...*` environment from http://releases.sapsailing.com/environments.
- Create a load balancer that redirects everything from HTTP port 8888 to HTTP port 8888 and leave the other switches and checkboxes on their default value
- As "Ping Port" enter HTTP port 8888 and use /index.html as the "Ping Path." Leave the other values on their defaults again.
- Create a load balancer that redirects everything from HTTP port 80 to HTTP port 80 as well as HTTPS port 443 to HTTPS port 443 and leave the other switches and checkboxes on their default value. For the HTTPS listener, use the `sapsailing.com` certificate that should be offered as an existing certificate from IAM.
- As "Ping Port" enter HTTPS port 443 and use /index.html as the "Ping Path." Leave the other values on their defaults again.
- Put the ELB into the "Sailing Analytics App" security group as it will appear in the landscape as a regular sailing analytics application server.
- Associate all your instances
- Connect your domain with the IP of the load balancer. It could be a good idea to use an Elastic IP that always stays the same for the domain and associate it with your load balancer. That way you can also easily switch between a load balancer and a single instance setup. Again, remember not to let the RCApp devices point to the ELB domain as their updates could hit a replica which wouldn't know how to handle!
+11 -1
View File
@@ -62,4 +62,14 @@ To have a non-SSL `VirtualHost` redirect to the SSL counterpart, use a definitio
ServerName jobs.sapsailing.com
RedirectPermanent / https://jobs.sapsailing.com/
</VirtualHost>
```
```
## Elastic Load Balancer (ELB) with SSL / HTTPS
Amazon EC2 supports uploading the private and public key as well as the certificate chain when adding an HTTPS listener to an ELB. However, this only seems to work properly in the us-east region. As the IAM module has global scope, however, the key uploaded will afterwards be available for ELB HTTPS listener creation in all zones.
I've uploaded the *.sapsailing.com certificate today (2016-03-06) and named it `sapsailing.com`.
When you add listeners, make sure they also have the certificate for *.sapsailing.com installed. Choose the `*-SSL` macro variants in your `/etc/httpd/conf.d/001-events.conf` configuration file (which is now the default being generated by the startup script in `/etc/init.d/sailing`).
If your ELB uses a health check based on HTTP or HTTPS against `/index.html`, make sure that your instance responds to that, given an internal IP as the server name. This will usually require that your `001-events.conf` configuration file has as its first record an entry that does _not_ use the ELB DNS name as its server name. For example, you may add a `Use Plain-SSL` entry as the first entry with the hosts internal IP address as the host name. This entry should by default be generated into the `001-events.conf` file by the startup script in `/etc/init.d/sailing`, too.
+3 -1
View File
@@ -20,4 +20,6 @@ Now push your changes to the remote Git repository. It will take some time befor
* [Application Level Caching with Automatic Invalidation](/doc/theses/20140703_Bertone_Application_Level_Caching_With_Automatic_Invalidation.pdf) (Bachelor Thesis, Aug 2014, Raul Bertone)
* [Authentication and Authorization for SAP Sailing Analytics](/doc/theses/20140915_Ebling_Authentication_and_Authorization_for_SAP_Sailing_Analytics.pdf) (Bachelor Thesis, Sep 2014, Benjamin Ebling)
* [Authentication and Authorization for SAP Sailing Analytics](/doc/theses/20140915_Ebling_Authentication_and_Authorization_for_SAP_Sailing_Analytics.pdf) (Bachelor Thesis, Sep 2014, Benjamin Ebling)
* [Buoy Position Modeling and Correction in the SAP Sailing Analytics Suite](/doc/theses/20150305_Dann_Buoy_Position_Modeling_and_Correction_in_the_SAP_Sailing_Analytics_Suite.pdf) (T3000 Project Thesis, Feb 2015, Jonas Dann)