added loading and storing for SailingServer instances

improved admin UI
This commit is contained in:
fmittag committed 2014-05-12 14:16:52 +02:00
1 parent 43b078b760
commit d4820f2c98
19 files changed
+396 -85

No files matched your search

@@ -11,6 +11,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaRegistry;
import com.sap.sailing.domain.base.SailingServer;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.common.RaceIdentifier;
@@ -85,6 +86,8 @@ public interface DomainObjectFactory {
Iterable<Event> loadAllEvents();
Iterable<SailingServer> loadAllSailingServers();
Regatta loadRegatta(String name, TrackedRegattaRegistry trackedRegattaRegistry);
Iterable<Regatta> loadAllRegattas(TrackedRegattaRegistry trackedRegattaRegistry);
@@ -1,6 +1,7 @@
package com.sap.sailing.domain.persistence;
import java.io.Serializable;
import java.util.List;
import com.mongodb.DB;
import com.mongodb.DBObject;
@@ -8,6 +9,7 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SailingServer;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.configuration.DeviceConfiguration;
import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
@@ -79,6 +81,12 @@ public interface MongoObjectFactory {
*/
void removeEvent(Serializable id);
/**
* Stores the registered sailing servers
* @param serves the servers to store
*/
void storeSailingServers(List<SailingServer> serves);
/**
* Stores the regatta together with its name, {@link Series} definitions and an optional link to the
* {@link Event} to which the regatta belongs.
@@ -25,11 +25,16 @@ public enum CollectionNames {
LEADERBOARD_GROUPS,
/**
* Top-level event information about events such as Kiel Week 2011, or IDM Travemünde 2011, including name and
* Top-level event information about events such as Kiel Week 2011, or IDM Travem�nde 2011, including name and
* course areas.
*/
EVENTS,
/**
* Stores the registered sailing servers.
*/
SAILING_SERVERS,
/**
* Stores regatta definitions including their series layout and fleets and race columns. Regattas can reference
* the event from the {@link #EVENTS} collection to which they belong.
@@ -1,6 +1,8 @@
package com.sap.sailing.domain.persistence.impl;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -41,6 +43,7 @@ import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaRegistry;
import com.sap.sailing.domain.base.SailingServer;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.Waypoint;
@@ -53,6 +56,7 @@ import com.sap.sailing.domain.base.impl.CourseDataImpl;
import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SailingServerImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.VenueImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
@@ -852,7 +856,41 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Error connecting to MongoDB, unable to load events.");
logger.log(Level.SEVERE, "loadEvents", e);
logger.log(Level.SEVERE, "loadAllEvents", e);
}
return result;
}
private SailingServer loadSailingSever(DBObject serverDBObject) {
SailingServer result = null;
String name = (String) serverDBObject.get(FieldNames.SERVER_NAME.name());
String urlAsString = (String) serverDBObject.get(FieldNames.SERVER_URL.name());
try {
URL serverUrl = new URL(urlAsString);
result = new SailingServerImpl(name, serverUrl);
} catch (MalformedURLException e) {
logger.log(Level.SEVERE, "Can't load the sailing server with URL " +urlAsString, e);
}
return result;
}
@Override
public Iterable<SailingServer> loadAllSailingServers() {
ArrayList<SailingServer> result = new ArrayList<SailingServer>();
DBCollection serverCollection = database.getCollection(CollectionNames.SAILING_SERVERS.name());
try {
for (DBObject o : serverCollection.find()) {
if(loadSailingSever(o) != null) {
result.add(loadSailingSever(o));
}
}
} catch (Exception e) {
logger.log(Level.SEVERE, "Error connecting to MongoDB, unable to load sailing server instances URLs.");
logger.log(Level.SEVERE, "loadAllSailingServers", e);
}
return result;
@@ -39,7 +39,7 @@ public enum FieldNames {
VENUE,
VENUE_NAME,
COURSE_AREAS,
COURSE_AREA_NAME,
COURSE_AREA_ID,
@@ -83,7 +83,10 @@ public enum FieldNames {
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_NAME, still used to migrate old races*/ @Deprecated GATE_NAME,
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_LEFT, still used to migrate old races*/ @Deprecated GATE_LEFT,
/** @deprecated Replaced by CONTROLPOINTWITHTWOMARKS_RIGHT, still used to migrate old races*/ @Deprecated GATE_RIGHT,
// sailing server
SERVER_NAME,
SERVER_URL,
// configurations
CONFIGURATION_MATCHER, CONFIGURATION_CONFIG, CONFIGURATION_MATCHER_ID, CONFIGURATION_MATCHER_TYPE, CONFIGURATION_MATCHER_CLIENTS,
@@ -27,6 +27,7 @@ import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.SailingServer;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Timed;
import com.sap.sailing.domain.base.Venue;
@@ -417,6 +418,24 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
leaderboardGroupCollection.update(query, update, /* upsert */ true, /* multi */ false, WriteConcern.SAFE);
}
@Override
public void storeSailingServers(List<SailingServer> servers) {
for(SailingServer server: servers) {
storeSailingServer(server);
}
}
private void storeSailingServer(SailingServer server) {
DBCollection serverCollection = database.getCollection(CollectionNames.SAILING_SERVERS.name());
serverCollection.ensureIndex(FieldNames.SERVER_NAME.name());
DBObject query = new BasicDBObject();
query.put(FieldNames.SERVER_NAME.name(), server.getName());
DBObject serverDBObject = new BasicDBObject();
serverDBObject.put(FieldNames.SERVER_NAME.name(), server.getName());
serverDBObject.put(FieldNames.SERVER_URL.name(), server.getURL().toExternalForm());
serverCollection.update(query, serverDBObject, /* upsrt */ true, /* multi */ false, WriteConcern.SAFE);
}
@Override
public void storeEvent(Event event) {
DBCollection eventCollection = database.getCollection(CollectionNames.EVENTS.name());
@@ -0,0 +1,14 @@
package com.sap.sailing.domain.base;
import java.net.URL;
import com.sap.sailing.domain.common.Named;
/**
* A SailingServer represents a runtime instance of our server.
* @author Frank
*
*/
public interface SailingServer extends Named {
URL getURL();
}
@@ -0,0 +1,23 @@
package com.sap.sailing.domain.base.impl;
import java.net.URL;
import com.sap.sailing.domain.base.SailingServer;
import com.sap.sailing.domain.common.impl.NamedImpl;
public class SailingServerImpl extends NamedImpl implements SailingServer {
private static final long serialVersionUID = 3561284977118738878L;
/** the URL of the server */
private URL url;
public SailingServerImpl(String name, URL url) {
super(name);
this.url = url;
}
@Override
public URL getURL() {
return url;
}
}
@@ -160,7 +160,7 @@ public class AdminConsoleEntryPoint extends AbstractEntryPoint implements Regatt
addScrollableTab(tabPanel, resultImportUrlsManagementPanel, stringMessages.resultImportUrls());
SailingServerInstancesManagementPanel sailingServerInstancesManagementPanel = new SailingServerInstancesManagementPanel(sailingService, this, stringMessages);
addScrollableTab(tabPanel, sailingServerInstancesManagementPanel, stringMessages.sailingServerInstanceUrls());
addScrollableTab(tabPanel, sailingServerInstancesManagementPanel, stringMessages.sailingServers());
ReplicationPanel replicationPanel = new ReplicationPanel(sailingService, this, stringMessages);
// replicationPanel.ensureDebugId("ReplicationManagement");
@@ -0,0 +1,109 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Collection;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.shared.SailingServerDTO;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
public class SailingServerCreateOrEditDialog extends DataEntryDialog<SailingServerDTO> {
private StringMessages stringConstants;
private TextBox nameTextBox;
private TextBox urlTextBox;
private static class SailingServerValidator implements Validator<SailingServerDTO> {
private StringMessages stringConstants;
private ArrayList<SailingServerDTO> existingSailingServers;
public SailingServerValidator(StringMessages stringConstants, Collection<SailingServerDTO> existingSailingServers) {
this.stringConstants = stringConstants;
this.existingSailingServers = new ArrayList<SailingServerDTO>(existingSailingServers);
}
@Override
public String getErrorMessage(SailingServerDTO serverToValidate) {
String errorMessage = null;
boolean nameNotEmpty = serverToValidate.getName() != null && serverToValidate.getName().length() > 0;
boolean urlNotEmpty = serverToValidate.getUrl() != null && serverToValidate.getUrl().length() > 0;
boolean unique = true;
for (SailingServerDTO event : existingSailingServers) {
if (event.getName().equals(serverToValidate.getName())) {
unique = false;
break;
}
}
if (!nameNotEmpty) {
errorMessage = stringConstants.pleaseEnterAName();
} else if (!urlNotEmpty) {
errorMessage = stringConstants.pleaseEnterNonEmptyUrl();
} else if (!unique) {
errorMessage = stringConstants.eventWithThisNameAlreadyExists();
}
return errorMessage;
}
}
public SailingServerCreateOrEditDialog(ArrayList<SailingServerDTO> existingSailingServers, StringMessages stringConstants,
DialogCallback<SailingServerDTO> callback) {
this(existingSailingServers, null, false, stringConstants, callback);
}
public SailingServerCreateOrEditDialog(ArrayList<SailingServerDTO> existingSailingServers, SailingServerDTO serverToEdit, StringMessages stringConstants,
DialogCallback<SailingServerDTO> callback) {
this(existingSailingServers, serverToEdit, true, stringConstants, callback);
}
private SailingServerCreateOrEditDialog(ArrayList<SailingServerDTO> existingSailingServers, SailingServerDTO serverToEdit, boolean isEditMode, StringMessages stringConstants,
DialogCallback<SailingServerDTO> callback) {
super("Sailing Server", null, stringConstants.ok(), stringConstants.cancel(),
new SailingServerValidator(stringConstants, existingSailingServers), callback);
this.stringConstants = stringConstants;
nameTextBox = createTextBox(isEditMode ? serverToEdit.getName() : null);
nameTextBox.setVisibleLength(50);
urlTextBox = createTextBox(isEditMode ? serverToEdit.getUrl() : null);
urlTextBox.setVisibleLength(100);
nameTextBox.setEnabled(!isEditMode);
}
@Override
protected SailingServerDTO getResult() {
return new SailingServerDTO(nameTextBox.getText(), urlTextBox.getText());
}
@Override
protected Widget getAdditionalWidget() {
final VerticalPanel panel = new VerticalPanel();
Widget additionalWidget = super.getAdditionalWidget();
if (additionalWidget != null) {
panel.add(additionalWidget);
}
Grid formGrid = new Grid(2, 2);
panel.add(formGrid);
formGrid.setWidget(0, 0, new Label(stringConstants.name() + ":"));
formGrid.setWidget(0, 1, nameTextBox);
formGrid.setWidget(1, 0, new Label(stringConstants.url() + ":"));
formGrid.setWidget(1, 1, urlTextBox);
return panel;
}
@Override
public void show() {
super.show();
nameTextBox.setFocus(true);
}
}
@@ -1,11 +1,15 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
@@ -13,18 +17,16 @@ import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.TextfieldEntryDialog;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
import com.sap.sailing.gwt.ui.shared.SailingServerDTO;
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
public class SailingServerInstancesManagementPanel extends FlowPanel {
private final ListBox urlListBox;
private final SailingServiceAsync sailingService;
private final ErrorReporter errorReporter;
private final StringMessages stringMessages;
@@ -33,12 +35,43 @@ public class SailingServerInstancesManagementPanel extends FlowPanel {
private final Button removeButton;
private final Button refreshButton;
private CellTable<SailingServerDTO> serverTable;
private MultiSelectionModel<SailingServerDTO> serverSelectionModel;
private ListDataProvider<SailingServerDTO> serverDataProvider;
private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class);
public SailingServerInstancesManagementPanel(SailingServiceAsync sailingService, ErrorReporter errorReporter,
StringMessages stringMessages) {
this.sailingService = sailingService;
this.errorReporter = errorReporter;
this.stringMessages = stringMessages;
urlListBox = new ListBox(/* multiple select */ true);
TextColumn<SailingServerDTO> serverNameColumn = new TextColumn<SailingServerDTO>() {
@Override
public String getValue(SailingServerDTO server) {
return server.getName() != null ? server.getName() : "";
}
};
TextColumn<SailingServerDTO> serverUrlColumn = new TextColumn<SailingServerDTO>() {
@Override
public String getValue(SailingServerDTO server) {
return server.getUrl() != null ? server.getUrl() : "";
}
};
serverTable = new CellTable<SailingServerDTO>(10000, tableRes);
serverTable.addColumn(serverNameColumn, stringMessages.name());
serverTable.addColumn(serverUrlColumn, stringMessages.url());
serverTable.setEmptyTableWidget(new Label("No sailing server instances yet."));
serverSelectionModel = new MultiSelectionModel<SailingServerDTO>();
serverTable.setSelectionModel(serverSelectionModel);
serverDataProvider = new ListDataProvider<SailingServerDTO>();
serverDataProvider.addDataDisplay(serverTable);
addButton = new Button(stringMessages.add());
removeButton = new Button(stringMessages.remove());
@@ -46,19 +79,19 @@ public class SailingServerInstancesManagementPanel extends FlowPanel {
addButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
addUrl();
addSailingServer();
}
});
removeButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
removeSelectedUrls();
removeSelectedSailingServers();
}
});
refreshButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
refreshUrlList();
refreshSailingServerList();
}
});
VerticalPanel vp = new VerticalPanel();
@@ -66,93 +99,78 @@ public class SailingServerInstancesManagementPanel extends FlowPanel {
providerSelectionPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
vp.add(providerSelectionPanel);
providerSelectionPanel.add(new Label("SailingServer Instance URL's"));
providerSelectionPanel.add(new Label("Registered SailingServer Instances"));
vp.add(urlListBox);
HorizontalPanel buttonPanel = new HorizontalPanel();
vp.add(buttonPanel);
buttonPanel.add(addButton);
buttonPanel.add(removeButton);
buttonPanel.add(refreshButton);
vp.add(serverTable);
vp.add(buttonPanel);
add(vp);
refreshUrlList();
refreshSailingServerList();
}
private void refreshUrlList() {
sailingService.getSailingServerInstanceUrls(new AsyncCallback<List<String>>() {
private void refreshSailingServerList() {
sailingService.getSailingServers(new AsyncCallback<List<SailingServerDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorRefreshingSailingServerInstanceUrlList(caught.getMessage()));
errorReporter.reportError(stringMessages.errorRefreshingSailingServers(caught.getMessage()));
}
@Override
public void onSuccess(List<String> result) {
urlListBox.clear();
for (String s : result) {
urlListBox.addItem(s);
}
public void onSuccess(List<SailingServerDTO> result) {
serverDataProvider.getList().clear();
serverDataProvider.getList().addAll(result);
}
});
}
private void removeSelectedUrls() {
private void removeSelectedSailingServers() {
Set<String> toRemove = new HashSet<String>();
for (int i=urlListBox.getItemCount()-1; i>=0; i--) {
if (urlListBox.isItemSelected(i)) {
toRemove.add(urlListBox.getItemText(i));
urlListBox.removeItem(i);
}
for (SailingServerDTO selectedServer: serverSelectionModel.getSelectedSet()) {
toRemove.add(selectedServer.getName());
}
sailingService.removeSailingServerInstanceURLs(toRemove, new AsyncCallback<Void>() {
sailingService.removeSailingServers(toRemove, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorRemovingSailingServerInstanceUrls(caught.getMessage()));
refreshUrlList();
errorReporter.reportError(stringMessages.errorRemovingSailingServers(caught.getMessage()));
}
@Override
public void onSuccess(Void result) {
Window.setStatus(stringMessages.successfullyUpdatedSailingServerInstanceUrls());
refreshSailingServerList();
Window.setStatus(stringMessages.successfullyUpdatedSailingServers());
}
});
}
private void addUrl() {
final TextfieldEntryDialog dialog = new TextfieldEntryDialog(stringMessages.addSailingServerInstanceUrl(),
stringMessages.addSailingServerInstanceUrl(), stringMessages.add(), stringMessages.cancel(), "http://",
new DataEntryDialog.Validator<String>() {
@Override
public String getErrorMessage(String valueToValidate) {
String result = null;
if (valueToValidate == null || valueToValidate.length() == 0) {
result = stringMessages.pleaseEnterNonEmptyUrl();
}
return result;
}
}, new DialogCallback<String>() {
private void addSailingServer() {
ArrayList<SailingServerDTO> existingServers = new ArrayList<SailingServerDTO>(serverDataProvider.getList());
SailingServerCreateOrEditDialog dialog = new SailingServerCreateOrEditDialog(existingServers, stringMessages, new DialogCallback<SailingServerDTO>() {
@Override
public void cancel() {
// user cancelled; just don't add
}
@Override
public void ok(final String url) {
sailingService.addSailingServerInstanceUrl(url, new AsyncCallback<Void>() {
public void ok(final SailingServerDTO server) {
sailingService.addSailingServer(server, new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError(stringMessages.errorAddingSailingServerInstanceUrl(caught.getMessage()));
errorReporter.reportError(stringMessages.errorAddingSailingServer(caught.getMessage()));
}
@Override
public void onSuccess(Void result) {
urlListBox.addItem(url);
Window.setStatus(stringMessages.successfullyUpdatedSailingServerInstanceUrls());
serverDataProvider.getList().add(server);
Window.setStatus(stringMessages.successfullyUpdatedSailingServers());
}
});
}
});
dialog.getEntryField().setVisibleLength(100);
dialog.show();
dialog.show();
}
}
@@ -53,6 +53,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO;
import com.sap.sailing.gwt.ui.shared.SailingServerDTO;
import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO;
@@ -279,11 +280,11 @@ public interface SailingService extends RemoteService {
WindInfoForRaceDTO getWindSourcesInfo(RegattaAndRaceIdentifier raceIdentifier);
List<String> getSailingServerInstanceUrls();
List<SailingServerDTO> getSailingServers();
void removeSailingServerInstanceURLs(Set<String> toRemove) throws Exception;
void removeSailingServers(Set<String> toRemove) throws Exception;
void addSailingServerInstanceUrl(String url) throws Exception;
void addSailingServer(SailingServerDTO sailingServer) throws Exception;
List<String> getResultImportUrls(String resultProviderName);
@@ -55,6 +55,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO;
import com.sap.sailing.gwt.ui.shared.SailingServerDTO;
import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO;
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
import com.sap.sailing.gwt.ui.shared.SwissTimingArchiveConfigurationDTO;
@@ -390,11 +391,11 @@ public interface SailingServiceAsync {
void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier, List<Pair<ControlPointDTO, PassingInstruction>> controlPoints, AsyncCallback<Void> callback);
void getSailingServerInstanceUrls(AsyncCallback<List<String>> callback);
void getSailingServers(AsyncCallback<List<SailingServerDTO>> callback);
void removeSailingServerInstanceURLs(Set<String> toRemove, AsyncCallback<Void> callback);
void removeSailingServers(Set<String> toRemove, AsyncCallback<Void> callback);
void addSailingServerInstanceUrl(String url, AsyncCallback<Void> callback);
void addSailingServer(SailingServerDTO sailingServer, AsyncCallback<Void> callback);
void getResultImportUrls(String resultProviderName, AsyncCallback<List<String>> callback);
@@ -358,12 +358,12 @@ public interface StringMessages extends Messages {
String pleaseEnterNonEmptyUrl();
String addResultImportUrl();
String errorAddingResultImportUrl(String message);
String sailingServerInstanceUrls();
String errorRefreshingSailingServerInstanceUrlList(String message);
String successfullyUpdatedSailingServerInstanceUrls();
String errorRemovingSailingServerInstanceUrls(String message);
String addSailingServerInstanceUrl();
String errorAddingSailingServerInstanceUrl(String message);
String sailingServers();
String errorRefreshingSailingServers(String message);
String successfullyUpdatedSailingServers();
String errorRemovingSailingServers(String message);
String addSailingServer();
String errorAddingSailingServer(String message);
String errorTryingToObtainLeaderboardContents(String message);
String lastScoreUpdate();
String warningBrowserUnsupported();
@@ -385,12 +385,12 @@ errorRemovingResultImportUrls=Error removing result import URLs: {0}
pleaseEnterNonEmptyUrl=Please enter a URL.
addResultImportUrl=Add result import URL
errorAddingResultImportUrl=Error adding result import URL: {0}
sailingServerInstanceUrls=SailingServer-Instance URLs
errorRefreshingSailingServerInstanceUrlList=Error refreshing SailingServer-Instance URL list: {0}
successfullyUpdatedSailingServerInstanceUrls=Successfully updated SailingServer-Instance URL list
errorRemovingSailingServerInstanceUrls=Error removing SailingServer-Instance URLs: {0}
addSailingServerInstanceUrl=Add SailingServer-Instance URL
errorAddingSailingServerInstanceUrl=Error adding SailingServer-Instance URL: {0}
sailingServers=SailingServer instances
errorRefreshingSailingServers=Error refreshing SailingServer instances: {0}
successfullyUpdatedSailingServers=Successfully updated SailingServer instances
errorRemovingSailingServers=Error removing SailingServer instances: {0}
addSailingServer=Add SailingServer instance
errorAddingSailingServer=Error adding SailingServer instance: {0}
errorTryingToObtainLeaderboardContents=Error trying to obtain leaderboard contents: {0}
lastScoreUpdate=Last Score Update
warningBrowserUnsupported=This website is not optimized for your browser. Please switch to a newer one like Firefox or Chrome.
@@ -386,12 +386,12 @@ errorRemovingResultImportUrls=Fehler beim Löschen von Ergebnisimport URLs: {0}
pleaseEnterNonEmptyUrl=Bitte gebe eine URL ein.
addResultImportUrl=Ergebnisimport-URL hinzufügen
errorAddingResultImportUrl=Fehler beim Hinzufügen einer Ergebnisimport URL: {0}
sailingServerInstanceUrls=SailingServer-Instanz URLs
errorRefreshingSailingServerInstanceUrlList=Fehler beim Aktualisieren der SailingServer-Instanz URL-Liste: {0}
successfullyUpdatedSailingServerInstanceUrls=SailingServer-Instanz URL-Liste erfolgreich aktualisiert
errorRemovingSailingServerInstanceUrls=Fehler beim Löschen von SailingServer-Instanz URLs: {0}
addSailingServerInstanceUrl=SailingServer-Instanz URL hinzufügen
errorAddingSailingServerInstanceUrl=Fehler beim Hinzufügen einer SailingServer-Instanz URL: {0}
sailingServers=SailingServer Instanzen
errorRefreshingSailingServers=Fehler beim Aktualisieren der SailingServer Instanzen: {0}
successfullyUpdatedSailingServers=SailingServer Instanzen erfolgreich aktualisiert
errorRemovingSailingServers=Fehler beim Löschen von SailingServer Instanzen: {0}
addSailingServer=SailingServer Instanz hinzufügen
errorAddingSailingServer=Fehler beim Hinzufügen einer SailingServer Instanz: {0}
errorTryingToObtainLeaderboardContents=Fehler beim Berechnen der Ergebnisliste: {0}
lastScoreUpdate=Letzte Ergebnisänderung
warningBrowserUnsupported=Diese Webseite ist für Ihren Browser nicht optimiert. Wir empfehlen den Firefox oder Chrome in der neuesten Version.
@@ -247,6 +247,7 @@ import com.sap.sailing.gwt.ui.shared.RegattaScoreCorrectionDTO.ScoreCorrectionEn
import com.sap.sailing.gwt.ui.shared.ReplicaDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationMasterDTO;
import com.sap.sailing.gwt.ui.shared.ReplicationStateDTO;
import com.sap.sailing.gwt.ui.shared.SailingServerDTO;
import com.sap.sailing.gwt.ui.shared.ScoreCorrectionProviderDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
import com.sap.sailing.gwt.ui.shared.SidelineDTO;
@@ -3173,17 +3174,18 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
@Override
public List<String> getSailingServerInstanceUrls() {
return null;
public List<SailingServerDTO> getSailingServers() {
List<SailingServerDTO> result = new ArrayList<SailingServerDTO>();
return result;
}
@Override
public void removeSailingServerInstanceURLs(Set<String> toRemove) throws Exception {
public void removeSailingServers(Set<String> namesOfSailingServersToRemove) throws Exception {
}
@Override
public void addSailingServerInstanceUrl(String url) throws Exception {
public void addSailingServer(SailingServerDTO sailingServer) throws Exception {
}
@@ -0,0 +1,22 @@
package com.sap.sailing.gwt.ui.shared;
import com.google.gwt.user.client.rpc.IsSerializable;
import com.sap.sailing.domain.common.dto.NamedDTO;
public class SailingServerDTO extends NamedDTO implements IsSerializable {
private static final long serialVersionUID = -4209262742778693873L;
private String url;
// for GWT
SailingServerDTO() {}
public SailingServerDTO(String name, String url) {
super(name);
this.url = url;
}
public String getUrl() {
return url;
}
}
@@ -1,11 +1,15 @@
package com.sap.sailing.server.impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -43,6 +47,7 @@ import com.sap.sailing.domain.base.RaceColumnInSeries;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaListener;
import com.sap.sailing.domain.base.SailingServer;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
@@ -181,6 +186,11 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
*/
protected final ConcurrentHashMap<Serializable, Event> eventsById;
/**
* Holds the {@link Event} objects for the events of all registerd sailing server instances.
*/
protected final ConcurrentHashMap<Serializable, Event> cachedEventsOfAllSailingServerInstancesById;
/**
* Holds the {@link Regatta} objects for those races registered with this service. Note that there may be
* {@link Regatta} objects that exist outside this service for regattas not (yet) registered here.
@@ -333,6 +343,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
regattasByName = new ConcurrentHashMap<String, Regatta>();
eventsById = new ConcurrentHashMap<Serializable, Event>();
cachedEventsOfAllSailingServerInstancesById = new ConcurrentHashMap<Serializable, Event>();
regattaTrackingCache = new ConcurrentHashMap<>();
raceTrackersByRegatta = new ConcurrentHashMap<>();
raceTrackersByID = new ConcurrentHashMap<>();
@@ -357,6 +368,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
loadStoredLeaderboardsAndGroups();
loadMediaLibary();
loadStoredDeviceConfigurations();
loadEventsForAllSailingServerInstances();
}
@Override
@@ -437,6 +449,39 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
}
}
private void loadEventsForAllSailingServerInstances() {
List<Event> allEvents = new ArrayList<Event>();
for (SailingServer server: domainObjectFactory.loadAllSailingServers()) {
String getEventsUrl = server.getURL().toExternalForm() + "sailingserver/api/v1/events";
try {
StringBuilder content = new StringBuilder();
URL url = new URL(getEventsUrl);
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
content.append(line + "\n");
}
bufferedReader.close();
}
catch (IOException e) {
}
}
synchronized (cachedEventsOfAllSailingServerInstancesById) {
cachedEventsOfAllSailingServerInstancesById.clear();
for (Event event : allEvents) {
if (event.getId() != null)
cachedEventsOfAllSailingServerInstancesById.put(event.getId(), event);
}
}
}
/**
* Collects media track references from the configured sources (mongo DB by default, ftp folder yet to be
* implemented). The method is expected to be called initially blocking the API until finished.