mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-06 19:12:23 +00:00
Merge branch 'master' into racecommittee_integrated
Conflicts: java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/MongoObjectFactory.java java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/base/impl/MarkImpl.java java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/DomainFactoryImpl.java java/com.sap.sailing.domain/META-INF/MANIFEST.MF java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/DomainFactory.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/RegattaLeaderboardImpl.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/meta/MetaLeaderboardColumn.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java java/com.sap.sailing.gwt.ui/.settings/com.google.gwt.eclipse.core.prefs java/com.sap.sailing.gwt.ui/SailingGWT.launch java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AbstractLeaderboardDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardCreateDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/FlexibleLeaderboardEditDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardDescriptor.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardCreateDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RegattaLeaderboardEditDialog.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/AbstractLeaderboardDTO.java java/com.sap.sailing.mongodb.test/src/com/sap/sailing/mongodb/test/TestStoringAndLoadingEventsAndRegattas.java java/com.sap.sailing.server.gateway/META-INF/MANIFEST.MF java/com.sap.sailing.server/SailingServer (No Proxy).launch java/com.sap.sailing.server/src/com/sap/sailing/server/impl/RacingEventServiceImpl.java java/pom.xml
This commit is contained in:
commit
5df89c7e7e
195 files changed
+10899
-5182
No files matched your search
Executable
+155
@@ -0,0 +1,155 @@
|
||||
#/bin/bash
|
||||
|
||||
# this holds for default installation
|
||||
USER_HOME=~
|
||||
PROJECT_HOME=$USER_HOME/git
|
||||
SERVERS_HOME=$USER_HOME/servers
|
||||
|
||||
# x86 or x86_64 should work for most cases
|
||||
ARCH=x86_64
|
||||
|
||||
# needed for maven to work correctly
|
||||
source $USER_HOME/.bash_profile
|
||||
|
||||
cd $PROJECT_HOME
|
||||
active_branch=$(git symbolic-ref -q HEAD)
|
||||
active_branch=`basename $active_branch`
|
||||
|
||||
ACDIR=$SERVERS_HOME/$active_branch
|
||||
|
||||
gwtcompile=1
|
||||
testing=1
|
||||
clean="clean"
|
||||
offline=0
|
||||
proxy=0
|
||||
extra=''
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "buildAndUpdateProduct [-g -t -o -c] [build|install|all]"
|
||||
echo ""
|
||||
echo "Active branch is $active_branch"
|
||||
echo ""
|
||||
echo "-g Disable GWT compile, no gwt files will be generated, old ones will be preserved."
|
||||
echo "-t Disable tests"
|
||||
echo "-o Enable offline mode (does not work for tycho surefire plugin)"
|
||||
echo "-c Disable cleaning (use only if you are sure that no java file has changed)"
|
||||
echo "-p Enable proxy mode"
|
||||
echo ""
|
||||
echo "build: builds the server code using Maven to $PROJECT_HOME"
|
||||
echo "install: installs product and configuration to $SERVERS_HOME/$active_branch. Overwrites any configuration by using config from branch."
|
||||
echo "all: calls build and then install"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
options=':gtocp'
|
||||
while getopts $options option
|
||||
do
|
||||
case $option in
|
||||
g) gwtcompile=0;;
|
||||
t) testing=0;;
|
||||
o) offline=1;;
|
||||
c) clean="";;
|
||||
p) proxy=1;;
|
||||
\?) echo "Invalid option"
|
||||
exit 2;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ! -d $ACDIR ]; then
|
||||
echo "Could not find directory $ACDIR - perhaps you are on a wrong branch?"
|
||||
exit
|
||||
fi
|
||||
|
||||
read -s -n1 -p "Currently branch $active_branch is active. Do you want to proceed (y/N): " answer
|
||||
case $answer in
|
||||
"Y" | "y") echo "Continuing";;
|
||||
*) echo "Aborting..."
|
||||
exit;;
|
||||
esac
|
||||
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [[ $@ == "" ]]; then
|
||||
echo "You need to specify an action [build|install]"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "Starting $@ of server..."
|
||||
|
||||
if [ ! -d "$ACDIR/plugins" ]; then
|
||||
mkdir $ACDIR/plugins
|
||||
fi
|
||||
|
||||
if [ ! -d "$ACDIR/configuration" ]; then
|
||||
mkdir $ACDIR/configuration
|
||||
fi
|
||||
|
||||
# make sure to have maven configuration here
|
||||
cp -v $PROJECT_HOME/configuration/maven-settings.xml $ACDIR/
|
||||
MAVEN_SETTINGS=$ACDIR/maven-settings.xml
|
||||
|
||||
if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
|
||||
# yield build so that we get updated product
|
||||
|
||||
# preserve old build log
|
||||
cp $ACDIR/build.log $ACDIR/build.log.old
|
||||
|
||||
cd $PROJECT_HOME/java
|
||||
if [ $gwtcompile -eq 1 ]; then
|
||||
echo "INFO: Compiling GWT (rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*)"
|
||||
rm -rf com.sap.sailing.gwt.ui/com.sap.sailing.*
|
||||
else
|
||||
echo "INFO: GWT Compilation disabled"
|
||||
extra="-Pdebug.no-gwt-compile"
|
||||
fi
|
||||
|
||||
if [ $testing -eq 0 ]; then
|
||||
echo "INFO: Skipping tests"
|
||||
extra="$extra -Dmaven.test.skip=true"
|
||||
fi
|
||||
|
||||
if [ $offline -eq 1 ]; then
|
||||
echo "INFO: Activating offline mode"
|
||||
extra="$extra -o"
|
||||
fi
|
||||
|
||||
if [ $proxy -eq 1 ]; then
|
||||
echo "INFO: Activating proxy profile"
|
||||
extra="$extra -P no-debug.with-proxy"
|
||||
else
|
||||
extra="$extra -P no-debug.without-proxy"
|
||||
fi
|
||||
|
||||
echo "Using following command: mvn $extra -fae -s $MAVEN_SETTINGS $clean install"
|
||||
mvn $extra -fae -s $MAVEN_SETTINGS $clean install 2>&1 | tee $ACDIR/build.log
|
||||
|
||||
echo "Build complete. Do not forget to install product..."
|
||||
fi
|
||||
|
||||
if [[ "$@" == "install" ]] || [[ "$@" == "all" ]]; then
|
||||
|
||||
cd $ACDIR
|
||||
|
||||
rm -rf $ACDIR/plugins/*.*
|
||||
rm -rf $ACDIR/org.eclipse.*
|
||||
rm -rf $ACDIR/configuration/org.eclipse.*
|
||||
|
||||
p2PluginRepository=$PROJECT_HOME/java/com.sap.sailing.feature.p2build/bin/products/raceanalysis.product.id/linux/gtk/$ARCH
|
||||
cp -v $p2PluginRepository/configuration/config.ini configuration/
|
||||
cp -r -v $p2PluginRepository/configuration/org.eclipse.equinox.simpleconfigurator configuration/
|
||||
cp -v $p2PluginRepository/plugins/*.jar plugins/
|
||||
|
||||
mkdir -p configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/jetty.xml configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/realm.properties configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/monitoring.properties configuration/
|
||||
|
||||
# Make sure mongodb configuration is active
|
||||
cp -v $PROJECT_HOME/configuration/mongodb.cfg $ACDIR/
|
||||
cp -rv $PROJECT_HOME/configuration/native-libraries $ACDIR/
|
||||
|
||||
# Make sure this script is up2date at least for the next run
|
||||
cp -v $PROJECT_HOME/configuration/buildAndUpdateProduct.sh $ACDIR/
|
||||
|
||||
echo "Installation complete. You may now start the server using ./start"
|
||||
fi
|
||||
@@ -0,0 +1,39 @@
|
||||
<settings>
|
||||
<servers>
|
||||
<server>
|
||||
<id>ssh-repository</id>
|
||||
<filePermissions>664</filePermissions>
|
||||
<directoryPermissions>775</directoryPermissions>
|
||||
</server>
|
||||
</servers>
|
||||
|
||||
<proxies>
|
||||
<proxy>
|
||||
<active>false</active>
|
||||
<protocol>http</protocol>
|
||||
<host>proxy.wdf.sap.corp</host>
|
||||
<port>8080</port>
|
||||
<nonProxyHosts>localhost|*.sap.corp</nonProxyHosts>
|
||||
</proxy>
|
||||
</proxies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>sailing.analytics</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<!-- Leave empty, if no proxy is needed in your environment! -->
|
||||
<parameters.proxy>
|
||||
</parameters.proxy>
|
||||
<!-- Change the configuration file to the one you like to use for the tests. -->
|
||||
<parameters.integration-tests>
|
||||
-Dselenium.test.environment.configuration=ci-test-environment.xml
|
||||
</parameters.integration-tests>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</settings>
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
port = 27017
|
||||
master = true
|
||||
dbpath = /opt/mongodb/data//mongodb-data
|
||||
logpath = /opt/mongodb/data/logs/mongodb-data/mongodb.log
|
||||
logappend = true
|
||||
directoryperdb = true
|
||||
rest = true
|
||||
syncdelay = 5
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
command -v tmux >/dev/null 2>&1 || { echo "I require tmux but it's not installed. Aborting." >&2; exit 1; }
|
||||
|
||||
sn=sailing
|
||||
|
||||
SERVERS_DIR=/home/trac/servers
|
||||
|
||||
# options
|
||||
tmux set-option default-path /home/trac/
|
||||
tmux set-option default-shell /bin/bash
|
||||
|
||||
cd /home/trac/git
|
||||
tmux new-session -s "$sn" -n "BUILD" -d "bash -c 'git symbolic-ref -q HEAD && echo \"./buildAndUpdateProduct.sh install\"'; bash"
|
||||
|
||||
counter=1
|
||||
for dir in dev test prod1 prod2; do
|
||||
cd $SERVERS_DIR/$dir
|
||||
tmux new-window -t "$sn:$counter" -n `basename $dir` "bash -c 'start'; bash"
|
||||
counter=$[counter + 1]
|
||||
done
|
||||
|
||||
cd /home/trac/servers/prod1
|
||||
tmux new-window -t "$sn:$counter" -n "UDP" "bash -c 'echo \"./udpmirror -v 2012 localhost 2010 localhost 2011 localhost 2013 localhost 2014\"'; bash"
|
||||
|
||||
cd /opt/mongodb/bin
|
||||
tmux new-window -t "$sn:$[counter+1]" -n "MongoDf" "bash -c './mongod --dbpath ../data/mongodb-default'; bash"
|
||||
|
||||
cd /opt/
|
||||
tmux new-window -t "$sn:$[counter+2]" -n "ATop" "bash -c 'apachetop -f /var/log/httpd/access_log'; bash"
|
||||
|
||||
cd /home/trac/servers
|
||||
tmux new-window -t "$sn:$[counter+4]" -n "Logs" "bash -c 'ls -lah'; bash"
|
||||
|
||||
tmux select-window -t "$sn:0"
|
||||
tmux -2 attach-session -t "$sn"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
export JAVA_HOME=/home/trac/jdk1.7.0_02
|
||||
jar=`find plugins -name 'com.sap.sailing.expeditionconnector_*.jar' | sort | tail -1`
|
||||
echo Using JAR file $jar
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
ARGS="-v 2012 localhost 2010 localhost 2011 localhost 2013 localhost 2014"
|
||||
else
|
||||
ARGS=$*
|
||||
fi
|
||||
|
||||
echo "Using $ARGS"
|
||||
java -cp "$jar" -Djava.util.logging.config.file=udpmirrorLog.properties com.sap.sailing.expeditionconnector.UDPMirror $ARGS
|
||||
@@ -1,7 +1,7 @@
|
||||
Extreme Sailing Series 2012 - Cardiff
|
||||
|
||||
Move wind data from test
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Extreme Sailing Series (Extreme40)'}" > /tmp/windtracks-ess40_cardiff.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Extreme Sailing Series (Extreme40)'}" > /tmp/windtracks-ess40_cardiff.json
|
||||
|
||||
to prod
|
||||
/opt/mongodb/bin/mongoimport --port 10202 -d winddb -c WIND_TRACKS /tmp/windtracks-ess40_cardiff.json
|
||||
@@ -1,18 +1,18 @@
|
||||
Kieler Woche 2012
|
||||
|
||||
Move wind data from test to prod
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (LASER)'}" > /tmp/windtracks-laser.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (470M)'}" > /tmp/windtracks-470m.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (470W)'}" > /tmp/windtracks-470w.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (49er)'}" > /tmp/windtracks-49er.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (SWAN)'}" > /tmp/windtracks-swan.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (RAD W)'}" > /tmp/windtracks-laserradial.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (Kite)'}" > /tmp/windtracks-kite.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (Finn)'}" > /tmp/windtracks-finn.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (LASER)'}" > /tmp/windtracks-laser.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (470M)'}" > /tmp/windtracks-470m.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (470W)'}" > /tmp/windtracks-470w.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (49er)'}" > /tmp/windtracks-49er.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (SWAN)'}" > /tmp/windtracks-swan.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (RAD W)'}" > /tmp/windtracks-laserradial.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (Kite)'}" > /tmp/windtracks-kite.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (Finn)'}" > /tmp/windtracks-finn.json
|
||||
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche 2012 (29er)'}" > /tmp/windtracks-29er.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche IC 2012 (STAR)'}" > /tmp/windtracks-star.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'Kieler Woche IC 2012 (5o5)'}" > /tmp/windtracks-5o5.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche 2012 (29er)'}" > /tmp/windtracks-29er.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche IC 2012 (STAR)'}" > /tmp/windtracks-star.json
|
||||
/opt/mongodb/bin/mongoexport --port 10201 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'Kieler Woche IC 2012 (5o5)'}" > /tmp/windtracks-5o5.json
|
||||
|
||||
|
||||
/opt/mongodb/bin/mongoimport --port 10202 -d winddb -c WIND_TRACKS /tmp/windtracks-laser.json
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
505 WM La Rochelle
|
||||
|
||||
Move wind data from prod to test/dev
|
||||
/opt/mongodb/bin/mongoexport --port 10202 -d winddb -c WIND_TRACKS -q "{ EVENT_NAME: 'SAP 505 World Championship 2012 (505)'}" > /tmp/windtracks-505.json
|
||||
/opt/mongodb/bin/mongoexport --port 10202 -d winddb -c WIND_TRACKS -q "{ REGATTA_NAME: 'SAP 505 World Championship 2012 (505)'}" > /tmp/windtracks-505.json
|
||||
|
||||
to test
|
||||
/opt/mongodb/bin/mongoimport --port 10201 -d winddb -c WIND_TRACKS /tmp/windtracks-505.json
|
||||
|
||||
@@ -26,7 +26,37 @@ http://germanmaster.traclive.dk/events/event_20100725_OWorlds/jsonservice.php
|
||||
Live-URI: tcp://germanmaster.traclive.dk:1520
|
||||
Stored-URI: tcp://germanmaster.traclive.dk:1521
|
||||
|
||||
505 World Championship 2012:
|
||||
http://germanmaster.traclive.dk/events/event_20120714_SAPWorldCh/jsonservice.php
|
||||
|
||||
Kieler Woche 2012:
|
||||
http://germanmaster.traclive.dk/events/event_20120615_KielerWoch/jsonservice.php
|
||||
http://germanmaster.traclive.dk/events/event_20120621_KielerWoch/jsonservice.php
|
||||
http://germanmaster.traclive.dk/events/event_20120615_KielerWoch1/jsonservice.php
|
||||
|
||||
Extreme Sailing Series 2012:
|
||||
http://germanmaster.traclive.dk/events/event_20120101_ExtremeSai/jsonservice.php
|
||||
|
||||
OBMR 2012:
|
||||
http://germanmaster.traclive.dk/events/event_20121031_OBMR/jsonservice.php
|
||||
|
||||
Academy Tracking 2011:
|
||||
http://germanmaster.traclive.dk/events/event_20110505_SailingTea/jsonservice.php
|
||||
|
||||
Academy Tracking 2012:
|
||||
http://germanmaster.traclive.dk/events/event_20120501_SailingTea/jsonservice.php
|
||||
|
||||
BMW Cup:
|
||||
http://kml.skitrac.traclive.dk/events/event_20120803_BMWCup/jsonservice.php
|
||||
|
||||
YES 2012:
|
||||
http://germanmaster.traclive.dk/events/event_20120525_YES/jsonservice.php
|
||||
|
||||
IDM Drachen 2012:
|
||||
http://kml.skitrac.traclive.dk/events/event_20120730_IDMDrachen/jsonservice.php
|
||||
|
||||
49er European Championship:
|
||||
http://traclive.dk/events/event_20120905_erEuropean/jsonservice.php
|
||||
|
||||
RC44 Sweden Cup:
|
||||
http://germanmaster.traclive.dk/events/event_20110815_RCSwedenCu/jsonservice.php
|
||||
@@ -0,0 +1,25 @@
|
||||
# Welcome to the SAP Sailing Wiki
|
||||
|
||||
This is the <img src="http://analysis.sapsailing.com/themes/logo.png" height="58" width="200" /> Wiki where useful information regarding this project can be found. This Wiki is being stored directly into the default GIT repository on branch **master**. You can edit information here freely but do not leave any nonsense here.
|
||||
|
||||
The syntax is relatively easy and is documented here http://daringfireball.net/projects/markdown/dingus. When you create a new Page then make sure to put some thinking into the right tree structure and then just extend the URL above.
|
||||
|
||||
**ATTENTION**:
|
||||
|
||||
* Make sure to always have _wiki/_ as the base path. So if you want to create `server/SystemBoot` then the correct URL is `wiki/server/SystemBoot`. Make sure to add you Page to the Table of Contents below by editing the document.
|
||||
|
||||
* Password can be found in the encrypted page [[Passwords|wiki/passwords]]. You can decrypt it by using `gpg -d < passwords.md` after having entered the password. If you want to edit, first decrypt and then encrypt again using `gpg -a --symmetric passwords.md`. Make sure to never save the unencrypted version!
|
||||
|
||||
If you have any questions then either contact Axel Uhl, Jens Rommel, Frank Mittag or Simon Pamiés.
|
||||
|
||||
### Table of Contents Wiki
|
||||
|
||||
* [[Architecture and Infrastructure|wiki/architecture-and-infrastructure]]
|
||||
* [[Configure Races on Server|wiki/configure-races-on-server]]
|
||||
|
||||
### Internal services (not related to wiki but useful)
|
||||
|
||||
* [Bugzilla Issue Tracking System](http://bugzilla.sapsailing.com/bugzilla/)
|
||||
* [Maven Repository Browser](http://maven.sapsailing.com/maven/)
|
||||
* [Main Sailing Website](http://www.sapsailing.com)
|
||||
* [Visitor Statistics](http://analysis.sapsailing.com/)
|
||||
+1
-1
@@ -12,7 +12,7 @@ import static com.sap.sailing.domain.common.SortingOrder.*;
|
||||
*
|
||||
*/
|
||||
public enum DetailType implements Serializable {
|
||||
DISTANCE_TRAVELED(0, ASCENDING), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING),
|
||||
DISTANCE_TRAVELED(0, ASCENDING), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), REGATTA_RANK(0, ASCENDING), OVERALL_RANK(0, ASCENDING),
|
||||
RANK_GAIN(0, DESCENDING), NUMBER_OF_MANEUVERS(0, ASCENDING), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING),
|
||||
ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1, ASCENDING), VELOCITY_MADE_GOOD_IN_KNOTS(2, DESCENDING),
|
||||
GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), GAP_CHANGE_SINCE_LEG_START_IN_SECONDS(0, ASCENDING),
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.sap.sailing.domain.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface PolarSheetGenerationTriggerResponse extends Serializable{
|
||||
|
||||
public String getId();
|
||||
|
||||
public String getBoatClassName();
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.sap.sailing.domain.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface PolarSheetsData extends Serializable {
|
||||
|
||||
Number[][] getAveragedPolarDataByWindSpeed();
|
||||
|
||||
int getDataCount();
|
||||
|
||||
boolean isComplete();
|
||||
|
||||
Integer[] getDataCountPerAngleForWindspeed(int beaufort);
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.domain.common;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface PolarSheetsHistogramData extends Serializable{
|
||||
|
||||
public int getAngle();
|
||||
|
||||
public int getDataCount();
|
||||
|
||||
public Number[] getyValues();
|
||||
|
||||
public Number[] getxValues();
|
||||
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
|
||||
|
||||
public class PolarSheetGenerationTriggerResponseImpl implements PolarSheetGenerationTriggerResponse {
|
||||
|
||||
private static final long serialVersionUID = -2160795576114448218L;
|
||||
private String id;
|
||||
private String boatClassName;
|
||||
|
||||
// For GWT serialization
|
||||
PolarSheetGenerationTriggerResponseImpl() {
|
||||
};
|
||||
|
||||
public PolarSheetGenerationTriggerResponseImpl(String id, String boatClassName) {
|
||||
this.id = id;
|
||||
this.boatClassName = boatClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBoatClassName() {
|
||||
return boatClassName;
|
||||
}
|
||||
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
|
||||
public class PolarSheetsDataImpl implements PolarSheetsData {
|
||||
|
||||
private static final long serialVersionUID = -4649254807341866894L;
|
||||
|
||||
private Number[][] averagedPolarDataByWindSpeed;
|
||||
|
||||
private boolean complete;
|
||||
|
||||
private int dataCount;
|
||||
|
||||
private Map<Integer,Integer[]> dataCountPerAngleForWindspeed;
|
||||
|
||||
//For GWT Serialization
|
||||
PolarSheetsDataImpl() {};
|
||||
|
||||
public PolarSheetsDataImpl(Number[][] averagedPolarDataByWindSpeed, boolean complete, int dataCount, Map<Integer,Integer[]> dataCountPerAngleForWindspeed) {
|
||||
this.averagedPolarDataByWindSpeed = averagedPolarDataByWindSpeed;
|
||||
this.complete = complete;
|
||||
this.dataCount = dataCount;
|
||||
this.dataCountPerAngleForWindspeed = dataCountPerAngleForWindspeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number[][] getAveragedPolarDataByWindSpeed() {
|
||||
return averagedPolarDataByWindSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataCount() {
|
||||
return dataCount;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Integer[] getDataCountPerAngleForWindspeed(int beaufort) {
|
||||
return dataCountPerAngleForWindspeed.get(beaufort);
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.PolarSheetsHistogramData;
|
||||
|
||||
public class PolarSheetsHistogramDataImpl implements PolarSheetsHistogramData {
|
||||
|
||||
private static final long serialVersionUID = 7492650285773447757L;
|
||||
|
||||
private Number[] yValues;
|
||||
|
||||
private Number[] xValues;
|
||||
|
||||
private int angle;
|
||||
|
||||
private int dataCount;
|
||||
|
||||
//For GWT serialization
|
||||
PolarSheetsHistogramDataImpl() {}
|
||||
|
||||
public PolarSheetsHistogramDataImpl(int angle, Number[] xValues, Number[] yValues, int dataCount) {
|
||||
super();
|
||||
this.angle = angle;
|
||||
this.yValues = yValues;
|
||||
this.xValues = xValues;
|
||||
this.dataCount = dataCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number[] getyValues() {
|
||||
return yValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Number[] getxValues() {
|
||||
return xValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAngle() {
|
||||
return angle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDataCount() {
|
||||
return dataCount;
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -84,4 +84,6 @@ public interface MongoObjectFactory {
|
||||
|
||||
void storeRegattaForRaceID(String id, Regatta regatta);
|
||||
|
||||
void removeRegattaForRaceID(String raceIDAsString, Regatta regatta);
|
||||
|
||||
}
|
||||
+2
@@ -219,6 +219,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
}
|
||||
if (result != null) {
|
||||
final Leaderboard finalResult = result;
|
||||
finalResult.setDisplayName((String) dbLeaderboard.get(FieldNames.LEADERBOARD_DISPLAY_NAME.name()));
|
||||
|
||||
DelayedLeaderboardCorrections loadedLeaderboardCorrections = new DelayedLeaderboardCorrectionsImpl(result);
|
||||
final boolean[] needsMigration = new boolean[1];
|
||||
loadedLeaderboardCorrections.addLeaderboardCorrectionsResolvedListener(new LeaderboardCorrectionsResolvedListener() {
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public enum FieldNames {
|
||||
COMPETITOR_ID, COMPETITOR_DISPLAY_NAME,
|
||||
|
||||
// leaderboard:
|
||||
LEADERBOARD_NAME, LEADERBOARD_SUPPRESSED_COMPETITORS, LEADERBOARD_SUPPRESSED_COMPETITOR_IDS,
|
||||
LEADERBOARD_NAME, LEADERBOARD_DISPLAY_NAME, LEADERBOARD_SUPPRESSED_COMPETITORS, LEADERBOARD_SUPPRESSED_COMPETITOR_IDS,
|
||||
LEADERBOARD_COLUMNS, LEADERBOARD_COLUMN_NAME, LEADERBOARD_COMPETITOR_DISPLAY_NAMES,
|
||||
LEADERBOARD_IS_MEDAL_RACE_COLUMN, LEADERBOARD_CARRIED_POINTS, LEADERBOARD_CARRIED_POINTS_BY_ID,
|
||||
LEADERBOARD_SCORE_CORRECTIONS, LEADERBOARD_DISCARDING_THRESHOLDS,
|
||||
|
||||
+10
@@ -150,6 +150,9 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
BasicDBObject query = new BasicDBObject(FieldNames.LEADERBOARD_NAME.name(), leaderboard.getName());
|
||||
BasicDBObject dbLeaderboard = new BasicDBObject();
|
||||
dbLeaderboard.put(FieldNames.LEADERBOARD_NAME.name(), leaderboard.getName());
|
||||
if(leaderboard.getDisplayName() != null) {
|
||||
dbLeaderboard.put(FieldNames.LEADERBOARD_DISPLAY_NAME.name(), leaderboard.getDisplayName());
|
||||
}
|
||||
BasicDBList dbSuppressedCompetitorIds = new BasicDBList();
|
||||
for (Competitor suppressedCompetitor : leaderboard.getSuppressedCompetitors()) {
|
||||
dbSuppressedCompetitorIds.add(suppressedCompetitor.getId());
|
||||
@@ -476,6 +479,13 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
regattaForRaceIDCollection.update(query, entry, /* upsrt */ true, /* multi */ false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegattaForRaceID(String raceIDAsString, Regatta regatta) {
|
||||
DBCollection regattaForRaceIDCollection = database.getCollection(CollectionNames.REGATTA_FOR_RACE_ID.name());
|
||||
DBObject query = new BasicDBObject(FieldNames.RACE_ID_AS_STRING.name(), raceIDAsString);
|
||||
regattaForRaceIDCollection.remove(query);
|
||||
}
|
||||
|
||||
public DBCollection getRaceLogCollection() {
|
||||
DBCollection result = database.getCollection(CollectionNames.RACE_LOGS.name());
|
||||
result.ensureIndex(new BasicDBObject(FieldNames.RACE_LOG_IDENTIFIER.name(), null));
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sailing.domain.common.Named;
|
||||
import com.sap.sailing.domain.common.WithID;
|
||||
|
||||
public interface ControlPoint extends Named {
|
||||
public interface ControlPoint extends WithID, Named {
|
||||
Iterable<Mark> getMarks();
|
||||
}
|
||||
+29
-2
@@ -1,27 +1,54 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.common.MarkType;
|
||||
|
||||
public interface SharedDomainFactory {
|
||||
|
||||
/**
|
||||
* Looks up or, if not found, creates a {@link Nationality} object and re-uses <code>threeLetterIOCCode</code> also as the
|
||||
* nationality's name.
|
||||
*/
|
||||
Nationality getOrCreateNationality(String threeLetterIOCCode);
|
||||
|
||||
Mark getOrCreateMark(String id);
|
||||
/**
|
||||
* The name will also be used as the mark's ID. If you have a unique ID, use {@link #getOrCreateMark(Serializable, String)} instead.
|
||||
*/
|
||||
Mark getOrCreateMark(String name);
|
||||
|
||||
/**
|
||||
* Since some ID types, such as {@link UUID}, cannot be serialized as objects to a GWT client, only the
|
||||
* {@link Object#toString()} representations of those IDs are serialized to the clients. When a client then requests
|
||||
* to identify a mark again, only the ID's string representation will be submitted to the server and now needs to be
|
||||
* mapped to the actual ID. This domain factory keeps a mapping of all mark ID's string representations to the
|
||||
* actual ID for all marks ever managed through any of the <code>getOrCreateMark(...)</code> overloads.
|
||||
* <p>
|
||||
*
|
||||
* This method first looks up the actual ID whose string representation is <code>toStringRepresentationOfID</code>
|
||||
* and then calls {@link #getOrCreateMark(Serializable, String)} with the result and the <code>name</code>
|
||||
* parameter, or with <code>ToStringRepresentationOfID</code> and <code>name</code> in case the string
|
||||
* representation of the ID is not known. So in the latter case, the string is used as the ID for the new mark.
|
||||
*/
|
||||
Mark getOrCreateMark(String toStringRepresentationOfID, String name);
|
||||
|
||||
Mark getOrCreateMark(Serializable id, String name);
|
||||
|
||||
/**
|
||||
* If the single mark with ID <code>id</code> already exists, it is returned. Its color may differ from <code>color</code>
|
||||
* in that case. Otherwise, a new {@link Mark} is created with <code>color</code> as its {@link Mark#getColor()}
|
||||
* and <code>shape</code> as its {@link Mark#getShape()}.
|
||||
*/
|
||||
Mark getOrCreateMark(String id, MarkType type, String color, String shape, String pattern);
|
||||
Mark getOrCreateMark(Serializable id, String name, MarkType type, String color, String shape, String pattern);
|
||||
|
||||
/**
|
||||
* @param name also uses the name as the gate's ID; if you have a real ID, use {@link #createGate(Serializable, Mark, Mark, String)} instead
|
||||
*/
|
||||
Gate createGate(Mark left, Mark right, String name);
|
||||
|
||||
Gate createGate(Serializable id, Mark left, Mark right, String name);
|
||||
|
||||
/**
|
||||
* The waypoint created is weakly cached so that when requested again by
|
||||
* {@link #getExistingWaypointById(Waypoint)} it is found.
|
||||
|
||||
+16
-2
@@ -1,19 +1,28 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Gate;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
|
||||
public class GateImpl implements Gate {
|
||||
private static final long serialVersionUID = 2807354812133070574L;
|
||||
private final Mark left;
|
||||
private final Mark right;
|
||||
private final String name;
|
||||
private final Serializable id;
|
||||
|
||||
/**
|
||||
* @param name also used as ID for the mark; if you have a better ID, use {@link GateImpl(Serializable, Mark, Mark, String)} instead.
|
||||
*/
|
||||
public GateImpl(Mark left, Mark right, String name) {
|
||||
super();
|
||||
this(/* ID */ name, left, right, name);
|
||||
}
|
||||
|
||||
public GateImpl(Serializable id, Mark left, Mark right, String name) {
|
||||
this.id = id;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.name = name;
|
||||
@@ -46,4 +55,9 @@ public class GateImpl implements Gate {
|
||||
result.add(getRight());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
+9
-31
@@ -15,41 +15,19 @@ public class MarkImpl extends NamedImpl implements Mark {
|
||||
private final String shape;
|
||||
private final String pattern;
|
||||
private final MarkType type;
|
||||
private final Serializable id;
|
||||
|
||||
public MarkImpl(String name) {
|
||||
super(name);
|
||||
type = MarkType.BUOY;
|
||||
color = null;
|
||||
shape = null;
|
||||
pattern = null;
|
||||
this(name, name);
|
||||
}
|
||||
|
||||
public MarkImpl(String name, MarkType type) {
|
||||
super(name);
|
||||
this.type = type;
|
||||
color = null;
|
||||
shape = null;
|
||||
pattern = null;
|
||||
public MarkImpl(Serializable id, String name) {
|
||||
this(id, name, MarkType.BUOY, /* color */ null, /* shape */ null, /* pattern */ null);
|
||||
}
|
||||
|
||||
public MarkImpl(String name, MarkType type, String color) {
|
||||
super(name);
|
||||
this.type = type;
|
||||
this.color = color;
|
||||
shape = null;
|
||||
pattern = null;
|
||||
}
|
||||
|
||||
public MarkImpl(String name, MarkType type, String color, String shape) {
|
||||
super(name);
|
||||
this.type = type;
|
||||
this.color = color;
|
||||
this.shape = shape;
|
||||
pattern = null;
|
||||
}
|
||||
|
||||
public MarkImpl(String name, MarkType type, String color, String shape, String pattern) {
|
||||
|
||||
public MarkImpl(Serializable id, String name, MarkType type, String color, String shape, String pattern) {
|
||||
super(name);
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.color = color;
|
||||
this.shape = shape;
|
||||
@@ -58,7 +36,7 @@ public class MarkImpl extends NamedImpl implements Mark {
|
||||
|
||||
@Override
|
||||
public Serializable getId() {
|
||||
return getName();
|
||||
return id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -70,7 +48,7 @@ public class MarkImpl extends NamedImpl implements Mark {
|
||||
|
||||
@Override
|
||||
public Mark resolve(SharedDomainFactory domainFactory) {
|
||||
Mark result = domainFactory.getOrCreateMark(getName(), type, color, shape, pattern);
|
||||
Mark result = domainFactory.getOrCreateMark(getId(), getName(), type, color, shape, pattern);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -28,6 +28,7 @@ import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WithID;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Course;
|
||||
@@ -248,13 +249,13 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the ID which is probably also used as the "device name" and the "sail number" in case of an
|
||||
* {@link MessageType#RPD RPD} message
|
||||
* @param trackerID
|
||||
* the "device name" and the "sail number" in case of an {@link MessageType#RPD RPD} message, used as the mark's
|
||||
* {@link Named#getName() name} and {@link WithID#getId() ID}.
|
||||
*/
|
||||
@Override
|
||||
public com.sap.sailing.domain.base.Mark getOrCreateMark(String id) {
|
||||
return baseDomainFactory.getOrCreateMark(id);
|
||||
public com.sap.sailing.domain.base.Mark getOrCreateMark(String trackerID) {
|
||||
return baseDomainFactory.getOrCreateMark(trackerID);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.polarsheets.PerRaceAndCompetitorPolarSheetGenerationWorker;
|
||||
import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker;
|
||||
import com.sap.sailing.domain.test.mock.MockedTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
|
||||
public class PolarSheetGenerationTest {
|
||||
|
||||
@Test
|
||||
public void testPolarSheetRawDataGeneration() throws InterruptedException {
|
||||
Executor executor = new ThreadPoolExecutor(/* corePoolSize */ 0,
|
||||
/* maximumPoolSize */ Runtime.getRuntime().availableProcessors(),
|
||||
/* keepAliveTime */ 60, TimeUnit.SECONDS,
|
||||
/* workQueue */ new LinkedBlockingQueue<Runnable>());
|
||||
|
||||
MockTrackedRaceForPolarSheetGeneration race = new MockTrackedRaceForPolarSheetGeneration();
|
||||
|
||||
TimePoint startTime = new MillisecondsTimePoint(1);
|
||||
TimePoint endTime = new MillisecondsTimePoint(4);
|
||||
//Only used for storing and exporting results in this test case:
|
||||
PolarSheetGenerationWorker resultContainer = new PolarSheetGenerationWorker(new HashSet<TrackedRace>(), executor);
|
||||
BoatClass forelle = new BoatClassImpl("Forelle", true);
|
||||
Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000"));
|
||||
PerRaceAndCompetitorPolarSheetGenerationWorker task = new PerRaceAndCompetitorPolarSheetGenerationWorker(race, resultContainer, startTime, endTime, competitor);
|
||||
|
||||
executor.execute(task);
|
||||
|
||||
double timeUntilTimeout = 1000;
|
||||
while (!task.isDone() && timeUntilTimeout > 0) {
|
||||
Thread.sleep(100);
|
||||
timeUntilTimeout = timeUntilTimeout - 0.1;
|
||||
}
|
||||
|
||||
Assert.assertTrue(task.isDone());
|
||||
|
||||
PolarSheetsData data = resultContainer.getPolarData();
|
||||
Assert.assertEquals(4, data.getDataCount());
|
||||
Assert.assertEquals(4.0, data.getAveragedPolarDataByWindSpeed()[1][45]);
|
||||
Assert.assertEquals(2.0, data.getAveragedPolarDataByWindSpeed()[1][55]);
|
||||
Assert.assertEquals(6.0, data.getAveragedPolarDataByWindSpeed()[1][30]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockTrackedRaceForPolarSheetGeneration extends MockedTrackedRace {
|
||||
@Override
|
||||
public DynamicGPSFixTrack<Competitor, GPSFixMoving> getTrack(Competitor competitor) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = new MockDynamicGPSFixMovinTrackForPolarSheetGeneration<Competitor>(competitor, 0);
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.0, 1.0), new MillisecondsTimePoint(1), new KnotSpeedWithBearingImpl(3.0, new DegreeBearingImpl(-45.0))));
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.001, 1.001), new MillisecondsTimePoint(2), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0))));
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.002, 1.002), new MillisecondsTimePoint(3), new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(-55.0))));
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.003, 1.003), new MillisecondsTimePoint(4), new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(-30.0))));
|
||||
return track;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getWind(Position p, TimePoint at) {
|
||||
Wind wind = new WindImpl(p, at, new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(180.0)));
|
||||
return wind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceDefinition getRace() {
|
||||
BoatClass forelle = new BoatClassImpl("Forelle", true);
|
||||
RaceDefinition race = new RaceDefinitionImpl("Forelle1", new CourseImpl("ForelleCourse", new ArrayList<Waypoint>()), forelle, new ArrayList<Competitor>());
|
||||
return race;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockGPSFixMovingForPolarSheetGeneration extends GPSFixMovingImpl {
|
||||
|
||||
public MockGPSFixMovingForPolarSheetGeneration(Position position, TimePoint timePoint, SpeedWithBearing speed) {
|
||||
super(position, timePoint, speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockDynamicGPSFixMovinTrackForPolarSheetGeneration<ItemType> extends DynamicGPSFixMovingTrackImpl<ItemType> {
|
||||
|
||||
public MockDynamicGPSFixMovinTrackForPolarSheetGeneration(ItemType trackedItem,
|
||||
long millisecondsOverWhichToAverage) {
|
||||
super(trackedItem, millisecondsOverWhichToAverage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValid(NavigableSet<GPSFixMoving> rawFixes, GPSFixMoving e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+8
-6
@@ -160,17 +160,19 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
String shape2 = controlPointMetadata.get("P2.Shape");
|
||||
String pattern1 = controlPointMetadata.get("P1.Pattern");
|
||||
String pattern2 = controlPointMetadata.get("P2.Pattern");
|
||||
|
||||
Mark mark1 = baseDomainFactory.getOrCreateMark(controlPointName + " (1)", type1, color1, shape1, pattern1);
|
||||
Mark mark2 = baseDomainFactory.getOrCreateMark(controlPointName + " (2)", type2, color2, shape2, pattern2);
|
||||
domainControlPoint = baseDomainFactory.createGate(mark1, mark2, controlPointName);
|
||||
final String name1 = controlPointName + " (1)";
|
||||
final Serializable id1 = name1; // TODO bug 1184; need to obtain mark ID through TTCM
|
||||
Mark mark1 = baseDomainFactory.getOrCreateMark(id1, name1, type1, color1, shape1, pattern1);
|
||||
final String name2 = controlPointName + " (2)";
|
||||
final Serializable id2 = name2; // TODO bug 1184; need to obtain mark ID through TTCM
|
||||
Mark mark2 = baseDomainFactory.getOrCreateMark(id2, name2, type2, color2, shape2, pattern2);
|
||||
domainControlPoint = baseDomainFactory.createGate(controlPoint.getId(), mark1, mark2, controlPointName);
|
||||
} else {
|
||||
MarkType type = resolveMarkTypeFromMetadata(controlPointMetadata, "Type");
|
||||
String color = controlPointMetadata.get("Color");
|
||||
String shape = controlPointMetadata.get("Shape");
|
||||
String pattern = controlPointMetadata.get("Pattern");
|
||||
|
||||
Mark mark = baseDomainFactory.getOrCreateMark(controlPointName, type, color, shape, pattern);
|
||||
Mark mark = baseDomainFactory.getOrCreateMark(controlPoint.getId(), controlPointName, type, color, shape, pattern);
|
||||
domainControlPoint = mark;
|
||||
}
|
||||
controlPointCache.put(controlPoint, domainControlPoint);
|
||||
|
||||
@@ -13,6 +13,7 @@ Export-Package: com.sap.sailing.domain.base,
|
||||
com.sap.sailing.domain.leaderboard,
|
||||
com.sap.sailing.domain.leaderboard.impl,
|
||||
com.sap.sailing.domain.leaderboard.meta,
|
||||
com.sap.sailing.domain.polarsheets,
|
||||
com.sap.sailing.domain.racelog.impl,
|
||||
com.sap.sailing.domain.tracking,
|
||||
com.sap.sailing.domain.tracking.impl,
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
public interface DomainFactory extends SharedDomainFactory {
|
||||
static DomainFactory INSTANCE = new DomainFactoryImpl();
|
||||
|
||||
|
||||
MarkPassing createMarkPassing(TimePoint timePoint, Waypoint waypoint, Competitor competitor);
|
||||
|
||||
/**
|
||||
|
||||
+50
-18
@@ -1,6 +1,5 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
|
||||
import java.awt.TrayIcon.MessageType;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
@@ -44,7 +43,14 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
*/
|
||||
private final Map<String, Nationality> nationalityCache;
|
||||
|
||||
private final Map<String, Mark> markCache;
|
||||
private final Map<Serializable, Mark> markCache;
|
||||
|
||||
/**
|
||||
* For all marks ever created by this factory, the mark {@link WithID#getId() ID}'s string representation
|
||||
* is mapped here to the actual ID. This allows clients to send only the string representation to the server
|
||||
* and still be able to identify a mark uniquely this way.
|
||||
*/
|
||||
private final Map<String, Serializable> markIdCache;
|
||||
|
||||
private final Map<String, BoatClass> boatClassCache;
|
||||
|
||||
@@ -87,7 +93,8 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
public DomainFactoryImpl() {
|
||||
waypointCacheReferenceQueue = new ReferenceQueue<Waypoint>();
|
||||
nationalityCache = new HashMap<String, Nationality>();
|
||||
markCache = new HashMap<String, Mark>();
|
||||
markCache = new HashMap<Serializable, Mark>();
|
||||
markIdCache = new HashMap<>();
|
||||
boatClassCache = new HashMap<String, BoatClass>();
|
||||
competitorCache = new HashMap<Serializable, Competitor>();
|
||||
waypointCache = new ConcurrentHashMap<Serializable, WeakWaypointReference>();
|
||||
@@ -106,27 +113,47 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* the ID which is probably also used as the "device name" and the "sail number" in case of an
|
||||
* {@link MessageType#RPD RPD} message
|
||||
*/
|
||||
@Override
|
||||
public Mark getOrCreateMark(String id) {
|
||||
Mark result = markCache.get(id);
|
||||
if (result == null) {
|
||||
result = new MarkImpl(id);
|
||||
markCache.put(id, result);
|
||||
}
|
||||
return result;
|
||||
public Mark getOrCreateMark(String name) {
|
||||
return getOrCreateMark(name, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mark getOrCreateMark(String id, MarkType type, String color, String shape, String pattern) {
|
||||
public Mark getOrCreateMark(Serializable id, String name) {
|
||||
Mark result = markCache.get(id);
|
||||
if (result == null) {
|
||||
result = new MarkImpl(id, type, color, shape, pattern);
|
||||
markCache.put(id, result);
|
||||
result = new MarkImpl(id, name);
|
||||
cacheMark(id, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mark getOrCreateMark(String toStringRepresentationOfID, String name) {
|
||||
final Mark result;
|
||||
if (markIdCache.containsKey(toStringRepresentationOfID)) {
|
||||
Serializable id = markIdCache.get(toStringRepresentationOfID);
|
||||
result = getOrCreateMark(id, name);
|
||||
} else {
|
||||
result = new MarkImpl(toStringRepresentationOfID, name);
|
||||
cacheMark(toStringRepresentationOfID, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void cacheMark(Serializable id, Mark result) {
|
||||
markCache.put(id, result);
|
||||
markIdCache.put(id.toString(), id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Mark getOrCreateMark(Serializable id, String name, MarkType type, String color, String shape, String pattern) {
|
||||
Mark result = markCache.get(id);
|
||||
if (result == null) {
|
||||
result = new MarkImpl(id, name, type, color, shape, pattern);
|
||||
cacheMark(id, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -136,6 +163,11 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
return new GateImpl(left, right, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Gate createGate(Serializable id, Mark left, Mark right, String name) {
|
||||
return new GateImpl(id, left, right, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Waypoint createWaypoint(ControlPoint controlPoint) {
|
||||
synchronized (waypointCache) {
|
||||
|
||||
+18
-1
@@ -213,6 +213,15 @@ public interface Leaderboard extends Named {
|
||||
* @throws NoWindException
|
||||
*/
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException;
|
||||
|
||||
/**
|
||||
* Returns the total rank of the given competitor.
|
||||
* @param competitor
|
||||
* @param timePoint
|
||||
* @return
|
||||
* @throws NoWindException
|
||||
*/
|
||||
int getTotalRankOfCompetitor(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
|
||||
/**
|
||||
* Fetches all entries for all competitors of all races tracked by this leaderboard in one sweep. This saves some
|
||||
@@ -268,12 +277,20 @@ public interface Leaderboard extends Named {
|
||||
|
||||
void setDisplayName(Competitor competitor, String displayName);
|
||||
|
||||
/**
|
||||
* If a display name for the leaderboard has been defined,
|
||||
* this method returns it; otherwise, <code>null</code> is returned.
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
void setDisplayName(String displayName);
|
||||
|
||||
/**
|
||||
* If a display name different from the competitor's {@link Competitor#getName() name} has been defined,
|
||||
* this method returns it; otherwise, <code>null</code> is returned.
|
||||
*/
|
||||
String getDisplayName(Competitor competitor);
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the column represented by <code>raceColumn</code> shall be considered when counting the number of "races
|
||||
* so far" for discarding. Although medal races are never discarded themselves, they still count in determining the
|
||||
|
||||
+3
@@ -25,6 +25,9 @@ public interface LeaderboardGroup extends Renamable {
|
||||
void removeLeaderboard(Leaderboard leaderboard);
|
||||
void removeAllLeaderboards(Collection<Leaderboard> leaderboards);
|
||||
void clearLeaderboards();
|
||||
/**
|
||||
* @return The overall leaderboard of this group or null if there is none.
|
||||
*/
|
||||
Leaderboard getOverallLeaderboard();
|
||||
void setOverallLeaderboard(Leaderboard leaderboard);
|
||||
}
|
||||
+721
-705
File diff suppressed because it is too large.
Load diff
+3
-9
@@ -30,12 +30,6 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
|
||||
private static final long serialVersionUID = 2370461218294770084L;
|
||||
private final Regatta regatta;
|
||||
|
||||
/**
|
||||
* If this member is <code>null</code>, {@link #getName()} will use the regatta name as the default name for this
|
||||
* leaderboard. Otherwise, the {@link #displayName} is used.
|
||||
*/
|
||||
private String displayName;
|
||||
|
||||
public RegattaLeaderboardImpl(Regatta regatta, SettableScoreCorrection scoreCorrection,
|
||||
ThresholdBasedResultDiscardingRule resultDiscardingRule, CourseArea courseArea) {
|
||||
super(scoreCorrection, resultDiscardingRule, courseArea);
|
||||
@@ -48,7 +42,7 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
|
||||
*/
|
||||
@Override
|
||||
public void setName(String newName) {
|
||||
displayName = newName;
|
||||
setDisplayName(newName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,8 +53,8 @@ public class RegattaLeaderboardImpl extends AbstractLeaderboardImpl implements R
|
||||
@Override
|
||||
public String getName() {
|
||||
String result;
|
||||
if (displayName != null) {
|
||||
result = displayName;
|
||||
if (getDisplayName() != null) {
|
||||
result = getDisplayName();
|
||||
} else {
|
||||
result = getRegatta().getName();
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class MetaLeaderboardColumn extends SimpleAbstractRaceColumn implements R
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return leaderboard.getName();
|
||||
return leaderboard.getDisplayName() != null ? leaderboard.getDisplayName() : leaderboard.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
|
||||
public interface BoatAndWindSpeed {
|
||||
|
||||
public Speed getBoatSpeed();
|
||||
|
||||
public Speed getWindSpeed();
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
|
||||
public class BoatAndWindSpeedImpl implements BoatAndWindSpeed{
|
||||
|
||||
private Speed boatSpeed;
|
||||
private Speed windSpeed;
|
||||
|
||||
|
||||
|
||||
public BoatAndWindSpeedImpl(Speed boatSpeed, Speed windSpeed) {
|
||||
this.boatSpeed = boatSpeed;
|
||||
this.windSpeed = windSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getBoatSpeed() {
|
||||
return boatSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getWindSpeed() {
|
||||
return windSpeed;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NavigableSet;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
/**
|
||||
* Iterates through the fixes of one competitor in one tracked race and fills the {@link PolarSheetGenerationWorker}
|
||||
* with datapoints that are found for the speed of the boat and its angle to the wind
|
||||
*
|
||||
* @author D054528 Frederik Petersen
|
||||
*
|
||||
*/
|
||||
public class PerRaceAndCompetitorPolarSheetGenerationWorker implements Runnable{
|
||||
|
||||
private final TrackedRace race;
|
||||
|
||||
private final PolarSheetGenerationWorker polarSheetGenerationWorker;
|
||||
|
||||
private TimePoint startTime;
|
||||
|
||||
private TimePoint endTime;
|
||||
|
||||
private final Competitor competitor;
|
||||
|
||||
private boolean done = false;
|
||||
|
||||
public PerRaceAndCompetitorPolarSheetGenerationWorker(TrackedRace race,
|
||||
PolarSheetGenerationWorker polarSheetGenerationWorker, TimePoint startTime, TimePoint endTime,
|
||||
Competitor competitor) {
|
||||
super();
|
||||
this.race = race;
|
||||
this.polarSheetGenerationWorker = polarSheetGenerationWorker;
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
this.competitor = competitor;
|
||||
optimizeStartTime();
|
||||
optimizeEndTime();
|
||||
}
|
||||
|
||||
private void optimizeEndTime() {
|
||||
NavigableSet<MarkPassing> markPassings = race.getMarkPassings(competitor);
|
||||
if (markPassings == null || markPassings.size() < 1) {
|
||||
return;
|
||||
}
|
||||
MarkPassing passedFinish = markPassings.last();
|
||||
TimePoint passedFinishTimePoint = passedFinish.getTimePoint();
|
||||
if (passedFinishTimePoint.before(endTime)) {
|
||||
endTime = passedFinishTimePoint;
|
||||
}
|
||||
}
|
||||
|
||||
private void optimizeStartTime() {
|
||||
NavigableSet<MarkPassing> markPassings = race.getMarkPassings(competitor);
|
||||
if (markPassings == null || markPassings.size() < 1) {
|
||||
return;
|
||||
}
|
||||
MarkPassing passedStart = markPassings.first();
|
||||
TimePoint passedStartTimePoint = passedStart.getTimePoint();
|
||||
if (passedStartTimePoint.after(startTime)) {
|
||||
startTime = passedStartTimePoint;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
GPSFixTrack<Competitor, GPSFixMoving> track = race.getTrack(competitor);
|
||||
track.lockForRead();
|
||||
Iterator<GPSFixMoving> fixesIterator = track.getFixesIterator(startTime, true);
|
||||
|
||||
while (fixesIterator.hasNext()) {
|
||||
GPSFixMoving fix = fixesIterator.next();
|
||||
if (fix.getTimePoint().after(endTime)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (track.hasDirectionChange(fix.getTimePoint(), race.getRace().getBoatClass()
|
||||
.getManeuverDegreeAngleThreshold())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SpeedWithBearing speedWithBearing = fix.getSpeed();
|
||||
Bearing bearing = speedWithBearing.getBearing();
|
||||
Position position = fix.getPosition();
|
||||
Wind wind = race.getWind(position, fix.getTimePoint());
|
||||
Bearing windBearing = wind.getFrom();
|
||||
double angleToWind = bearing.getDifferenceTo(windBearing).getDegrees();
|
||||
|
||||
polarSheetGenerationWorker.addPolarData(Math.round(angleToWind), speedWithBearing, wind);
|
||||
}
|
||||
|
||||
track.unlockAfterRead();
|
||||
done = true;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return done;
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
package com.sap.sailing.domain.polarsheets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.PolarSheetsDataImpl;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
|
||||
/**
|
||||
* Allows extracting data about average speed for each angle creating the foundation of polar-sheet generation. Tasks
|
||||
* are assigned to the executor per race & per competitor and the results are filled on the go to allow progress
|
||||
* indication in the polar-sheet itself.
|
||||
*
|
||||
* @author D054528 Frederik Petersen
|
||||
*
|
||||
*/
|
||||
public class PolarSheetGenerationWorker {
|
||||
|
||||
private final Set<PerRaceAndCompetitorPolarSheetGenerationWorker> workers;
|
||||
|
||||
private final List<List<BoatAndWindSpeed>> polarData;
|
||||
|
||||
private final Executor executor;
|
||||
|
||||
/**
|
||||
* Will prepare the {@link PerRaceAndCompetitorPolarSheetGenerationWorker}s per race & per competitor. This includes
|
||||
* determining start and end time.
|
||||
*
|
||||
* @param trackedRaces
|
||||
* from which the data is to be collected
|
||||
* @param executor
|
||||
* executes the tasks upon {@link #startPolarSheetGeneration()}
|
||||
*/
|
||||
public PolarSheetGenerationWorker(Set<TrackedRace> trackedRaces, Executor executor) {
|
||||
polarData = initializePolarDataContainer();
|
||||
this.executor = executor;
|
||||
workers = new HashSet<PerRaceAndCompetitorPolarSheetGenerationWorker>();
|
||||
for (TrackedRace race : trackedRaces) {
|
||||
TimePoint startTime = race.getStartOfRace();
|
||||
TimePoint endTime = race.getEndOfRace();
|
||||
if (endTime == null) {
|
||||
// TODO Figure out if there is an alternative:
|
||||
endTime = race.getTimePointOfNewestEvent();
|
||||
}
|
||||
RaceDefinition raceDefinition = race.getRace();
|
||||
Iterable<Competitor> competitors = raceDefinition.getCompetitors();
|
||||
|
||||
for (Competitor competitor : competitors) {
|
||||
PerRaceAndCompetitorPolarSheetGenerationWorker task = new PerRaceAndCompetitorPolarSheetGenerationWorker(race, this, startTime, endTime, competitor);
|
||||
workers.add(task);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private List<List<BoatAndWindSpeed>> initializePolarDataContainer() {
|
||||
List<List<BoatAndWindSpeed>> container = new ArrayList<List<BoatAndWindSpeed>>();
|
||||
for (int i = 0; i < 360; i++) {
|
||||
container.add(new ArrayList<BoatAndWindSpeed>());
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the {@link PerRaceAndCompetitorPolarSheetGenerationWorker}s
|
||||
*/
|
||||
public void startPolarSheetGeneration() {
|
||||
for (Runnable task : workers) {
|
||||
executor.execute(task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from {@link PerRaceAndCompetitorPolarSheetGenerationWorker} for adding a datapoint to the list of
|
||||
* results
|
||||
*
|
||||
* @param roundedAngle
|
||||
* boat's angle to the wind
|
||||
* @param boatSpeed
|
||||
* boat's speed in knots
|
||||
* @param windSpeed
|
||||
* wind's speed in knots
|
||||
*/
|
||||
protected void addPolarData(long roundedAngle, Speed boatSpeed, Speed windSpeed) {
|
||||
int angle = (int) roundedAngle;
|
||||
if (angle < 0) {
|
||||
angle = (360 + angle);
|
||||
}
|
||||
BoatAndWindSpeed speeds = new BoatAndWindSpeedImpl(boatSpeed, windSpeed);
|
||||
polarData.get(angle).add(speeds);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return results already averaged per angle. Also datacount overall and per angle. And a completion flag to show
|
||||
* if the complete polar sheet has been generated or if the current results are only an intermediate
|
||||
* product.
|
||||
*/
|
||||
public PolarSheetsData getPolarData() {
|
||||
Number[][] averagedPolarDataByWindSpeed = new Number[13][360];
|
||||
Integer[] dataCountPerAngle = new Integer[360];
|
||||
int dataCount = 0;
|
||||
Map<Integer, Integer[]> dataCountPerAngleForWindspeed = new HashMap<Integer, Integer[]>();
|
||||
for (int i = 0; i < 13; i++) {
|
||||
dataCountPerAngleForWindspeed.put(i, new Integer[360]);
|
||||
}
|
||||
for (int i = 0; i < 360; i++) {
|
||||
// Avoid Concurrent modification, lock would slow things down
|
||||
BoatAndWindSpeed[] values = polarData.get(i).toArray(new BoatAndWindSpeed[polarData.get(i).size()]);
|
||||
dataCount = dataCount + values.length;
|
||||
dataCountPerAngle[i] = values.length;
|
||||
double[] sumsPerWindSpeed = new double[13];
|
||||
int[] dataCountPerWindSpeed = new int[13];
|
||||
for (BoatAndWindSpeed singleDataPoint : values) {
|
||||
if (singleDataPoint != null) {
|
||||
int windSpeed = (int) singleDataPoint.getWindSpeed().getBeaufort();
|
||||
//Somehow beaufort sometimes gets bigger than twelve. TODO: Investigation
|
||||
if (windSpeed > 12) {
|
||||
windSpeed = 12;
|
||||
}
|
||||
//TODO enable different kinds of metrics for boats speed
|
||||
sumsPerWindSpeed[windSpeed] = sumsPerWindSpeed[windSpeed] + singleDataPoint.getBoatSpeed().getKnots();
|
||||
dataCountPerWindSpeed[windSpeed]++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 13; j++) {
|
||||
Double average = sumsPerWindSpeed[j] / dataCountPerWindSpeed[j];
|
||||
if (average.isNaN()) {
|
||||
average = new Double(0);
|
||||
}
|
||||
averagedPolarDataByWindSpeed[j][i] = average;
|
||||
dataCountPerAngleForWindspeed.get(j)[i] = dataCountPerWindSpeed[j];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
boolean complete = true;
|
||||
for (PerRaceAndCompetitorPolarSheetGenerationWorker task : workers) {
|
||||
if (!task.isDone()) {
|
||||
complete = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PolarSheetsData data = new PolarSheetsDataImpl(averagedPolarDataByWindSpeed, complete, dataCount,
|
||||
dataCountPerAngleForWindspeed);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to present more detailed data.
|
||||
*
|
||||
* @return The complete set of datapoints that have been added. Can be quite big, depending on the amount of races
|
||||
* and competitors.
|
||||
*/
|
||||
public List<List<BoatAndWindSpeed>> getCompleteData() {
|
||||
return polarData;
|
||||
}
|
||||
|
||||
}
|
||||
+119
-115
@@ -42,41 +42,42 @@ import com.sap.sailing.domain.racelog.RaceLog;
|
||||
*/
|
||||
public interface TrackedRace extends Serializable {
|
||||
final long MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS = 30000;
|
||||
|
||||
|
||||
final long DEFAULT_LIVE_DELAY_IN_MILLISECONDS = 5000;
|
||||
|
||||
RaceDefinition getRace();
|
||||
|
||||
|
||||
RegattaAndRaceIdentifier getRaceIdentifier();
|
||||
|
||||
|
||||
/**
|
||||
* Computes the estimated start time for this race (not to be confused with the {@link #getStartOfTracking()} time point
|
||||
* which is expected to be before the race start time). When there are no {@link MarkPassing}s for the first mark, <code>null</code>
|
||||
* is returned. If there are mark passings for the first mark and the start time is less than
|
||||
* {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} before the first mark passing for the
|
||||
* Computes the estimated start time for this race (not to be confused with the {@link #getStartOfTracking()} time
|
||||
* point which is expected to be before the race start time). When there are no {@link MarkPassing}s for the first
|
||||
* mark, <code>null</code> is returned. If there are mark passings for the first mark and the start time is less
|
||||
* than {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} before the first mark passing for the
|
||||
* first mark. Otherwise, the first mark passing for the first mark minus
|
||||
* {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} is returned as the race start time.<p>
|
||||
* {@link #MAX_TIME_BETWEEN_START_AND_FIRST_MARK_PASSING_IN_MILLISECONDS} is returned as the race start time.
|
||||
* <p>
|
||||
*
|
||||
* If no start time can be determined this way, <code>null</code> is returned.
|
||||
*/
|
||||
TimePoint getStartOfRace();
|
||||
|
||||
|
||||
/**
|
||||
* Determine the race end time is tricky. Boats may sink, stop, not finish, although they started the race. We therefore
|
||||
* cannot wait for all boats to reach the finish line.
|
||||
* The following rules are used to calculate the endOfRace:
|
||||
* Determine the race end time is tricky. Boats may sink, stop, not finish, although they started the race. We
|
||||
* therefore cannot wait for all boats to reach the finish line. The following rules are used to calculate the
|
||||
* endOfRace:
|
||||
* <ol>
|
||||
* <li>Returns <code>null</code> if no boat passed the finish line</li>
|
||||
* <li>Returns time of the last mark passing recorded for the finish line</li>
|
||||
* <li>TODO: Returns the time of the first passing of the finish line + the target window (defined in the competition rules)
|
||||
* if a target window has been defined for the race</li>
|
||||
* </ol>
|
||||
* <li>Returns <code>null</code> if no boat passed the finish line</li>
|
||||
* <li>Returns time of the last mark passing recorded for the finish line</li>
|
||||
* <li>TODO: Returns the time of the first passing of the finish line + the target window (defined in the
|
||||
* competition rules) if a target window has been defined for the race</li>
|
||||
* </ol>
|
||||
*/
|
||||
TimePoint getEndOfRace();
|
||||
|
||||
/**
|
||||
* Returns a list of the first and last mark passing times of all course waypoints. Callers wanting to iterate over the
|
||||
* result must <code>synchronize</code> on the result.
|
||||
* Returns a list of the first and last mark passing times of all course waypoints. Callers wanting to iterate over
|
||||
* the result must <code>synchronize</code> on the result.
|
||||
*/
|
||||
Iterable<Pair<Waypoint, Pair<TimePoint, TimePoint>>> getMarkPassingsTimes();
|
||||
|
||||
@@ -84,89 +85,84 @@ public interface TrackedRace extends Serializable {
|
||||
* Shorthand for <code>{@link #getStart()}.{@link TimePoint#compareTo(TimePoint) compareTo(at)} <= 0</code>
|
||||
*/
|
||||
boolean hasStarted(TimePoint at);
|
||||
|
||||
|
||||
/**
|
||||
* Clients can safely iterate over the iterable returned because it's a non-live copy of the tracked legs of this
|
||||
* tracked race. This implies that should an update to the underlying list of waypoints in this race's {@link Course}
|
||||
* take place after this method has returned, then this won't be reflected in the result returned. Callers should
|
||||
* obtain the {@link Course#lockForRead() course's read lock} while using the result of this call if they want to
|
||||
* ensure that no course update is applied concurrently.
|
||||
* tracked race. This implies that should an update to the underlying list of waypoints in this race's
|
||||
* {@link Course} take place after this method has returned, then this won't be reflected in the result returned.
|
||||
* Callers should obtain the {@link Course#lockForRead() course's read lock} while using the result of this call if
|
||||
* they want to ensure that no course update is applied concurrently.
|
||||
*/
|
||||
Iterable<TrackedLeg> getTrackedLegs();
|
||||
|
||||
|
||||
TrackedLeg getTrackedLeg(Leg leg);
|
||||
|
||||
|
||||
/**
|
||||
* Tracking information about the leg <code>competitor</code> is on at <code>timePoint</code>, or
|
||||
* <code>null</code> if the competitor hasn't started any leg yet at <code>timePoint</code> or has
|
||||
* already finished the race.
|
||||
* Tracking information about the leg <code>competitor</code> is on at <code>timePoint</code>, or <code>null</code>
|
||||
* if the competitor hasn't started any leg yet at <code>timePoint</code> or has already finished the race.
|
||||
*/
|
||||
TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Tells which leg the leader at <code>timePoint</code> is on
|
||||
*/
|
||||
TrackedLeg getCurrentLeg(TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Precondition: waypoint must still be part of {@link #getRace()}.{@link RaceDefinition#getCourse() getCourse()}.
|
||||
*/
|
||||
TrackedLeg getTrackedLegFinishingAt(Waypoint endOfLeg);
|
||||
|
||||
|
||||
/**
|
||||
* Precondition: waypoint must still be part of {@link #getRace()}.{@link RaceDefinition#getCourse() getCourse()}.
|
||||
*/
|
||||
TrackedLeg getTrackedLegStartingAt(Waypoint startOfLeg);
|
||||
|
||||
|
||||
/**
|
||||
* The raw, updating feed of a single competitor participating in this race
|
||||
*/
|
||||
GPSFixTrack<Competitor, GPSFixMoving> getTrack(Competitor competitor);
|
||||
|
||||
|
||||
/**
|
||||
* Tells the leg on which the <code>competitor</code> was at time <code>at</code>.
|
||||
* If the competitor hasn't passed the start waypoint yet, <code>null</code> is
|
||||
* returned because the competitor was not yet on any leg at that point in time. If
|
||||
* the time point happens to be after the last fix received from that competitor,
|
||||
* the last known leg for that competitor is returned. If the time point is after the
|
||||
* competitor's mark passing for the finish line, <code>null</code> is returned.
|
||||
* For all legs except the last, if the time point equals a mark passing time point
|
||||
* of the leg's starting waypoint, that leg is returned. For the time point of
|
||||
* the mark passing for the finish line, the last leg is returned.
|
||||
* Tells the leg on which the <code>competitor</code> was at time <code>at</code>. If the competitor hasn't passed
|
||||
* the start waypoint yet, <code>null</code> is returned because the competitor was not yet on any leg at that point
|
||||
* in time. If the time point happens to be after the last fix received from that competitor, the last known leg for
|
||||
* that competitor is returned. If the time point is after the competitor's mark passing for the finish line,
|
||||
* <code>null</code> is returned. For all legs except the last, if the time point equals a mark passing time point
|
||||
* of the leg's starting waypoint, that leg is returned. For the time point of the mark passing for the finish line,
|
||||
* the last leg is returned.
|
||||
*/
|
||||
TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, TimePoint at);
|
||||
|
||||
|
||||
TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, Leg leg);
|
||||
|
||||
|
||||
/**
|
||||
* @return a sequential number counting the updates that occurred to this tracked race. Callers may use this to ask
|
||||
* for updates newer than such a sequence number.
|
||||
*/
|
||||
long getUpdateCount();
|
||||
|
||||
|
||||
int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Computes the rank of the competitor in this race for the current time.
|
||||
* Computes the rank of the competitor in this race for the current time.
|
||||
*/
|
||||
int getRank(Competitor competitor) throws NoWindException;
|
||||
|
||||
|
||||
/**
|
||||
* Computes the rank of <code>competitor</code> in this race. A competitor is ahead of all
|
||||
* competitors that are one or more legs behind. Within the same leg, the rank is determined
|
||||
* by the windward distance to go and therefore depends on the assumptions of the wind direction
|
||||
* for the given <code>timePoint</code>. If the race hasn't {@link #hasStarted(TimePoint) started}
|
||||
* yet, the result is undefined.
|
||||
* Computes the rank of <code>competitor</code> in this race. A competitor is ahead of all competitors that are one
|
||||
* or more legs behind. Within the same leg, the rank is determined by the windward distance to go and therefore
|
||||
* depends on the assumptions of the wind direction for the given <code>timePoint</code>. If the race hasn't
|
||||
* {@link #hasStarted(TimePoint) started} yet, the result is undefined.
|
||||
*
|
||||
* @return <code>0</code> in case the competitor hasn't participated in the race; a rank starting
|
||||
* with <code>1</code> where rank <code>1</code> identifies the leader otherwise
|
||||
* @return <code>0</code> in case the competitor hasn't participated in the race; a rank starting with
|
||||
* <code>1</code> where rank <code>1</code> identifies the leader otherwise
|
||||
*/
|
||||
int getRank(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
|
||||
|
||||
/**
|
||||
* For a competitor, computes the distance (TODO not yet clear whether over ground or
|
||||
* projected onto wind direction) into the race <code>secondsIntoTheRace</code> after
|
||||
* the race {@link TrackedRace#getStart() started}.
|
||||
* For a competitor, computes the distance (TODO not yet clear whether over ground or projected onto wind direction)
|
||||
* into the race <code>secondsIntoTheRace</code> after the race {@link TrackedRace#getStart() started}.
|
||||
*/
|
||||
Distance getStartAdvantage(Competitor competitor, double secondsIntoTheRace);
|
||||
|
||||
@@ -184,14 +180,14 @@ public interface TrackedRace extends Serializable {
|
||||
Iterable<MarkPassing> getMarkPassingsInOrder(Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Obtains the {@link MarkPassing} for <code>competitor</code> passing <code>waypoint</code>. If no such
|
||||
* mark passing has been reported (yet), <code>null</code> is returned.
|
||||
* Obtains the {@link MarkPassing} for <code>competitor</code> passing <code>waypoint</code>. If no such mark
|
||||
* passing has been reported (yet), <code>null</code> is returned.
|
||||
*/
|
||||
MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint);
|
||||
|
||||
/**
|
||||
* Yields the track describing <code>mark</code>'s movement over time; never <code>null</code> because a
|
||||
* new track will be created in case no track was present for <code>mark</code> so far.
|
||||
* Yields the track describing <code>mark</code>'s movement over time; never <code>null</code> because a new track
|
||||
* will be created in case no track was present for <code>mark</code> so far.
|
||||
*/
|
||||
GPSFixTrack<Mark, GPSFix> getOrCreateTrack(Mark mark);
|
||||
|
||||
@@ -205,7 +201,7 @@ public interface TrackedRace extends Serializable {
|
||||
* is returned. Otherwise, the center of gravity between the mark positions is computed and returned.
|
||||
*/
|
||||
Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Same as {@link #getWind(Position, TimePoint, Iterable) getWind(p, at, Collections.emptyList())}
|
||||
*/
|
||||
@@ -213,8 +209,8 @@ public interface TrackedRace extends Serializable {
|
||||
|
||||
/**
|
||||
* Obtains estimated interpolated wind information for a given position and time point. The information is taken
|
||||
* from all wind sources available except for those listed in <code>windSourcesToExclude</code>, using the confidences
|
||||
* of the wind values provided by the various sources during averaging.
|
||||
* from all wind sources available except for those listed in <code>windSourcesToExclude</code>, using the
|
||||
* confidences of the wind values provided by the various sources during averaging.
|
||||
*/
|
||||
Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude);
|
||||
|
||||
@@ -232,10 +228,11 @@ public interface TrackedRace extends Serializable {
|
||||
Iterable<WindSource> getWindSources();
|
||||
|
||||
/**
|
||||
* Same as {@link #getOrCreateWindTrack(WindSource, long) getOrCreateWindTrack(windSource, getMillisecondsOverWhichToAverageWind())}.
|
||||
* Same as {@link #getOrCreateWindTrack(WindSource, long) getOrCreateWindTrack(windSource,
|
||||
* getMillisecondsOverWhichToAverageWind())}.
|
||||
*/
|
||||
WindTrack getOrCreateWindTrack(WindSource windSource);
|
||||
|
||||
|
||||
WindTrack getOrCreateWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation);
|
||||
|
||||
/**
|
||||
@@ -244,26 +241,26 @@ public interface TrackedRace extends Serializable {
|
||||
void waitForNextUpdate(int sinceUpdate) throws InterruptedException;
|
||||
|
||||
/**
|
||||
* Time stamp of the start of the actual tracking.
|
||||
* The value can be null (e.g. if we have not received any signal from the tracking infrastructure)
|
||||
* Time stamp of the start of the actual tracking. The value can be null (e.g. if we have not received any signal
|
||||
* from the tracking infrastructure)
|
||||
*/
|
||||
TimePoint getStartOfTracking();
|
||||
|
||||
/**
|
||||
* Time stamp of the end of the actual tracking.
|
||||
* The value can be null (e.g. if we have not received any signal from the tracking infrastructure)
|
||||
* Time stamp of the end of the actual tracking. The value can be null (e.g. if we have not received any signal from
|
||||
* the tracking infrastructure)
|
||||
*/
|
||||
TimePoint getEndOfTracking();
|
||||
|
||||
/**
|
||||
* Regardless of the order in which events were received, this method returns the latest time point contained by any of
|
||||
* the events received and processed.
|
||||
* Regardless of the order in which events were received, this method returns the latest time point contained by any
|
||||
* of the events received and processed.
|
||||
*/
|
||||
TimePoint getTimePointOfNewestEvent();
|
||||
|
||||
/**
|
||||
* Regardless of the order in which events were received, this method returns the oldest time point contained by any of
|
||||
* the events received and processed.
|
||||
* Regardless of the order in which events were received, this method returns the oldest time point contained by any
|
||||
* of the events received and processed.
|
||||
*/
|
||||
TimePoint getTimePointOfOldestEvent();
|
||||
|
||||
@@ -275,17 +272,18 @@ public interface TrackedRace extends Serializable {
|
||||
* some tracking providers such as TracTrac. If the caller wants to iterate on the resulting collection or
|
||||
* construct a {@link SortedSet#headSet(Object)} or {@link SortedSet#tailSet(Object)} and then iterate over
|
||||
* that, the caller needs to invoke {@link #lockForRead(Iterable)} with the collection returned as parameter
|
||||
* because insertions into the competitor's mark passing collection will obtain the corresponding write lock.
|
||||
* because insertions into the competitor's mark passing collection will obtain the corresponding write
|
||||
* lock.
|
||||
*/
|
||||
NavigableSet<MarkPassing> getMarkPassings(Competitor competitor);
|
||||
|
||||
|
||||
void lockForRead(Iterable<MarkPassing> markPassings);
|
||||
|
||||
|
||||
void unlockAfterRead(Iterable<MarkPassing> markPassings);
|
||||
|
||||
/**
|
||||
* Time stamp that the event received last from the underlying push service carried on it.
|
||||
* Note that these times may not increase monotonically.
|
||||
* Time stamp that the event received last from the underlying push service carried on it. Note that these times may
|
||||
* not increase monotonically.
|
||||
*/
|
||||
TimePoint getTimePointOfLastEvent();
|
||||
|
||||
@@ -297,7 +295,7 @@ public interface TrackedRace extends Serializable {
|
||||
* Gets the current delay of incoming events to the real time of the events in milliseconds
|
||||
*/
|
||||
long getDelayToLiveInMillis();
|
||||
|
||||
|
||||
/**
|
||||
* Estimates the wind direction based on the observed boat courses at the time given for the position provided. The
|
||||
* estimate is based on the assumption that the boats which are on an upwind or a downwind leg sail with very
|
||||
@@ -322,13 +320,12 @@ public interface TrackedRace extends Serializable {
|
||||
* we may be able to also infer the wind speed from the boat tracks.
|
||||
*/
|
||||
Wind getEstimatedWindDirection(Position position, TimePoint timePoint);
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether the <code>competitor</code> is sailing on port or starboard tack at the
|
||||
* <code>timePoint</code> requested. Note that this will have to retrieve information about the wind.
|
||||
* This, in turn, can lead to the current thread obtaining the monitor of the various wind tracks,
|
||||
* and, if the {@link WindSource#TRACK_BASED_ESTIMATION} source is used, also the monitors of the
|
||||
* competitors' GPS tracks.
|
||||
* Determines whether the <code>competitor</code> is sailing on port or starboard tack at the <code>timePoint</code>
|
||||
* requested. Note that this will have to retrieve information about the wind. This, in turn, can lead to the
|
||||
* current thread obtaining the monitor of the various wind tracks, and, if the
|
||||
* {@link WindSource#TRACK_BASED_ESTIMATION} source is used, also the monitors of the competitors' GPS tracks.
|
||||
*/
|
||||
Tack getTack(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
|
||||
@@ -346,30 +343,34 @@ public interface TrackedRace extends Serializable {
|
||||
* mark positions are not known (yet)
|
||||
*/
|
||||
Wind getDirectionFromStartToNextMark(TimePoint at);
|
||||
|
||||
|
||||
/**
|
||||
* Uses a {@link DouglasPeucker Douglas-Peucker} algorithm to approximate this track's fixes starting at
|
||||
* time <code>from</code> until time point <code>to</code> such that the maximum distance between the
|
||||
* track's fixes and the approximation is at most <code>maxDistance</code>.
|
||||
* Uses a {@link DouglasPeucker Douglas-Peucker} algorithm to approximate this track's fixes starting at time
|
||||
* <code>from</code> until time point <code>to</code> such that the maximum distance between the track's fixes and
|
||||
* the approximation is at most <code>maxDistance</code>.
|
||||
*/
|
||||
List<GPSFixMoving> approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to);
|
||||
|
||||
/**
|
||||
* @return a non-<code>null</code> but perhaps empty list of the maneuvers that <code>competitor</code> performed in
|
||||
* this race between <code>from</code> and <code>to</code>.
|
||||
* this race between <code>from</code> and <code>to</code>. Depending on <code>waitForLatest</code> the
|
||||
* result is taken from the cache straight away (<code>waitForLatest==false</code>) or, if a re-calculation
|
||||
* for the <code>key</code> is still ongoing, the result of that ongoing re-calculation is returned.
|
||||
*/
|
||||
List<Maneuver> getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) throws NoWindException;
|
||||
List<Maneuver> getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest)
|
||||
throws NoWindException;
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this race is known to start with an {@link LegType#UPWIND upwind} leg.
|
||||
* If this is the case, the wind estimation may default to using the first leg's direction at race start
|
||||
* time as the direction the wind comes from.
|
||||
* @return <code>true</code> if this race is known to start with an {@link LegType#UPWIND upwind} leg. If this is
|
||||
* the case, the wind estimation may default to using the first leg's direction at race start time as the
|
||||
* direction the wind comes from.
|
||||
*/
|
||||
boolean raceIsKnownToStartUpwind();
|
||||
|
||||
/**
|
||||
* Many calculations require valid wind data. In order to prevent NoWindException's to be handled by those calculation
|
||||
* this method can be used to check whether the tracked race has sufficient wind information available.
|
||||
* Many calculations require valid wind data. In order to prevent NoWindException's to be handled by those
|
||||
* calculation this method can be used to check whether the tracked race has sufficient wind information available.
|
||||
*
|
||||
* @return <code>true</code> if {@link #getWind(Position, TimePoint)} delivers a (not null) wind fix.
|
||||
*/
|
||||
boolean hasWindData();
|
||||
@@ -381,23 +382,23 @@ public interface TrackedRace extends Serializable {
|
||||
boolean hasGPSData();
|
||||
|
||||
/**
|
||||
* Adds a race change listener to the set of listeners that will be notified about changes to this race.
|
||||
* The listener won't be serialized together with this object.
|
||||
* Adds a race change listener to the set of listeners that will be notified about changes to this race. The
|
||||
* listener won't be serialized together with this object.
|
||||
*/
|
||||
void addListener(RaceChangeListener listener);
|
||||
|
||||
|
||||
void removeListener(RaceChangeListener listener);
|
||||
|
||||
Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint) throws NoWindException;
|
||||
|
||||
|
||||
/**
|
||||
* Calls {@link #getWindWithConfidence(Position, TimePoint, Iterable)} and excludes those wind sources listed in
|
||||
* {@link #getWindSourcesToExclude}.
|
||||
*/
|
||||
WindWithConfidence<Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at);
|
||||
|
||||
|
||||
/**
|
||||
* Lists those wind sources which by default are not considered in {@link #getWind(Position, TimePoint)} and
|
||||
* {@link #getWindWithConfidence(Position, TimePoint)}.
|
||||
@@ -407,8 +408,8 @@ public interface TrackedRace extends Serializable {
|
||||
/**
|
||||
* Loops over this tracked race's wind sources and from each asks its averaged wind for the position <code>p</code>
|
||||
* and time point <code>at</code>, using the particular wind source's averaging interval. The confidences delivered
|
||||
* by each wind source are used during computing the averaged result across the wind sources. The result has the averaged
|
||||
* confidence attached.
|
||||
* by each wind source are used during computing the averaged result across the wind sources. The result has the
|
||||
* averaged confidence attached.
|
||||
*/
|
||||
WindWithConfidence<Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
|
||||
Iterable<WindSource> windSourcesToExclude);
|
||||
@@ -420,7 +421,8 @@ public interface TrackedRace extends Serializable {
|
||||
WindWithConfidence<TimePoint> getEstimatedWindDirectionWithConfidence(Position position, TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* After the call returns, {@link #getWindSourcesToExclude()} returns an iterable that equals <code>windSourcesToExclude</code>
|
||||
* After the call returns, {@link #getWindSourcesToExclude()} returns an iterable that equals
|
||||
* <code>windSourcesToExclude</code>
|
||||
*/
|
||||
void setWindSourcesToExclude(Iterable<? extends WindSource> windSourcesToExclude);
|
||||
|
||||
@@ -431,25 +433,27 @@ public interface TrackedRace extends Serializable {
|
||||
* if <code>true</code> and any cache update is currently going on, wait for the update to complete and
|
||||
* then fetch the updated value; otherwise, serve this requests from whatever is currently in the cache
|
||||
*/
|
||||
Distance getAverageCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException;
|
||||
Distance getAverageCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis)
|
||||
throws NoWindException;
|
||||
|
||||
WindStore getWindStore();
|
||||
|
||||
Competitor getOverallLeader(TimePoint timePoint) throws NoWindException;
|
||||
|
||||
/**
|
||||
* Returns the competitors of this tracked race, according to their ranking. Competitors whose {@link #getRank(Competitor)} is 0 will
|
||||
* be sorted "worst".
|
||||
* Returns the competitors of this tracked race, according to their ranking. Competitors whose
|
||||
* {@link #getRank(Competitor)} is 0 will be sorted "worst".
|
||||
*/
|
||||
List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) throws NoWindException;
|
||||
|
||||
Distance getAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses) throws NoWindException;
|
||||
Distance getAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly,
|
||||
boolean waitForLatestAnalyses) throws NoWindException;
|
||||
|
||||
/**
|
||||
* When provided with a {@link WindStore} during construction, the tracked race will asynchronously load the wind
|
||||
* data for this tracked race from the wind store in a background thread and update this tracked race with the results.
|
||||
* Clients that want to wait for the wind loading process to complete can do so by calling this method which will block
|
||||
* until the wind loading has completed.
|
||||
* data for this tracked race from the wind store in a background thread and update this tracked race with the
|
||||
* results. Clients that want to wait for the wind loading process to complete can do so by calling this method
|
||||
* which will block until the wind loading has completed.
|
||||
*/
|
||||
void waitUntilWindLoadingComplete() throws InterruptedException;
|
||||
|
||||
|
||||
+9
-6
@@ -68,7 +68,6 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
windSourcesToExclude.add(new WindSourceImpl(WindSourceType.COURSE_BASED));
|
||||
setWindSourcesToExclude(windSourcesToExclude);
|
||||
}
|
||||
|
||||
for (Competitor competitor : getRace().getCompetitors()) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = getTrack(competitor);
|
||||
track.addListener(this);
|
||||
@@ -90,7 +89,11 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
* {@link #raceIsKnownToStartUpwind} (see also {@link #raceIsKnownToStartUpwind()}) is initialized based on the <code>race</code>'s
|
||||
* {@link RaceDefinition#getBoatClass()} boat class's {@link BoatClass#typicallyStartsUpwind()} result. It can be changed
|
||||
* using {@link #setRaceIsKnownToStartUpwind(boolean)}. Uses <code>millisecondsOverWhichToAverageWind/2</code> for the
|
||||
* <code>delayForCacheInvalidationOfWindEstimation</code> argument of the constructor.
|
||||
* <code>delayForCacheInvalidationOfWindEstimation</code> argument of the constructor.<p>
|
||||
*
|
||||
* Loading wind tracks from the <code>windStore</code> happens asynchronously which means that when the constructor returns,
|
||||
* the caller cannot assume that all wind tracks have yet been loaded completely. The caller may call {@link #waitUntilWindLoadingComplete()}
|
||||
* to wait until all persistent wind sources have been successfully and completely loaded.
|
||||
*/
|
||||
public DynamicTrackedRaceImpl(TrackedRegatta trackedRegatta, RaceDefinition race,
|
||||
WindStore windStore, long delayToLiveInMillis,
|
||||
@@ -542,8 +545,8 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
|
||||
/**
|
||||
* In addition to calling the super class implementation, notifies all race listeners registered with this tracked
|
||||
* race which in particular replicates all wind fixes that may have been loaded from the wind store for the new
|
||||
* track.
|
||||
* race using their {@link RaceChangeListener#windDataReceived(Wind, WindSource)} method. In particular this
|
||||
* replicates all wind fixes that may have been loaded from the wind store for the new track.
|
||||
*/
|
||||
@Override
|
||||
protected WindTrack createWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation) {
|
||||
@@ -553,8 +556,8 @@ public class DynamicTrackedRaceImpl extends TrackedRaceImpl implements
|
||||
result.lockForRead();
|
||||
try {
|
||||
for (Wind wind : result.getRawFixes()) {
|
||||
notifyListeners(wind, windSource);
|
||||
}
|
||||
notifyListeners(wind, windSource); // Note that this doesn't notify the track's listeners but the tracked race's listeners.
|
||||
} // In particular, the wind store won't receive events (again) for the wind fixes it already has.
|
||||
} finally {
|
||||
result.unlockAfterRead();
|
||||
}
|
||||
|
||||
+10
-10
@@ -305,7 +305,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
MarkPassingByTimeComparator.INSTANCE));
|
||||
}
|
||||
markPassingsTimes = new ArrayList<Pair<Waypoint, Pair<TimePoint, TimePoint>>>();
|
||||
windTracks = new HashMap<WindSource, WindTrack>();
|
||||
windTracks = new ConcurrentHashMap<WindSource, WindTrack>();
|
||||
new Thread("Wind loader for tracked race "+getRace().getName()) {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -316,20 +316,20 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
try {
|
||||
final Map<? extends WindSource, ? extends WindTrack> loadedWindTracks = windStore.loadWindTracks(
|
||||
trackedRegatta, TrackedRaceImpl.this, millisecondsOverWhichToAverageWind);
|
||||
windTracks.putAll(loadedWindTracks);
|
||||
synchronized (windTracks) {
|
||||
windTracks.putAll(loadedWindTracks);
|
||||
}
|
||||
} finally {
|
||||
LockUtil.unlockAfterRead(serializationLock);
|
||||
}
|
||||
synchronized (TrackedRaceImpl.this) {
|
||||
windLoadingCompleted = true;
|
||||
TrackedRaceImpl.this.notifyAll();
|
||||
synchronized (TrackedRaceImpl.this) {
|
||||
windLoadingCompleted = true;
|
||||
TrackedRaceImpl.this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
// by default, a tracked race offers one course-based wind estimation, one track-based wind estimation track and
|
||||
// one "WEB" track for manual or REST-based wind reception; other wind tracks may be added as fixes are received
|
||||
// for them.
|
||||
// by default, a tracked race offers one course-based wind estimation and one track-based wind estimation track;
|
||||
// other wind tracks may be added as fixes are received for them and as they are loaded from the persistent store
|
||||
WindSource courseBasedWindSource = new WindSourceImpl(WindSourceType.COURSE_BASED);
|
||||
windTracks.put(courseBasedWindSource, getOrCreateWindTrack(courseBasedWindSource, delayForWindEstimationCacheInvalidation));
|
||||
WindSource trackBasedWindSource = new WindSourceImpl(WindSourceType.TRACK_BASED_ESTIMATION);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
<plugin id="com.sap.sailing.monitoring" autoStart="true" startLevel="5" />
|
||||
<plugin id="com.sap.sailing.server" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server.gateway" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server.gateway.ess40" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.server.replication" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.www" autoStart="true" startLevel="4" />
|
||||
<plugin id="com.sap.sailing.www.events" autoStart="true" startLevel="4" />
|
||||
|
||||
@@ -71,6 +71,13 @@ Computes leaderboard information for sailing races and offers RESTful APIs to al
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.sap.sailing.server.gateway.ess40"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="com.tractrac.clientmodule"
|
||||
download-size="0"
|
||||
|
||||
@@ -7,7 +7,8 @@ Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Fragment-Host: com.sap.sailing.gwt.ui
|
||||
Require-Bundle: com.sap.sailing.server,
|
||||
org.hamcrest.core;bundle-version="1.1.0"
|
||||
org.hamcrest.core;bundle-version="1.1.0",
|
||||
com.sap.sailing.expeditionconnector
|
||||
Bundle-ClassPath: .
|
||||
Import-Package: javax.jms;version="1.1.0",
|
||||
javax.servlet;version="2.5.0",
|
||||
|
||||
+734
@@ -0,0 +1,734 @@
|
||||
package com.sap.sailing.gwt.ui.test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceColumnListener;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.RegattaListener;
|
||||
import com.sap.sailing.domain.base.Leg;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaIdentifier;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.RaceListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.WindStore;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.WindWithConfidence;
|
||||
import com.sap.sailing.domain.tracking.impl.WindTrackImpl;
|
||||
|
||||
public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
private static final long serialVersionUID = 5827912985564121181L;
|
||||
private final WindTrack windTrack = new WindTrackImpl(/* millisecondsOverWhichToAverage */ 30000, /* useSpeed */ true, "TestWindTrack");
|
||||
|
||||
public WindTrack getWindTrack() {
|
||||
return windTrack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceDefinition getRace() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getStartOfRace() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<TrackedLeg> getTrackedLegs() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLeg getTrackedLeg(Leg leg) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLeg getCurrentLeg(TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLeg getTrackedLegFinishingAt(Waypoint endOfLeg) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLeg getTrackedLegStartingAt(Waypoint startOfLeg) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, TimePoint at) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, Leg leg) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getUpdateCount() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRank(Competitor competitor) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRank(Competitor competitor, TimePoint timePoint) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getStartAdvantage(Competitor competitor, double secondsIntoTheRace) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<MarkPassing> getMarkPassingsInOrder(Waypoint waypoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicGPSFixTrack<Mark, GPSFix> getOrCreateTrack(Mark mark) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindTrack getOrCreateWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForNextUpdate(int sinceUpdate) throws InterruptedException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getStartOfTracking() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePointOfNewestEvent() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFix(Competitor competitor, GPSFixMoving fix) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordWind(Wind wind, WindSource windSource) {
|
||||
if (windSource.getType() == WindSourceType.EXPEDITION) {
|
||||
windTrack.add(wind);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(RaceChangeListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMarkPassings(Competitor competitor, Iterable<MarkPassing> markPassings) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartTimeReceived(TimePoint start) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicGPSFixTrack<Competitor, GPSFixMoving> getTrack(Competitor competitor) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWind(Wind wind, WindSource windSource) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePointOfLastEvent() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMillisecondsOverWhichToAverageSpeed(long millisecondsOverWhichToAverageSpeed) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMillisecondsOverWhichToAverageWind(long millisecondsOverWhichToAverageWind) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMillisecondsOverWhichToAverageSpeed() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMillisecondsOverWhichToAverageWind() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getEstimatedWindDirection(Position position, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStarted(TimePoint at) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicTrackedRegatta getTrackedRegatta() {
|
||||
return new DynamicTrackedRegatta() {
|
||||
private static final long serialVersionUID = 2651590861333064588L;
|
||||
|
||||
@Override
|
||||
public Regatta getRegatta() {
|
||||
return new Regatta() {
|
||||
private static final long serialVersionUID = -4908774269425170811L;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "A Mocked Test Regatta";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getId() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<RaceDefinition> getAllRaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoatClass getBoatClass() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Competitor> getCompetitors() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRace(RaceDefinition race) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRace(RaceDefinition raceDefinition) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceDefinition getRaceByName(String raceName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRegattaListener(RegattaListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRegattaListener(RegattaListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaIdentifier getRegattaIdentifier() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<? extends Series> getSeries() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Series getSeriesByName(String seriesName) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPersistent() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRaceColumnListener(RaceColumnListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRaceColumnListener(RaceColumnListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScoringScheme getScoringScheme() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<TrackedRace> getTrackedRaces() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<TrackedRace> getTrackedRaces(BoatClass boatClass) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTrackedRace(TrackedRace trackedRace) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTrackedRace(TrackedRace trackedRace) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRaceListener(RaceListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicTrackedRace getTrackedRace(RaceDefinition race) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicTrackedRace getExistingTrackedRace(RaceDefinition race) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTrackedRace(RaceDefinition raceDefinition) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, WindStore windStore,
|
||||
long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
|
||||
DynamicRaceDefinitionSet raceDefinitionSetToUpdate) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tack getTack(Competitor competitor, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getDirectionFromStartToNextMark(TimePoint at) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GPSFixMoving> approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Maneuver> getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean raceIsKnownToStartUpwind() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRaceIsKnownToStartUpwind(boolean raceIsKnownToStartUpwind) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaAndRaceIdentifier getRaceIdentifier() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getEndOfRace() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint)
|
||||
throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getWind(Position p, TimePoint at) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getWind(Position p, TimePoint at, Iterable<WindSource> windSourcesToExclude) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<WindSource> getWindSources(WindSourceType type) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<WindSource> getWindSources() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindWithConfidence<Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at,
|
||||
Iterable<WindSource> windSourcesToExclude) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindWithConfidence<TimePoint> getEstimatedWindDirectionWithConfidence(Position position, TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindWithConfidence<Pair<Position, TimePoint>> getWindWithConfidence(Position p, TimePoint at) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<WindSource> getWindSourcesToExclude() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getEndOfTracking() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getTimePointOfOldestEvent() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStartOfTrackingReceived(TimePoint startOfTrackingReceived) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEndOfTrackingReceived(TimePoint endOfTrackingReceived) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Pair<Waypoint, Pair<TimePoint, TimePoint>>> getMarkPassingsTimes() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindTrack getOrCreateWindTrack(WindSource windSource) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordFix(Mark mark, GPSFix fix) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(RaceChangeListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public WindStore getWindStore() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWindSourcesToExclude(Iterable<? extends WindSource> windSourcesToExclude) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getOverallLeader(TimePoint timePoint) throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDelayToLiveInMillis() {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDelayToLiveInMillis(long delayToLiveInMillis) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAndFixDelayToLiveInMillis(long delayToLiveInMillis) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Competitor> getCompetitorsFromBestToWorst(TimePoint timePoint) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses)
|
||||
throws NoWindException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitUntilWindLoadingComplete() throws InterruptedException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Mark> getMarks() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasWindData() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGPSData() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockForRead(Iterable<MarkPassing> markPassings) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockAfterRead(Iterable<MarkPassing> markPassings) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedRaceStatus getStatus() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStatus(TrackedRaceStatus newStatus) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitUntilNotLoading() {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceLog getRaceLog() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
package com.sap.sailing.gwt.ui.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.UUID;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.ScoreCorrectionProvider;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
import com.sap.sailing.gwt.ui.client.SailingService;
|
||||
import com.sap.sailing.gwt.ui.server.SailingServiceImpl;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import com.sap.sailing.server.replication.ReplicationService;
|
||||
|
||||
public class PolarSheetGenerationServiceTest {
|
||||
|
||||
private static final String BOAT_CLASS = "Forelle";
|
||||
|
||||
@Test
|
||||
public void testPolarSheetGenerationService() throws InterruptedException {
|
||||
|
||||
SailingService service = new MockSailingServiceForPolarSheetGeneration();
|
||||
|
||||
List<RegattaAndRaceIdentifier> idList = new ArrayList<RegattaAndRaceIdentifier>();
|
||||
idList.add(new RegattaNameAndRaceName("IrgendeineRegatta", "IrgendeinRennen"));
|
||||
|
||||
PolarSheetGenerationTriggerResponse triggerData = service.generatePolarSheetForRaces(idList);
|
||||
Assert.assertNotNull(triggerData);
|
||||
Assert.assertEquals(BOAT_CLASS, triggerData.getBoatClassName());
|
||||
Assert.assertNotNull(triggerData.getId());
|
||||
|
||||
boolean complete = false;
|
||||
PolarSheetsData results = null;
|
||||
double timeOut = 10;
|
||||
while (!complete && timeOut > 0) {
|
||||
Thread.sleep(200);
|
||||
timeOut = timeOut - 0.2;
|
||||
results = service.getPolarSheetsGenerationResults(triggerData.getId());
|
||||
complete = results.isComplete();
|
||||
}
|
||||
|
||||
Assert.assertTrue(complete);
|
||||
Assert.assertNotNull(results);
|
||||
|
||||
Assert.assertEquals(4, results.getDataCount());
|
||||
Assert.assertEquals(4.0, results.getAveragedPolarDataByWindSpeed()[1][45]);
|
||||
Assert.assertEquals(2.0, results.getAveragedPolarDataByWindSpeed()[1][55]);
|
||||
Assert.assertEquals(6.0, results.getAveragedPolarDataByWindSpeed()[1][30]);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockSailingServiceForPolarSheetGeneration extends SailingServiceImpl {
|
||||
|
||||
@Override
|
||||
protected RacingEventService getService() {
|
||||
RacingEventService service = new MockRacingEventServiceForPolarSheetGeneration();
|
||||
return service;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceTracker<RacingEventService, RacingEventService> createAndOpenRacingEventServiceTracker(
|
||||
BundleContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceTracker<ReplicationService, ReplicationService> createAndOpenReplicationServiceTracker(
|
||||
BundleContext context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServiceTracker<ScoreCorrectionProvider, ScoreCorrectionProvider> createAndOpenScoreCorrectionProviderServiceTracker(
|
||||
BundleContext bundleContext) {;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class MockRacingEventServiceForPolarSheetGeneration extends RacingEventServiceImpl {
|
||||
|
||||
@Override
|
||||
public TrackedRace getTrackedRace(RegattaAndRaceIdentifier raceIdentifier) {
|
||||
MockTrackedRaceForPolarSheetGeneration trackedRace = new MockTrackedRaceForPolarSheetGeneration();
|
||||
return trackedRace;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockTrackedRaceForPolarSheetGeneration extends MockedTrackedRace {
|
||||
|
||||
|
||||
@Override
|
||||
public DynamicGPSFixTrack<Competitor, GPSFixMoving> getTrack(Competitor competitor) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = new MockDynamicGPSFixMovinTrackForPolarSheetGeneration<Competitor>(competitor, 0);
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.0, 1.0), new MillisecondsTimePoint(1), new KnotSpeedWithBearingImpl(3.0, new DegreeBearingImpl(-45.0))));
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.001, 1.001), new MillisecondsTimePoint(2), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0))));
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.002, 1.002), new MillisecondsTimePoint(3), new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(-55.0))));
|
||||
track.addGPSFix(new MockGPSFixMovingForPolarSheetGeneration(new DegreePosition(1.003, 1.003), new MillisecondsTimePoint(4), new KnotSpeedWithBearingImpl(6.0, new DegreeBearingImpl(-30.0))));
|
||||
|
||||
//Should not be taken into consideration because it happens after the race has ended
|
||||
track.addGPSFix(new GPSFixMovingImpl(new DegreePosition(2.0, 3.0), new MillisecondsTimePoint(7), new KnotSpeedWithBearingImpl(5.0, new DegreeBearingImpl(-45.0))));
|
||||
return track;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getWind(Position p, TimePoint at) {
|
||||
Wind wind = new WindImpl(p, at, new KnotSpeedWithBearingImpl(2.0, new DegreeBearingImpl(180.0)));
|
||||
return wind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceDefinition getRace() {
|
||||
BoatClass forelle = new BoatClassImpl(BOAT_CLASS, true);
|
||||
Competitor competitor = new CompetitorImpl(UUID.randomUUID(), "Hans Frantz", new TeamImpl("SAP", null, null), new BoatImpl("Schnelle Forelle", forelle, "GER000"));
|
||||
ArrayList<Competitor> competitors = new ArrayList<Competitor>();
|
||||
competitors.add(competitor);
|
||||
RaceDefinition race = new RaceDefinitionImpl("Forelle1", new CourseImpl("ForelleCourse", new ArrayList<Waypoint>()), forelle, competitors);
|
||||
return race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getStartOfRace() {
|
||||
return new MillisecondsTimePoint(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getEndOfRace() {
|
||||
return new MillisecondsTimePoint(5);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockGPSFixMovingForPolarSheetGeneration extends GPSFixMovingImpl {
|
||||
|
||||
public MockGPSFixMovingForPolarSheetGeneration(Position position, TimePoint timePoint, SpeedWithBearing speed) {
|
||||
super(position, timePoint, speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class MockDynamicGPSFixMovinTrackForPolarSheetGeneration<ItemType> extends DynamicGPSFixMovingTrackImpl<ItemType> {
|
||||
|
||||
public MockDynamicGPSFixMovinTrackForPolarSheetGeneration(ItemType trackedItem,
|
||||
long millisecondsOverWhichToAverage) {
|
||||
super(trackedItem, millisecondsOverWhichToAverage);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValid(NavigableSet<GPSFixMoving> rawFixes, GPSFixMoving e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
eclipse.preferences.version=1
|
||||
entryPointModules=
|
||||
filesCopiedToWebInfLib=gwt-servlet.jar
|
||||
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBW11dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14NTEybV1dPjwvdm0tYXJncz48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuQWRtaW5Db25zb2xlPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLkxlYWRlcmJvYXJkPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLkxlYWRlcmJvYXJkRWRpdGluZzwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5SYWNlQm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuU3BlY3RhdG9yPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlVzZXJNYW5hZ2VtZW50PC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlR2VmlldzwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5WaWRlb1BvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLllvdXR1YmVQb3B1cDwvZW50cnktcG9pbnQtbW9kdWxlPjwvZ3d0LWNvbXBpbGUtc2V0dGluZ3M+
|
||||
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBWy13YXIgLiAtbG9jYWxXb3JrZXJzIDMgLXN0cmljdCAtbG9nTGV2ZWwgVFJBQ0VdXT48L2V4dHJhLWFyZ3M+PHZtLWFyZ3M+PCFbQ0RBVEFbLVhteDEwMjRtXV0+PC92bS1hcmdzPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5BZG1pbkNvbnNvbGU8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuTGVhZGVyYm9hcmRFZGl0aW5nPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlJhY2VCb2FyZDwvZW50cnktcG9pbnQtbW9kdWxlPjxlbnRyeS1wb2ludC1tb2R1bGU+Y29tLnNhcC5zYWlsaW5nLmd3dC51aS5TcGVjdGF0b3I8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVXNlck1hbmFnZW1lbnQ8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuVHZWaWV3PC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlZpZGVvUG9wdXA8L2VudHJ5LXBvaW50LW1vZHVsZT48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5zYXAuc2FpbGluZy5nd3QudWkuWW91dHViZVBvcHVwPC9lbnRyeS1wb2ludC1tb2R1bGU+PGVudHJ5LXBvaW50LW1vZHVsZT5jb20uc2FwLnNhaWxpbmcuZ3d0LnVpLlBvbGFyU2hlZXRzPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\=
|
||||
@@ -32,10 +32,6 @@ h1 {
|
||||
}
|
||||
|
||||
/** Most GWT widgets already have a style name defined */
|
||||
.gwt-DialogBox {
|
||||
width: 400px;
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.dialogVPanel {
|
||||
margin: 5px;
|
||||
@@ -96,6 +92,10 @@ h1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gwt-DialogBox {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .Caption {
|
||||
background: none repeat scroll 0 0 #e5e5e5;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
@import url(fontface.css);
|
||||
@import url(CommonControls.css);
|
||||
|
||||
/** Add css rules here for your application. */
|
||||
/*
|
||||
body #calendar:after
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
*/
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
font-size: 1px;
|
||||
height: 0px;
|
||||
line-height: 0px;
|
||||
margin: -1px 0 0;
|
||||
width: 100%; }
|
||||
|
||||
.cover {
|
||||
left: -1000px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: -1000px; }
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
font-family: 'UbuntuRegular', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 85px 0 120px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/** Example rules used by the template application (remove for your app) */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #777777;
|
||||
margin: 40px 0px 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: separate; }
|
||||
|
||||
.leaderboardMargin {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.leaderboardContent {
|
||||
}
|
||||
|
||||
.leaderboardContent td, .leaderboardContent th {
|
||||
vertical-align: bottom;
|
||||
line-height: 1.3;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.leaderboardContent-toolbar {
|
||||
|
||||
}
|
||||
|
||||
.leaderboardLabel {
|
||||
border-bottom: 2px solid #007dc0;
|
||||
font-weight: bold;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.refreshAndSettings {
|
||||
background: #f2f2f2;
|
||||
border-bottom: 2px solid #fff;
|
||||
border-top: 2px solid #fff;
|
||||
height: 30px; }
|
||||
|
||||
.refreshAndSettings table td {
|
||||
padding: 0 10px 0 0;}
|
||||
|
||||
.refreshAndSettings table table td{
|
||||
padding: 0 0 0 0;}
|
||||
|
||||
input.magnifier{
|
||||
display: block;
|
||||
margin: 3px auto 0 auto !important;
|
||||
}
|
||||
|
||||
body, table td, select, button {
|
||||
font-family: 'UbuntuLight', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.busyIndicator-simpleBusyIndicator {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.errorLabel {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.abstractChartPanel-importantMessageOfChart {
|
||||
font-family: 'UbuntuBold',Arial,Verdana,sans-serif;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
padding: 49px 0 0 80px;
|
||||
width: 300px;
|
||||
color: #7c7c7c;
|
||||
background: url(images/important-message.png) left center no-repeat;
|
||||
}
|
||||
|
||||
.LeaderboardHeader {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
text-align: center;
|
||||
font-family: 'UbuntuRegular', Arial, Verdana, sans-serif;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
margin-top: 22px;
|
||||
}
|
||||
|
||||
.leaderboardHeading {
|
||||
font-size: 16px;
|
||||
font-family: 'UbuntuRegular', Arial, Verdana, sans-serif;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gwt-DialogBox {
|
||||
z-index: 20;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title>SAP Sailing Analytics Polar Sheets</title>
|
||||
<meta content='width = device-width, initial-scale = 1.0, user-scalable = yes' name='viewport'>
|
||||
<meta content='yes' name='apple-mobile-web-app-capable'>
|
||||
<meta content='black' name='apple-mobile-web-app-status-bar-style'>
|
||||
<!-- <link href='iphone-splash-screen.png' rel='apple-touch-startup-image'> -->
|
||||
<link href='images/sap-sailing-app-icon.png' rel='apple-touch-icon'>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="images/sap.ico" />
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="highcharts/js/highcharts.js"></script>
|
||||
<script type="text/javascript" src="highcharts/js/highcharts-more.js"></script>
|
||||
|
||||
<!-- Optionally, add a highcharts theme file -->
|
||||
<script type="text/javascript" src="highcharts/js/themes/grid.js"></script>
|
||||
|
||||
<script type="text/javascript" language="javascript" src="com.sap.sailing.gwt.ui.PolarSheets/com.sap.sailing.gwt.ui.PolarSheets.nocache.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
|
||||
<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
|
||||
<noscript>
|
||||
<div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
|
||||
Your web browser must have JavaScript enabled
|
||||
in order for this application to display correctly.
|
||||
</div>
|
||||
</noscript>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 18 KiB |
+8
-3
@@ -18,9 +18,12 @@ public class GetCompetitorsRaceDataAction extends DefaultAsyncAction<Competitors
|
||||
private final Date toDate;
|
||||
private final long stepSizeInMs;
|
||||
private final DetailType detailType;
|
||||
private final String leaderboarGroupName;
|
||||
private final String leaderboardName;
|
||||
|
||||
public GetCompetitorsRaceDataAction(SailingServiceAsync sailingService, RegattaAndRaceIdentifier raceIdentifier, List<CompetitorDTO> competitors,
|
||||
Date fromDate, Date toDate, long stepSizeInMs, DetailType detailType, AsyncCallback<CompetitorsRaceDataDTO> callback) {
|
||||
public GetCompetitorsRaceDataAction(SailingServiceAsync sailingService, RegattaAndRaceIdentifier raceIdentifier,
|
||||
List<CompetitorDTO> competitors, Date fromDate, Date toDate, long stepSizeInMs, DetailType detailType,
|
||||
String leaderboardGroupName, String leaderboardName, AsyncCallback<CompetitorsRaceDataDTO> callback) {
|
||||
super(callback);
|
||||
this.sailingService = sailingService;
|
||||
this.raceIdentifier = raceIdentifier;
|
||||
@@ -29,11 +32,13 @@ public class GetCompetitorsRaceDataAction extends DefaultAsyncAction<Competitors
|
||||
this.toDate = toDate;
|
||||
this.stepSizeInMs = stepSizeInMs;
|
||||
this.detailType = detailType;
|
||||
this.leaderboarGroupName = leaderboardGroupName;
|
||||
this.leaderboardName = leaderboardName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(AsyncActionsExecutor asyncActionsExecutor) {
|
||||
sailingService.getCompetitorsRaceData(raceIdentifier, competitors, fromDate, toDate, stepSizeInMs, detailType,
|
||||
sailingService.getCompetitorsRaceData(raceIdentifier, competitors, fromDate, toDate, stepSizeInMs, detailType, leaderboarGroupName, leaderboardName,
|
||||
(AsyncCallback<CompetitorsRaceDataDTO>) getWrapperCallback(asyncActionsExecutor));
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.sap.sailing.gwt.ui.actions;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.PolarSheetsHistogramData;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
|
||||
public class GetPolarSheetDataByAngleAction extends DefaultAsyncAction<PolarSheetsHistogramData> {
|
||||
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final String polarSheetId;
|
||||
private final int angle;
|
||||
private final int windSpeed;
|
||||
|
||||
|
||||
|
||||
public GetPolarSheetDataByAngleAction(SailingServiceAsync sailingService,
|
||||
String polarSheetId, int angle, int windSpeed, AsyncCallback<PolarSheetsHistogramData> callback) {
|
||||
super(callback);
|
||||
this.sailingService = sailingService;
|
||||
this.polarSheetId = polarSheetId;
|
||||
this.angle = angle;
|
||||
this.windSpeed = windSpeed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(AsyncActionsExecutor asyncActionsExecutor) {
|
||||
sailingService.getPolarSheetData(polarSheetId, angle, windSpeed, (AsyncCallback<PolarSheetsHistogramData>) getWrapperCallback(asyncActionsExecutor));
|
||||
}
|
||||
|
||||
}
|
||||
+2
@@ -19,6 +19,7 @@ import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
public abstract class AbstractLeaderboardDialog extends DataEntryDialog<LeaderboardDescriptor> {
|
||||
protected final StringMessages stringMessages;
|
||||
protected TextBox nameTextBox;
|
||||
protected TextBox displayNameTextBox;
|
||||
protected LeaderboardDescriptor leaderboard;
|
||||
protected ListBox sailingEventsListBox;
|
||||
protected Collection<EventDTO> existingEvents;
|
||||
@@ -41,6 +42,7 @@ public abstract class AbstractLeaderboardDialog extends DataEntryDialog<Leaderbo
|
||||
protected LeaderboardDescriptor getResult() {
|
||||
int[] discardThresholdsBoxContents = getDiscardThresholds(discardThresholdBoxes);
|
||||
leaderboard.setName(nameTextBox.getValue());
|
||||
leaderboard.setDisplayName(displayNameTextBox.getValue());
|
||||
leaderboard.setDiscardThresholds(discardThresholdsBoxContents);
|
||||
CourseAreaDTO courseArea = getSelectedCourseArea();
|
||||
if (courseArea == null) {
|
||||
|
||||
+1
@@ -13,6 +13,7 @@ public class FlexibleLeaderboardCreateDialog extends FlexibleLeaderboardDialog {
|
||||
Collection<EventDTO> existingEvents, ErrorReporter errorReporter, DialogCallback<LeaderboardDescriptor> callback) {
|
||||
super(stringMessages.createFlexibleLeaderboard(), new LeaderboardDescriptor(), stringMessages, existingEvents, errorReporter, new FlexibleLeaderboardDialog.LeaderboardParameterValidator(stringMessages, existingLeaderboards), callback);
|
||||
nameTextBox = createTextBox(null);
|
||||
displayNameTextBox = createTextBox(null);
|
||||
scoringSchemeListBox = createScoringSchemeListBox(this, stringMessages);
|
||||
sailingEventsListBox = createSailingEventListBox(this, stringMessages);
|
||||
discardThresholdBoxes = initEmptyDiscardThresholdBoxes(this);
|
||||
|
||||
+15
-10
@@ -2,11 +2,12 @@ package com.sap.sailing.gwt.ui.adminconsole;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
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.user.client.ui.Widget;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -78,17 +79,19 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
|
||||
|
||||
@Override
|
||||
protected Widget getAdditionalWidget() {
|
||||
VerticalPanel mainPanel = new VerticalPanel();
|
||||
Grid formGrid = new Grid(5,2);
|
||||
FlowPanel mainPanel = new FlowPanel();
|
||||
Grid formGrid = new Grid(5,3);
|
||||
formGrid.setCellSpacing(3);
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.name() + ":"));
|
||||
formGrid.setWidget(0, 0, createLabel(stringMessages.name()));
|
||||
formGrid.setWidget(0, 1, nameTextBox);
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.scoringSystem() + ":"));
|
||||
formGrid.setWidget(1, 1, scoringSchemeListBox);
|
||||
formGrid.setWidget(2, 0, new Label(stringMessages.event() + ":"));
|
||||
formGrid.setWidget(2, 1, sailingEventsListBox);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.courseArea() + ":"));
|
||||
formGrid.setWidget(3, 1, courseAreaListBox);
|
||||
formGrid.setWidget(1, 0, createLabel(stringMessages.displayName()));
|
||||
formGrid.setWidget(1, 1, displayNameTextBox);
|
||||
formGrid.setWidget(2, 0, createLabel(stringMessages.scoringSystem()));
|
||||
formGrid.setWidget(2, 1, scoringSchemeListBox);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.event() + ":"));
|
||||
formGrid.setWidget(3, 1, sailingEventsListBox);
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.courseArea() + ":"));
|
||||
formGrid.setWidget(4, 1, courseAreaListBox);
|
||||
mainPanel.add(formGrid);
|
||||
mainPanel.add(new Label(stringMessages.discardRacesFromHowManyStartedRacesOn()));
|
||||
HorizontalPanel hp = new HorizontalPanel();
|
||||
@@ -97,7 +100,9 @@ public abstract class FlexibleLeaderboardDialog extends AbstractLeaderboardDialo
|
||||
hp.add(new Label("" + (i + 1) + "."));
|
||||
hp.add(discardThresholdBoxes[i]);
|
||||
}
|
||||
alignAllPanelWidgetsVertically(hp, HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
mainPanel.add(hp);
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ public class FlexibleLeaderboardEditDialog extends FlexibleLeaderboardDialog {
|
||||
stringConstants, otherExistingLeaderboards), callback);
|
||||
|
||||
nameTextBox = createTextBox(leaderboard.getName());
|
||||
|
||||
displayNameTextBox = createTextBox(leaderboard.getDisplayName());
|
||||
scoringSchemeListBox = createListBox(false);
|
||||
int j = 0;
|
||||
for (ScoringSchemeType scoringSchemeType: ScoringSchemeType.values()) {
|
||||
|
||||
+11
-1
@@ -199,6 +199,14 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
|
||||
return sortList.size() > 0 & sortList.get(0).isAscending();
|
||||
}
|
||||
});
|
||||
|
||||
TextColumn<StrippedLeaderboardDTO> leaderboardDisplayNameColumn = new TextColumn<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public String getValue(StrippedLeaderboardDTO leaderboard) {
|
||||
return leaderboard.getDisplayName() !=null ? leaderboard.getDisplayName() : "";
|
||||
}
|
||||
};
|
||||
|
||||
TextColumn<StrippedLeaderboardDTO> discardingOptionsColumn = new TextColumn<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public String getValue(StrippedLeaderboardDTO leaderboard) {
|
||||
@@ -266,6 +274,7 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
|
||||
}
|
||||
});
|
||||
leaderboardTable.addColumn(linkColumn, stringMessages.name());
|
||||
leaderboardTable.addColumn(leaderboardDisplayNameColumn, stringMessages.displayName());
|
||||
leaderboardTable.addColumn(discardingOptionsColumn, stringMessages.discarding());
|
||||
leaderboardTable.addColumn(leaderboardTypeColumn, stringMessages.type());
|
||||
leaderboardTable.addColumn(scoringSystemColumn, stringMessages.scoringSystem());
|
||||
@@ -1022,7 +1031,7 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
|
||||
}
|
||||
|
||||
private void updateLeaderboard(final String oldLeaderboardName, final LeaderboardDescriptor leaderboardToUdate) {
|
||||
sailingService.updateLeaderboard(oldLeaderboardName, leaderboardToUdate.getName(),
|
||||
sailingService.updateLeaderboard(oldLeaderboardName, leaderboardToUdate.getName(), leaderboardToUdate.getDisplayName(),
|
||||
leaderboardToUdate.getDiscardThresholds(), new AsyncCallback<Void>() {
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
@@ -1036,6 +1045,7 @@ public class LeaderboardConfigPanel extends FormPanel implements RegattaDisplaye
|
||||
StrippedLeaderboardDTO dao = leaderboardList.getList().get(i);
|
||||
if (dao.name.equals(oldLeaderboardName)) {
|
||||
dao.name = leaderboardToUdate.getName();
|
||||
dao.displayName = leaderboardToUdate.getDisplayName();
|
||||
dao.discardThresholds = leaderboardToUdate.getDiscardThresholds();
|
||||
break;
|
||||
}
|
||||
|
||||
+9
@@ -9,6 +9,15 @@ import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
*/
|
||||
public class LeaderboardDescriptor {
|
||||
private String name;
|
||||
private String displayName;
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
private ScoringSchemeType scoringScheme;
|
||||
private int[] discardThresholds;
|
||||
private String regattaName;
|
||||
|
||||
+5
-4
@@ -126,7 +126,7 @@ public class RaceCourseManagementPanel extends AbstractRaceManagementPanel {
|
||||
MarkDTO left;
|
||||
MarkDTO right;
|
||||
String gateName;
|
||||
if (first.name.toLowerCase().contains("left")) {
|
||||
if (first.name.matches("^.*"+REGEX_FOR_LEFT+".*$")) {
|
||||
left = first;
|
||||
right = second;
|
||||
} else {
|
||||
@@ -134,7 +134,7 @@ public class RaceCourseManagementPanel extends AbstractRaceManagementPanel {
|
||||
right = first;
|
||||
}
|
||||
gateName = left.name.replaceFirst(REGEX_FOR_LEFT, "");
|
||||
result = new GateDTO(gateName, left, right);
|
||||
result = new GateDTO(/* generate UUID on the server */ null, gateName, left, right);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ public class RaceCourseManagementPanel extends AbstractRaceManagementPanel {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String REGEX_FOR_LEFT = "( \\()?[lL][eE][fF][tT]\\)?";
|
||||
private static final String REGEX_FOR_LEFT = "( \\()?(([lL][eE][fF][tT])|(1))\\)?";
|
||||
|
||||
/**
|
||||
* A table that lists the marks for which events have been received for the race selected. Note that this list may
|
||||
@@ -375,7 +375,8 @@ public class RaceCourseManagementPanel extends AbstractRaceManagementPanel {
|
||||
}
|
||||
}
|
||||
assert newLeft != null && newRight != null;
|
||||
return new GateDTO(oldGate.name, newLeft, newRight);
|
||||
// if old gate had null ID, the new gate will have a null ID too, causing the server to generate one
|
||||
return new GateDTO(oldGate.getIdAsString(), oldGate.name, newLeft, newRight);
|
||||
}
|
||||
|
||||
private CellTable<MarkDTO> createAvailableMarksTable(final StringMessages stringMessages, AdminConsoleTableResources tableRes,
|
||||
|
||||
+1
@@ -15,6 +15,7 @@ public class RegattaLeaderboardCreateDialog extends RegattaLeaderboardDialog {
|
||||
super(stringConstants.createRegattaLeaderboard(), new LeaderboardDescriptor(), existingRegattas, stringConstants, existingEvents, errorReporter, new RegattaLeaderboardDialog.LeaderboardParameterValidator(stringConstants, existingLeaderboards), callback);
|
||||
|
||||
nameTextBox = createTextBox(null);
|
||||
displayNameTextBox = createTextBox(null);
|
||||
|
||||
regattaListBox = createListBox(false);
|
||||
regattaListBox.addItem(stringConstants.pleaseSelectARegatta());
|
||||
|
||||
+12
-8
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.adminconsole;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.google.gwt.user.client.ui.Grid;
|
||||
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;
|
||||
@@ -86,16 +87,18 @@ public abstract class RegattaLeaderboardDialog extends AbstractLeaderboardDialog
|
||||
protected Widget getAdditionalWidget() {
|
||||
VerticalPanel mainPanel = new VerticalPanel();
|
||||
|
||||
Grid formGrid = new Grid(5,2);
|
||||
Grid formGrid = new Grid(5,3);
|
||||
formGrid.setCellSpacing(3);
|
||||
formGrid.setWidget(0, 0, new Label(stringMessages.name() + ":"));
|
||||
formGrid.setWidget(0, 0, createLabel(stringMessages.name()));
|
||||
formGrid.setWidget(0, 1, nameTextBox);
|
||||
formGrid.setWidget(1, 0, new Label(stringMessages.regatta() + ":"));
|
||||
formGrid.setWidget(1, 1, regattaListBox);
|
||||
formGrid.setWidget(2, 0, new Label(stringMessages.event() + ":"));
|
||||
formGrid.setWidget(2, 1, sailingEventsListBox);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.courseArea() + ":"));
|
||||
formGrid.setWidget(3, 1, courseAreaListBox);
|
||||
formGrid.setWidget(1, 0, createLabel(stringMessages.displayName()));
|
||||
formGrid.setWidget(1, 1, displayNameTextBox);
|
||||
formGrid.setWidget(2, 0, createLabel(stringMessages.regatta()));
|
||||
formGrid.setWidget(2, 1, regattaListBox);
|
||||
formGrid.setWidget(3, 0, new Label(stringMessages.event() + ":"));
|
||||
formGrid.setWidget(3, 1, sailingEventsListBox);
|
||||
formGrid.setWidget(4, 0, new Label(stringMessages.courseArea() + ":"));
|
||||
formGrid.setWidget(4, 1, courseAreaListBox);
|
||||
|
||||
mainPanel.add(formGrid);
|
||||
|
||||
@@ -106,6 +109,7 @@ public abstract class RegattaLeaderboardDialog extends AbstractLeaderboardDialog
|
||||
hp.add(new Label("" + (i + 1) + "."));
|
||||
hp.add(discardThresholdBoxes[i]);
|
||||
}
|
||||
alignAllPanelWidgetsVertically(hp, HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
mainPanel.add(hp);
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ public class RegattaLeaderboardEditDialog extends RegattaLeaderboardDialog {
|
||||
stringConstants, otherExistingLeaderboards), callback);
|
||||
|
||||
nameTextBox = createTextBox(leaderboard.getName());
|
||||
displayNameTextBox = createTextBox(leaderboard.getDisplayName());
|
||||
|
||||
regattaListBox = createListBox(false);
|
||||
regattaListBox.addItem(stringConstants.pleaseSelectARegatta());
|
||||
|
||||
+15
-1
@@ -89,6 +89,7 @@ public abstract class DataEntryDialog<T> {
|
||||
okButton = new Button(okButtonName);
|
||||
okButton.getElement().getStyle().setMargin(3, Unit.PX);
|
||||
FlowPanel dialogFPanel = new FlowPanel();
|
||||
dialogFPanel.setWidth("100%");
|
||||
statusLabel = new Label();
|
||||
dialogFPanel.add(statusLabel);
|
||||
if (message != null) {
|
||||
@@ -98,6 +99,7 @@ public abstract class DataEntryDialog<T> {
|
||||
}
|
||||
|
||||
panelForAdditionalWidget = new FlowPanel();
|
||||
panelForAdditionalWidget.setWidth("100%");
|
||||
dialogFPanel.add(panelForAdditionalWidget);
|
||||
FlowPanel buttonPanel = new FlowPanel();
|
||||
dialogFPanel.add(buttonPanel);
|
||||
@@ -139,7 +141,7 @@ public abstract class DataEntryDialog<T> {
|
||||
}
|
||||
|
||||
protected abstract T getResult();
|
||||
|
||||
|
||||
/**
|
||||
* Creates a text box with a key-up listener attached which ensures the value is updated after each
|
||||
* key-up event and the entire dialog is {@link #validate() validated} in this case.
|
||||
@@ -335,6 +337,18 @@ public abstract class DataEntryDialog<T> {
|
||||
AbstractEntryPoint.linkEscapeToButton(getCancelButton(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a standard label for input fields.
|
||||
* The label has some default formatting like "no wrap" and a colon right after the label text
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public Label createLabel(String name) {
|
||||
Label result = new Label(name + ":");
|
||||
result.setWordWrap(false);
|
||||
return result;
|
||||
}
|
||||
|
||||
public ListBox createListBox(boolean isMultipleSelect) {
|
||||
ListBox result = new ListBox(isMultipleSelect);
|
||||
|
||||
+10
@@ -20,6 +20,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.rankGain();
|
||||
case RACE_RANK:
|
||||
return stringMessages.rank();
|
||||
case REGATTA_RANK:
|
||||
return stringMessages.regattaRank();
|
||||
case OVERALL_RANK:
|
||||
return stringMessages.overallRank();
|
||||
case NUMBER_OF_MANEUVERS:
|
||||
return stringMessages.numberOfManeuvers();
|
||||
case CURRENT_SPEED_OVER_GROUND_IN_KNOTS:
|
||||
@@ -128,6 +132,8 @@ public class DetailTypeFormatter {
|
||||
|
||||
// Cases for detail types without unit, so that an empty string is returned.
|
||||
case RACE_RANK:
|
||||
case REGATTA_RANK:
|
||||
case OVERALL_RANK:
|
||||
case CURRENT_LEG:
|
||||
case TACK:
|
||||
case JIBE:
|
||||
@@ -205,6 +211,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.gapToLeaderInSecondsTooltip();
|
||||
case RACE_RANK:
|
||||
return stringMessages.rankTooltip();
|
||||
case REGATTA_RANK:
|
||||
return stringMessages.regattaRankTooltip();
|
||||
case OVERALL_RANK:
|
||||
return stringMessages.overallRankTooltip();
|
||||
case RANK_GAIN:
|
||||
return stringMessages.rankGainTooltip();
|
||||
case TACK:
|
||||
|
||||
Regular → Executable
File mode changed.
+169
-252
@@ -14,6 +14,9 @@ import com.sap.sailing.domain.common.Color;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.PolarSheetsHistogramData;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaIdentifier;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
@@ -54,333 +57,247 @@ import com.sap.sailing.gwt.ui.shared.WindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
|
||||
/**
|
||||
* The client side stub for the RPC service. Usually, when a <code>null</code>
|
||||
* date is passed to the time-dependent service methods, an empty (non-
|
||||
* <code>null</code>) result is returned.
|
||||
* The client side stub for the RPC service. Usually, when a <code>null</code> date is passed to
|
||||
* the time-dependent service methods, an empty (non-<code>null</code>) result is returned.
|
||||
*/
|
||||
@RemoteServiceRelativePath("sailing")
|
||||
public interface SailingService extends RemoteService {
|
||||
List<TracTracConfigurationDTO> getPreviousTracTracConfigurations()
|
||||
throws Exception;
|
||||
List<TracTracConfigurationDTO> getPreviousTracTracConfigurations() throws Exception;
|
||||
|
||||
List<RegattaDTO> getRegattas();
|
||||
|
||||
List<RegattaDTO> getRegattas();
|
||||
List<EventDTO> getEvents();
|
||||
|
||||
List<EventDTO> getEvents();
|
||||
Pair<String, List<TracTracRaceRecordDTO>> listTracTracRacesInEvent(String eventJsonURL) throws Exception;
|
||||
|
||||
Pair<String, List<TracTracRaceRecordDTO>> listTracTracRacesInEvent(
|
||||
String eventJsonURL) throws Exception;
|
||||
void trackWithTracTrac(RegattaIdentifier regattaToAddTo, Iterable<TracTracRaceRecordDTO> rrs, String liveURI,
|
||||
String storedURI, boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow) throws Exception;
|
||||
|
||||
void trackWithTracTrac(RegattaIdentifier regattaToAddTo,
|
||||
Iterable<TracTracRaceRecordDTO> rrs, String liveURI,
|
||||
String storedURI, boolean trackWind,
|
||||
boolean correctWindByDeclination, boolean simulateWithStartTimeNow)
|
||||
throws Exception;
|
||||
void trackWithSwissTiming(RegattaIdentifier regattaToAddTo, Iterable<SwissTimingRaceRecordDTO> rrs, String hostname, int port,
|
||||
boolean canSendRequests, boolean trackWind, boolean correctWindByDeclination) throws Exception;
|
||||
|
||||
void replaySwissTimingRace(RegattaIdentifier regattaIdentifier, Iterable<SwissTimingReplayRaceDTO> replayRaces,
|
||||
boolean trackWind, boolean correctWindByDeclination, boolean simulateWithStartTimeNow);
|
||||
|
||||
void trackWithSwissTiming(RegattaIdentifier regattaToAddTo,
|
||||
Iterable<SwissTimingRaceRecordDTO> rrs, String hostname, int port,
|
||||
boolean canSendRequests, boolean trackWind,
|
||||
boolean correctWindByDeclination) throws Exception;
|
||||
void storeTracTracConfiguration(String name, String jsonURL, String liveDataURI, String storedDataURI) throws Exception;
|
||||
|
||||
void replaySwissTimingRace(RegattaIdentifier regattaIdentifier,
|
||||
Iterable<SwissTimingReplayRaceDTO> replayRaces, boolean trackWind,
|
||||
boolean correctWindByDeclination, boolean simulateWithStartTimeNow);
|
||||
void stopTrackingEvent(RegattaIdentifier eventIdentifier) throws Exception;
|
||||
|
||||
void storeTracTracConfiguration(String name, String jsonURL,
|
||||
String liveDataURI, String storedDataURI) throws Exception;
|
||||
void stopTrackingRaces(Iterable<RegattaAndRaceIdentifier> racesToStopTracking) throws Exception;
|
||||
|
||||
void removeAndUntrackRaces(Iterable<RegattaAndRaceIdentifier> regattaNamesAndRaceNames);
|
||||
|
||||
void stopTrackingEvent(RegattaIdentifier eventIdentifier) throws Exception;
|
||||
WindInfoForRaceDTO getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier, Collection<WindSource> windSources);
|
||||
|
||||
void stopTrackingRaces(
|
||||
Iterable<RegattaAndRaceIdentifier> racesToStopTracking)
|
||||
throws Exception;
|
||||
void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind);
|
||||
|
||||
void removeAndUntrackRaces(
|
||||
Iterable<RegattaAndRaceIdentifier> regattaNamesAndRaceNames);
|
||||
WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth,
|
||||
int numberOfFixes, Collection<String> windSourceTypeNames) throws NoWindException;
|
||||
|
||||
WindInfoForRaceDTO getRawWindFixes(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Collection<WindSource> windSources);
|
||||
WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, Date to, long resolutionInMilliseconds,
|
||||
Collection<String> windSourceTypeNames);
|
||||
|
||||
void setWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO wind);
|
||||
WindInfoForRaceDTO getAveragedWindInfo(RegattaAndRaceIdentifier raceIdentifier, Date from, long millisecondsStepWidth,
|
||||
int numberOfFixes, double latDeg, double lngDeg, Collection<String> windSources) throws NoWindException;
|
||||
|
||||
WindInfoForRaceDTO getAveragedWindInfo(
|
||||
RegattaAndRaceIdentifier raceIdentifier, Date from,
|
||||
long millisecondsStepWidth, int numberOfFixes,
|
||||
Collection<String> windSourceTypeNames) throws NoWindException;
|
||||
RaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier, Date date, Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to,
|
||||
boolean extrapolate) throws NoWindException;
|
||||
|
||||
Map<CompetitorDTO, List<GPSFixDTO>> getBoatPositions(RegattaAndRaceIdentifier raceIdentifier, Map<CompetitorDTO, Date> from,
|
||||
Map<CompetitorDTO, Date> to, boolean extrapolate) throws NoWindException;
|
||||
|
||||
WindInfoForRaceDTO getAveragedWindInfo(
|
||||
RegattaAndRaceIdentifier raceIdentifier, Date from, Date to,
|
||||
long resolutionInMilliseconds,
|
||||
Collection<String> windSourceTypeNames);
|
||||
RaceTimesInfoDTO getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
List<RaceTimesInfoDTO> getRaceTimesInfos(Collection<RegattaAndRaceIdentifier> raceIdentifiers);
|
||||
|
||||
CourseDTO getCoursePositions(RegattaAndRaceIdentifier raceIdentifier, Date date);
|
||||
|
||||
WindInfoForRaceDTO getAveragedWindInfo(
|
||||
RegattaAndRaceIdentifier raceIdentifier, Date from,
|
||||
long millisecondsStepWidth, int numberOfFixes, double latDeg,
|
||||
double lngDeg, Collection<String> windSources)
|
||||
throws NoWindException;
|
||||
List<ControlPointDTO> getRaceCourse(RegattaAndRaceIdentifier raceIdentifier, Date date);
|
||||
|
||||
RaceMapDataDTO getRaceMapData(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Date date, Map<CompetitorDTO, Date> from,
|
||||
Map<CompetitorDTO, Date> to, boolean extrapolate)
|
||||
throws NoWindException;
|
||||
List<QuickRankDTO> getQuickRanks(RegattaAndRaceIdentifier raceIdentifier, Date date) throws NoWindException;
|
||||
|
||||
Map<CompetitorDTO, List<GPSFixDTO>> getBoatPositions(
|
||||
RegattaAndRaceIdentifier raceIdentifier,
|
||||
Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to,
|
||||
boolean extrapolate) throws NoWindException;
|
||||
void removeWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO windDTO);
|
||||
|
||||
RaceTimesInfoDTO getRaceTimesInfo(RegattaAndRaceIdentifier raceIdentifier);
|
||||
public List<String> getLeaderboardNames() throws Exception;
|
||||
|
||||
LeaderboardDTO getLeaderboardByName(String leaderboardName, Date date,
|
||||
Collection<String> namesOfRaceColumnsForWhichToLoadLegDetails) throws Exception;
|
||||
|
||||
List<RaceTimesInfoDTO> getRaceTimesInfos(
|
||||
Collection<RegattaAndRaceIdentifier> raceIdentifiers);
|
||||
List<StrippedLeaderboardDTO> getLeaderboards();
|
||||
|
||||
List<StrippedLeaderboardDTO> getLeaderboardsByEvent(RegattaDTO regatta);
|
||||
|
||||
void updateLeaderboard(String leaderboardName, String newLeaderboardName, String newLeaderboardDisplayName, int[] newDiscardingThreasholds);
|
||||
|
||||
CourseDTO getCoursePositions(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Date date);
|
||||
StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, ScoringSchemeType scoringSchemeType, Serializable courseAreaId);
|
||||
|
||||
List<ControlPointDTO> getRaceCourse(
|
||||
RegattaAndRaceIdentifier raceIdentifier, Date date);
|
||||
StrippedLeaderboardDTO createRegattaLeaderboard(RegattaIdentifier regattaIdentifier, int[] discardThresholds, Serializable courseAreaId);
|
||||
|
||||
List<QuickRankDTO> getQuickRanks(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Date date) throws NoWindException;
|
||||
void removeLeaderboard(String leaderboardName);
|
||||
|
||||
void removeWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO windDTO);
|
||||
void renameLeaderboard(String leaderboardName, String newLeaderboardName);
|
||||
|
||||
public List<String> getLeaderboardNames() throws Exception;
|
||||
void renameLeaderboardColumn(String leaderboardName, String oldColumnName, String newColumnName);
|
||||
|
||||
LeaderboardDTO getLeaderboardByName(String leaderboardName, Date date,
|
||||
Collection<String> namesOfRaceColumnsForWhichToLoadLegDetails)
|
||||
throws Exception;
|
||||
void removeLeaderboardColumn(String leaderboardName, String columnName);
|
||||
|
||||
void addColumnToLeaderboard(String columnName, String leaderboardName, boolean medalRace);
|
||||
|
||||
void moveLeaderboardColumnUp(String leaderboardName, String columnName);
|
||||
|
||||
void moveLeaderboardColumnDown(String leaderboardName, String columnName);
|
||||
|
||||
RegattaDTO createRegatta(String regattaName, String boatClassName,
|
||||
LinkedHashMap<String, Pair<List<Triple<String, Integer, Color>>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal,
|
||||
boolean persistent, ScoringSchemeType scoringSchemeType);
|
||||
|
||||
void removeRegatta(RegattaIdentifier regattaIdentifier);
|
||||
|
||||
List<RaceColumnInSeriesDTO> addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName, List<String> columnNames);
|
||||
|
||||
List<StrippedLeaderboardDTO> getLeaderboards();
|
||||
RaceColumnInSeriesDTO addRaceColumnToSeries(RegattaIdentifier regattaIdentifier, String seriesName, String columnName);
|
||||
|
||||
List<StrippedLeaderboardDTO> getLeaderboardsByEvent(RegattaDTO regatta);
|
||||
void removeRaceColumnsFromSeries(RegattaIdentifier regattaIdentifier, String seriesName, List<String> columnNames);
|
||||
|
||||
void updateLeaderboard(String leaderboardName, String newLeaderboardName,
|
||||
int[] newDiscardingThreasholds);
|
||||
void removeRaceColumnFromSeries(RegattaIdentifier regattaIdentifier, String seriesName, String columnName);
|
||||
|
||||
StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName,
|
||||
int[] discardThresholds, ScoringSchemeType scoringSchemeType,
|
||||
Serializable courseAreaId);
|
||||
void moveRaceColumnInSeriesUp(RegattaIdentifier regattaIdentifier, String seriesName, String columnName);
|
||||
|
||||
StrippedLeaderboardDTO createRegattaLeaderboard(
|
||||
RegattaIdentifier regattaIdentifier, int[] discardThresholds,
|
||||
Serializable courseAreaId);
|
||||
void moveRaceColumnInSeriesDown(RegattaIdentifier regattaIdentifier, String seriesName, String columnName);
|
||||
|
||||
void removeLeaderboard(String leaderboardName);
|
||||
boolean connectTrackedRaceToLeaderboardColumn(String leaderboardName, String raceColumnName,
|
||||
String fleetName, RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName, String raceColumnName, String fleetName);
|
||||
|
||||
Map<String, RegattaAndRaceIdentifier> getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn(String leaderboardName, String raceColumnName);
|
||||
|
||||
void renameLeaderboard(String leaderboardName, String newLeaderboardName);
|
||||
void updateLeaderboardCarryValue(String leaderboardName, String competitorIdAsString, Double carriedPoints);
|
||||
|
||||
void renameLeaderboardColumn(String leaderboardName, String oldColumnName,
|
||||
String newColumnName);
|
||||
/**
|
||||
* @return the new net points in {@link Pair#getA()} and the new total points in {@link Pair#getB()} for time point
|
||||
* <code>date</code> after the max points reason has been updated to <code>maxPointsReasonAsString</code>.
|
||||
*/
|
||||
Triple<Double, Double, Boolean> updateLeaderboardMaxPointsReason(String leaderboardName, String competitorIdAsString,
|
||||
String raceColumnName, MaxPointsReason maxPointsReason, Date date) throws NoWindException;
|
||||
|
||||
void removeLeaderboardColumn(String leaderboardName, String columnName);
|
||||
Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(String leaderboardName, String competitorIdAsString,
|
||||
String columnName, Double correctedScore, Date date) throws NoWindException;
|
||||
|
||||
void addColumnToLeaderboard(String columnName, String leaderboardName,
|
||||
boolean medalRace);
|
||||
void updateCompetitorDisplayNameInLeaderboard(String leaderboardName, String competitorIdAsString, String displayName);
|
||||
|
||||
void updateIsMedalRace(String leaderboardName, String columnName, boolean isMedalRace);
|
||||
|
||||
void moveLeaderboardColumnUp(String leaderboardName, String columnName);
|
||||
List<SwissTimingConfigurationDTO> getPreviousSwissTimingConfigurations();
|
||||
|
||||
void moveLeaderboardColumnDown(String leaderboardName, String columnName);
|
||||
List<SwissTimingRaceRecordDTO> listSwissTimingRaces(String hostname, int port, boolean canSendRequests) throws Exception;
|
||||
|
||||
RegattaDTO createRegatta(
|
||||
String regattaName,
|
||||
String boatClassName,
|
||||
LinkedHashMap<String, Pair<List<Triple<String, Integer, Color>>, Boolean>> seriesNamesWithFleetNamesAndFleetOrderingAndMedal,
|
||||
boolean persistent, ScoringSchemeType scoringSchemeType);
|
||||
void storeSwissTimingConfiguration(String configName, String hostname, int port, boolean canSendRequests);
|
||||
|
||||
void removeRegatta(RegattaIdentifier regattaIdentifier);
|
||||
void sendSwissTimingDummyRace(String racMessage, String stlMesssage, String ccgMessage) throws IllegalArgumentException;
|
||||
|
||||
List<RaceColumnInSeriesDTO> addRaceColumnsToSeries(
|
||||
RegattaIdentifier regattaIdentifier, String seriesName,
|
||||
List<String> columnNames);
|
||||
String[] getCountryCodes();
|
||||
|
||||
Map<CompetitorDTO, List<GPSFixDTO>> getDouglasPoints(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to, double meters) throws NoWindException;
|
||||
|
||||
RaceColumnInSeriesDTO addRaceColumnToSeries(
|
||||
RegattaIdentifier regattaIdentifier, String seriesName,
|
||||
String columnName);
|
||||
Map<CompetitorDTO, List<ManeuverDTO>> getManeuvers(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to) throws NoWindException;
|
||||
|
||||
void removeRaceColumnsFromSeries(RegattaIdentifier regattaIdentifier,
|
||||
String seriesName, List<String> columnNames);
|
||||
List<StrippedLeaderboardDTO> getLeaderboardsByRace(RaceDTO race);
|
||||
|
||||
List<LeaderboardGroupDTO> getLeaderboardGroups(boolean withGeoLocationData);
|
||||
|
||||
LeaderboardGroupDTO getLeaderboardGroupByName(String groupName, boolean withGeoLocationData);
|
||||
|
||||
void renameLeaderboardGroup(String oldName, String newName);
|
||||
|
||||
void removeLeaderboardGroup(String groupName);
|
||||
|
||||
LeaderboardGroupDTO createLeaderboardGroup(String groupName, String description,
|
||||
boolean displayGroupsInReverseOrder, int[] overallLeaderboardDiscardThresholds,
|
||||
ScoringSchemeType overallLeaderboardScoringSchemeType);
|
||||
|
||||
void updateLeaderboardGroup(String oldName, String newName, String description, List<String> leaderboardNames,
|
||||
int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType);
|
||||
|
||||
void removeRaceColumnFromSeries(RegattaIdentifier regattaIdentifier,
|
||||
String seriesName, String columnName);
|
||||
CompetitorsRaceDataDTO getCompetitorsRaceData(RegattaAndRaceIdentifier race, List<CompetitorDTO> competitors, Date from, Date to,
|
||||
long stepSizeInMs, DetailType detailType, String leaderboardGroupName, String leaderboardName) throws NoWindException;
|
||||
|
||||
void moveRaceColumnInSeriesUp(RegattaIdentifier regattaIdentifier,
|
||||
String seriesName, String columnName);
|
||||
void setRaceIsKnownToStartUpwind(RegattaAndRaceIdentifier raceIdentifier, boolean raceIsKnownToStartUpwind);
|
||||
|
||||
void moveRaceColumnInSeriesDown(RegattaIdentifier regattaIdentifier,
|
||||
String seriesName, String columnName);
|
||||
void setWindSourcesToExclude(RegattaAndRaceIdentifier raceIdentifier, Iterable<WindSource> windSourcesToExclude);
|
||||
|
||||
ReplicationStateDTO getReplicaInfo();
|
||||
|
||||
boolean connectTrackedRaceToLeaderboardColumn(String leaderboardName,
|
||||
String raceColumnName, String fleetName,
|
||||
RegattaAndRaceIdentifier raceIdentifier);
|
||||
void startReplicatingFromMaster(String masterName, String exchangeName, int servletPort, int messagingPort) throws Exception;
|
||||
|
||||
void disconnectLeaderboardColumnFromTrackedRace(String leaderboardName,
|
||||
String raceColumnName, String fleetName);
|
||||
void updateRaceDelayToLive(RegattaAndRaceIdentifier regattaAndRaceIdentifier, long delayToLiveInMs);
|
||||
|
||||
Map<String, RegattaAndRaceIdentifier> getRegattaAndRaceNameOfTrackedRaceConnectedToLeaderboardColumn(
|
||||
String leaderboardName, String raceColumnName);
|
||||
void updateRacesDelayToLive(List<RegattaAndRaceIdentifier> regattaAndRaceIdentifiers, long delayToLiveInMs);
|
||||
|
||||
void updateLeaderboardCarryValue(String leaderboardName,
|
||||
String competitorIdAsString, Double carriedPoints);
|
||||
void updateEvent(String eventName, Serializable id, VenueDTO venue, String publicationUrl, boolean isPublic,
|
||||
List<String> regattaNames);
|
||||
|
||||
/**
|
||||
* @return the new net points in {@link Pair#getA()} and the new total
|
||||
* points in {@link Pair#getB()} for time point <code>date</code>
|
||||
* after the max points reason has been updated to
|
||||
* <code>maxPointsReasonAsString</code>.
|
||||
*/
|
||||
Triple<Double, Double, Boolean> updateLeaderboardMaxPointsReason(
|
||||
String leaderboardName, String competitorIdAsString,
|
||||
String raceColumnName, MaxPointsReason maxPointsReason, Date date)
|
||||
throws NoWindException;
|
||||
EventDTO createEvent(String eventName, String venueName, String publicationUrl, boolean isPublic, List<String> courseAreaNames);
|
||||
|
||||
Triple<Double, Double, Boolean> updateLeaderboardScoreCorrection(
|
||||
String leaderboardName, String competitorIdAsString,
|
||||
String columnName, Double correctedScore, Date date)
|
||||
throws NoWindException;
|
||||
void removeEvent(Serializable id);
|
||||
|
||||
void updateCompetitorDisplayNameInLeaderboard(String leaderboardName,
|
||||
String competitorIdAsString, String displayName);
|
||||
void renameEvent(Serializable id, String newName);
|
||||
|
||||
void updateIsMedalRace(String leaderboardName, String columnName,
|
||||
boolean isMedalRace);
|
||||
EventDTO getEventByName(String eventName);
|
||||
|
||||
List<SwissTimingConfigurationDTO> getPreviousSwissTimingConfigurations();
|
||||
Iterable<ScoreCorrectionProviderDTO> getScoreCorrectionProviderDTOs() throws Exception;
|
||||
|
||||
List<SwissTimingRaceRecordDTO> listSwissTimingRaces(String hostname,
|
||||
int port, boolean canSendRequests) throws Exception;
|
||||
RegattaScoreCorrectionDTO getScoreCorrections(String scoreCorrectionProviderName, String eventName, String boatClassName,
|
||||
Date timePointWhenResultPublished) throws Exception;
|
||||
|
||||
void storeSwissTimingConfiguration(String configName, String hostname,
|
||||
int port, boolean canSendRequests);
|
||||
void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(BulkScoreCorrectionDTO updates) throws NoWindException;
|
||||
|
||||
void sendSwissTimingDummyRace(String racMessage, String stlMesssage,
|
||||
String ccgMessage) throws IllegalArgumentException;
|
||||
WindInfoForRaceDTO getWindSourcesInfo(RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
String[] getCountryCodes();
|
||||
List<String> getFregResultUrls();
|
||||
|
||||
Map<CompetitorDTO, List<GPSFixDTO>> getDouglasPoints(
|
||||
RegattaAndRaceIdentifier raceIdentifier,
|
||||
Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to,
|
||||
double meters) throws NoWindException;
|
||||
void removeFregURLs(Set<String> toRemove) throws Exception;
|
||||
|
||||
Map<CompetitorDTO, List<ManeuverDTO>> getManeuvers(
|
||||
RegattaAndRaceIdentifier raceIdentifier,
|
||||
Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to)
|
||||
throws NoWindException;
|
||||
void addFragUrl(String result) throws Exception;
|
||||
|
||||
List<StrippedLeaderboardDTO> getLeaderboardsByRace(RaceDTO race);
|
||||
Void updateLeaderboardScoreCorrectionMetadata(String leaderboardName, Date timePointOfLastCorrectionValidity,
|
||||
String comment);
|
||||
|
||||
List<LeaderboardGroupDTO> getLeaderboardGroups(boolean withGeoLocationData);
|
||||
RaceCourseMarksDTO getRaceCourseMarks(RegattaAndRaceIdentifier raceIdentifier, Date date);
|
||||
|
||||
LeaderboardGroupDTO getLeaderboardGroupByName(String groupName,
|
||||
boolean withGeoLocationData);
|
||||
void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier, List<ControlPointDTO> controlPoints);
|
||||
|
||||
void addColumnsToLeaderboard(String leaderboardName, List<Pair<String, Boolean>> columnsToAdd);
|
||||
|
||||
void removeLeaderboardGroup(String groupName);
|
||||
void removeLeaderboardColumns(String leaderboardName, List<String> columnsToRemove);
|
||||
|
||||
LeaderboardGroupDTO createLeaderboardGroup(String groupName,
|
||||
String description, boolean displayGroupsInReverseOrder,
|
||||
int[] overallLeaderboardDiscardThresholds,
|
||||
ScoringSchemeType overallLeaderboardScoringSchemeType);
|
||||
StrippedLeaderboardDTO getLeaderboard(String leaderboardName);
|
||||
|
||||
void updateLeaderboardGroup(String oldName, String newName,
|
||||
String description, List<String> leaderboardNames,
|
||||
int[] overallLeaderboardDiscardThresholds,
|
||||
ScoringSchemeType overallLeaderboardScoringSchemeType);
|
||||
void suppressCompetitorInLeaderboard(String leaderboardName, String competitorIdAsString, boolean suppressed);
|
||||
|
||||
CompetitorsRaceDataDTO getCompetitorsRaceData(
|
||||
RegattaAndRaceIdentifier race, List<CompetitorDTO> competitors,
|
||||
Date from, Date to, long stepSizeInMs, DetailType detailType)
|
||||
throws NoWindException;
|
||||
void updateLeaderboardColumnFactor(String leaderboardName, String columnName, Double newFactor);
|
||||
|
||||
void setRaceIsKnownToStartUpwind(RegattaAndRaceIdentifier raceIdentifier,
|
||||
boolean raceIsKnownToStartUpwind);
|
||||
List<SwissTimingReplayRaceDTO> listSwissTiminigReplayRaces(String swissTimingUrl);
|
||||
|
||||
void setWindSourcesToExclude(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Iterable<WindSource> windSourcesToExclude);
|
||||
List<Pair<String, List<CompetitorDTO>>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(String leaderboardName, Date date) throws NoWindException;
|
||||
|
||||
ReplicationStateDTO getReplicaInfo();
|
||||
List<String> getOverallLeaderboardNamesContaining(String leaderboardName);
|
||||
|
||||
void startReplicatingFromMaster(String masterName, String exchangeName,
|
||||
int servletPort, int messagingPort) throws Exception;
|
||||
List<SwissTimingArchiveConfigurationDTO> getPreviousSwissTimingArchiveConfigurations();
|
||||
|
||||
void updateRaceDelayToLive(
|
||||
RegattaAndRaceIdentifier regattaAndRaceIdentifier,
|
||||
long delayToLiveInMs);
|
||||
void storeSwissTimingArchiveConfiguration(String swissTimingUrl);
|
||||
|
||||
void updateRacesDelayToLive(
|
||||
List<RegattaAndRaceIdentifier> regattaAndRaceIdentifiers,
|
||||
long delayToLiveInMs);
|
||||
|
||||
void updateEvent(String eventName, Serializable id, VenueDTO venue,
|
||||
String publicationUrl, boolean isPublic, List<String> regattaNames);
|
||||
|
||||
EventDTO createEvent(String eventName, String venueName,
|
||||
String publicationUrl, boolean isPublic, List<String> courseAreas);
|
||||
|
||||
void removeEvent(Serializable id);
|
||||
|
||||
void renameEvent(Serializable id, String newName);
|
||||
|
||||
EventDTO getEventByName(String eventName);
|
||||
|
||||
CourseAreaDTO createCourseArea(Serializable id, String courseAreaName);
|
||||
|
||||
EventDTO getEventById(Serializable id);
|
||||
|
||||
Iterable<ScoreCorrectionProviderDTO> getScoreCorrectionProviderDTOs()
|
||||
throws Exception;
|
||||
|
||||
RegattaScoreCorrectionDTO getScoreCorrections(
|
||||
String scoreCorrectionProviderName, String eventName,
|
||||
String boatClassName, Date timePointWhenResultPublished)
|
||||
throws Exception;
|
||||
|
||||
void updateLeaderboardScoreCorrectionsAndMaxPointsReasons(
|
||||
BulkScoreCorrectionDTO updates) throws NoWindException;
|
||||
|
||||
WindInfoForRaceDTO getWindSourcesInfo(
|
||||
RegattaAndRaceIdentifier raceIdentifier);
|
||||
|
||||
List<String> getFregResultUrls();
|
||||
|
||||
void removeFregURLs(Set<String> toRemove) throws Exception;
|
||||
|
||||
void addFragUrl(String result) throws Exception;
|
||||
|
||||
Void updateLeaderboardScoreCorrectionMetadata(String leaderboardName,
|
||||
Date timePointOfLastCorrectionValidity, String comment);
|
||||
|
||||
RaceCourseMarksDTO getRaceCourseMarks(
|
||||
RegattaAndRaceIdentifier raceIdentifier, Date date);
|
||||
|
||||
void updateRaceCourse(RegattaAndRaceIdentifier raceIdentifier,
|
||||
List<ControlPointDTO> controlPoints);
|
||||
|
||||
void removeLeaderboardColumns(String leaderboardName,
|
||||
List<String> columnsToRemove);
|
||||
|
||||
StrippedLeaderboardDTO getLeaderboard(String leaderboardName);
|
||||
|
||||
void suppressCompetitorInLeaderboard(String leaderboardName,
|
||||
String competitorIdAsString, boolean suppressed);
|
||||
|
||||
RaceEventLogDTO getRaceEventLog();
|
||||
|
||||
void updateLeaderboardColumnFactor(String leaderboardName,
|
||||
String columnName, Double newFactor);
|
||||
|
||||
List<SwissTimingReplayRaceDTO> listSwissTiminigReplayRaces(
|
||||
String swissTimingUrl);
|
||||
|
||||
List<Pair<String, List<CompetitorDTO>>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(
|
||||
String leaderboardName, Date date) throws NoWindException;
|
||||
|
||||
List<String> getOverallLeaderboardNamesContaining(String leaderboardName);
|
||||
|
||||
List<SwissTimingArchiveConfigurationDTO> getPreviousSwissTimingArchiveConfigurations();
|
||||
|
||||
void storeSwissTimingArchiveConfiguration(String swissTimingUrl);
|
||||
|
||||
void renameLeaderboardGroup(String oldName, String newName);
|
||||
}
|
||||
PolarSheetGenerationTriggerResponse generatePolarSheetForRaces(List<RegattaAndRaceIdentifier> selectedRaces);
|
||||
|
||||
PolarSheetsData getPolarSheetsGenerationResults(String id);
|
||||
|
||||
PolarSheetsHistogramData getPolarSheetData(String polarSheetId, int angle, int windSpeed);
|
||||
|
||||
RaceEventLogDTO getRaceEventLog();
|
||||
|
||||
EventDTO getEventById(Serializable id);
|
||||
|
||||
CourseAreaDTO createCourseArea(Serializable id, String courseAreaName);
|
||||
}
|
||||
+12
-3
@@ -12,6 +12,9 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.Color;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.PolarSheetsHistogramData;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaIdentifier;
|
||||
@@ -206,8 +209,8 @@ public interface SailingServiceAsync {
|
||||
|
||||
void getLeaderboardsByRace(RaceDTO race, AsyncCallback<List<StrippedLeaderboardDTO>> callback);
|
||||
|
||||
void updateLeaderboard(String leaderboardName, String newLeaderboardName, int[] newDiscardingThreasholds,
|
||||
AsyncCallback<Void> callback);
|
||||
void updateLeaderboard(String leaderboardName, String newLeaderboardName, String newLeaderboardDisplayName,
|
||||
int[] newDiscardingThreasholds, AsyncCallback<Void> callback);
|
||||
|
||||
void createFlexibleLeaderboard(String leaderboardName, int[] discardThresholds, ScoringSchemeType scoringSchemeType, Serializable courseAreaId,
|
||||
AsyncCallback<StrippedLeaderboardDTO> asyncCallback);
|
||||
@@ -429,7 +432,7 @@ public interface SailingServiceAsync {
|
||||
AsyncCallback<List<Pair<String, List<CompetitorDTO>>>> callback);
|
||||
|
||||
void getCompetitorsRaceData(RegattaAndRaceIdentifier race, List<CompetitorDTO> competitors, Date from, Date to,
|
||||
long stepSize, DetailType detailType, AsyncCallback<CompetitorsRaceDataDTO> callback);
|
||||
long stepSize, DetailType detailType, String leaderboarGroupName, String leaderboardName, AsyncCallback<CompetitorsRaceDataDTO> callback);
|
||||
|
||||
/**
|
||||
* Finds out the names of all {@link com.sap.sailing.domain.leaderboard.MetaLeaderboard}s managed by this server that
|
||||
@@ -443,4 +446,10 @@ public interface SailingServiceAsync {
|
||||
AsyncCallback<List<SwissTimingArchiveConfigurationDTO>> asyncCallback);
|
||||
|
||||
void storeSwissTimingArchiveConfiguration(String swissTimingUrl, AsyncCallback<Void> asyncCallback);
|
||||
|
||||
void generatePolarSheetForRaces(List<RegattaAndRaceIdentifier> selectedRaces, AsyncCallback<PolarSheetGenerationTriggerResponse> asyncCallback);
|
||||
|
||||
void getPolarSheetsGenerationResults(String id, AsyncCallback<PolarSheetsData> asyncCallback);
|
||||
|
||||
void getPolarSheetData(String polarSheetId, int angle, int windSpeed, AsyncCallback<PolarSheetsHistogramData> wrapperCallback);
|
||||
}
|
||||
+11
@@ -482,6 +482,8 @@ public interface StringMessages extends Messages {
|
||||
String gapChangeSinceLegStartInSecondsTooltip();
|
||||
String velocityMadeGoodInKnotsTooltip();
|
||||
String sideToWhichMarkAtLegStartWasRoundedTooltip();
|
||||
String generatePolarSheet();
|
||||
String polarSheetChart();
|
||||
String numberOfManeuversInRaceTooltip();
|
||||
String competitorColumnTooltip();
|
||||
String sailIdColumnTooltip();
|
||||
@@ -491,6 +493,15 @@ public interface StringMessages extends Messages {
|
||||
String windData();
|
||||
String gpsData();
|
||||
String status();
|
||||
String regattaRank();
|
||||
String regattaRankTooltip();
|
||||
String overallRank();
|
||||
String overallRankTooltip();
|
||||
String noDataFound();
|
||||
String displayName();
|
||||
String histogram();
|
||||
String numberOfDataPoints();
|
||||
String angleAndTotalNumberOfDataPoints(int angle, int numberOfDataPoints);
|
||||
String addCourseArea();
|
||||
String courseAreas();
|
||||
String courseArea();
|
||||
|
||||
+12
@@ -59,6 +59,10 @@ renameRace=Rename Race
|
||||
openSelectedLeaderboard=Open Selected Leaderboard
|
||||
rank=Rank
|
||||
rankTooltip=Competitor''s rank in the race
|
||||
regattaRank=Regatta Rank
|
||||
regattaRankTooltip=Competitor''s rank in the regatta
|
||||
overallRank=Overall Rank
|
||||
overallRankTooltip=Competitor''s rank in the series
|
||||
totalRank=Total rank
|
||||
collapse=-
|
||||
expand=+
|
||||
@@ -482,8 +486,11 @@ sideToWhichMarkAtLegStartWasRounded=Mark rounded to
|
||||
sideToWhichMarkAtLegStartWasRoundedTooltip=Side to which the mark at leg start was rounded.
|
||||
raceIsLive=Race {0} is live
|
||||
racesAreLive=Races {0} are live
|
||||
knotsUnit=kts
|
||||
scoringSchemeHighPointFirstGetsTen=High Point, winner gets 10 points
|
||||
knotsUnit=kts
|
||||
generatePolarSheet=Generate Polar Sheet
|
||||
polarSheetChart=Polar Sheet
|
||||
competitorColumnTooltip=Names of the members of this competitor.
|
||||
sailIdColumnTooltip=Shows the flag of the country and the sail number of the competitor.
|
||||
rankColumnTooltip=The overall rank of this competitor in the regatta.
|
||||
@@ -492,6 +499,11 @@ totalsColumnTooltip=The total of all points of a competitor in the regatta.
|
||||
windData=Wind data
|
||||
gpsData=GPS data
|
||||
status=Status
|
||||
noDataFound=No data found
|
||||
displayName=Display name
|
||||
histogram=Histogram
|
||||
numberOfDataPoints=Number of data points
|
||||
angleAndTotalNumberOfDataPoints=Angle: {0}; Total number of data-points: {1}
|
||||
addCourseArea=Add course area
|
||||
courseAreas=Course areas
|
||||
courseArea=Course area
|
||||
|
||||
+11
@@ -59,6 +59,10 @@ renameRace=Rennen umbenennen
|
||||
openSelectedLeaderboard=Ausgewählte Rangliste öffnen
|
||||
rank=Platz
|
||||
rankTooltip=Platzierung des Teilnehmers im Rennen
|
||||
regattaRank=Platz in der Regatta
|
||||
regattaRankTooltip=Platzierung des Teilnehmers in der Regatta
|
||||
overallRank=Platz in der Serie
|
||||
overallRankTooltip=Platzierung des Teilnehmers in der Serie
|
||||
totalRank=Gesamtplatz
|
||||
collapse=-
|
||||
expand=+
|
||||
@@ -485,6 +489,8 @@ raceIsLive=Rennen {0} ist live
|
||||
racesAreLive=Rennen {0} sind live
|
||||
scoringSchemeHighPointFirstGetsTen=High Point System, Gewinner erhält 10 Punkte
|
||||
knotsUnit=kn
|
||||
generatePolarSheet=Polardiagramm erstellen
|
||||
polarSheetChart=Polardiagramm
|
||||
competitorColumnTooltip=Namen der Segler dieses Teilnehmers
|
||||
sailIdColumnTooltip=Zeigt die Länderflagge und die Segelnummer des Teilnehmers
|
||||
rankColumnTooltip=Der Gesamtplatz des Teilnehmers in der Regatta
|
||||
@@ -493,6 +499,11 @@ totalsColumnTooltip=Summe aller Punkte eines Teilnehmers in der Regatta
|
||||
windData=Winddaten
|
||||
gpsData=GPS-Daten
|
||||
status=Status
|
||||
noDataFound=Keine Daten gefunden
|
||||
displayName=Anzeigename
|
||||
histogram=Histogramm
|
||||
numberOfDataPoints=Anzahl Datenpunkte
|
||||
angleAndTotalNumberOfDataPoints=Winkel: {0}; Anzahl Datenpunkte: {1}
|
||||
addCourseArea=Kursbereich hinzufügen
|
||||
courseAreas=Kursbereiche
|
||||
courseArea=Kursbereich
|
||||
|
||||
+2
-2
@@ -55,7 +55,7 @@ public class CompareCompetitorsChartDialog extends DialogBoxExt implements RaceT
|
||||
|
||||
public CompareCompetitorsChartDialog(SailingServiceAsync sailingService,
|
||||
List<RegattaAndRaceIdentifier> races, final RaceTimesInfoProvider raceTimesInfoProvider, final CompetitorSelectionProvider competitorSelectionProvider,
|
||||
Timer timer, StringMessages stringMessages, ErrorReporter errorReporter) {
|
||||
Timer timer, StringMessages stringMessages, ErrorReporter errorReporter, String leaderboardGroupName, String leaderboardName) {
|
||||
super(new Label(stringMessages.close()));
|
||||
this.sailingService = sailingService;
|
||||
this.timer = timer;
|
||||
@@ -71,7 +71,7 @@ public class CompareCompetitorsChartDialog extends DialogBoxExt implements RaceT
|
||||
raceSelectionProvider.setAllRaces(races);
|
||||
|
||||
multiChartPanel = new MultiChartPanel(sailingService, new AsyncActionsExecutor(), competitorSelectionProvider, raceSelectionProvider,
|
||||
timer, timeRangeWithZoomProvider, stringMessages, errorReporter, false, false);
|
||||
timer, timeRangeWithZoomProvider, stringMessages, errorReporter, false, false, leaderboardGroupName, leaderboardName);
|
||||
multiChartPanel.setSize("100%", "100%");
|
||||
|
||||
VerticalPanel contentPanel = new VerticalPanel();
|
||||
|
||||
+3
-3
@@ -125,9 +125,9 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, new AsyncActionsExecutor(),
|
||||
leaderboardSettings,
|
||||
preselectedRace, new CompetitorSelectionModel(
|
||||
/* hasMultiSelection */true), timer, leaderboardName, LeaderboardEntryPoint.this,
|
||||
stringMessages, userAgent, showRaceDetails, /* raceTimesInfoProvider */ null, Window.Location.getParameterMap().containsKey(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN) ?
|
||||
Boolean.valueOf(Window.Location.getParameterMap().get(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN).get(0)) : false);
|
||||
/* hasMultiSelection */true), timer, leaderboardGroupName, leaderboardName,
|
||||
LeaderboardEntryPoint.this, stringMessages, userAgent, showRaceDetails, /* raceTimesInfoProvider */ null, Window.Location.getParameterMap().containsKey(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN) ?
|
||||
Boolean.valueOf(Window.Location.getParameterMap().get(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN).get(0)) : false);
|
||||
leaderboardPanel.addStyleName(LeaderboardPanel.LEADERBOARD_MARGIN_STYLE);
|
||||
contentScrollPanel.setWidget(leaderboardPanel);
|
||||
|
||||
|
||||
+2394
-2391
File diff suppressed because it is too large.
Load diff
+31
@@ -0,0 +1,31 @@
|
||||
package com.sap.sailing.gwt.ui.polarsheets;
|
||||
|
||||
import com.sap.sailing.gwt.ui.adminconsole.AbstractTrackedRacesListComposite;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.RaceSelectionProvider;
|
||||
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.RaceDTO;
|
||||
|
||||
public abstract class AbstractFilteredTrackedRacesList extends AbstractTrackedRacesListComposite {
|
||||
|
||||
private RaceFilter filter;
|
||||
|
||||
public AbstractFilteredTrackedRacesList(SailingServiceAsync sailingService, ErrorReporter errorReporter,
|
||||
RegattaRefresher regattaRefresher, RaceSelectionProvider raceSelectionProvider,
|
||||
StringMessages stringMessages, boolean hasMultiSelection, RaceFilter filter) {
|
||||
super(sailingService, errorReporter, regattaRefresher, raceSelectionProvider, stringMessages, hasMultiSelection);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean raceIsToBeAddedToList(RaceDTO race) {
|
||||
if (filter!=null) {
|
||||
return filter.compliesToFilter(race);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loaded 100 of 195 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user