Merge remote-tracking branch 'origin/master' into ribdashboard

This commit is contained in:
Alexander Ries committed 2015-05-28 09:20:27 +02:00
commit e1fb488635
27 files changed
+219 -106

No files matched your search

@@ -43,7 +43,7 @@ public enum BoatClassMasterdata {
NACRA_17 ("Nacra 17", true, 5.25, 2.59, BoatHullType.CATAMARAN, true, "N17", "Nacra-17"),
OK ("OK Dinghy", true, 5.25, 2.59, BoatHullType.MONOHULL, false, "OK-Dinghy", "OK-Jolle", "OK"),
OPTIMIST ("Optimist", true, 2.34, 1.07, BoatHullType.MONOHULL, false, "Opti", "Optimist Dinghy"),
PIRAT ("Pirat", true, 5.00, 1.61, BoatHullType.MONOHULL, false, "Pirate", "Piraten"),
PIRATE ("Pirate", true, 5.00, 1.61, BoatHullType.MONOHULL, false, "Pirat", "Piraten"),
PLATU_25 ("Platu 25", true, 7.53, 2.62, BoatHullType.MONOHULL, true, "Platu", "Platu-25", "PLA", "B25"),
RS_X ("RS:X", true, 2.86, 0.93, BoatHullType.SURFERBOARD, false, "RS-X", "RSX", "RS:X"),
SONAR ("Sonar", true, 7.01, 2.39, BoatHullType.MONOHULL, true),
@@ -16,4 +16,6 @@ public interface LiveDataConnection {
boolean waitForConnection(long timeoutInMillis) throws InterruptedException;
void addListener(BulkFixReceiver listener);
void removeListener(BulkFixReceiver listener);
}
@@ -26,7 +26,7 @@ public class IgtimiWindTracker extends AbstractWindTracker implements WindTracke
private static final Logger logger = Logger.getLogger(IgtimiWindTracker.class.getName());
private static final int TIME_INTERVAL_TO_TRACK_BEFORE_RACE_START_MILLIS = 10*60*1000; // 10 minutes
private static final long TIME_INTERVAL_TO_TRACK_AFTER_END_OF_RACE_MILLIS = 60*60*1000; // 60 minutes
private final Map<LiveDataConnection, Util.Pair<Iterable<String>, Account>> liveConnectionsAndDeviceSerialNumber;
private final Map<LiveDataConnection, Util.Triple<Iterable<String>, Account, IgtimiWindReceiver>> liveConnectionsAndDeviceSerialNumber;
private final IgtimiWindTrackerFactory windTrackerFactory;
private boolean stopping;
@@ -51,7 +51,8 @@ public class IgtimiWindTracker extends AbstractWindTracker implements WindTracke
IgtimiWindReceiver windReceiver = new IgtimiWindReceiver(correctByDeclination ? DeclinationService.INSTANCE : null);
liveConnection.addListener(windReceiver);
windReceiver.addListener(new WindListenerSendingToTrackedRace(Collections.singleton(getTrackedRace()), windTrackerFactory));
liveConnectionsAndDeviceSerialNumber.put(liveConnection, new Util.Pair<Iterable<String>, Account>(devicesWeShouldListenTo, account));
liveConnectionsAndDeviceSerialNumber.put(liveConnection, new Util.Triple<Iterable<String>, Account, IgtimiWindReceiver>(
devicesWeShouldListenTo, account, windReceiver));
}
}
} catch (Exception e) {
@@ -111,15 +112,16 @@ public class IgtimiWindTracker extends AbstractWindTracker implements WindTracke
synchronized (this) {
windTrackerFactory.windTrackerStopped(getTrackedRace().getRace(), this);
for (LiveDataConnection ldc : liveConnectionsAndDeviceSerialNumber.keySet()) {
final Util.Triple<Iterable<String>, Account, IgtimiWindReceiver> deviceSerialNumberAndAccountAndReceiver = liveConnectionsAndDeviceSerialNumber.get(ldc);
try {
logger.info("Stopping Igtimi live connection "+ldc);
ldc.stop();
ldc.stop(); // does reference counting and stops the live connection only if no other client is active anymore
ldc.removeListener(deviceSerialNumberAndAccountAndReceiver.getC());
} catch (Exception e) {
final Util.Pair<Iterable<String>, Account> deviceSerialNumberAndAccount = liveConnectionsAndDeviceSerialNumber.get(ldc);
logger.log(Level.INFO,
"Exception trying to stop Igtimi live connection for wind receiver for race "
+ getTrackedRace().getRace() + " and device " + deviceSerialNumberAndAccount.getA()
+ " in account " + deviceSerialNumberAndAccount.getB());
+ getTrackedRace().getRace() + " and device " + deviceSerialNumberAndAccountAndReceiver.getA()
+ " in account " + deviceSerialNumberAndAccountAndReceiver.getB());
}
}
}
@@ -33,9 +33,12 @@ public class LiveDataConnectionFactoryImpl implements LiveDataConnectionFactory
Util.addAll(deviceSerialNumbers, deviceSerialNumbersAsSet);
LiveDataConnection result = dataConnectionsForDeviceSerialNumbers.get(deviceSerialNumbersAsSet);
if (result == null) {
logger.info("Didn't find an existing Igtimi LiveDataConnection for devices "+deviceSerialNumbersAsSet+"; creating one...");
result = new WebSocketConnectionManager(connectionFactory, deviceSerialNumbers, account);
dataConnectionsForDeviceSerialNumbers.put(deviceSerialNumbersAsSet, result);
deviceSerialNumersForDataConnections.put(result, deviceSerialNumbersAsSet);
} else {
logger.info("Found an existing Igtimi LiveDataConnection for devices "+deviceSerialNumbersAsSet+"; using it.");
}
Integer usageCount = usageCounts.get(result);
if (usageCount == null) {
@@ -34,6 +34,11 @@ public class LiveDataConnectionWrapper implements LiveDataConnection {
actualConnection.addListener(listener);
}
@Override
public void removeListener(BulkFixReceiver listener) {
actualConnection.removeListener(listener);
}
/**
* Makes the actual connection available to other classes in this package, particularly the test classes in the test fragment of the same package
*/
@@ -152,6 +152,11 @@ public class WebSocketConnectionManager extends WebSocketAdapter implements Live
listeners.put(listener, listener);
}
@Override
public void removeListener(BulkFixReceiver listener) {
listeners.remove(listener);
}
private void notifyListeners(List<Fix> fixes) {
for (BulkFixReceiver listener : listeners.keySet()) {
try {
@@ -11,6 +11,4 @@ public interface RaceStateEventScheduler {
void unscheduleStateEvent(RaceStateEvents stateEventName);
void unscheduleAllEvents();
}
@@ -68,27 +68,35 @@ public class RaceStartedAndFinishedReceiver extends AbstractReceiverWithQueue<IR
System.out.print("StartStop");
DynamicTrackedRace trackedRace = getTrackedRace(event.getA());
if (trackedRace != null) {
IStartStopData startEndTrackingTimesData = event.getB();
if (startEndTrackingTimesData != null) {
final long startTrackingTime = startEndTrackingTimesData.getStartTime();
TimePoint startOfTracking = startTrackingTime == 0 ? null : getSimulator() == null ?
new MillisecondsTimePoint(startTrackingTime) :
getSimulator().advance(new MillisecondsTimePoint(startTrackingTime));
trackedRace.setStartOfTrackingReceived(startOfTracking);
final long endTrackingTime = startEndTrackingTimesData.getStopTime();
TimePoint endOfTracking = endTrackingTime == 0 ? null : getSimulator() == null ?
new MillisecondsTimePoint(endTrackingTime) :
getSimulator().advance(new MillisecondsTimePoint(endTrackingTime));
trackedRace.setEndOfTrackingReceived(endOfTracking);
}
IStartStopData startEndRaceTimesData = event.getC();
if (startEndRaceTimesData != null) {
final long startTime = startEndRaceTimesData.getStartTime();
TimePoint startOfRace = startTime == 0 ? null : getSimulator() == null ?
new MillisecondsTimePoint(startTime) :
getSimulator().advance(new MillisecondsTimePoint(startTime));
trackedRace.setStartTimeReceived(startOfRace);
// Note that end of race can't currently be set on a tracked race
final IRace race = event.getA();
// An uninitialized race means that all timing data is not valid; we replace start of tracking,
// end of tracking and start time received by null values.
if (!race.isInitialized()) {
trackedRace.setStartOfTrackingReceived(null);
trackedRace.setEndOfTrackingReceived(null);
trackedRace.setStartTimeReceived(null);
} else {
IStartStopData startEndTrackingTimesData = event.getB();
if (startEndTrackingTimesData != null) {
final long startTrackingTime = startEndTrackingTimesData.getStartTime();
TimePoint startOfTracking = startTrackingTime == 0 ? null
: getSimulator() == null ? new MillisecondsTimePoint(startTrackingTime) : getSimulator()
.advance(new MillisecondsTimePoint(startTrackingTime));
trackedRace.setStartOfTrackingReceived(startOfTracking);
final long endTrackingTime = startEndTrackingTimesData.getStopTime();
TimePoint endOfTracking = endTrackingTime == 0 ? null
: getSimulator() == null ? new MillisecondsTimePoint(endTrackingTime) : getSimulator()
.advance(new MillisecondsTimePoint(endTrackingTime));
trackedRace.setEndOfTrackingReceived(endOfTracking);
}
IStartStopData startEndRaceTimesData = event.getC();
if (startEndRaceTimesData != null) {
final long startTime = startEndRaceTimesData.getStartTime();
TimePoint startOfRace = startTime == 0 ? null : getSimulator() == null ? new MillisecondsTimePoint(
startTime) : getSimulator().advance(new MillisecondsTimePoint(startTime));
trackedRace.setStartTimeReceived(startOfRace);
// Note that end of race can't currently be set on a tracked race
}
}
} else {
logger.warning("Couldn't find tracked race for race " + event.getA().getName()
@@ -51,6 +51,8 @@ public interface Series extends SeriesBase {
*/
RaceColumnInSeries addRaceColumn(String raceColumnName, TrackedRegattaRegistry trackedRegattaRegistry);
RaceColumnInSeries addRaceColumn(int insertIndex, String raceColumnName, TrackedRegattaRegistry trackedRegattaRegistry);
void moveRaceColumnUp(String raceColumnName);
void moveRaceColumnDown(String raceColumnName);
@@ -141,10 +141,15 @@ public class SeriesImpl extends RenamableImpl implements Series, RaceColumnListe
*/
@Override
public RaceColumnInSeries addRaceColumn(String raceColumnName, TrackedRegattaRegistry trackedRegattaRegistry) {
return addRaceColumn(raceColumns.size(), raceColumnName, trackedRegattaRegistry);
}
@Override
public RaceColumnInSeries addRaceColumn(int insertIndex, String raceColumnName, TrackedRegattaRegistry trackedRegattaRegistry) {
RaceColumnInSeriesImpl result = createRaceColumn(raceColumnName, trackedRegattaRegistry);
if (raceColumnListeners.canAddRaceColumnToContainer(result)) {
result.addRaceColumnListener(this);
raceColumns.add(result);
raceColumns.add(insertIndex, result);
raceColumnListeners.notifyListenersAboutRaceColumnAddedToContainer(result);
} else {
result = null;
@@ -75,6 +75,9 @@ public class WaypointPositionAndDistanceCache {
private final TrackedRace trackedRace;
/**
* A synchronized list
*/
private final List<Waypoint> waypoints;
public WaypointPositionAndDistanceCache(TrackedRace race, Duration timeRangeResolution) {
@@ -190,24 +193,28 @@ public class WaypointPositionAndDistanceCache {
SortedMap<TimePoint, Position> map = waypointPositionCache.get(controlPoint);
if (map != null) {
final SortedMap<TimePoint, Position> tailMap = map.tailMap(roundToResolution(affectedTimeRange.from()));
for (Entry<TimePoint, Position> e : tailMap.entrySet()) {
final TimePoint timePoint = e.getKey();
if (timePoint.after(affectedTimeRange.to())) {
break;
}
assert timePoint.equals(roundToResolution(timePoint));
map.remove(timePoint);
synchronized (waypoints) {
for (Waypoint otherWaypoint : waypoints) {
ControlPoint otherControlPoint = otherWaypoint.getControlPoint();
if (otherControlPoint != controlPoint) {
final Map<TimePoint, Distance> distanceMap = distanceCache.get(new Pair<>(controlPoint, otherControlPoint));
if (distanceMap != null) {
distanceMap.remove(timePoint);
}
final Map<TimePoint, Distance> otherDistanceMap = distanceCache.get(new Pair<>(otherControlPoint, controlPoint));
if (otherDistanceMap != null) {
otherDistanceMap.remove(timePoint);
synchronized (map) {
for (Entry<TimePoint, Position> e : tailMap.entrySet()) {
final TimePoint timePoint = e.getKey();
if (timePoint.after(affectedTimeRange.to())) {
break;
}
assert timePoint.equals(roundToResolution(timePoint));
map.remove(timePoint);
synchronized (waypoints) {
for (Waypoint otherWaypoint : waypoints) {
ControlPoint otherControlPoint = otherWaypoint.getControlPoint();
if (otherControlPoint != controlPoint) {
final Map<TimePoint, Distance> distanceMap = distanceCache.get(new Pair<>(controlPoint,
otherControlPoint));
if (distanceMap != null) {
distanceMap.remove(timePoint);
}
final Map<TimePoint, Distance> otherDistanceMap = distanceCache.get(new Pair<>(
otherControlPoint, controlPoint));
if (otherDistanceMap != null) {
otherDistanceMap.remove(timePoint);
}
}
}
}
@@ -785,11 +785,17 @@ public interface TrackedRace extends Serializable {
boolean isUsingMarkPassingCalculator();
/**
* @param timepoint Used for positions of marks and wind information
* Calculates the estimated time it takes a competitor to sail the race, from start to finish.
*
* @param timepoint
* Used for positions of marks and wind information; note that sometimes the marks are not in place yet
* when the race starts and that a windward mark may be collected already before the race finishes.
*
* @return estimated time it takes to complete the race
* @throws NotEnoughDataHasBeenAddedException thrown if not enough polar data has been added or polar data service
* is not available
* @throws NoWindException
*
* @throws NotEnoughDataHasBeenAddedException
* thrown if not enough polar data has been added or polar data service is not available
* @throws NoWindException
*/
Duration getEstimatedTimeToComplete(TimePoint timepoint) throws NotEnoughDataHasBeenAddedException, NoWindException;
@@ -4,21 +4,6 @@
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
<listEntry value="com.sap.sailing.gwt.ui.Simulator"/>
<listEntry value="com.sap.sailing.gwt.ui.Leaderboard"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
<listEntry value="com.sap.sailing.gwt.ui.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.DataMining"/>
<listEntry value="com.sap.sailing.gwt.Home"/>
<listEntry value="com.sap.sailing.gwt.ui.RaceBoard"/>
<listEntry value="com.sap.sailing.gwt.ui.YoutubePopup"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
</listAttribute>
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/gwt/Home.html"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
@@ -71,7 +56,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.regattaoverview.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.regattaoverview.RegattaOverview com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.ui.RegattaOverview"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xms1024m -Xmx3072m"/>
</launchConfiguration>
@@ -12,7 +12,7 @@
<listEntry value="com.sap.sailing.gwt.ui.LeaderboardEditing"/>
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
<listEntry value="com.sap.sailing.gwt.ui.Spectator"/>
<listEntry value="com.sap.sailing.gwt.ui.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<listEntry value="com.sap.sailing.gwt.AutoPlay"/>
<listEntry value="com.sap.sailing.gwt.ui.VideoPopup"/>
<listEntry value="com.sap.sailing.gwt.ui.PolarSheets"/>
@@ -69,7 +69,7 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /security/ui/Login.html com.sap.sse.security.ui.Login -startupUrl /security/ui/EditProfile.html com.sap.sse.security.ui.EditProfile -startupUrl /security/ui/EmailValidation.html com.sap.sse.security.ui.EmailValidation com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.RegattaOverview com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort auto -startupUrl /gwt/Home.html com.sap.sailing.gwt.Home -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.ui.AdminConsole -startupUrl /gwt/LeaderboardEditing.html com.sap.sailing.gwt.ui.LeaderboardEditing -startupUrl /gwt/Leaderboard.html com.sap.sailing.gwt.ui.Leaderboard -startupUrl /gwt/Spectator.html com.sap.sailing.gwt.ui.Spectator -startupUrl /gwt/RaceBoard.html com.sap.sailing.gwt.ui.RaceBoard -startupUrl /gwt/PolarSheets.html com.sap.sailing.gwt.ui.PolarSheets -startupUrl /gwt/RegattaOverview.html com.sap.sailing.gwt.ui.RegattaOverview -startupUrl /gwt/DataMining.html com.sap.sailing.gwt.ui.DataMining -startupUrl /gwt/Simulator.html com.sap.sailing.gwt.ui.Simulator -startupUrl /gwt/VideoPopup.html com.sap.sailing.gwt.ui.VideoPopup -startupUrl /security/ui/Login.html com.sap.sse.security.ui.Login -startupUrl /security/ui/EditProfile.html com.sap.sse.security.ui.EditProfile -startupUrl /security/ui/EmailValidation.html com.sap.sse.security.ui.EmailValidation com.sap.sailing.gwt.ui.Simulator com.sap.sailing.gwt.ui.Leaderboard com.sap.sailing.gwt.ui.PolarSheets com.sap.sailing.gwt.ui.VideoPopup com.sap.sailing.gwt.AutoPlay com.sap.sailing.gwt.ui.Spectator com.sap.sailing.gwt.ui.AdminConsole com.sap.sailing.gwt.ui.LeaderboardEditing com.sap.sailing.gwt.ui.YoutubePopup com.sap.sailing.gwt.ui.DataMining com.sap.sailing.gwt.Home com.sap.sailing.gwt.ui.RaceBoard com.sap.sailing.gwt.regattaoverview.RegattaOverview"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
</launchConfiguration>
@@ -58,7 +58,7 @@ public class BoatClassImageResolver {
boatClassIconsMap.put(BoatClassMasterdata.NACRA_17.getDisplayName(), imageResources.Nacra17Icon());
boatClassIconsMap.put(BoatClassMasterdata.OK.getDisplayName(), imageResources.OKIcon());
boatClassIconsMap.put(BoatClassMasterdata.OPTIMIST.getDisplayName(), imageResources.OptimistIcon());
boatClassIconsMap.put(BoatClassMasterdata.PIRAT.getDisplayName(), imageResources.PiratIcon());
boatClassIconsMap.put(BoatClassMasterdata.PIRATE.getDisplayName(), imageResources.PiratIcon());
boatClassIconsMap.put(BoatClassMasterdata.PLATU_25.getDisplayName(), imageResources.Platu25Icon());
boatClassIconsMap.put(BoatClassMasterdata.RS_X.getDisplayName(), imageResources.RSXIcon());
boatClassIconsMap.put(BoatClassMasterdata.SONAR.getDisplayName(), imageResources.SonarIcon());
@@ -31,6 +31,7 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.SeriesDTO;
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;
@@ -289,14 +290,16 @@ public class RegattaDetailsComposite extends Composite {
final boolean seriesNameChanged = !series.getName().equals(seriesDescriptor.getSeriesName());
final RegattaIdentifier regattaIdentifier = new RegattaName(regatta.getName());
List<RaceColumnDTO> existingRaceColumns = series.getRaceColumns();
final List<String> raceColumnsToAdd = new ArrayList<String>();
final List<String> raceColumnsToRemove = new ArrayList<String>();
final List<Pair<String, Integer>> raceColumnNamesToAddWithInsertIndex = new ArrayList<>();
final List<String> raceColumnsToRemove = new ArrayList<>();
// TODO see bug 1447: the resulting order currently doesn't necessarily match the order of races in this dialog!
int insertIndex = 0;
for (RaceColumnDTO newRaceColumn : newRaceColumns) {
if (!existingRaceColumns.contains(newRaceColumn)) {
raceColumnsToAdd.add(newRaceColumn.getName());
raceColumnNamesToAddWithInsertIndex.add(new Pair<>(newRaceColumn.getName(), insertIndex));
}
insertIndex++;
}
for (RaceColumnDTO existingRaceColumn : existingRaceColumns) {
if (!newRaceColumns.contains(existingRaceColumn)) {
@@ -314,32 +317,32 @@ public class RegattaDetailsComposite extends Composite {
racesToRemove.append(raceColumnToRemove);
}
if (raceColumnsToRemove.isEmpty() || Window.confirm(stringMessages.reallyRemoveRace(racesToRemove.toString()))) {
sailingService.addRaceColumnsToSeries(regattaIdentifier, series.getName(), raceColumnsToAdd,
new AsyncCallback<List<RaceColumnInSeriesDTO>>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to add race columns " + raceColumnsToAdd
+ " to series " + series.getName() + ": " + caught.getMessage());
}
@Override
public void onSuccess(List<RaceColumnInSeriesDTO> raceColumns) {
regattaRefresher.fillRegattas();
}
});
// first remove:
sailingService.removeRaceColumnsFromSeries(regattaIdentifier, series.getName(), raceColumnsToRemove,
new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
errorReporter.reportError("Error trying to remove race columns " + raceColumnsToAdd
errorReporter.reportError("Error trying to remove race columns " + raceColumnNamesToAddWithInsertIndex
+ " from series " + series.getName() + ": " + caught.getMessage());
}
@Override
public void onSuccess(Void v) {
regattaRefresher.fillRegattas();
// when successfully removed, insert:
sailingService.addRaceColumnsToSeries(regattaIdentifier, 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) {
regattaRefresher.fillRegattas();
}
});
}
});
if (isMedalChanged || seriesResultDiscardingThresholdsChanged || isStartsWithZeroScoreChanged
@@ -205,7 +205,8 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
void updateRegatta(RegattaIdentifier regattaIdentifier, Date startDate, Date endDate, UUID defaultCourseAreaUuid,
RegattaConfigurationDTO regattaConfiguration, boolean useStartTimeInference);
List<RaceColumnInSeriesDTO> addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List<String> columnNames);
List<RaceColumnInSeriesDTO> addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName,
List<Pair<String, Integer>> columnNames);
void updateSeries(RegattaIdentifier regattaIdentifier, String seriesName, String newSeriesName, boolean isMedal,
int[] resultDiscardingThresholds, boolean startsWithZeroScore,
@@ -396,7 +396,7 @@ public interface SailingServiceAsync extends BuildVersionRetriever, FileStorageM
RegattaCreationParametersDTO seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent,
ScoringSchemeType scoringSchemeType, UUID defaultCourseAreaId, boolean useStartTimeInference, AsyncCallback<RegattaDTO> callback);
void addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List<String> columnNames,
void addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List<Pair<String, Integer>> columnNames,
AsyncCallback<List<RaceColumnInSeriesDTO>> callback);
void updateSeries(RegattaIdentifier regattaIdentifier, String seriesName, String newSeriesName, boolean isMedal,
@@ -3615,11 +3615,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public List<RaceColumnInSeriesDTO> addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName,
List<String> columnNames) {
List<Pair<String, Integer>> columnNamesWithInsertIndex) {
List<RaceColumnInSeriesDTO> result = new ArrayList<RaceColumnInSeriesDTO>();
for (String columnName : columnNames) {
for (Pair<String, Integer> columnNameAndInsertIndex : columnNamesWithInsertIndex) {
RaceColumnInSeries raceColumnInSeries = getService().apply(
new AddColumnToSeries(regattaIdentifier, seriesName, columnName));
new AddColumnToSeries(columnNameAndInsertIndex.getB(), regattaIdentifier, seriesName, columnNameAndInsertIndex.getA()));
if (raceColumnInSeries != null) {
result.add(convertToRaceColumnInSeriesDTO(raceColumnInSeries));
}
@@ -3990,11 +3990,13 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
*/
private void addRaceColumnsToRegattaSeries(RegattaDTO regatta, String eventName) {
for (SeriesDTO series : regatta.series) {
List<String> raceNames = new ArrayList<String>();
List<Pair<String, Integer>> raceNamesAndInsertIndex = new ArrayList<>();
int insertIndex = 0;
for (RaceColumnDTO raceColumnInSeries : series.getRaceColumns()) {
raceNames.add(raceColumnInSeries.getName());
raceNamesAndInsertIndex.add(new Pair<>(raceColumnInSeries.getName(), insertIndex));
insertIndex++;
}
addRaceColumnsToSeries(regatta.getRegattaIdentifier(), series.getName(), raceNames);
addRaceColumnsToSeries(regatta.getRegattaIdentifier(), series.getName(), raceNamesAndInsertIndex);
}
}
@@ -197,7 +197,7 @@ public class PolarFixFilterCriteria implements FilterCriterion<GPSFixMovingWithP
TimePoint raceStartTime = race.getStartOfRace();
TimePoint startTime;
TimePoint passedStartTimePoint = startPassing.getTimePoint();
if (passedStartTimePoint.after(raceStartTime)) {
if (raceStartTime == null || passedStartTimePoint.after(raceStartTime)) {
startTime = passedStartTimePoint;
} else {
startTime = raceStartTime;
@@ -73,6 +73,8 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
try {
if (liveDataConnection != null) {
liveDataConnection.stop();
liveDataConnection.removeListener(igtimiWindReceiver);
liveDataConnection.removeListener(this);
}
} catch (Exception e) {
e.printStackTrace();
@@ -97,7 +99,7 @@ public class WindStatusServlet extends SailingServerHttpServlet implements Igtim
out.println("<meta http-equiv=refresh content='10; url="+req.getRequestURI()+"'>");
out.println("</head>");
out.println("<body>");
out.println("<p>Reload wind connectors with parameter reloadWindReceiver=true. This will force a connection reset and a reloading of the wind receivers.</p>");
out.println("<p>Reload wind connectors with parameter <a href=\"/sailingserver/windStatus?reloadWindReceiver=true\">reloadWindReceiver=true</a>. This will force a connection reset and a reloading of the wind receivers.</p>");
out.println("<h3>Igtimi Wind Status ("+igtimiRawMessageCount+" raw messages received)</h3>");
if (lastIgtimiMessages != null && !lastIgtimiMessages.isEmpty()) {
final List<IgtimiMessageInfo> copyOfLastIgtimiMessages;
@@ -12,7 +12,10 @@
<h2>URL: /api/v1/regattas/{regattaname}/races/{racename}/targettime</h2>
<b>Description:</b>
<p>Gets the estimated target time of the race</p>
<p>Gets the estimated time it will take to sail a race. The mark positions and the wind data are
taken from the optional timeasmillis parameter which defaults to the current time. Note that sometimes the marks are not in place yet
when the race starts and that a windward mark may be collected already before the race finishes.
</p>
<br/>
<table>
<tr>
@@ -9,8 +9,18 @@ import com.sap.sailing.server.RacingEventServiceOperation;
public class AddColumnToSeries extends AbstractColumnInSeriesOperation<RaceColumnInSeries> {
private static final long serialVersionUID = 8987540636040301063L;
/**
* -1 means append
*/
private final int insertIndex;
public AddColumnToSeries(RegattaIdentifier regattaIdentifier, String seriesName, String columnName) {
this(/* insertIndex==-1 means append */ -1, regattaIdentifier, seriesName, columnName);
}
public AddColumnToSeries(int insertIndex, RegattaIdentifier regattaIdentifier, String seriesName, String columnName) {
super(regattaIdentifier, seriesName, columnName);
this.insertIndex = insertIndex;
}
@Override
@@ -18,7 +28,11 @@ public class AddColumnToSeries extends AbstractColumnInSeriesOperation<RaceColum
RaceColumnInSeries result = null;
Series series = getSeries(toState);
if (series != null) {
result = series.addRaceColumn(getColumnName(), toState);
if (insertIndex == -1) {
result = series.addRaceColumn(getColumnName(), toState);
} else {
result = series.addRaceColumn(insertIndex, getColumnName(), toState);
}
if (result != null && series.getRegatta().isPersistent()) {
toState.updateStoredRegatta(series.getRegatta());
}
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: TracTrac Client module
Bundle-SymbolicName: com.tractrac.clientmodule
Bundle-Version: 3.0.10
Bundle-Version: 3.0.11
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ClassPath: .,
lib/TracAPI.jar
+60
View File
@@ -16,6 +16,66 @@ It contains also some files:
- test.sh -> script that compiles the code in the src folder, creates the test.jar library and execute the code of the example.
- Manifest.txt -> manifest used to create the test.jar file
********************************************
************* TracAPI 3.0.11 ***************
********************************************
This is a final version. It fixes bugs in the implementation and it adds a some features.
These features add methods to the API, but they keep the backward compatibility.
This version provides a new JavaDoc version.
Release date: 27/05/2015
Build number: 10715
1) Features
- Adding the method IRace.setInitialized(boolean) that allows to load control point positions despite of
the race is not initialized (Requested by Jorge Piera, 17/05/2015)
1) Bugs
- The subscription library sends (per each control point) an "ControlPointPosition" event with the positions
of the parameters with a time stamp equals to the tracking start time. If the control point is static (it
doesn't have a tracker), it means that this control won't exist until the tracking start time arrives: it is
not possible to open a subscription connection before the tracking start time and see the control point. But
if the control is static, it has to exist during all the event. Now when a control is static, the subscription
library sends a "ControlPointPosition" event with the event start time and then it sends other "ControlPointPosition"
event with the tracking start time. It allows to connect with future races and see the static controls (Requested
by Jakob Odum, 25/02/2015)
- It is possible to add two or more subscriptions for the same subscriber (Reported by Jorge Piera, 02/05/2015)
- An initialized race is a race where the tracking is on. A not
initialized race is a race where the tracking is off. If a race is in a
not initialized state and it is loaded using the parameters file, the
library assumes that the consumer application wants to load the race and
it changes its initialized attribute to true (the tracking is on). This
assumption is wrong. Now, if a race is not initialized it will continue
being uninitialized until the event administrator changes its state to
initialized.
When a race changes its state from not initialized to initialized,
some events are thrown in the system:
1.
IRaceStartStopTimesChangeListener.gotTrackingStartStopTime(IRace,
IStartStopData): where the IStartStopData object contains the new
tracking interval.
2. IRacesListener.startTracking(UUID): the UUID is the race
identifier
3. IRacesListener.updateRace(IRace): IRace is the new updated
race where the IRace.isInitialized is true and it has values for both
the getTrackingStartTime and the getTrackingEndTime methods.
When a race changes its state from initialized to not initialized,
the following events are thrown in the system:
1.
IRaceStartStopTimesChangeListener.gotTrackingStartStopTime(IRace,
IStartStopData): where the IStartStopData object contains the null
interval ([0, 0])
2. IRacesListener.abandonRace(UUID): the UUID is the race identifier
3. IRacesListener.updateRace(IRace): IRace is the new updated
race where the IRace.isInitialized is false and it has null values for
both the getTrackingStartTime and the getTrackingEndTime methods.
(Reported by Axel Uhl, 17/05/2015)
********************************************
************* TracAPI 3.0.10 ***************
********************************************
Binary file not shown.
+1 -1
View File
@@ -8,6 +8,6 @@
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.tractrac.clientmodule</artifactId>
<version>3.0.10</version>
<version>3.0.11</version>
<packaging>eclipse-plugin</packaging>
</project>