f4e221edaf5edcad7c3d253761b8ee0eabd69fe5
configuration/sailing
| ... | ... | @@ -4,6 +4,18 @@ |
| 4 | 4 | # |
| 5 | 5 | # chkconfig: 2345 95 10 |
| 6 | 6 | # description: Sailing contains all sailing services |
| 7 | +# |
|
| 8 | +### BEGIN INIT INFO |
|
| 9 | +# Provides: sailing |
|
| 10 | +# Required-Start: $local_fs $network $named $remote_fs |
|
| 11 | +# Should-Start: |
|
| 12 | +# Required-Stop: |
|
| 13 | +# Should-Stop: |
|
| 14 | +# Default-Start: 2 3 4 5 |
|
| 15 | +# Default-Stop: 0 1 6 |
|
| 16 | +# Short-Description: The sailing service |
|
| 17 | +# Description: Start all sailing services required for this instance |
|
| 18 | +### END INIT INFO |
|
| 7 | 19 | |
| 8 | 20 | # Source function library. |
| 9 | 21 | . /etc/init.d/functions |
| ... | ... | @@ -14,8 +26,8 @@ JAVA_START_INSTANCES="server" |
| 14 | 26 | SERVERS_DIR=/home/sailing/servers |
| 15 | 27 | GIT_REPOSITORY=/home/sailing/code |
| 16 | 28 | APACHE_CONFIG_DIR=/etc/httpd/conf.d |
| 17 | -rm /var/log/sailing.out |
|
| 18 | -rm /var/log/sailing.err |
|
| 29 | + |
|
| 30 | +echo "Executing with $1" >>/var/log/sailing.out |
|
| 19 | 31 | |
| 20 | 32 | start_tmux() { |
| 21 | 33 | su - sailing -c "/home/sailing/bin/tmuxConsole.sh unattended" |
| ... | ... | @@ -63,13 +75,21 @@ start_servers() { |
| 63 | 75 | |
| 64 | 76 | stop_servers() { |
| 65 | 77 | for conf in $JAVA_START_INSTANCES; do |
| 66 | - echo "Stopping Java server $conf" |
|
| 78 | + echo "Stopping Java server $conf" >> /var/log/sailing.out |
|
| 67 | 79 | su - sailing -c "cd $SERVERS_DIR/$conf && ./stop" |
| 68 | 80 | RETVAL=$? |
| 69 | 81 | [ $RETVAL -eq 0 ] && success || failure |
| 82 | + stop_httpd |
|
| 83 | + sync_logs |
|
| 70 | 84 | done |
| 71 | 85 | } |
| 72 | 86 | |
| 87 | +sync_logs() { |
|
| 88 | + echo "Executing logrotate followed by a sync to ensure that logs are synchronized" >> /var/log/sailing.out |
|
| 89 | + logrotate -f /etc/logrotate.conf |
|
| 90 | + sync |
|
| 91 | +} |
|
| 92 | + |
|
| 73 | 93 | # launch_httpd(server_name, port, event_id) |
| 74 | 94 | launch_httpd() { |
| 75 | 95 | echo "Will try to launch httpd so this replica can work with an ELB easily." >>/var/log/sailing.out |
| ... | ... | @@ -78,7 +98,7 @@ launch_httpd() { |
| 78 | 98 | source $SERVERS_DIR/$FIRST_SERVER/env.sh |
| 79 | 99 | # Append Apache macro invocation for /internal-server-status based on mod_status and INSTANCE_DNS to $APACHE_CONFIG_DIR/001-events.conf |
| 80 | 100 | echo "Appending macro usage for $INSTANCE_DNS/internal-server-status URL for mod_status based Apache monitoring to $APACHE_CONFIG_DIR/001-events.conf" >>/var/log/sailing.out |
| 81 | - echo "## SERVER STATUS" >>$APACHE_CONFIG_DIR/001-events.conf |
|
| 101 | + echo "## SERVER STATUS" >>$APACHE_CONFIG_DIR/001-events.conf |
|
| 82 | 102 | echo "Use Status $INSTANCE_DNS internal-server-status" >>$APACHE_CONFIG_DIR/001-events.conf |
| 83 | 103 | echo "Launching httpd..." >>/var/log/sailing.out |
| 84 | 104 | service httpd start |
| ... | ... | @@ -87,13 +107,23 @@ launch_httpd() { |
| 87 | 107 | fi |
| 88 | 108 | } |
| 89 | 109 | |
| 110 | +stop_httpd() { |
|
| 111 | + if [ -x /etc/init.d/httpd ]; then |
|
| 112 | + service httpd stop |
|
| 113 | + echo "Stopped httpd..." >>/var/log/sailing.out |
|
| 114 | + fi |
|
| 115 | +} |
|
| 116 | + |
|
| 90 | 117 | # See how we were called. |
| 91 | 118 | case "$1" in |
| 92 | 119 | start) |
| 120 | + /usr/sbin/update-motd |
|
| 93 | 121 | start_servers |
| 122 | + touch /var/lock/subsys/sailing |
|
| 94 | 123 | ;; |
| 95 | 124 | stop) |
| 96 | 125 | stop_servers |
| 126 | + rm -f /var/lock/subsys/sailing |
|
| 97 | 127 | ;; |
| 98 | 128 | status) |
| 99 | 129 | status java |
java/com.sap.sailing.dashboards.gwt/.project
| ... | ... | @@ -21,16 +21,6 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | - <arguments> |
|
| 26 | - </arguments> |
|
| 27 | - </buildCommand> |
|
| 28 | - <buildCommand> |
|
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | - <arguments> |
|
| 31 | - </arguments> |
|
| 32 | - </buildCommand> |
|
| 33 | - <buildCommand> |
|
| 34 | 24 | <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
| 35 | 25 | <arguments> |
| 36 | 26 | </arguments> |
| ... | ... | @@ -44,7 +34,6 @@ |
| 44 | 34 | <natures> |
| 45 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 46 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 47 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 48 | 37 | <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
| 49 | 38 | </natures> |
| 50 | 39 | </projectDescription> |
java/com.sap.sailing.dashboards.gwt/GWT Dashboards DevMode.launch
| ... | ... | @@ -1,103 +1,47 @@ |
| 1 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| 2 | 2 | <launchConfiguration type="com.gwtplugins.gdt.eclipse.suite.webapp"> |
| 3 | -<booleanAttribute key="com.gwtplugins.gdt.eclipse.core.RUN_SERVER" value="false"/> |
|
| 4 | -<stringAttribute key="com.gwtplugins.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/> |
|
| 5 | -<booleanAttribute key="com.gwtplugins.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> |
|
| 6 | -<stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9876"/> |
|
| 7 | -<stringAttribute key="com.gwtplugins.gwt.eclipse.core.URL" value="/security/ui/Login.html"/> |
|
| 8 | -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
|
| 9 | -<listEntry value="/com.sap.sailing.dashboards.gwt"/> |
|
| 10 | -</listAttribute> |
|
| 11 | -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
|
| 12 | -<listEntry value="4"/> |
|
| 13 | -</listAttribute> |
|
| 14 | -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> |
|
| 15 | -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> |
|
| 16 | -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> |
|
| 17 | -</listAttribute> |
|
| 18 | -<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/> |
|
| 19 | -<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/> |
|
| 20 | -<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/> |
|
| 21 | -<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> |
|
| 22 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/> |
|
| 23 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/resources" path="3" type="2"/> "/> |
|
| 24 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/> |
|
| 25 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/> |
|
| 26 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.googlecode.java-diff-utils/src" path="3" type="2"/> "/> |
|
| 27 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.shared.android/src" path="3" type="2"/> "/> |
|
| 28 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/> |
|
| 29 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/> |
|
| 30 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.annotations/src" path="3" type="2"/> "/> |
|
| 31 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/src" path="3" type="2"/> "/> |
|
| 32 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.common/resources" path="3" type="2"/> "/> |
|
| 33 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.shared.android/src" path="3" type="2"/> "/> |
|
| 34 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.json.simple/src" path="3" type="2"/> "/> |
|
| 35 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.geocoding/src" path="3" type="2"/> "/> |
|
| 36 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining.shared/src" path="3" type="2"/> "/> |
|
| 37 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse/src" path="3" type="2"/> "/> |
|
| 38 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/src" path="3" type="2"/> "/> |
|
| 39 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.declination/resources" path="3" type="2"/> "/> |
|
| 40 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/> |
|
| 41 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/resources" path="3" type="2"/> "/> |
|
| 42 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/> |
|
| 43 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.udpconnector/src" path="3" type="2"/> "/> |
|
| 44 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server.gateway.serialization.shared.android/src" path="3" type="2"/> "/> |
|
| 45 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector.common/src" path="3" type="2"/> "/> |
|
| 46 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/> |
|
| 47 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/resources" path="3" type="2"/> "/> |
|
| 48 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.filestorage/src" path="3" type="2"/> "/> |
|
| 49 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.filestorage/resources" path="3" type="2"/> "/> |
|
| 50 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mongodb/src" path="3" type="2"/> "/> |
|
| 51 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.replication/src" path="3" type="2"/> "/> |
|
| 52 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.operationaltransformation/src" path="3" type="2"/> "/> |
|
| 53 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector.persistence/src" path="3" type="2"/> "/> |
|
| 54 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.persistence/src" path="3" type="2"/> "/> |
|
| 55 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server.gateway.serialization/src" path="3" type="2"/> "/> |
|
| 56 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.simulator/src" path="3" type="2"/> "/> |
|
| 57 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.simulator/resources" path="3" type="2"/> "/> |
|
| 58 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter/src" path="3" type="2"/> "/> |
|
| 59 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.tractrac.clientmodule/src" path="3" type="2"/> "/> |
|
| 60 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security/src" path="3" type="2"/> "/> |
|
| 61 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security/resources" path="3" type="2"/> "/> |
|
| 62 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.mail/src" path="3" type="2"/> "/> |
|
| 63 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter/src" path="3" type="2"/> "/> |
|
| 64 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.xrr.resultimport/src" path="3" type="2"/> "/> |
|
| 65 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.resultimport/src" path="3" type="2"/> "/> |
|
| 66 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.competitorimport/src" path="3" type="2"/> "/> |
|
| 67 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.xrr.schema/src" path="3" type="2"/> "/> |
|
| 68 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingadapter.persistence/src" path="3" type="2"/> "/> |
|
| 69 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.tractracadapter.persistence/src" path="3" type="2"/> "/> |
|
| 70 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/> |
|
| 71 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.freg.resultimport/src" path="3" type="2"/> "/> |
|
| 72 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.swisstimingreplayadapter/src" path="3" type="2"/> "/> |
|
| 73 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.igtimiadapter/src" path="3" type="2"/> "/> |
|
| 74 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.igtimiadapter.persistence/src" path="3" type="2"/> "/> |
|
| 75 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.shared/src" path="3" type="2"/> "/> |
|
| 76 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining/src" path="3" type="2"/> "/> |
|
| 77 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining/resources" path="3" type="2"/> "/> |
|
| 78 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining/src" path="3" type="2"/> "/> |
|
| 79 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.datamining/resources" path="3" type="2"/> "/> |
|
| 80 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.datamining.provider/src" path="3" type="2"/> "/> |
|
| 81 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.racelogtrackingadapter/src" path="3" type="2"/> "/> |
|
| 82 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.racelogtrackingadapter/resources" path="3" type="2"/> "/> |
|
| 83 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.manage2sail/src" path="3" type="2"/> "/> |
|
| 84 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.manage2sail/resources" path="3" type="2"/> "/> |
|
| 85 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.xrr.structureimport/src" path="3" type="2"/> "/> |
|
| 86 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/java" path="3" type="2"/> "/> |
|
| 87 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.security.ui/src/main/resources" path="3" type="2"/> "/> |
|
| 88 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/> |
|
| 89 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.news/src" path="3" type="2"/> "/> |
|
| 90 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.polars.datamining.shared/src" path="3" type="2"/> "/> |
|
| 91 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.polars.datamining/src" path="3" type="2"/> "/> |
|
| 92 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.polars.datamining/resources" path="3" type="2"/> "/> |
|
| 93 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.gwt.ui"/> </runtimeClasspathEntry> "/> |
|
| 94 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="com.sap.sse.common" type="1"/> "/> |
|
| 95 | -</listAttribute> |
|
| 96 | -<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/> |
|
| 97 | -<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> |
|
| 98 | -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> |
|
| 99 | -<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -startupUrl /security/ui/Login.html -logLevel INFO -noserver -incremental -workDir "${project_loc:com.sap.sse.security.ui}/.tmp/gwt-work" -war "${project_loc:com.sap.sse.security.ui}" -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -codeServerPort 9876 com.sap.sailing.dashboards.gwt.RibDashboard -startupUrl /dashboards/RibDashboard.html com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 100 | -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/> |
|
| 101 | -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:+UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/> |
|
| 102 | -<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/> |
|
| 3 | + <booleanAttribute key="com.gwtplugins.gdt.eclipse.core.RUN_SERVER" value="false"/> |
|
| 4 | + <stringAttribute key="com.gwtplugins.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/> |
|
| 5 | + <booleanAttribute key="com.gwtplugins.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> |
|
| 6 | + <stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9875"/> |
|
| 7 | + <listAttribute key="com.gwtplugins.gwt.eclipse.core.ENTRY_POINT_MODULES"> |
|
| 8 | + <listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 9 | + </listAttribute> |
|
| 10 | + <stringAttribute key="com.gwtplugins.gwt.eclipse.core.URL" value="/security/ui/Login.html"/> |
|
| 11 | + <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
|
| 12 | + <listEntry value="/com.sap.sailing.dashboards.gwt"/> |
|
| 13 | + </listAttribute> |
|
| 14 | + <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
|
| 15 | + <listEntry value="4"/> |
|
| 16 | + </listAttribute> |
|
| 17 | + <listAttribute key="org.eclipse.debug.ui.favoriteGroups"> |
|
| 18 | + <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> |
|
| 19 | + <listEntry value="org.eclipse.debug.ui.launchGroup.run"/> |
|
| 20 | + </listAttribute> |
|
| 21 | + <booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/> |
|
| 22 | + <booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/> |
|
| 23 | + <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/> |
|
| 24 | + <listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> |
|
| 25 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/> |
|
| 26 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/> |
|
| 27 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/> |
|
| 28 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/java" path="3" type="2"/> "/> |
|
| 29 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/> |
|
| 30 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/> |
|
| 31 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/> |
|
| 32 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/> |
|
| 33 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.dashboards.gwt"/> </runtimeClasspathEntry> "/> |
|
| 34 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/> |
|
| 35 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/> |
|
| 36 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/> |
|
| 37 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/> |
|
| 38 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector.common/src" path="3" type="2"/> "/> |
|
| 39 | + </listAttribute> |
|
| 40 | + <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/> |
|
| 41 | + <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> |
|
| 42 | + <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> |
|
| 43 | + <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -startupUrl /security/ui/Login.html -logLevel INFO -noserver -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -codeServerPort 9875 -startupUrl /dashboards/RibDashboard.html com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 44 | + <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/> |
|
| 45 | + <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:+UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/> |
|
| 46 | + <stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/> |
|
| 103 | 47 | </launchConfiguration> |
java/com.sap.sailing.dashboards.gwt/GWT Dashboards SDM.launch
| ... | ... | @@ -1,46 +1,48 @@ |
| 1 | 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> |
| 2 | 2 | <launchConfiguration type="com.gwtplugins.gdt.eclipse.suite.webapp"> |
| 3 | -<booleanAttribute key="com.gwtplugins.gdt.eclipse.core.RUN_SERVER" value="false"/> |
|
| 4 | -<stringAttribute key="com.gwtplugins.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/> |
|
| 5 | -<booleanAttribute key="com.gwtplugins.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> |
|
| 6 | -<stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9876"/> |
|
| 7 | -<listAttribute key="com.gwtplugins.gwt.eclipse.core.ENTRY_POINT_MODULES"> |
|
| 8 | -<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 9 | -</listAttribute> |
|
| 10 | -<booleanAttribute key="com.gwtplugins.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/> |
|
| 11 | -<stringAttribute key="com.gwtplugins.gwt.eclipse.core.URL" value="/security/ui/Login.html"/> |
|
| 12 | -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
|
| 13 | -<listEntry value="/com.sap.sailing.dashboards.gwt"/> |
|
| 14 | -</listAttribute> |
|
| 15 | -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
|
| 16 | -<listEntry value="4"/> |
|
| 17 | -</listAttribute> |
|
| 18 | -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> |
|
| 19 | -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> |
|
| 20 | -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> |
|
| 21 | -</listAttribute> |
|
| 22 | -<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/> |
|
| 23 | -<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/> |
|
| 24 | -<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/> |
|
| 25 | -<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> |
|
| 26 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/> |
|
| 27 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/> |
|
| 28 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/> |
|
| 29 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/java" path="3" type="2"/> "/> |
|
| 30 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/> |
|
| 31 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/> |
|
| 32 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/> |
|
| 33 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/> |
|
| 34 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.dashboards.gwt"/> </runtimeClasspathEntry> "/> |
|
| 35 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/> |
|
| 36 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/> |
|
| 37 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/> |
|
| 38 | -</listAttribute> |
|
| 39 | -<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/> |
|
| 40 | -<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> |
|
| 41 | -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> |
|
| 42 | -<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-startupUrl /security/ui/Login.html -logLevel INFO -noserver -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -codeServerPort 9876 com.sap.sailing.dashboards.gwt.RibDashboard -startupUrl /dashboards/RibDashboard.html com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 43 | -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/> |
|
| 44 | -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:+UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/> |
|
| 45 | -<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/> |
|
| 3 | + <booleanAttribute key="com.gwtplugins.gdt.eclipse.core.RUN_SERVER" value="false"/> |
|
| 4 | + <stringAttribute key="com.gwtplugins.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/> |
|
| 5 | + <booleanAttribute key="com.gwtplugins.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/> |
|
| 6 | + <stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9875"/> |
|
| 7 | + <listAttribute key="com.gwtplugins.gwt.eclipse.core.ENTRY_POINT_MODULES"> |
|
| 8 | + <listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 9 | + </listAttribute> |
|
| 10 | + <booleanAttribute key="com.gwtplugins.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/> |
|
| 11 | + <stringAttribute key="com.gwtplugins.gwt.eclipse.core.URL" value="/security/ui/Login.html"/> |
|
| 12 | + <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> |
|
| 13 | + <listEntry value="/com.sap.sailing.dashboards.gwt"/> |
|
| 14 | + </listAttribute> |
|
| 15 | + <listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> |
|
| 16 | + <listEntry value="4"/> |
|
| 17 | + </listAttribute> |
|
| 18 | + <listAttribute key="org.eclipse.debug.ui.favoriteGroups"> |
|
| 19 | + <listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> |
|
| 20 | + <listEntry value="org.eclipse.debug.ui.launchGroup.run"/> |
|
| 21 | + </listAttribute> |
|
| 22 | + <booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/> |
|
| 23 | + <booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/> |
|
| 24 | + <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="false"/> |
|
| 25 | + <listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> |
|
| 26 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" javaProject="com.sap.sailing.gwt.ui" path="1" type="4"/> "/> |
|
| 27 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/> |
|
| 28 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src/main/java" path="3" type="2"/> "/> |
|
| 29 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/java" path="3" type="2"/> "/> |
|
| 30 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/> |
|
| 31 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/> |
|
| 32 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/> |
|
| 33 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/> |
|
| 34 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.dashboards.gwt"/> </runtimeClasspathEntry> "/> |
|
| 35 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/> |
|
| 36 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/> |
|
| 37 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/> |
|
| 38 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector/src" path="3" type="2"/> "/> |
|
| 39 | + <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.expeditionconnector.common/src" path="3" type="2"/> "/> |
|
| 40 | + </listAttribute> |
|
| 41 | + <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/> |
|
| 42 | + <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> |
|
| 43 | + <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/> |
|
| 44 | + <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-startupUrl /security/ui/Login.html -logLevel INFO -noserver -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -codeServerPort 9875 -startupUrl /dashboards/RibDashboard.html com.sap.sailing.dashboards.gwt.RibDashboard"/> |
|
| 45 | + <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/> |
|
| 46 | + <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:+UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/> |
|
| 47 | + <stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/> |
|
| 46 | 48 | </launchConfiguration> |
java/com.sap.sailing.datamining.shared/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/impl/components/TestLeaderboardGroupRetrievalProcessor.java
| ... | ... | @@ -15,7 +15,7 @@ import org.junit.Before; |
| 15 | 15 | import org.junit.Ignore; |
| 16 | 16 | import org.junit.Test; |
| 17 | 17 | |
| 18 | -import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext; |
|
| 18 | +import com.sap.sailing.datamining.data.HasLeaderboardGroupContext; |
|
| 19 | 19 | import com.sap.sailing.datamining.test.util.ConcurrencyTestsUtil; |
| 20 | 20 | import com.sap.sailing.datamining.test.util.NullProcessor; |
| 21 | 21 | import com.sap.sailing.domain.leaderboard.Leaderboard; |
| ... | ... | @@ -27,7 +27,7 @@ import com.sap.sse.datamining.components.Processor; |
| 27 | 27 | public class TestLeaderboardGroupRetrievalProcessor { |
| 28 | 28 | |
| 29 | 29 | private RacingEventService service; |
| 30 | - private Processor<RacingEventService, LeaderboardGroupWithContext> retriever; |
|
| 30 | + private Processor<RacingEventService, HasLeaderboardGroupContext> retriever; |
|
| 31 | 31 | |
| 32 | 32 | private Collection<LeaderboardGroup> retrievedGroups; |
| 33 | 33 | |
| ... | ... | @@ -37,14 +37,14 @@ public class TestLeaderboardGroupRetrievalProcessor { |
| 37 | 37 | stub(service.getLeaderboardGroups()).toReturn(getGroupsInService()); |
| 38 | 38 | |
| 39 | 39 | retrievedGroups = new HashSet<>(); |
| 40 | - Processor<LeaderboardGroupWithContext, Void> receiver = new NullProcessor<LeaderboardGroupWithContext, Void>(LeaderboardGroupWithContext.class, Void.class) { |
|
| 40 | + Processor<HasLeaderboardGroupContext, Void> receiver = new NullProcessor<HasLeaderboardGroupContext, Void>(HasLeaderboardGroupContext.class, Void.class) { |
|
| 41 | 41 | @Override |
| 42 | - public void processElement(LeaderboardGroupWithContext element) { |
|
| 42 | + public void processElement(HasLeaderboardGroupContext element) { |
|
| 43 | 43 | retrievedGroups.add(element.getLeaderboardGroup()); |
| 44 | 44 | } |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | - Collection<Processor<LeaderboardGroupWithContext, ?>> resultReceivers = new ArrayList<>(); |
|
| 47 | + Collection<Processor<HasLeaderboardGroupContext, ?>> resultReceivers = new ArrayList<>(); |
|
| 48 | 48 | resultReceivers.add(receiver); |
| 49 | 49 | retriever = new LeaderboardGroupRetrievalProcessor(ConcurrencyTestsUtil.getExecutor(), resultReceivers, 0); |
| 50 | 50 | } |
java/com.sap.sailing.datamining/.project
| ... | ... | @@ -21,18 +21,19 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | - </buildCommand> </buildSpec> |
|
| 32 | + </buildCommand> |
|
| 33 | + </buildSpec> |
|
| 33 | 34 | <natures> |
| 34 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 35 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 36 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | 38 | </natures> |
| 38 | 39 | </projectDescription> |
java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties
| ... | ... | @@ -188,7 +188,7 @@ AbsRelativeBearingToNextMarkAfterManeuver=Abs. relative bearing to the next mark |
| 188 | 188 | RatioBetweenDistanceSailedWithAndWithoutManeuver=Ratio between distance sailed with and without maneuver |
| 189 | 189 | RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver=Ratio between distance sailed toward middle angle projection with and without maneuver |
| 190 | 190 | DurationLostByManeuver=Duration lost by maneuver |
| 191 | -DurationLostByManeuverTowardMiddleAngleProjection=duration lost by maneuver toward middle angle projection |
|
| 191 | +DurationLostByManeuverTowardMiddleAngleProjection=Duration lost by maneuver toward middle angle projection |
|
| 192 | 192 | JibingCount=Jibing count |
| 193 | 193 | TackingCount=Tacking count |
| 194 | 194 | AbsTwaAtMaxTurningRate=Abs. TWA at max. turning rate |
| ... | ... | @@ -198,4 +198,5 @@ PercentageOfMainCurveProgressUntilLowestSpeed=Percentage of main curve progress |
| 198 | 198 | PercentageOfMainCurveProgressUntilHighestSpeed=Percentage of main curve progress until highest speed |
| 199 | 199 | PercentageOfMainCurveProgressUntilMaxTurningRate=Percentage of main curve progress until max. turning rate speed |
| 200 | 200 | AbsTwaAtManeuverMiddle=Abs. TWA at maneuver middle |
| 201 | -GpsSamplingRate=GPS sampling rate |
|
| ... | ... | \ No newline at end of file |
| 0 | +GpsSamplingRate=GPS sampling rate |
|
| 1 | +RaceDuration=Race duration |
|
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties
| ... | ... | @@ -201,4 +201,5 @@ PercentageOfMainCurveProgressUntilHighestSpeed=Prozentualer Fortschritt der Haup |
| 201 | 201 | PercentageOfMainCurveProgressUntilMaxTurningRate=Prozentualer Fortschritt der Hauptkurve bis zum Erreichen von max. Drehrate |
| 202 | 202 | ManeuverTypeForCompleteManeuverCurve=Manövertyp für komplette Manöverkurve |
| 203 | 203 | AbsTwaAtManeuverMiddle=Abs. TWA während Manövermitte |
| 204 | -GpsSamplingRate=GPS-Samplingrate |
|
| ... | ... | \ No newline at end of file |
| 0 | +GpsSamplingRate=GPS-Samplingrate |
|
| 1 | +RaceDuration=Renndauer |
|
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/SailingDataRetrievalChainDefinitions.java
| ... | ... | @@ -5,12 +5,13 @@ import java.util.Collection; |
| 5 | 5 | |
| 6 | 6 | import com.sap.sailing.datamining.data.HasBravoFixContext; |
| 7 | 7 | import com.sap.sailing.datamining.data.HasBravoFixTrackContext; |
| 8 | +import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext; |
|
| 8 | 9 | import com.sap.sailing.datamining.data.HasFoilingSegmentContext; |
| 9 | 10 | import com.sap.sailing.datamining.data.HasGPSFixContext; |
| 10 | 11 | import com.sap.sailing.datamining.data.HasLeaderboardContext; |
| 12 | +import com.sap.sailing.datamining.data.HasLeaderboardGroupContext; |
|
| 11 | 13 | import com.sap.sailing.datamining.data.HasManeuverContext; |
| 12 | 14 | import com.sap.sailing.datamining.data.HasManeuverSpeedDetailsContext; |
| 13 | -import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext; |
|
| 14 | 15 | import com.sap.sailing.datamining.data.HasMarkPassingContext; |
| 15 | 16 | import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext; |
| 16 | 17 | import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext; |
| ... | ... | @@ -22,13 +23,13 @@ import com.sap.sailing.datamining.data.HasWindTrackContext; |
| 22 | 23 | import com.sap.sailing.datamining.impl.components.BravoFixRetrievalProcessor; |
| 23 | 24 | import com.sap.sailing.datamining.impl.components.BravoFixTrackRetrievalProcessor; |
| 24 | 25 | import com.sap.sailing.datamining.impl.components.CompetitorOfRaceInLeaderboardRetrievalProcessor; |
| 26 | +import com.sap.sailing.datamining.impl.components.CompleteManeuverCurveWithEstimationDataRetrievalProcessor; |
|
| 25 | 27 | import com.sap.sailing.datamining.impl.components.FoilingSegmentRetrievalProcessor; |
| 26 | 28 | import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor; |
| 27 | 29 | import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProcessor; |
| 28 | 30 | import com.sap.sailing.datamining.impl.components.LeaderboardRetrievalProcessor; |
| 29 | 31 | import com.sap.sailing.datamining.impl.components.ManeuverRetrievalProcessor; |
| 30 | 32 | import com.sap.sailing.datamining.impl.components.ManeuverSpeedDetailsRetrievalProcessor; |
| 31 | -import com.sap.sailing.datamining.impl.components.CompleteManeuverCurveWithEstimationDataRetrievalProcessor; |
|
| 32 | 33 | import com.sap.sailing.datamining.impl.components.MarkPassingRetrievalProcessor; |
| 33 | 34 | import com.sap.sailing.datamining.impl.components.RaceOfCompetitorRetrievalProcessor; |
| 34 | 35 | import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor; |
| ... | ... | @@ -36,7 +37,6 @@ import com.sap.sailing.datamining.impl.components.TrackedLegRetrievalProcessor; |
| 36 | 37 | import com.sap.sailing.datamining.impl.components.TrackedRaceRetrievalProcessor; |
| 37 | 38 | import com.sap.sailing.datamining.impl.components.WindFixRetrievalProcessor; |
| 38 | 39 | import com.sap.sailing.datamining.impl.components.WindTrackRetrievalProcessor; |
| 39 | -import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext; |
|
| 40 | 40 | import com.sap.sailing.datamining.shared.FoilingSegmentsDataMiningSettings; |
| 41 | 41 | import com.sap.sailing.datamining.shared.ManeuverSettings; |
| 42 | 42 | import com.sap.sailing.datamining.shared.ManeuverSettingsImpl; |
| ... | ... | @@ -55,7 +55,7 @@ public class SailingDataRetrievalChainDefinitions { |
| 55 | 55 | |
| 56 | 56 | final DataRetrieverChainDefinition<RacingEventService, HasLeaderboardContext> leaderboardRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>( |
| 57 | 57 | RacingEventService.class, HasLeaderboardContext.class, "LeaderboardSailingDomainRetrieverChain"); |
| 58 | - leaderboardRetrieverChainDefinition.startWith(LeaderboardGroupRetrievalProcessor.class, LeaderboardGroupWithContext.class, "LeaderboardGroup"); |
|
| 58 | + leaderboardRetrieverChainDefinition.startWith(LeaderboardGroupRetrievalProcessor.class, HasLeaderboardGroupContext.class, "LeaderboardGroup"); |
|
| 59 | 59 | leaderboardRetrieverChainDefinition.endWith(LeaderboardGroupRetrievalProcessor.class, LeaderboardRetrievalProcessor.class, |
| 60 | 60 | HasLeaderboardContext.class, "Leaderboard"); |
| 61 | 61 |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasBravoFixContext.java
| ... | ... | @@ -16,7 +16,7 @@ public interface HasBravoFixContext { |
| 16 | 16 | @Connector(ordinal=1) |
| 17 | 17 | BravoFix getBravoFix(); |
| 18 | 18 | |
| 19 | - @Connector(messageKey="Speed") |
|
| 19 | + @Connector(messageKey="") |
|
| 20 | 20 | SpeedWithBearing getSpeed(); |
| 21 | 21 | |
| 22 | 22 | @Connector(messageKey="Wind") |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasLeaderboardContext.java
| ... | ... | @@ -2,7 +2,6 @@ package com.sap.sailing.datamining.data; |
| 2 | 2 | |
| 3 | 3 | import com.sap.sailing.domain.base.BoatClass; |
| 4 | 4 | import com.sap.sailing.domain.leaderboard.Leaderboard; |
| 5 | -import com.sap.sailing.domain.polars.PolarDataService; |
|
| 6 | 5 | import com.sap.sse.datamining.annotations.Connector; |
| 7 | 6 | import com.sap.sse.datamining.annotations.Dimension; |
| 8 | 7 | |
| ... | ... | @@ -12,8 +11,6 @@ public interface HasLeaderboardContext { |
| 12 | 11 | |
| 13 | 12 | Leaderboard getLeaderboard(); |
| 14 | 13 | |
| 15 | - PolarDataService getPolarDataService(); |
|
| 16 | - |
|
| 17 | 14 | @Dimension(messageKey="Leaderboard", ordinal=1) |
| 18 | 15 | String getName(); |
| 19 | 16 |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasRaceOfCompetitorContext.java
| ... | ... | @@ -4,6 +4,7 @@ import com.sap.sailing.domain.base.Competitor; |
| 4 | 4 | import com.sap.sailing.domain.common.NoWindException; |
| 5 | 5 | import com.sap.sailing.domain.common.Tack; |
| 6 | 6 | import com.sap.sse.common.Distance; |
| 7 | +import com.sap.sse.common.Duration; |
|
| 7 | 8 | import com.sap.sse.common.Util.Pair; |
| 8 | 9 | import com.sap.sse.common.Speed; |
| 9 | 10 | import com.sap.sse.datamining.annotations.Connector; |
| ... | ... | @@ -14,74 +15,74 @@ import com.sap.sse.datamining.shared.impl.dto.ClusterDTO; |
| 14 | 15 | public interface HasRaceOfCompetitorContext { |
| 15 | 16 | |
| 16 | 17 | @Connector(scanForStatistics=false) |
| 17 | - public HasTrackedRaceContext getTrackedRaceContext(); |
|
| 18 | + HasTrackedRaceContext getTrackedRaceContext(); |
|
| 18 | 19 | |
| 19 | 20 | @Connector(messageKey="Competitor") |
| 20 | - @Statistic(messageKey="") |
|
| 21 | - public Competitor getCompetitor(); |
|
| 21 | + @Statistic(messageKey="Competitor") |
|
| 22 | + Competitor getCompetitor(); |
|
| 22 | 23 | |
| 23 | 24 | @Dimension(messageKey="TackAtStart", ordinal=12) |
| 24 | - public Tack getTackAtStart() throws NoWindException; |
|
| 25 | + Tack getTackAtStart() throws NoWindException; |
|
| 25 | 26 | |
| 26 | 27 | @Dimension(messageKey="DistanceToStarboardSideAtStartOfCompetitor", ordinal=13) |
| 27 | - public ClusterDTO getPercentageClusterForDistanceToStarboardSideAtStart(); |
|
| 28 | + ClusterDTO getPercentageClusterForDistanceToStarboardSideAtStart(); |
|
| 28 | 29 | |
| 29 | 30 | @Dimension(messageKey="RelativeScoreInPercent", ordinal=14) |
| 30 | - public ClusterDTO getPercentageClusterForRelativeScore(); |
|
| 31 | + ClusterDTO getPercentageClusterForRelativeScore(); |
|
| 31 | 32 | |
| 32 | 33 | @Statistic(messageKey="DistanceAtStart", resultDecimals=2, ordinal=0) |
| 33 | - public Distance getDistanceToStartLineAtStart(); |
|
| 34 | + Distance getDistanceToStartLineAtStart(); |
|
| 34 | 35 | |
| 35 | 36 | @Statistic(messageKey="DistanceToStarboardSideAtStartOfCompetitor", resultDecimals=2, ordinal=1) |
| 36 | - public Double getNormalizedDistanceToStarboardSideAtStartOfCompetitor(); |
|
| 37 | + Double getNormalizedDistanceToStarboardSideAtStartOfCompetitor(); |
|
| 37 | 38 | |
| 38 | 39 | @Statistic(messageKey="DistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark", resultDecimals=2, ordinal=1) |
| 39 | - public Pair<Double, Double> getNormalizedDistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark(); |
|
| 40 | + Pair<Double, Double> getNormalizedDistanceToStarboardSideAtStartOfCompetitorVsRankAtFirstMark(); |
|
| 40 | 41 | |
| 41 | 42 | @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineAtStartOfRace", resultDecimals=2, ordinal=2) |
| 42 | - public Distance getWindwardDistanceToAdvantageousLineEndAtStartofRace(); |
|
| 43 | + Distance getWindwardDistanceToAdvantageousLineEndAtStartofRace(); |
|
| 43 | 44 | |
| 44 | 45 | @Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLineAtStartOfCompetitor", resultDecimals=2, ordinal=2) |
| 45 | - public Distance getWindwardDistanceToAdvantageousLineEndAtStartofCompetitor(); |
|
| 46 | + Distance getWindwardDistanceToAdvantageousLineEndAtStartofCompetitor(); |
|
| 46 | 47 | |
| 47 | 48 | @Connector(messageKey="SpeedWhenStarting", ordinal=3) |
| 48 | - public Speed getSpeedWhenStarting(); |
|
| 49 | + Speed getSpeedWhenStarting(); |
|
| 49 | 50 | |
| 50 | 51 | @Connector(messageKey="SpeedTenSecondsBeforeStart", ordinal=4) |
| 51 | - public Speed getSpeedTenSecondsBeforeStart(); |
|
| 52 | + Speed getSpeedTenSecondsBeforeStart(); |
|
| 52 | 53 | |
| 53 | 54 | @Connector(messageKey="SpeedTenSecondsAfterStart", ordinal=5) |
| 54 | - public Speed getSpeedTenSecondsAfterStartOfRace(); |
|
| 55 | + Speed getSpeedTenSecondsAfterStartOfRace(); |
|
| 55 | 56 | |
| 56 | 57 | @Statistic(messageKey="RankThirtySecondsAfterStart", resultDecimals=2, ordinal=6) |
| 57 | - public Double getRankThirtySecondsAfterStartOfRace(); |
|
| 58 | + Double getRankThirtySecondsAfterStartOfRace(); |
|
| 58 | 59 | |
| 59 | 60 | @Statistic(messageKey="RankAfterHalfOfTheFirstLeg", resultDecimals=2, ordinal=7) |
| 60 | - public Double getRankAfterHalfOfTheFirstLeg(); |
|
| 61 | + Double getRankAfterHalfOfTheFirstLeg(); |
|
| 61 | 62 | |
| 62 | 63 | @Statistic(messageKey="RankAtFirstMark", resultDecimals=2, ordinal=8) |
| 63 | - public Double getRankAtFirstMark(); |
|
| 64 | + Double getRankAtFirstMark(); |
|
| 64 | 65 | |
| 65 | 66 | @Statistic(messageKey="RankGainsOrLossesBetweenFirstMarkAndFinish", resultDecimals=2, ordinal=9) |
| 66 | - public Double getRankGainsOrLossesBetweenFirstMarkAndFinish(); |
|
| 67 | + Double getRankGainsOrLossesBetweenFirstMarkAndFinish(); |
|
| 67 | 68 | |
| 68 | 69 | @Statistic(messageKey="NumberOfManeuvers", resultDecimals=0, ordinal=10) |
| 69 | - public int getNumberOfManeuvers(); |
|
| 70 | + int getNumberOfManeuvers(); |
|
| 70 | 71 | |
| 71 | 72 | @Statistic(messageKey="NumberOfTacks", resultDecimals=0, ordinal=11) |
| 72 | - public int getNumberOfTacks(); |
|
| 73 | + int getNumberOfTacks(); |
|
| 73 | 74 | |
| 74 | 75 | @Statistic(messageKey="NumberOfJibes", resultDecimals=0, ordinal=12) |
| 75 | - public int getNumberOfJibes(); |
|
| 76 | + int getNumberOfJibes(); |
|
| 76 | 77 | |
| 77 | 78 | @Statistic(messageKey="NumberOfPenaltyCircles", resultDecimals=0, ordinal=13) |
| 78 | - public int getNumberOfPenaltyCircles(); |
|
| 79 | + int getNumberOfPenaltyCircles(); |
|
| 79 | 80 | |
| 80 | 81 | @Statistic(messageKey="DistanceTraveled", resultDecimals=1) |
| 81 | - public Distance getDistanceTraveled(); |
|
| 82 | + Distance getDistanceTraveled(); |
|
| 82 | 83 | |
| 83 | 84 | @Statistic(messageKey="LineLengthAtStart", resultDecimals=1) |
| 84 | - public Distance getLineLengthAtStart(); |
|
| 85 | + Distance getLineLengthAtStart(); |
|
| 85 | 86 | |
| 86 | 87 | @Statistic(messageKey="AbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor", resultDecimals=2) |
| 87 | 88 | Distance getAbsoluteWindwardDistanceToStarboardSideAtStartOfCompetitor(); |
| ... | ... | @@ -94,4 +95,8 @@ public interface HasRaceOfCompetitorContext { |
| 94 | 95 | |
| 95 | 96 | @Statistic(messageKey="RelativeDistanceToAdvantageousEndOfLineAtStartOfRace", resultDecimals=2) |
| 96 | 97 | Double getRelativeDistanceToAdvantageousEndOfLineAtStartOfRace(); |
| 98 | + |
|
| 99 | + @Statistic(messageKey="RaceDuration") |
|
| 100 | + Duration getDuration(); |
|
| 101 | + |
|
| 97 | 102 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasTrackedRaceContext.java
| ... | ... | @@ -8,6 +8,7 @@ import com.sap.sailing.domain.base.RaceDefinition; |
| 8 | 8 | import com.sap.sailing.domain.base.Regatta; |
| 9 | 9 | import com.sap.sailing.domain.common.NauticalSide; |
| 10 | 10 | import com.sap.sailing.domain.tracking.TrackedRace; |
| 11 | +import com.sap.sse.common.Duration; |
|
| 11 | 12 | import com.sap.sse.datamining.annotations.Connector; |
| 12 | 13 | import com.sap.sse.datamining.annotations.Dimension; |
| 13 | 14 | import com.sap.sse.datamining.annotations.Statistic; |
| ... | ... | @@ -46,10 +47,13 @@ public interface HasTrackedRaceContext { |
| 46 | 47 | @Dimension(messageKey="IsTracked", ordinal=9) |
| 47 | 48 | public Boolean isTracked(); |
| 48 | 49 | |
| 49 | - @Statistic(messageKey="NumberOfCompetitorFixes", resultDecimals=0, ordinal=0) |
|
| 50 | + @Statistic(messageKey="RaceDuration", ordinal=0) |
|
| 51 | + public Duration getDuration(); |
|
| 52 | + |
|
| 53 | + @Statistic(messageKey="NumberOfCompetitorFixes", resultDecimals=0, ordinal=1) |
|
| 50 | 54 | public int getNumberOfCompetitorFixes(); |
| 51 | 55 | |
| 52 | - @Statistic(messageKey="NumberOfMarkFixes", resultDecimals=0, ordinal=1) |
|
| 56 | + @Statistic(messageKey="NumberOfMarkFixes", resultDecimals=0, ordinal=2) |
|
| 53 | 57 | public int getNumberOfMarkFixes(); |
| 54 | 58 | |
| 55 | 59 | // Convenience methods for race dependent calculation to avoid code duplication |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/data/HasWindFixContext.java
| ... | ... | @@ -11,7 +11,7 @@ public interface HasWindFixContext extends HasWind { |
| 11 | 11 | @Connector(scanForStatistics=false) |
| 12 | 12 | public HasTrackedRaceContext getTrackedRaceContext(); |
| 13 | 13 | |
| 14 | - @Statistic(messageKey="", ordinal=0) |
|
| 14 | + @Statistic(messageKey="WindFix", ordinal=0) |
|
| 15 | 15 | public Wind getWind(); |
| 16 | 16 | |
| 17 | 17 | @Statistic(messageKey="windFrom", resultDecimals=1, ordinal=1) |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/BravoFixRetrievalProcessor.java
| ... | ... | @@ -24,21 +24,24 @@ public class BravoFixRetrievalProcessor extends AbstractRetrievalProcessor<HasTr |
| 24 | 24 | @Override |
| 25 | 25 | protected Iterable<HasBravoFixContext> retrieveData(HasTrackedLegOfCompetitorContext element) { |
| 26 | 26 | Collection<HasBravoFixContext> bravoFixesWithContext = new ArrayList<>(); |
| 27 | - BravoFixTrack<Competitor> bravoFixTrack = element.getTrackedLegContext().getTrackedRaceContext().getTrackedRace().getSensorTrack(element.getCompetitor(), BravoFixTrack.TRACK_NAME); |
|
| 28 | - if (bravoFixTrack != null) { |
|
| 29 | - bravoFixTrack.lockForRead(); |
|
| 30 | - try { |
|
| 31 | - TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor(); |
|
| 32 | - if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) { |
|
| 27 | + TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor(); |
|
| 28 | + if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) { |
|
| 29 | + BravoFixTrack<Competitor> bravoFixTrack = element.getTrackedLegContext().getTrackedRaceContext().getTrackedRace().getSensorTrack(element.getCompetitor(), BravoFixTrack.TRACK_NAME); |
|
| 30 | + if (bravoFixTrack != null) { |
|
| 31 | + bravoFixTrack.lockForRead(); |
|
| 32 | + try { |
|
| 33 | 33 | for (BravoFix bravoFix : bravoFixTrack.getFixes(trackedLegOfCompetitor.getStartTime(), true, trackedLegOfCompetitor.getFinishTime(), true)) { |
| 34 | + if (isAborted()) { |
|
| 35 | + break; |
|
| 36 | + } |
|
| 34 | 37 | BravoFixWithContext gpsFixWithContext = new BravoFixWithContext( |
| 35 | 38 | new TrackedLegOfCompetitorWithSpecificTimePointWithContext( |
| 36 | 39 | element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), bravoFix.getTimePoint()), bravoFix); |
| 37 | 40 | bravoFixesWithContext.add(gpsFixWithContext); |
| 38 | 41 | } |
| 42 | + } finally { |
|
| 43 | + bravoFixTrack.unlockAfterRead(); |
|
| 39 | 44 | } |
| 40 | - } finally { |
|
| 41 | - bravoFixTrack.unlockAfterRead(); |
|
| 42 | 45 | } |
| 43 | 46 | } |
| 44 | 47 | return bravoFixesWithContext; |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/BravoFixTrackRetrievalProcessor.java
| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | package com.sap.sailing.datamining.impl.components; |
| 2 | 2 | |
| 3 | -import java.util.ArrayList; |
|
| 4 | 3 | import java.util.Collection; |
| 4 | +import java.util.Collections; |
|
| 5 | 5 | import java.util.concurrent.ExecutorService; |
| 6 | 6 | |
| 7 | 7 | import com.sap.sailing.datamining.data.HasBravoFixTrackContext; |
| ... | ... | @@ -28,13 +28,9 @@ public class BravoFixTrackRetrievalProcessor extends AbstractRetrievalProcessor< |
| 28 | 28 | |
| 29 | 29 | @Override |
| 30 | 30 | protected Iterable<HasBravoFixTrackContext> retrieveData(HasRaceOfCompetitorContext element) { |
| 31 | - Collection<HasBravoFixTrackContext> bravoTracksWithContext = new ArrayList<>(); |
|
| 32 | 31 | final TrackedRace trackedRace = element.getTrackedRaceContext().getTrackedRace(); |
| 33 | 32 | final BravoFixTrack<Competitor> bravoFixTrack = trackedRace.getSensorTrack(element.getCompetitor(), BravoFixTrack.TRACK_NAME); |
| 34 | - if (bravoFixTrack != null) { |
|
| 35 | - bravoTracksWithContext.add(new BravoFixTrackWithContext(element, bravoFixTrack)); |
|
| 36 | - } |
|
| 37 | - return bravoTracksWithContext; |
|
| 33 | + return bravoFixTrack == null ? Collections.emptySet() : Collections.singleton(new BravoFixTrackWithContext(element, bravoFixTrack)); |
|
| 38 | 34 | } |
| 39 | 35 | |
| 40 | 36 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/CompetitorOfRaceInLeaderboardRetrievalProcessor.java
| ... | ... | @@ -24,9 +24,15 @@ public class CompetitorOfRaceInLeaderboardRetrievalProcessor extends |
| 24 | 24 | protected Iterable<HasRaceResultOfCompetitorContext> retrieveData(HasLeaderboardContext element) { |
| 25 | 25 | Collection<HasRaceResultOfCompetitorContext> raceResultsOfCompetitor = new ArrayList<>(); |
| 26 | 26 | for (RaceColumn raceColumn : element.getLeaderboard().getRaceColumns()) { |
| 27 | + if (isAborted()) { |
|
| 28 | + break; |
|
| 29 | + } |
|
| 27 | 30 | for (Competitor competitor : element.getLeaderboard().getCompetitors()) { |
| 31 | + if (isAborted()) { |
|
| 32 | + break; |
|
| 33 | + } |
|
| 28 | 34 | HasRaceResultOfCompetitorContext raceResultOfCompetitorContext = new RaceResultOfCompetitorWithContext(element, raceColumn, competitor, |
| 29 | - element.getPolarDataService()); |
|
| 35 | + element.getLeaderboardGroupContext().getPolarDataService()); |
|
| 30 | 36 | raceResultsOfCompetitor.add(raceResultOfCompetitorContext); |
| 31 | 37 | } |
| 32 | 38 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/CompleteManeuverCurveWithEstimationDataRetrievalProcessor.java
| ... | ... | @@ -48,15 +48,27 @@ public class CompleteManeuverCurveWithEstimationDataRetrievalProcessor extends |
| 48 | 48 | Competitor competitor = element.getCompetitor(); |
| 49 | 49 | ManeuverDetectorWithEstimationDataSupport maneuverDetector = new ManeuverDetectorWithEstimationDataSupportDecoratorImpl( |
| 50 | 50 | new ManeuverDetectorImpl(trackedRace, competitor), |
| 51 | - element.getTrackedRaceContext().getLeaderboardContext().getPolarDataService()); |
|
| 51 | + element.getTrackedRaceContext().getLeaderboardContext().getLeaderboardGroupContext().getPolarDataService()); |
|
| 52 | + |
|
| 52 | 53 | Iterable<Maneuver> maneuvers = trackedRace.getManeuvers(competitor, false); |
| 54 | + if (isAborted()) { |
|
| 55 | + return result; |
|
| 56 | + } |
|
| 57 | + |
|
| 53 | 58 | Iterable<CompleteManeuverCurve> maneuverCurves = maneuverDetector.getCompleteManeuverCurves(maneuvers); |
| 59 | + if (isAborted()) { |
|
| 60 | + return result; |
|
| 61 | + } |
|
| 62 | + |
|
| 54 | 63 | Iterable<CompleteManeuverCurveWithEstimationData> maneuversWithEstimationData = maneuverDetector |
| 55 | 64 | .getCompleteManeuverCurvesWithEstimationData(maneuverCurves); |
| 56 | - |
|
| 57 | 65 | CompleteManeuverCurveWithEstimationData previousManeuver = null; |
| 58 | 66 | CompleteManeuverCurveWithEstimationData currentManeuver = null; |
| 59 | 67 | for (CompleteManeuverCurveWithEstimationData nextManeuver : maneuversWithEstimationData) { |
| 68 | + if (isAborted()) { |
|
| 69 | + break; |
|
| 70 | + } |
|
| 71 | + |
|
| 60 | 72 | if (currentManeuver != null) { |
| 61 | 73 | CompleteManeuverCurveWithEstimationDataWithContext maneuverWithContext = new CompleteManeuverCurveWithEstimationDataWithContext( |
| 62 | 74 | element, currentManeuver, settings, previousManeuver, nextManeuver); |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/FoilingSegmentRetrievalProcessor.java
| ... | ... | @@ -50,6 +50,9 @@ public class FoilingSegmentRetrievalProcessor extends AbstractRetrievalProcessor |
| 50 | 50 | bravoFixTrack.lockForRead(); |
| 51 | 51 | try { |
| 52 | 52 | for (final BravoFix bravoFix : bravoFixTrack.getFixes(startOfRace, /* fromInclusive */ true, end, /* toInclusive */ false)) { |
| 53 | + if (isAborted()) { |
|
| 54 | + break; |
|
| 55 | + } |
|
| 53 | 56 | final boolean currentFixIsFoiling = |
| 54 | 57 | (bravoFix.isFoiling(settings.getMinimumRideHeight()) && |
| 55 | 58 | (settings.getMinimumSpeedForFoiling() == null || settings.getMinimumSpeedForFoiling().compareTo( |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/GPSFixRetrievalProcessor.java
| ... | ... | @@ -30,6 +30,9 @@ public class GPSFixRetrievalProcessor extends AbstractRetrievalProcessor<HasTrac |
| 30 | 30 | TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor(); |
| 31 | 31 | if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) { |
| 32 | 32 | for (GPSFixMoving gpsFix : competitorTrack.getFixes(trackedLegOfCompetitor.getStartTime(), true, trackedLegOfCompetitor.getFinishTime(), true)) { |
| 33 | + if (isAborted()) { |
|
| 34 | + break; |
|
| 35 | + } |
|
| 33 | 36 | HasGPSFixContext gpsFixWithContext = new GPSFixWithContext(new TrackedLegOfCompetitorWithSpecificTimePointWithContext( |
| 34 | 37 | element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), gpsFix.getTimePoint()), gpsFix); |
| 35 | 38 | gpsFixesWithContext.add(gpsFixWithContext); |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java
| ... | ... | @@ -1,30 +1,36 @@ |
| 1 | 1 | package com.sap.sailing.datamining.impl.components; |
| 2 | 2 | |
| 3 | 3 | import java.util.Collection; |
| 4 | +import java.util.HashSet; |
|
| 5 | +import java.util.Set; |
|
| 4 | 6 | import java.util.concurrent.ExecutorService; |
| 5 | -import java.util.stream.Collectors; |
|
| 6 | 7 | |
| 8 | +import com.sap.sailing.datamining.data.HasLeaderboardGroupContext; |
|
| 7 | 9 | import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext; |
| 10 | +import com.sap.sailing.domain.leaderboard.LeaderboardGroup; |
|
| 8 | 11 | import com.sap.sailing.domain.polars.PolarDataService; |
| 9 | 12 | import com.sap.sailing.server.RacingEventService; |
| 10 | 13 | import com.sap.sse.datamining.components.Processor; |
| 11 | 14 | import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor; |
| 12 | 15 | |
| 13 | -public class LeaderboardGroupRetrievalProcessor extends AbstractRetrievalProcessor<RacingEventService, LeaderboardGroupWithContext> { |
|
| 16 | +public class LeaderboardGroupRetrievalProcessor extends AbstractRetrievalProcessor<RacingEventService, HasLeaderboardGroupContext> { |
|
| 14 | 17 | |
| 15 | 18 | public LeaderboardGroupRetrievalProcessor(ExecutorService executor, |
| 16 | - Collection<Processor<LeaderboardGroupWithContext, ?>> resultReceivers, int retrievalLevel) { |
|
| 17 | - super(RacingEventService.class, LeaderboardGroupWithContext.class, executor, resultReceivers, retrievalLevel); |
|
| 19 | + Collection<Processor<HasLeaderboardGroupContext, ?>> resultReceivers, int retrievalLevel) { |
|
| 20 | + super(RacingEventService.class, HasLeaderboardGroupContext.class, executor, resultReceivers, retrievalLevel); |
|
| 18 | 21 | } |
| 19 | 22 | |
| 20 | 23 | @Override |
| 21 | - protected Iterable<LeaderboardGroupWithContext> retrieveData(RacingEventService element) { |
|
| 22 | - final PolarDataService polarDataService = element.getPolarDataService(); |
|
| 23 | - return element.getLeaderboardGroups() |
|
| 24 | - .values() |
|
| 25 | - .stream() |
|
| 26 | - .map(lg -> new LeaderboardGroupWithContext(lg, polarDataService)) |
|
| 27 | - .collect(Collectors.toSet()); |
|
| 24 | + protected Iterable<HasLeaderboardGroupContext> retrieveData(RacingEventService element) { |
|
| 25 | + Set<HasLeaderboardGroupContext> data = new HashSet<>(); |
|
| 26 | + PolarDataService polarDataService = element.getPolarDataService(); |
|
| 27 | + for (LeaderboardGroup leaderboardGroup : element.getLeaderboardGroups().values()) { |
|
| 28 | + if (isAborted()) { |
|
| 29 | + break; |
|
| 30 | + } |
|
| 31 | + data.add(new LeaderboardGroupWithContext(leaderboardGroup, polarDataService)); |
|
| 32 | + } |
|
| 33 | + return data; |
|
| 28 | 34 | } |
| 29 | 35 | |
| 30 | 36 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardRetrievalProcessor.java
| ... | ... | @@ -5,24 +5,27 @@ import java.util.Collection; |
| 5 | 5 | import java.util.concurrent.ExecutorService; |
| 6 | 6 | |
| 7 | 7 | import com.sap.sailing.datamining.data.HasLeaderboardContext; |
| 8 | -import com.sap.sailing.datamining.impl.data.LeaderboardGroupWithContext; |
|
| 8 | +import com.sap.sailing.datamining.data.HasLeaderboardGroupContext; |
|
| 9 | 9 | import com.sap.sailing.datamining.impl.data.LeaderboardWithContext; |
| 10 | 10 | import com.sap.sailing.domain.leaderboard.Leaderboard; |
| 11 | 11 | import com.sap.sse.datamining.components.Processor; |
| 12 | 12 | import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor; |
| 13 | 13 | |
| 14 | -public class LeaderboardRetrievalProcessor extends AbstractRetrievalProcessor<LeaderboardGroupWithContext, HasLeaderboardContext> { |
|
| 14 | +public class LeaderboardRetrievalProcessor extends AbstractRetrievalProcessor<HasLeaderboardGroupContext, HasLeaderboardContext> { |
|
| 15 | 15 | |
| 16 | 16 | public LeaderboardRetrievalProcessor(ExecutorService executor, |
| 17 | 17 | Collection<Processor<HasLeaderboardContext, ?>> resultReceivers, int retrievalLevel) { |
| 18 | - super(LeaderboardGroupWithContext.class, HasLeaderboardContext.class, executor, resultReceivers, retrievalLevel); |
|
| 18 | + super(HasLeaderboardGroupContext.class, HasLeaderboardContext.class, executor, resultReceivers, retrievalLevel); |
|
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | @Override |
| 22 | - protected Iterable<HasLeaderboardContext> retrieveData(LeaderboardGroupWithContext element) { |
|
| 22 | + protected Iterable<HasLeaderboardContext> retrieveData(HasLeaderboardGroupContext element) { |
|
| 23 | 23 | Collection<HasLeaderboardContext> leaderboardsWithContext = new ArrayList<>(); |
| 24 | 24 | for (Leaderboard leaderboard : element.getLeaderboardGroup().getLeaderboards()) { |
| 25 | - leaderboardsWithContext.add(new LeaderboardWithContext(leaderboard, element, element.getPolarDataService())); |
|
| 25 | + if (isAborted()) { |
|
| 26 | + break; |
|
| 27 | + } |
|
| 28 | + leaderboardsWithContext.add(new LeaderboardWithContext(leaderboard, element)); |
|
| 26 | 29 | } |
| 27 | 30 | return leaderboardsWithContext; |
| 28 | 31 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/ManeuverRetrievalProcessor.java
| ... | ... | @@ -48,6 +48,10 @@ public class ManeuverRetrievalProcessor |
| 48 | 48 | Maneuver previousManeuver = null; |
| 49 | 49 | Maneuver currentManeuver = null; |
| 50 | 50 | for (Maneuver nextManeuver : maneuvers) { |
| 51 | + if (isAborted()) { |
|
| 52 | + break; |
|
| 53 | + } |
|
| 54 | + |
|
| 51 | 55 | if (currentManeuver != null) { |
| 52 | 56 | ManeuverWithContext maneuverWithContext = new ManeuverWithContext(new TrackedLegOfCompetitorWithSpecificTimePointWithContext( |
| 53 | 57 | element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), currentManeuver.getTimePoint()), currentManeuver, |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/ManeuverSpeedDetailsRetrievalProcessor.java
| ... | ... | @@ -87,6 +87,10 @@ public class ManeuverSpeedDetailsRetrievalProcessor |
| 87 | 87 | |
| 88 | 88 | double directionChangeForAnalysisSignum = Math.signum(directionChangeInDegreesForAnalysis); |
| 89 | 89 | for (SpeedWithBearingStep bearingStep : maneuverBearingSteps) { |
| 90 | + if (isAborted()) { |
|
| 91 | + break; |
|
| 92 | + } |
|
| 93 | + |
|
| 90 | 94 | currentDirectionChangeSumInDegrees += bearingStep.getCourseChangeInDegrees(); |
| 91 | 95 | if (previousRoundedTWA != -1 |
| 92 | 96 | && Math.signum(currentDirectionChangeSumInDegrees) != directionChangeForAnalysisSignum |
| ... | ... | @@ -123,6 +127,9 @@ public class ManeuverSpeedDetailsRetrievalProcessor |
| 123 | 127 | for (int step = 1, fillingTWA = twaIterationFunction |
| 124 | 128 | .apply(previousRoundedTWA); fillingTWA != roundedTWA; fillingTWA = twaIterationFunction |
| 125 | 129 | .apply(fillingTWA), ++step) { |
| 130 | + if (isAborted()) { |
|
| 131 | + break; |
|
| 132 | + } |
|
| 126 | 133 | if (speedPerTWA[fillingTWA] == 0) { |
| 127 | 134 | speedPerTWA[fillingTWA] = previousSpeed |
| 128 | 135 | + diffWithPreviousSpeed * step / diffWithPreviousTWA; |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java
| ... | ... | @@ -29,6 +29,9 @@ public class MarkPassingRetrievalProcessor extends AbstractRetrievalProcessor<Ha |
| 29 | 29 | try { |
| 30 | 30 | Iterable<Maneuver> maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false); |
| 31 | 31 | for (Maneuver maneuver : maneuvers) { |
| 32 | + if (isAborted()) { |
|
| 33 | + break; |
|
| 34 | + } |
|
| 32 | 35 | if (maneuver.isMarkPassing()) { |
| 33 | 36 | maneuversWithContext.add(new MarkPassingWithContext(new TrackedLegOfCompetitorWithSpecificTimePointWithContext( |
| 34 | 37 | element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), maneuver.getTimePoint()), maneuver)); |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/RaceOfCompetitorRetrievalProcessor.java
| ... | ... | @@ -22,6 +22,9 @@ public class RaceOfCompetitorRetrievalProcessor extends AbstractRetrievalProcess |
| 22 | 22 | protected Iterable<HasRaceOfCompetitorContext> retrieveData(HasTrackedRaceContext element) { |
| 23 | 23 | Collection<HasRaceOfCompetitorContext> raceOfCompetitorsWithContext = new ArrayList<>(); |
| 24 | 24 | for (Competitor competitor : element.getTrackedRace().getRace().getCompetitors()) { |
| 25 | + if (isAborted()) { |
|
| 26 | + break; |
|
| 27 | + } |
|
| 25 | 28 | HasRaceOfCompetitorContext raceOfCompetitorWithContext = new RaceOfCompetitorWithContext(element, competitor); |
| 26 | 29 | raceOfCompetitorsWithContext.add(raceOfCompetitorWithContext); |
| 27 | 30 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegOfCompetitorRetrievalProcessor.java
| ... | ... | @@ -22,6 +22,9 @@ public class TrackedLegOfCompetitorRetrievalProcessor extends AbstractRetrievalP |
| 22 | 22 | protected Iterable<HasTrackedLegOfCompetitorContext> retrieveData(HasTrackedLegContext element) { |
| 23 | 23 | Collection<HasTrackedLegOfCompetitorContext> trackedLegOfCompetitorsWithContext = new ArrayList<>(); |
| 24 | 24 | for (Competitor competitor : element.getTrackedRaceContext().getTrackedRace().getRace().getCompetitors()) { |
| 25 | + if (isAborted()) { |
|
| 26 | + break; |
|
| 27 | + } |
|
| 25 | 28 | HasTrackedLegOfCompetitorContext trackedLegOfCompetitorWithContext = new TrackedLegOfCompetitorWithContext(element, element.getTrackedLeg().getTrackedLeg(competitor)); |
| 26 | 29 | trackedLegOfCompetitorsWithContext.add(trackedLegOfCompetitorWithContext); |
| 27 | 30 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegRetrievalProcessor.java
| ... | ... | @@ -23,6 +23,9 @@ public class TrackedLegRetrievalProcessor extends AbstractRetrievalProcessor<Has |
| 23 | 23 | Collection<HasTrackedLegContext> trackedLegsWithContext = new ArrayList<>(); |
| 24 | 24 | int legNumber = 1; |
| 25 | 25 | for (TrackedLeg trackedLeg : element.getTrackedRace().getTrackedLegs()) { |
| 26 | + if (isAborted()) { |
|
| 27 | + break; |
|
| 28 | + } |
|
| 26 | 29 | HasTrackedLegContext trackedLegWithContext = new TrackedLegWithContext(element, trackedLeg, legNumber); |
| 27 | 30 | trackedLegsWithContext.add(trackedLegWithContext); |
| 28 | 31 | legNumber++; |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedRaceRetrievalProcessor.java
| ... | ... | @@ -25,7 +25,13 @@ public class TrackedRaceRetrievalProcessor extends AbstractRetrievalProcessor<Ha |
| 25 | 25 | protected Iterable<HasTrackedRaceContext> retrieveData(HasLeaderboardContext element) { |
| 26 | 26 | Collection<HasTrackedRaceContext> trackedRacesWithContext = new ArrayList<>(); |
| 27 | 27 | for (RaceColumn raceColumn : element.getLeaderboard().getRaceColumns()) { |
| 28 | + if (isAborted()) { |
|
| 29 | + break; |
|
| 30 | + } |
|
| 28 | 31 | for (Fleet fleet : raceColumn.getFleets()) { |
| 32 | + if (isAborted()) { |
|
| 33 | + break; |
|
| 34 | + } |
|
| 29 | 35 | TrackedRace trackedRace = raceColumn.getTrackedRace(fleet); |
| 30 | 36 | if (trackedRace != null) { |
| 31 | 37 | Regatta regatta = trackedRace.getTrackedRegatta().getRegatta(); |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/WindFixRetrievalProcessor.java
| ... | ... | @@ -33,6 +33,9 @@ public class WindFixRetrievalProcessor extends AbstractRetrievalProcessor<HasWin |
| 33 | 33 | windTrack.lockForRead(); |
| 34 | 34 | try { |
| 35 | 35 | for (final Wind wind : windTrack.getFixes()) { |
| 36 | + if (isAborted()) { |
|
| 37 | + break; |
|
| 38 | + } |
|
| 36 | 39 | windFixesWithContext.add(new WindFixWithContext(element.getTrackedRaceContext(), wind, element.getWindSourceType())); |
| 37 | 40 | } |
| 38 | 41 | } finally { |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/WindTrackRetrievalProcessor.java
| ... | ... | @@ -31,6 +31,9 @@ public class WindTrackRetrievalProcessor extends AbstractRetrievalProcessor<HasT |
| 31 | 31 | Collection<HasWindTrackContext> windTracksWithContext = new ArrayList<>(); |
| 32 | 32 | final TrackedRace trackedRace = element.getTrackedRace(); |
| 33 | 33 | for (final WindSource windSource : trackedRace.getWindSources()) { |
| 34 | + if (isAborted()) { |
|
| 35 | + break; |
|
| 36 | + } |
|
| 34 | 37 | if (!trackedRace.getWindSourcesToExclude().contains(windSource)) { |
| 35 | 38 | final WindTrack windTrack = trackedRace.getOrCreateWindTrack(windSource); |
| 36 | 39 | windTracksWithContext.add(new WindTrackWithContext(element, windTrack, windSource)); |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/aggregators/AbstractParallelAverageAggregationProcessor.java
| ... | ... | @@ -64,6 +64,9 @@ public abstract class AbstractParallelAverageAggregationProcessor<T extends Comp |
| 64 | 64 | Map<GroupKey, T> minAggregation = minAggregationProcessor.getResult(); |
| 65 | 65 | Map<GroupKey, T> maxAggregation = maxAggregationProcessor.getResult(); |
| 66 | 66 | for (Entry<GroupKey, T> sumAggregationEntry : sumAggregation.entrySet()) { |
| 67 | + if (isAborted()) { |
|
| 68 | + break; |
|
| 69 | + } |
|
| 67 | 70 | GroupKey key = sumAggregationEntry.getKey(); |
| 68 | 71 | result.put(key, new AverageWithStatsImpl<>( |
| 69 | 72 | /* average */ divide(sumAggregationEntry.getValue(), elementAmountPerKey.get(key).longValue()), |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/aggregators/AbstractParallelSumAggregationProcessor.java
| ... | ... | @@ -19,8 +19,6 @@ public abstract class AbstractParallelSumAggregationProcessor<T> extends |
| 19 | 19 | super(executor, resultReceivers, "Sum"); |
| 20 | 20 | results = new HashMap<>(); |
| 21 | 21 | } |
| 22 | - |
|
| 23 | - protected abstract T add(T t1, T t2); |
|
| 24 | 22 | |
| 25 | 23 | @Override |
| 26 | 24 | protected void handleElement(GroupedDataEntry<T> element) { |
| ... | ... | @@ -31,6 +29,8 @@ public abstract class AbstractParallelSumAggregationProcessor<T> extends |
| 31 | 29 | results.put(key, add(results.get(key), element.getDataEntry())); |
| 32 | 30 | } |
| 33 | 31 | } |
| 32 | + |
|
| 33 | + protected abstract T add(T t1, T t2); |
|
| 34 | 34 | |
| 35 | 35 | @Override |
| 36 | 36 | protected Map<GroupKey, T> getResult() { |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/aggregators/ParallelBearingAverageDegreesAggregationProcessor.java
| ... | ... | @@ -47,6 +47,9 @@ public class ParallelBearingAverageDegreesAggregationProcessor |
| 47 | 47 | protected Map<GroupKey, Double> aggregateResult() { |
| 48 | 48 | Map<GroupKey, Double> result = new HashMap<>(); |
| 49 | 49 | for (Entry<GroupKey, BearingCluster> clusterEntry : results.entrySet()) { |
| 50 | + if (isAborted()) { |
|
| 51 | + break; |
|
| 52 | + } |
|
| 50 | 53 | GroupKey key = clusterEntry.getKey(); |
| 51 | 54 | result.put(key, clusterEntry.getValue().getAverage().getDegrees()); |
| 52 | 55 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/aggregators/ParallelDistanceMedianAggregationProcessor.java
| ... | ... | @@ -50,6 +50,9 @@ public class ParallelDistanceMedianAggregationProcessor |
| 50 | 50 | protected Map<GroupKey, Distance> aggregateResult() { |
| 51 | 51 | Map<GroupKey, Distance> result = new HashMap<>(); |
| 52 | 52 | for (Entry<GroupKey, List<Distance>> groupedValuesEntry : groupedValues.entrySet()) { |
| 53 | + if (isAborted()) { |
|
| 54 | + break; |
|
| 55 | + } |
|
| 53 | 56 | result.put(groupedValuesEntry.getKey(), getMedianOf(groupedValuesEntry.getValue())); |
| 54 | 57 | } |
| 55 | 58 | return result; |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/LeaderboardWithContext.java
| ... | ... | @@ -4,17 +4,14 @@ import com.sap.sailing.datamining.data.HasLeaderboardContext; |
| 4 | 4 | import com.sap.sailing.datamining.data.HasLeaderboardGroupContext; |
| 5 | 5 | import com.sap.sailing.domain.base.BoatClass; |
| 6 | 6 | import com.sap.sailing.domain.leaderboard.Leaderboard; |
| 7 | -import com.sap.sailing.domain.polars.PolarDataService; |
|
| 8 | 7 | |
| 9 | 8 | public class LeaderboardWithContext implements HasLeaderboardContext { |
| 10 | 9 | private final Leaderboard leaderboard; |
| 11 | 10 | private final HasLeaderboardGroupContext leaderboardGroupContext; |
| 12 | - private final PolarDataService polarDataService; |
|
| 13 | 11 | |
| 14 | - public LeaderboardWithContext(Leaderboard leaderboard, HasLeaderboardGroupContext leaderboardGroupContext, PolarDataService polarDataService) { |
|
| 12 | + public LeaderboardWithContext(Leaderboard leaderboard, HasLeaderboardGroupContext leaderboardGroupContext) { |
|
| 15 | 13 | this.leaderboard = leaderboard; |
| 16 | 14 | this.leaderboardGroupContext = leaderboardGroupContext; |
| 17 | - this.polarDataService = polarDataService; |
|
| 18 | 15 | } |
| 19 | 16 | |
| 20 | 17 | public HasLeaderboardGroupContext getLeaderboardGroupContext() { |
| ... | ... | @@ -32,11 +29,6 @@ public class LeaderboardWithContext implements HasLeaderboardContext { |
| 32 | 29 | } |
| 33 | 30 | |
| 34 | 31 | @Override |
| 35 | - public PolarDataService getPolarDataService() { |
|
| 36 | - return polarDataService; |
|
| 37 | - } |
|
| 38 | - |
|
| 39 | - @Override |
|
| 40 | 32 | public String getName() { |
| 41 | 33 | return getLeaderboard().getName(); |
| 42 | 34 | } |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/RaceOfCompetitorWithContext.java
| ... | ... | @@ -29,10 +29,12 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor; |
| 29 | 29 | import com.sap.sailing.domain.tracking.TrackedRace; |
| 30 | 30 | import com.sap.sailing.domain.tracking.WindPositionMode; |
| 31 | 31 | import com.sap.sse.common.Distance; |
| 32 | +import com.sap.sse.common.Duration; |
|
| 32 | 33 | import com.sap.sse.common.Speed; |
| 33 | 34 | import com.sap.sse.common.TimePoint; |
| 34 | 35 | import com.sap.sse.common.Util; |
| 35 | 36 | import com.sap.sse.common.Util.Pair; |
| 37 | +import com.sap.sse.common.impl.MillisecondsDurationImpl; |
|
| 36 | 38 | import com.sap.sse.common.impl.MillisecondsTimePoint; |
| 37 | 39 | import com.sap.sse.datamining.data.Cluster; |
| 38 | 40 | import com.sap.sse.datamining.shared.impl.dto.ClusterDTO; |
| ... | ... | @@ -357,4 +359,18 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext { |
| 357 | 359 | return distance / length; |
| 358 | 360 | } |
| 359 | 361 | |
| 362 | + @Override |
|
| 363 | + public Duration getDuration() { |
|
| 364 | + Duration duration = null; |
|
| 365 | + TrackedRace race = getTrackedRace(); |
|
| 366 | + Course course = race.getRace().getCourse(); |
|
| 367 | + MarkPassing startPassing = race.getMarkPassing(competitor, course.getFirstWaypoint()); |
|
| 368 | + MarkPassing finishPassing = race.getMarkPassing(competitor, course.getLastWaypoint()); |
|
| 369 | + if (startPassing != null && finishPassing != null) { |
|
| 370 | + long durationMillis = finishPassing.getTimePoint().asMillis() - startPassing.getTimePoint().asMillis(); |
|
| 371 | + duration = new MillisecondsDurationImpl(durationMillis); |
|
| 372 | + } |
|
| 373 | + return duration; |
|
| 374 | + } |
|
| 375 | + |
|
| 360 | 376 | } |
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/data/TrackedRaceWithContext.java
| ... | ... | @@ -17,8 +17,10 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving; |
| 17 | 17 | import com.sap.sailing.domain.tracking.GPSFixTrack; |
| 18 | 18 | import com.sap.sailing.domain.tracking.LineDetails; |
| 19 | 19 | import com.sap.sailing.domain.tracking.TrackedRace; |
| 20 | +import com.sap.sse.common.Duration; |
|
| 20 | 21 | import com.sap.sse.common.TimePoint; |
| 21 | 22 | import com.sap.sse.common.Util; |
| 23 | +import com.sap.sse.common.impl.MillisecondsDurationImpl; |
|
| 22 | 24 | import com.sap.sse.common.impl.MillisecondsTimePoint; |
| 23 | 25 | |
| 24 | 26 | public class TrackedRaceWithContext implements HasTrackedRaceContext { |
| ... | ... | @@ -113,6 +115,26 @@ public class TrackedRaceWithContext implements HasTrackedRaceContext { |
| 113 | 115 | public Boolean isTracked() { |
| 114 | 116 | return getTrackedRace().hasStarted(MillisecondsTimePoint.now()); |
| 115 | 117 | } |
| 118 | + |
|
| 119 | + @Override |
|
| 120 | + public Duration getDuration() { |
|
| 121 | + Duration duration = null; |
|
| 122 | + TrackedRace race = getTrackedRace(); |
|
| 123 | + TimePoint start = race.getStartOfRace(); |
|
| 124 | + if (start == null) { |
|
| 125 | + start = race.getStartOfTracking(); |
|
| 126 | + } |
|
| 127 | + if (start != null) { |
|
| 128 | + TimePoint end = race.getEndOfRace(); |
|
| 129 | + if (end == null) { |
|
| 130 | + end = race.getEndOfTracking(); |
|
| 131 | + } |
|
| 132 | + if (end != null) { |
|
| 133 | + duration = new MillisecondsDurationImpl(end.asMillis() - start.asMillis()); |
|
| 134 | + } |
|
| 135 | + } |
|
| 136 | + return duration; |
|
| 137 | + } |
|
| 116 | 138 | |
| 117 | 139 | @Override |
| 118 | 140 | public int getNumberOfCompetitorFixes() { |
java/com.sap.sailing.domain.common/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/maneuverdetection/impl/IncrementalManeuverComputationTest.java
| ... | ... | @@ -130,11 +130,14 @@ public class IncrementalManeuverComputationTest extends AbstractManeuverDetectio |
| 130 | 130 | performanceMeasurementStartedAt = System.currentTimeMillis(); |
| 131 | 131 | List<Maneuver> normallyDetectedManeuvers = normalManeuverDetector.detectManeuvers(); |
| 132 | 132 | long millisForNormalManeuverDetection = System.currentTimeMillis() - performanceMeasurementStartedAt; |
| 133 | + int performanceBenefitOfIncrementalManeuverDetectionInPercent = (int) ((1.0 * (millisForNormalManeuverDetection - millisForIncrementalManeuverDetection) |
|
| 134 | + / millisForNormalManeuverDetection) * 100); |
|
| 133 | 135 | assertEquals("Incrementally calculated maneuvers differ from normally calculated maneuvers", |
| 134 | 136 | normallyDetectedManeuvers, incrementallyDetectedManeuvers); |
| 135 | 137 | assertTrue( |
| 136 | - "Incremental maneuver detection was not 30% faster in detecting maneuvers incrementally, than the full maneuver detection", |
|
| 137 | - millisForIncrementalManeuverDetection * 1.3 < millisForNormalManeuverDetection); |
|
| 138 | + "Incremental maneuver detection was not 20% faster in detecting maneuvers incrementally, than the full maneuver detection. The actual performance benefit was: " |
|
| 139 | + + performanceBenefitOfIncrementalManeuverDetectionInPercent + "%", |
|
| 140 | + performanceBenefitOfIncrementalManeuverDetectionInPercent >= 20); |
|
| 138 | 141 | } |
| 139 | 142 | |
| 140 | 143 | } |
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RouteAssemblyTest.java
| ... | ... | @@ -15,6 +15,7 @@ import com.sap.sailing.domain.tractracadapter.LoadingQueueDoneCallBack; |
| 15 | 15 | import com.sap.sailing.domain.tractracadapter.Receiver; |
| 16 | 16 | import com.sap.sse.common.Util; |
| 17 | 17 | import com.tractrac.model.lib.api.route.IControlRoute; |
| 18 | +import com.tractrac.model.lib.api.route.IPathRoute; |
|
| 18 | 19 | import com.tractrac.subscription.lib.api.control.IControlRouteChangeListener; |
| 19 | 20 | |
| 20 | 21 | public class RouteAssemblyTest extends AbstractTracTracLiveTest { |
| ... | ... | @@ -66,6 +67,11 @@ public class RouteAssemblyTest extends AbstractTracTracLiveTest { |
| 66 | 67 | first = false; |
| 67 | 68 | } |
| 68 | 69 | } |
| 70 | + |
|
| 71 | + @Override |
|
| 72 | + public void gotRouteChange(IPathRoute pathRoute, long timeStamp) { |
|
| 73 | + // will never be invoked for sailing events |
|
| 74 | + } |
|
| 69 | 75 | }); |
| 70 | 76 | } |
| 71 | 77 |
java/com.sap.sailing.domain.tractracadapter/src/com/sap/sailing/domain/tractracadapter/impl/RaceCourseReceiver.java
| ... | ... | @@ -37,6 +37,7 @@ import com.tractrac.model.lib.api.event.IEvent; |
| 37 | 37 | import com.tractrac.model.lib.api.event.IRace; |
| 38 | 38 | import com.tractrac.model.lib.api.route.IControl; |
| 39 | 39 | import com.tractrac.model.lib.api.route.IControlRoute; |
| 40 | +import com.tractrac.model.lib.api.route.IPathRoute; |
|
| 40 | 41 | import com.tractrac.model.lib.api.route.IRoute; |
| 41 | 42 | import com.tractrac.subscription.lib.api.IEventSubscriber; |
| 42 | 43 | import com.tractrac.subscription.lib.api.IRaceSubscriber; |
| ... | ... | @@ -97,6 +98,13 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute, |
| 97 | 98 | public void gotRouteChange(IControlRoute controlRoute, long timeStamp) { |
| 98 | 99 | enqueue(new Triple<IControlRoute, Long, Void>(controlRoute, timeStamp, null)); |
| 99 | 100 | } |
| 101 | + |
|
| 102 | + @Override |
|
| 103 | + public void gotRouteChange(IPathRoute pathRoute, long timeStamp) { |
|
| 104 | + // will never be invoked for sailing events; Jorge Llodra (2018-07-30): |
|
| 105 | + // "The IControlRouteChangeListener has been extended adding a new method to get updates of a |
|
| 106 | + // IPathRoute. If you are managing "sailing events" this method will never be invoked." |
|
| 107 | + } |
|
| 100 | 108 | }; |
| 101 | 109 | } |
| 102 | 110 |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/CompleteManeuverCurveWithEstimationData.java
| ... | ... | @@ -100,9 +100,9 @@ public interface CompleteManeuverCurveWithEstimationData extends Timed, Position |
| 100 | 100 | |
| 101 | 101 | Distance getDistanceToClosestMark(); |
| 102 | 102 | |
| 103 | - Double getDeviationOfManeuverAngleFromTargetTackAngleInDegrees(); |
|
| 103 | + Double getTargetTackAngleInDegrees(); |
|
| 104 | 104 | |
| 105 | - Double getDeviationOfManeuverAngleFromTargetJibeAngleInDegrees(); |
|
| 105 | + Double getTargetJibeAngleInDegrees(); |
|
| 106 | 106 | |
| 107 | 107 | /** |
| 108 | 108 | * Gets whether a mark was crossed within the maneuver curve. |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/CompleteManeuverCurveWithEstimationDataImpl.java
| ... | ... | @@ -27,14 +27,15 @@ public class CompleteManeuverCurveWithEstimationDataImpl implements CompleteMane |
| 27 | 27 | private final boolean markPassing; |
| 28 | 28 | private final Position position; |
| 29 | 29 | private final Distance distanceToClosestMark; |
| 30 | - private final Double deviationOfManeuverAngleFromTargetTackAngleInDegrees; |
|
| 31 | - private final Double deviationOfManeuverAngleFromTargetJibeAngleInDegrees; |
|
| 30 | + private final Double targetTackAngleInDegrees; |
|
| 31 | + private final Double targetJibeAngleInDegrees; |
|
| 32 | 32 | |
| 33 | 33 | public CompleteManeuverCurveWithEstimationDataImpl(Position position, ManeuverMainCurveWithEstimationData mainCurve, |
| 34 | 34 | ManeuverCurveWithUnstableCourseAndSpeedWithEstimationData curveWithUnstableCourseAndSpeed, Wind wind, |
| 35 | 35 | int tackingCount, int jibingCount, boolean maneuverStartsByRunningAwayFromWind, |
| 36 | 36 | Bearing relativeBearingToNextMarkBeforeManeuver, Bearing relativeBearingToNextMarkAfterManeuver, |
| 37 | - boolean markPassing, Distance distanceToClosestMark, Double deviationOfManeuverAngleFromTargetTackAngleInDegrees, Double deviationOfManeuverAngleFromTargetJibeAngleInDegrees) { |
|
| 37 | + boolean markPassing, Distance distanceToClosestMark, Double targetTackAngleInDegrees, |
|
| 38 | + Double targetJibeAngleInDegrees) { |
|
| 38 | 39 | this.position = position; |
| 39 | 40 | this.mainCurve = mainCurve; |
| 40 | 41 | this.curveWithUnstableCourseAndSpeed = curveWithUnstableCourseAndSpeed; |
| ... | ... | @@ -46,8 +47,8 @@ public class CompleteManeuverCurveWithEstimationDataImpl implements CompleteMane |
| 46 | 47 | this.relativeBearingToNextMarkAfterManeuver = relativeBearingToNextMarkAfterManeuver; |
| 47 | 48 | this.markPassing = markPassing; |
| 48 | 49 | this.distanceToClosestMark = distanceToClosestMark; |
| 49 | - this.deviationOfManeuverAngleFromTargetTackAngleInDegrees = deviationOfManeuverAngleFromTargetTackAngleInDegrees; |
|
| 50 | - this.deviationOfManeuverAngleFromTargetJibeAngleInDegrees = deviationOfManeuverAngleFromTargetJibeAngleInDegrees; |
|
| 50 | + this.targetTackAngleInDegrees = targetTackAngleInDegrees; |
|
| 51 | + this.targetJibeAngleInDegrees = targetJibeAngleInDegrees; |
|
| 51 | 52 | } |
| 52 | 53 | |
| 53 | 54 | @Override |
| ... | ... | @@ -99,20 +100,20 @@ public class CompleteManeuverCurveWithEstimationDataImpl implements CompleteMane |
| 99 | 100 | public Position getPosition() { |
| 100 | 101 | return position; |
| 101 | 102 | } |
| 102 | - |
|
| 103 | + |
|
| 103 | 104 | @Override |
| 104 | 105 | public Distance getDistanceToClosestMark() { |
| 105 | 106 | return distanceToClosestMark; |
| 106 | 107 | } |
| 107 | - |
|
| 108 | + |
|
| 108 | 109 | @Override |
| 109 | - public Double getDeviationOfManeuverAngleFromTargetTackAngleInDegrees() { |
|
| 110 | - return deviationOfManeuverAngleFromTargetTackAngleInDegrees; |
|
| 110 | + public Double getTargetTackAngleInDegrees() { |
|
| 111 | + return targetTackAngleInDegrees; |
|
| 111 | 112 | } |
| 112 | - |
|
| 113 | + |
|
| 113 | 114 | @Override |
| 114 | - public Double getDeviationOfManeuverAngleFromTargetJibeAngleInDegrees() { |
|
| 115 | - return deviationOfManeuverAngleFromTargetJibeAngleInDegrees; |
|
| 115 | + public Double getTargetJibeAngleInDegrees() { |
|
| 116 | + return targetJibeAngleInDegrees; |
|
| 116 | 117 | } |
| 117 | 118 | |
| 118 | 119 | } |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/maneuverdetection/impl/ManeuverDetectorWithEstimationDataSupportDecoratorImpl.java
| ... | ... | @@ -278,7 +278,8 @@ public class ManeuverDetectorWithEstimationDataSupportDecoratorImpl |
| 278 | 278 | stepWithHighestSpeed.getSpeedWithBearing(), stepWithHighestSpeed.getTimePoint(), |
| 279 | 279 | maneuverCurve.getMainCurveBoundaries().getTimePoint(), |
| 280 | 280 | maneuverCurve.getMainCurveBoundaries().getMaxTurningRateInDegreesPerSecond(), courseAtMaxTurningRate, |
| 281 | - distanceSailedWithinManeuver, projectedManeuverLoss.getDistanceSailedProjectedOnMiddleManeuverAngle(), distanceSailedIfNotManeuvering, |
|
| 281 | + distanceSailedWithinManeuver, projectedManeuverLoss.getDistanceSailedProjectedOnMiddleManeuverAngle(), |
|
| 282 | + distanceSailedIfNotManeuvering, |
|
| 282 | 283 | projectedManeuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle(), |
| 283 | 284 | Math.abs(maneuverCurve.getMainCurveBoundaries().getDirectionChangeInDegrees()) |
| 284 | 285 | / maneuverCurve.getMainCurveBoundaries().getDuration().asSeconds(), |
| ... | ... | @@ -338,9 +339,9 @@ public class ManeuverDetectorWithEstimationDataSupportDecoratorImpl |
| 338 | 339 | gpsFixesCountFromPreviousManeuver, durationAndAvgSpeedWithBearingAfter.getB(), |
| 339 | 340 | durationAndAvgSpeedWithBearingAfter.getA(), gpsFixesCountToNextManeuver, distanceSailedWithinManeuver, |
| 340 | 341 | projectedManeuverLoss.getDistanceSailedProjectedOnMiddleManeuverAngle(), distanceSailedIfNotManeuvering, |
| 341 | - projectedManeuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle(), gpsFixCountWithinWholeCurve, |
|
| 342 | - longestGpsFixIntervalBetweenTwoFixes, intervalBetweenLastFixOfCurveAndNextFix, |
|
| 343 | - intervalBetweenFirstFixOfCurveAndPreviousFix); |
|
| 342 | + projectedManeuverLoss.getDistanceSailedIfNotManeuveringProjectedOnMiddleManeuverAngle(), |
|
| 343 | + gpsFixCountWithinWholeCurve, longestGpsFixIntervalBetweenTwoFixes, |
|
| 344 | + intervalBetweenLastFixOfCurveAndNextFix, intervalBetweenFirstFixOfCurveAndPreviousFix); |
|
| 344 | 345 | TimePoint maneuverTimePoint = maneuverCurve.getMainCurveBoundaries().getTimePoint(); |
| 345 | 346 | Position maneuverPosition = maneuverDetector.track.getEstimatedPosition(maneuverTimePoint, |
| 346 | 347 | /* extrapolate */false); |
| ... | ... | @@ -357,8 +358,8 @@ public class ManeuverDetectorWithEstimationDataSupportDecoratorImpl |
| 357 | 358 | .getManeuverCurveWithStableSpeedAndCourseBoundaries().getSpeedWithBearingAfter().getBearing()); |
| 358 | 359 | BoatClass boatClass = maneuverDetector.trackedRace.getRace().getBoatOfCompetitor(maneuverDetector.competitor) |
| 359 | 360 | .getBoatClass(); |
| 360 | - Double deviationFromTackAngle = null; |
|
| 361 | - Double deviationFromJibeAngle = null; |
|
| 361 | + Double targetTackAngle = null; |
|
| 362 | + Double targetJibeAngle = null; |
|
| 362 | 363 | Speed boatSpeed = curveWithUnstableCourseAndSpeed.getSpeedWithBearingBefore() |
| 363 | 364 | .compareTo(curveWithUnstableCourseAndSpeed.getSpeedWithBearingAfter()) < 0 |
| 364 | 365 | ? curveWithUnstableCourseAndSpeed.getSpeedWithBearingBefore() |
| ... | ... | @@ -369,11 +370,11 @@ public class ManeuverDetectorWithEstimationDataSupportDecoratorImpl |
| 369 | 370 | SpeedWithBearingWithConfidence<Void> closestJibeTwa = polarDataService.getClosestTwaTws(ManeuverType.JIBE, |
| 370 | 371 | boatSpeed, curveWithUnstableCourseAndSpeed.getDirectionChangeInDegrees(), boatClass); |
| 371 | 372 | if (closestTackTwa != null) { |
| 372 | - deviationFromTackAngle = polarDataService.getManeuverAngleInDegreesFromTwa( |
|
| 373 | + targetTackAngle = polarDataService.getManeuverAngleInDegreesFromTwa( |
|
| 373 | 374 | closestTackTwa.getObject().getBearing().getDegrees(), ManeuverType.TACK); |
| 374 | 375 | } |
| 375 | 376 | if (closestJibeTwa != null) { |
| 376 | - deviationFromJibeAngle = polarDataService.getManeuverAngleInDegreesFromTwa( |
|
| 377 | + targetJibeAngle = polarDataService.getManeuverAngleInDegreesFromTwa( |
|
| 377 | 378 | closestJibeTwa.getObject().getBearing().getDegrees(), ManeuverType.JIBE); |
| 378 | 379 | } |
| 379 | 380 | } |
| ... | ... | @@ -383,7 +384,7 @@ public class ManeuverDetectorWithEstimationDataSupportDecoratorImpl |
| 383 | 384 | curveWithUnstableCourseAndSpeed, wind, numberOfTacks, numberOfJibes, |
| 384 | 385 | maneuverStartsByRunningAwayFromWind, relativeBearingToNextMarkPassingBeforeManeuver, |
| 385 | 386 | relativeBearingToNextMarkPassingAfterManeuver, maneuverCurve.isMarkPassing(), closestDistanceToMark, |
| 386 | - deviationFromTackAngle, deviationFromJibeAngle); |
|
| 387 | + targetTackAngle, targetJibeAngle); |
|
| 387 | 388 | } |
| 388 | 389 | |
| 389 | 390 | public Distance getClosestDistanceToMark(TimePoint timePoint) { |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/CandidateFinder.java
| ... | ... | @@ -54,6 +54,13 @@ public interface CandidateFinder { |
| 54 | 54 | Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> getCandidateDeltasAfterRaceStartTimeChange(); |
| 55 | 55 | |
| 56 | 56 | /** |
| 57 | + * Notifies this finder about the race's start of tracking time having changed. In case of a race that infers |
|
| 58 | + * the race start time from the start mark passings, a change in start of tracking needs to adjust the time range |
|
| 59 | + * in which candidates are considered valid. |
|
| 60 | + */ |
|
| 61 | + Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> getCandidateDeltasAfterStartOfTrackingChange(); |
|
| 62 | + |
|
| 63 | + /** |
|
| 57 | 64 | * Notifies this finder about the race's finished time having changed. The candidates collections are adjusted |
| 58 | 65 | * accordingly: new candidates may be added if the finished time was moved to a later point in time and therefore |
| 59 | 66 | * extends the time range for candidates; candidates are removed if the finished time was moved to an earlier point |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/MarkPassingUpdateListener.java
| ... | ... | @@ -196,6 +196,25 @@ public class MarkPassingUpdateListener extends AbstractRaceChangeListener { |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | 198 | @Override |
| 199 | + public void startOfTrackingChanged(TimePoint oldStartOfTracking, TimePoint newStartOfTracking) { |
|
| 200 | + markPassingCalculator.enqueueUpdate(new StorePositionUpdateStrategy() { |
|
| 201 | + @Override |
|
| 202 | + public void storePositionUpdate(Map<Competitor, List<GPSFix>> competitorFixes, |
|
| 203 | + Map<Mark, List<GPSFix>> markFixes, List<Waypoint> addedWaypoints, List<Waypoint> removedWaypoints, |
|
| 204 | + IntHolder smallestChangedWaypointIndex, |
|
| 205 | + List<Triple<Competitor, Integer, TimePoint>> fixedMarkPassings, |
|
| 206 | + List<Pair<Competitor, Integer>> removedMarkPassings, |
|
| 207 | + List<Pair<Competitor, Integer>> suppressedMarkPassings, List<Competitor> unSuppressedMarkPassings, CandidateFinder candidateFinder, CandidateChooser candidateChooser) { |
|
| 208 | + final Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> newAndRemovedCandidatesPerCompetitor = |
|
| 209 | + candidateFinder.getCandidateDeltasAfterStartOfTrackingChange(); |
|
| 210 | + for (final Entry<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> i : newAndRemovedCandidatesPerCompetitor.entrySet()) { |
|
| 211 | + candidateChooser.calculateMarkPassDeltas(i.getKey(), i.getValue().getA(), i.getValue().getB()); |
|
| 212 | + } |
|
| 213 | + } |
|
| 214 | + }); |
|
| 215 | + } |
|
| 216 | + |
|
| 217 | + @Override |
|
| 199 | 218 | public void finishedTimeChanged(TimePoint oldFinishedTime, TimePoint newFinishedTime) { |
| 200 | 219 | markPassingCalculator.enqueueUpdate(new StorePositionUpdateStrategy() { |
| 201 | 220 | @Override |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/impl/CandidateFinderImpl.java
| ... | ... | @@ -37,6 +37,7 @@ import com.sap.sailing.domain.tracking.DynamicGPSFixTrack; |
| 37 | 37 | import com.sap.sailing.domain.tracking.DynamicTrackedRace; |
| 38 | 38 | import com.sap.sailing.domain.tracking.GPSFixTrack; |
| 39 | 39 | import com.sap.sailing.domain.tracking.MarkPositionAtTimePointCache; |
| 40 | +import com.sap.sailing.domain.tracking.TrackedRace; |
|
| 40 | 41 | import com.sap.sailing.domain.tracking.impl.MarkPositionAtTimePointCacheImpl; |
| 41 | 42 | import com.sap.sailing.domain.tracking.impl.TimedComparator; |
| 42 | 43 | import com.sap.sse.common.Bearing; |
| ... | ... | @@ -1455,12 +1456,26 @@ public class CandidateFinderImpl implements CandidateFinder { |
| 1455 | 1456 | /** |
| 1456 | 1457 | * If the {@link #race}'s regatta is configured to infer the start times from start mark passings then {@code null} |
| 1457 | 1458 | * must be tolerated as a value for {@code from}, leading to an open interval starting at the |
| 1458 | - * {@link TimePoint#BeginningOfTime beginning of time}. However, if the start time is expected to be set and not |
|
| 1459 | - * inferred, mark passings need to be detected only from the start minus some tolerance interval. In this case, |
|
| 1460 | - * an interval that has {@code null} as its {@code from} time point and thus is considered empty will be returned. |
|
| 1461 | - * It hence returns {@code null} from its {@link TimeRangeWithNullStartMeaningEmpty#getTimeRangeOrNull()} method. |
|
| 1459 | + * {@link TrackedRace#getStartOfTracking()} or, if not set, the {@link TimePoint#BeginningOfTime beginning of time}. |
|
| 1460 | + * However, if the start time is expected to be set and not inferred, mark passings need to be detected only from |
|
| 1461 | + * the start minus some tolerance interval. In this case, an interval that has {@code null} as its {@code from} time |
|
| 1462 | + * point and thus is considered empty will be returned. It hence returns {@code null} from its |
|
| 1463 | + * {@link TimeRangeWithNullStartMeaningEmpty#getTimeRangeOrNull()} method. |
|
| 1462 | 1464 | */ |
| 1463 | 1465 | private TimeRangeWithNullStartMeaningEmpty getTimeRangeOrNull(TimePoint from, TimePoint to) { |
| 1466 | + final TimePoint effectiveFrom = getEffectiveFrom(from); |
|
| 1467 | + return new TimeRangeWithNullStartMeaningEmpty(effectiveFrom, to); |
|
| 1468 | + } |
|
| 1469 | + |
|
| 1470 | + /** |
|
| 1471 | + * If the {@link #race}'s regatta is configured to infer the start times from start mark passings then {@code null} |
|
| 1472 | + * must be tolerated as a value for {@code from}, leading to an open interval starting at the |
|
| 1473 | + * {@link TrackedRace#getStartOfTracking()} or, if not set, the {@link TimePoint#BeginningOfTime beginning of time}. |
|
| 1474 | + * However, if the start time is expected to be set and not inferred, mark passings need to be detected only from |
|
| 1475 | + * the start minus some tolerance interval. In this case, for an interval that has {@code null} as its {@code from} time |
|
| 1476 | + * point and thus is considered empty, {@code null} will be returned. |
|
| 1477 | + */ |
|
| 1478 | + private TimePoint getEffectiveFrom(TimePoint from) { |
|
| 1464 | 1479 | final TimePoint effectiveFrom; |
| 1465 | 1480 | if (from == null && race.getTrackedRegatta().getRegatta().useStartTimeInference()) { |
| 1466 | 1481 | // need to check the whole track to be able to find start mark passings |
| ... | ... | @@ -1470,15 +1485,22 @@ public class CandidateFinderImpl implements CandidateFinder { |
| 1470 | 1485 | } else { |
| 1471 | 1486 | effectiveFrom = from; |
| 1472 | 1487 | } |
| 1473 | - return new TimeRangeWithNullStartMeaningEmpty(effectiveFrom, to); |
|
| 1488 | + return effectiveFrom; |
|
| 1474 | 1489 | } |
| 1475 | 1490 | |
| 1476 | 1491 | @Override |
| 1477 | 1492 | public Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> getCandidateDeltasAfterRaceStartTimeChange() { |
| 1478 | - final Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> result; |
|
| 1479 | 1493 | final TimePoint newNonInferredStartTime = race.getStartOfRace(/* inferred */ false); |
| 1480 | 1494 | final TimePoint newTimePointWhenToStartConsideringCandidates = getTimePointWhenToStartConsideringCandidates(newNonInferredStartTime); |
| 1481 | - final TimeRangeWithNullStartMeaningEmpty newTimeRange = timeRangeForValidCandidates.getWithNewFrom(newTimePointWhenToStartConsideringCandidates); |
|
| 1495 | + final TimePoint newEffectiveTimePointWhenToStartConsideringCandidates = getEffectiveFrom(newTimePointWhenToStartConsideringCandidates); |
|
| 1496 | + final TimeRangeWithNullStartMeaningEmpty newTimeRange = timeRangeForValidCandidates.getWithNewFrom(newEffectiveTimePointWhenToStartConsideringCandidates); |
|
| 1497 | + return getCandidateDeltasAfterTimingChange(newEffectiveTimePointWhenToStartConsideringCandidates, newTimeRange); |
|
| 1498 | + } |
|
| 1499 | + |
|
| 1500 | + private Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> getCandidateDeltasAfterTimingChange( |
|
| 1501 | + final TimePoint newTimePointWhenToStartConsideringCandidates, |
|
| 1502 | + final TimeRangeWithNullStartMeaningEmpty newTimeRange) { |
|
| 1503 | + final Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> result; |
|
| 1482 | 1504 | if (!Util.equalsWithNull(newTimeRange, timeRangeForValidCandidates)) { |
| 1483 | 1505 | if (newTimeRange.getTimeRangeOrNull() == null) { |
| 1484 | 1506 | result = clearAllCandidates(); |
| ... | ... | @@ -1500,6 +1522,15 @@ public class CandidateFinderImpl implements CandidateFinder { |
| 1500 | 1522 | } |
| 1501 | 1523 | |
| 1502 | 1524 | @Override |
| 1525 | + public Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> getCandidateDeltasAfterStartOfTrackingChange() { |
|
| 1526 | + final TimePoint newNonInferredStartTime = race.getStartOfRace(/* inferred */ false); |
|
| 1527 | + final TimePoint newTimePointWhenToStartConsideringCandidates = getTimePointWhenToStartConsideringCandidates(newNonInferredStartTime); |
|
| 1528 | + final TimePoint newEffectiveTimePointWhenToStartConsideringCandidates = getEffectiveFrom(newTimePointWhenToStartConsideringCandidates); |
|
| 1529 | + final TimeRangeWithNullStartMeaningEmpty newTimeRange = timeRangeForValidCandidates.getWithNewFrom(newEffectiveTimePointWhenToStartConsideringCandidates); |
|
| 1530 | + return getCandidateDeltasAfterTimingChange(newEffectiveTimePointWhenToStartConsideringCandidates, newTimeRange); |
|
| 1531 | + } |
|
| 1532 | + |
|
| 1533 | + @Override |
|
| 1503 | 1534 | public Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> getCandidateDeltasAfterRaceFinishedTimeChange( |
| 1504 | 1535 | TimePoint oldFinishedTime, TimePoint newFinishedTime) { |
| 1505 | 1536 | final Map<Competitor, Pair<Iterable<Candidate>, Iterable<Candidate>>> result; |
java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CrossTrackErrorCache.java
| ... | ... | @@ -205,6 +205,7 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { |
| 205 | 205 | owner.addListener(this); |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | + @FunctionalInterface |
|
| 208 | 209 | private interface CrossTrackErrorMeterRetriever { |
| 209 | 210 | double getDistanceInMetersSumFromStart(CrossTrackErrorSumAndNumberOfFixes cacheEntry); |
| 210 | 211 | } |
| ... | ... | @@ -220,12 +221,7 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { |
| 220 | 221 | */ |
| 221 | 222 | public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, |
| 222 | 223 | boolean waitForLatest) throws NoWindException { |
| 223 | - CrossTrackErrorMeterRetriever absoluteMetersRetriever = new CrossTrackErrorMeterRetriever() { |
|
| 224 | - @Override |
|
| 225 | - public double getDistanceInMetersSumFromStart(CrossTrackErrorSumAndNumberOfFixes cacheEntry) { |
|
| 226 | - return cacheEntry.getAbsoluteDistanceInMetersSumFromStart(); |
|
| 227 | - } |
|
| 228 | - }; |
|
| 224 | + CrossTrackErrorMeterRetriever absoluteMetersRetriever = cacheEntry->cacheEntry.getAbsoluteDistanceInMetersSumFromStart(); |
|
| 229 | 225 | return getAbsoluteOrSignedAverageCrossTrackError(competitor, from, to, upwindOnly, waitForLatest, absoluteMetersRetriever); |
| 230 | 226 | } |
| 231 | 227 | |
| ... | ... | @@ -240,20 +236,15 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { |
| 240 | 236 | */ |
| 241 | 237 | public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, |
| 242 | 238 | boolean waitForLatest) throws NoWindException { |
| 243 | - CrossTrackErrorMeterRetriever signedMetersRetriever = new CrossTrackErrorMeterRetriever() { |
|
| 244 | - @Override |
|
| 245 | - public double getDistanceInMetersSumFromStart(CrossTrackErrorSumAndNumberOfFixes cacheEntry) { |
|
| 246 | - return cacheEntry.getSignedDistanceInMetersSumFromStart(); |
|
| 247 | - } |
|
| 248 | - }; |
|
| 239 | + CrossTrackErrorMeterRetriever signedMetersRetriever = cacheEntry->cacheEntry.getSignedDistanceInMetersSumFromStart(); |
|
| 249 | 240 | return getAbsoluteOrSignedAverageCrossTrackError(competitor, from, to, upwindOnly, waitForLatest, signedMetersRetriever); |
| 250 | 241 | } |
| 251 | 242 | |
| 252 | 243 | /** |
| 253 | - * @param absoluteMetersRetriever determines whether the absolute or signed cross track error will be aggregated |
|
| 244 | + * @param absoluteOrSignedMetersRetriever determines whether the absolute or signed cross track error will be aggregated |
|
| 254 | 245 | */ |
| 255 | 246 | private Distance getAbsoluteOrSignedAverageCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, |
| 256 | - boolean upwindOnly, boolean waitForLatest, CrossTrackErrorMeterRetriever absoluteMetersRetriever) |
|
| 247 | + boolean upwindOnly, boolean waitForLatest, CrossTrackErrorMeterRetriever absoluteOrSignedMetersRetriever) |
|
| 257 | 248 | throws NoWindException { |
| 258 | 249 | Track<CrossTrackErrorSumAndNumberOfFixes> cacheForCompetitor = cachePerCompetitor.get(competitor, waitForLatest); |
| 259 | 250 | double distanceInMeters = 0; |
| ... | ... | @@ -268,7 +259,7 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { |
| 268 | 259 | final MarkPassing legStartMarkPassing = owner.getMarkPassing(competitor, leg.getFrom()); |
| 269 | 260 | if (legStartMarkPassing != null) { |
| 270 | 261 | if (!upwindOnly || trackedLeg.getLegType(legStartMarkPassing.getTimePoint()) == LegType.UPWIND) { |
| 271 | - TimePoint start; |
|
| 262 | + final TimePoint start; |
|
| 272 | 263 | final TimePoint legStart = legStartMarkPassing.getTimePoint(); |
| 273 | 264 | if (legStart.compareTo(from) < 0) { |
| 274 | 265 | // the interval requested starts after this leg's start: |
| ... | ... | @@ -277,7 +268,7 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { |
| 277 | 268 | start = legStart; |
| 278 | 269 | } |
| 279 | 270 | final MarkPassing legEndMarkPassing = owner.getMarkPassing(competitor, leg.getTo()); |
| 280 | - TimePoint end; |
|
| 271 | + final TimePoint end; |
|
| 281 | 272 | if (legEndMarkPassing == null || legEndMarkPassing.getTimePoint().compareTo(to) >= 0) { |
| 282 | 273 | // no next mark passing, or next mark passing is beyond the "to" time point; aggregate up to "to" |
| 283 | 274 | end = to; |
| ... | ... | @@ -294,7 +285,7 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { |
| 294 | 285 | } |
| 295 | 286 | CrossTrackErrorSumAndNumberOfFixes endAggregate = cacheForCompetitor.getLastFixAtOrBefore(end); |
| 296 | 287 | if (endAggregate != null) { |
| 297 | - distanceInMeters += absoluteMetersRetriever.getDistanceInMetersSumFromStart(endAggregate) - absoluteMetersRetriever.getDistanceInMetersSumFromStart(startAggregate); |
|
| 288 | + distanceInMeters += absoluteOrSignedMetersRetriever.getDistanceInMetersSumFromStart(endAggregate) - absoluteOrSignedMetersRetriever.getDistanceInMetersSumFromStart(startAggregate); |
|
| 298 | 289 | count += endAggregate.getFixCountFromStart() - startAggregate.getFixCountFromStart(); |
| 299 | 290 | startAggregate = endAggregate; |
| 300 | 291 | } |
java/com.sap.sailing.expeditionconnector.common/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sailing.gwt.ui.test/.project
| ... | ... | @@ -21,16 +21,6 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | - <arguments> |
|
| 26 | - </arguments> |
|
| 27 | - </buildCommand> |
|
| 28 | - <buildCommand> |
|
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | - <arguments> |
|
| 31 | - </arguments> |
|
| 32 | - </buildCommand> |
|
| 33 | - <buildCommand> |
|
| 34 | 24 | <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
| 35 | 25 | <arguments> |
| 36 | 26 | </arguments> |
| ... | ... | @@ -44,7 +34,6 @@ |
| 44 | 34 | <natures> |
| 45 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 46 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 47 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 48 | 37 | <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
| 49 | 38 | </natures> |
| 50 | 39 | </projectDescription> |
java/com.sap.sailing.gwt.ui/.project
| ... | ... | @@ -21,16 +21,6 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | - <arguments> |
|
| 26 | - </arguments> |
|
| 27 | - </buildCommand> |
|
| 28 | - <buildCommand> |
|
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | - <arguments> |
|
| 31 | - </arguments> |
|
| 32 | - </buildCommand> |
|
| 33 | - <buildCommand> |
|
| 34 | 24 | <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
| 35 | 25 | <arguments> |
| 36 | 26 | </arguments> |
| ... | ... | @@ -44,7 +34,6 @@ |
| 44 | 34 | <natures> |
| 45 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 46 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 47 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 48 | 37 | <nature>org.eclipse.wst.jsdt.core.jsNature</nature> |
| 49 | 38 | <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
| 50 | 39 | </natures> |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html
| ... | ... | @@ -6,8 +6,13 @@ |
| 6 | 6 | <div class="innerContent"> |
| 7 | 7 | <h5 class="articleSubheadline">July 2018</h5> |
| 8 | 8 | <ul class="bulletList"> |
| 9 | - <li>In <tt>RaceBoard.html</tt> there is a new feature for maneuver loss visualization. There is a setting in the map settings and in the maneuver pop up. |
|
| 9 | + <li>The Maneuver Table now uses the same color coding for competitors as the leaderboard to help |
|
| 10 | + recognize competitor tracks for selected maneuvers more easily.</li> |
|
| 11 | + <li>In <tt>RaceBoard.html</tt> there is a new feature for maneuver loss visualization. There is a setting in the map settings and in the maneuver pop up.</li> |
|
| 10 | 12 | <li>In <tt>RaceBoard.html</tt> when zooming into a specific time range, the time slider will provide a "reset zoom" button in expanded mode.</li> |
| 13 | + <li>Issues with sporadic incorrect zoom/pan states in the Race Board / race viewer have been fixed.</li> |
|
| 14 | + <li>Fixed an issue with the "Winning Lanes" mode for large races that could lead to full tails for |
|
| 15 | + all competitors to be loaded instead of only the ones for the podium competitors.</li> |
|
| 11 | 16 | </ul> |
| 12 | 17 | |
| 13 | 18 | <h5 class="articleSubheadline">June 2018</h5> |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetition.gss
| ... | ... | @@ -180,18 +180,18 @@ |
| 180 | 180 | text-overflow: ellipsis; |
| 181 | 181 | } |
| 182 | 182 | |
| 183 | -.regattacompetition_phase_fleetfullwidth, .regattacompetition_phase_fleet_race_title { |
|
| 183 | +.regattacompetition_phase_fleet_race_title_big { |
|
| 184 | 184 | width: 27%; |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | 187 | @media (min-width: 375px) { |
| 188 | - .regattacompetition_phase_fleetfullwidth, .regattacompetition_phase_fleet_race_title { |
|
| 188 | + .regattacompetition_phase_fleet_race_title_big { |
|
| 189 | 189 | width: 33%; |
| 190 | 190 | } |
| 191 | 191 | } |
| 192 | 192 | |
| 193 | 193 | @media (min-width: 700px) { |
| 194 | - .regattacompetition_phase_fleetfullwidth, .regattacompetition_phase_fleet_race_title { |
|
| 194 | + .regattacompetition_phase_fleet_race_title_big { |
|
| 195 | 195 | width: 40%; |
| 196 | 196 | } |
| 197 | 197 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetitionFleet.java
| ... | ... | @@ -17,6 +17,9 @@ import com.sap.sailing.gwt.home.shared.partials.regattacompetition.RegattaCompet |
| 17 | 17 | public class RegattaCompetitionFleet extends AbstractRegattaCompetitionFleet { |
| 18 | 18 | |
| 19 | 19 | private static RegattaCompetitionFleetUiBinder uiBinder = GWT.create(RegattaCompetitionFleetUiBinder.class); |
| 20 | + |
|
| 21 | + private int fleetCount = -1; |
|
| 22 | + private RegattaCompetitionFleetRace raceView; |
|
| 20 | 23 | |
| 21 | 24 | interface RegattaCompetitionFleetUiBinder extends UiBinder<Widget, RegattaCompetitionFleet> { |
| 22 | 25 | } |
| ... | ... | @@ -32,8 +35,9 @@ public class RegattaCompetitionFleet extends AbstractRegattaCompetitionFleet { |
| 32 | 35 | |
| 33 | 36 | @Override |
| 34 | 37 | public RegattaCompetitionRaceView addRaceView(SimpleRaceMetadataDTO race, RegattaCompetitionPresenter presenter) { |
| 35 | - RegattaCompetitionFleetRace raceView = new RegattaCompetitionFleetRace(race, presenter); |
|
| 38 | + raceView = new RegattaCompetitionFleetRace(race, presenter); |
|
| 36 | 39 | raceContainerUi.add(raceView); |
| 40 | + updateRaceViewIfReady(); |
|
| 37 | 41 | return raceView; |
| 38 | 42 | } |
| 39 | 43 | |
| ... | ... | @@ -42,6 +46,8 @@ public class RegattaCompetitionFleet extends AbstractRegattaCompetitionFleet { |
| 42 | 46 | getElement().getStyle().setWidth(100.0 / fleetCount, Unit.PCT); |
| 43 | 47 | setStyleName(local_res.css().regattacompetition_phase_fleetfullwidth(), fleetCount < 2); |
| 44 | 48 | setStyleName(local_res.css().regattacompetition_phase_fleetcompact(), fleetCount > 4); |
| 49 | + this.fleetCount = fleetCount; |
|
| 50 | + updateRaceViewIfReady(); |
|
| 45 | 51 | } |
| 46 | 52 | |
| 47 | 53 | @Override |
| ... | ... | @@ -64,5 +70,10 @@ public class RegattaCompetitionFleet extends AbstractRegattaCompetitionFleet { |
| 64 | 70 | protected Element getFleetCornerUiElement() { |
| 65 | 71 | return fleetCornerUi; |
| 66 | 72 | } |
| 67 | - |
|
| 73 | + |
|
| 74 | + private void updateRaceViewIfReady() { |
|
| 75 | + if (raceView != null && fleetCount > 1) { |
|
| 76 | + raceView.removeBigRaceTitleCSS(); |
|
| 77 | + } |
|
| 78 | + } |
|
| 68 | 79 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetitionFleetRace.java
| ... | ... | @@ -65,5 +65,9 @@ public class RegattaCompetitionFleetRace extends AbstractRegattaCompetitionFleet |
| 65 | 65 | protected String getRaceUntrackedStyleName() { |
| 66 | 66 | return local_res.css().regattacompetition_phase_fleet_raceuntracked(); |
| 67 | 67 | } |
| 68 | + |
|
| 69 | + public void removeBigRaceTitleCSS() { |
|
| 70 | + raceNameUi.removeClassName(local_res.css().regattacompetition_phase_fleet_race_title_big()); |
|
| 71 | + } |
|
| 68 | 72 | |
| 69 | 73 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetitionFleetRace.ui.xml
| ... | ... | @@ -1,15 +1,15 @@ |
| 1 | 1 | <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> |
| 2 | 2 | <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" |
| 3 | - xmlns:mp="urn:import:com.sap.sailing.gwt.home.mobile.partials" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> |
|
| 4 | - <ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" /> |
|
| 5 | - <ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" /> |
|
| 6 | - <ui:with field="local_res" type="com.sap.sailing.gwt.home.mobile.partials.regattacompetition.RegattaCompetitionResources" /> |
|
| 3 | + xmlns:mp="urn:import:com.sap.sailing.gwt.home.mobile.partials" xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"> |
|
| 4 | + <ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" /> |
|
| 5 | + <ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" /> |
|
| 6 | + <ui:with field="local_res" type="com.sap.sailing.gwt.home.mobile.partials.regattacompetition.RegattaCompetitionResources" /> |
|
| 7 | 7 | <div class="{local_res.css.regattacompetition_phase_fleet_race}" style="display:block; text-decoration:none;"> |
| 8 | - <div class="{local_res.css.regattacompetition_phase_fleet_race_title}" ui:field="raceNameUi"></div> |
|
| 9 | - <div class="{local_res.css.regattacompetition_phase_fleet_race_subtitle}"> |
|
| 10 | - <div class="{local_res.css.regattacompetition_phase_fleet_race_state}" ui:field="raceStateUi"></div> |
|
| 11 | - <div class="{local_res.css.regattacompetition_phase_fleet_race_date}" ui:field="raceDateUi"></div> |
|
| 12 | - </div> |
|
| 8 | + <div class="{local_res.css.regattacompetition_phase_fleet_race_title} {local_res.css.regattacompetition_phase_fleet_race_title_big}" ui:field="raceNameUi"></div> |
|
| 9 | + <div class="{local_res.css.regattacompetition_phase_fleet_race_subtitle}"> |
|
| 10 | + <div class="{local_res.css.regattacompetition_phase_fleet_race_state}" ui:field="raceStateUi"></div> |
|
| 11 | + <div class="{local_res.css.regattacompetition_phase_fleet_race_date}" ui:field="raceDateUi"></div> |
|
| 12 | + </div> |
|
| 13 | 13 | <div class="{local_res.css.regattacompetition_phase_fleet_race_arrow}"></div> |
| 14 | - </div> |
|
| 14 | + </div> |
|
| 15 | 15 | </ui:UiBinder> |
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/mobile/partials/regattacompetition/RegattaCompetitionResources.java
| ... | ... | @@ -33,5 +33,6 @@ public interface RegattaCompetitionResources extends SharedHomeResources { |
| 33 | 33 | String regattacompetition_phase_fleet_raceplanned(); |
| 34 | 34 | String regattacompetition_phase_fleet_race_state(); |
| 35 | 35 | String regattacompetition_phase_fleet_race_date(); |
| 36 | + String regattacompetition_phase_fleet_race_title_big(); |
|
| 36 | 37 | } |
| 37 | 38 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/actions/GetBoatPositionsAction.java
| ... | ... | @@ -20,7 +20,6 @@ public class GetBoatPositionsAction extends AbstractGetMapRelatedDataAction<Comp |
| 20 | 20 | @Override |
| 21 | 21 | public void execute(final AsyncCallback<CompactBoatPositionsDTO> callback) { |
| 22 | 22 | Map<String, Date> fromByCompetitorIdAsString = new HashMap<String, Date>(); |
| 23 | - System.out.println(fromByCompetitorIdAsString); |
|
| 24 | 23 | for (Map.Entry<CompetitorDTO, Date> fromEntry : getFrom().entrySet()) { |
| 25 | 24 | fromByCompetitorIdAsString.put(fromEntry.getKey().getIdAsString(), fromEntry.getValue()); |
| 26 | 25 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_es.properties
| ... | ... | @@ -1163,7 +1163,8 @@ racesScoredTooltip=Número de carreras que ha completado un competidor o en las |
| 1163 | 1163 | averageNumberOfOperationsPerMessage=Número promedio de operaciones por mensaje |
| 1164 | 1164 | showUncorrectedTotalPoints=Mostrar puntos totales no corregidos |
| 1165 | 1165 | setStartTimeReceived=Fijar hora de inicio recibida |
| 1166 | -setStartTimeReceivedDescription=Fija la HoraInicioRecibida del RegistroRastreado seleccionado que no es persistente. Esto significa que el nuevo valor se ignorará después del reinicio del servidor. |
|
| 1166 | +setStartTimeReceivedDescription=Fija la startTimeReceived de la TrackedRace seleccionada en el valor proporcionado. Deje el valor en blanco para eliminar la startTimeReceived actual. |
|
| 1167 | +setStartTimeReceivedNotice=Esta modificación no es persistente, es decir, el valor nuevo se olvidará cuando se reinicie el servidor. |
|
| 1167 | 1168 | lastScoreCorrectionsTime=Última hora de corrección de puntuación |
| 1168 | 1169 | lastScoreCorrectionsComment=Último comentario de corrección de puntuación |
| 1169 | 1170 | setTimeToNow=Fijar la hora a "ahora" |
| ... | ... | @@ -1275,11 +1276,13 @@ uploadSuccessful=Carga correcta |
| 1275 | 1276 | fileUploadResult=Carga de archivos: {0} {1}. En caso de error, compruebe que su servicio de alojamiento de archivos está configurado correctamente. |
| 1276 | 1277 | removeUploadedFile=Eliminar archivo |
| 1277 | 1278 | showCompetitorBoatColumn=Embarcación del competidor |
| 1279 | +showCompetitorSailIdColumn=ID de vela |
|
| 1280 | +showCompetitorSailIdColumnTooltip=Muestra el ID de vela más la bandera del país o imagen del competidor. Si está disponible, se prioriza la imagen de competidor a la bandera del país. Se mostrarán ambos iconos si se fija "{0}". |
|
| 1278 | 1281 | showCompetitorShortNameColumn=Denominación breve de competidor |
| 1279 | 1282 | showCompetitorShortNameColumnTooltip=Muestra el nombre breve más la bandera del país o imagen del competidor. Si está disponible, se prioriza la imagen de competidor a la bandera del país. Se mostrarán ambos iconos si se fija "{0}". |
| 1280 | 1283 | showCompetitorFullNameColumn=Nombre completo del competidor |
| 1281 | -showCompetitorNationalityColumn=Siempre mostrar la nacionalidad del competidor |
|
| 1282 | -showCompetitorNationalityColumnTooltip=Muestra ambos, las banderas de país así como las imágenes de competidor, si están disponibles. |
|
| 1284 | +alwaysShowCompetitorNationalityColumn=Siempre mostrar la nacionalidad del competidor |
|
| 1285 | +alwaysShowCompetitorNationalityColumnTooltip=Muestra ambos, las banderas de país así como las imágenes de competidor, si están disponibles. |
|
| 1283 | 1286 | loadingDimensionValues=Cargando valores de dimensión |
| 1284 | 1287 | inviteBuoyTenders=Invitar a balizadores |
| 1285 | 1288 | orMultipleEmails=o varios correos electrónicos separados por una coma |
| ... | ... | @@ -1970,7 +1973,7 @@ windFinderWindSourceTypeName=Windfinder |
| 1970 | 1973 | windFinderWindSourceTypeTooltip=Viento medido de uno o más puntos de www.windfinder.com |
| 1971 | 1974 | windFinder=Windfinder |
| 1972 | 1975 | enterTagsForTheVideo=Indique las etiquetas para el vídeo |
| 1973 | -enterIdOfWindfinderReviewedSpotCollection=Indique el ID de una colección de puntos de Windfinder revisada, por ejemplo "schilksee" |
|
| 1976 | +enterIdOfWindFinderReviewedSpotCollection=Indique el ID de una colección de puntos de Windfinder revisada, por ejemplo "schilksee" |
|
| 1974 | 1977 | windFinderSpotCollectionsList=Colecciones de puntos de WindFinder |
| 1975 | 1978 | enterTagsForTheImage=Indique las etiquetas para la imagen |
| 1976 | 1979 | unableToResolveWindFinderSpotId=Imposible resolver el punto Windfinder con ID {0}: {1} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_fr.properties
| ... | ... | @@ -1163,7 +1163,8 @@ racesScoredTooltip=Nombre de courses que le concurrent a terminées, ou pour les |
| 1163 | 1163 | averageNumberOfOperationsPerMessage=Nombre moyen d''opérations par message |
| 1164 | 1164 | showUncorrectedTotalPoints=Afficher total des points non corrigé |
| 1165 | 1165 | setStartTimeReceived=Afficher heure de départ reçue |
| 1166 | -setStartTimeReceivedDescription=Définit l''heure de départ reçue de la course suivie sélectionnée non persistante. Cela signifie que la nouvelle valeur sera oubliée une fois que le serveur sera relancé. |
|
| 1166 | +setStartTimeReceivedDescription=Définit l''heure de départ reçue de la course suivie sélectionnée sur la valeur indiquée. Ne renseignez pas cette valeur si vous voulez supprimer l''actuelle heure de départ reçue définie. |
|
| 1167 | +setStartTimeReceivedNotice=Cette modification n''est pas persistante. Cela signifie que la nouvelle valeur sera oubliée une fois que le serveur sera redémarré. |
|
| 1167 | 1168 | lastScoreCorrectionsTime=Dernière heure de correction du score |
| 1168 | 1169 | lastScoreCorrectionsComment=Dernier commentaire sur la correction du score |
| 1169 | 1170 | setTimeToNow=Définir heure sur "maintenant" |
| ... | ... | @@ -1275,11 +1276,13 @@ uploadSuccessful=Chargement réussi |
| 1275 | 1276 | fileUploadResult=Chargement du fichier : {0} {1}.\nEn cas d''erreur, vérifiez que votre service de stockage de fichier est correctement configuré. |
| 1276 | 1277 | removeUploadedFile=Supprimer fichier chargé |
| 1277 | 1278 | showCompetitorBoatColumn=Bateau du concurrent |
| 1279 | +showCompetitorSailIdColumn=ID de voile |
|
| 1280 | +showCompetitorSailIdColumnTooltip=Affiche l''ID de voile ainsi que le drapeau national ou l''image du concurrent. Si les deux sont disponibles, l''image du concurrent aura la priorité sur le drapeau national. Si le code "{0}" est activé, les deux icônes seront affichées. |
|
| 1278 | 1281 | showCompetitorShortNameColumn=Nom court du concurrent |
| 1279 | 1282 | showCompetitorShortNameColumnTooltip=Affiche le nom court ainsi que le drapeau national ou l''image du concurrent. Si les deux sont disponibles, l''image du concurrent aura la priorité sur le drapeau national. Si le code "{0}" est activé, les deux icônes seront affichées. |
| 1280 | 1283 | showCompetitorFullNameColumn=Nom complet du concurrent |
| 1281 | -showCompetitorNationalityColumn=Afficher toujours la nationalité du concurrent |
|
| 1282 | -showCompetitorNationalityColumnTooltip=Si disponibles, afficher les deux : le drapeau national ainsi que l''image du concurrent |
|
| 1284 | +alwaysShowCompetitorNationalityColumn=Afficher toujours la nationalité du concurrent |
|
| 1285 | +alwaysShowCompetitorNationalityColumnTooltip=Si disponibles, afficher les deux : le drapeau national ainsi que l''image du concurrent |
|
| 1283 | 1286 | loadingDimensionValues=Chargement des valeurs de dimension |
| 1284 | 1287 | inviteBuoyTenders=Inviter navire baliseur |
| 1285 | 1288 | orMultipleEmails=ou plusieurs adresses e-mails séparées par des virgules |
| ... | ... | @@ -1970,7 +1973,7 @@ windFinderWindSourceTypeName=WindFinder |
| 1970 | 1973 | windFinderWindSourceTypeTooltip=Vent mesuré d''un ou plusieurs endroits de www.windfinder.com |
| 1971 | 1974 | windFinder=WindFinder |
| 1972 | 1975 | enterTagsForTheVideo=Entrez des balises pour la vidéo. |
| 1973 | -enterIdOfWindfinderReviewedSpotCollection=Entrez l''ID d''un ensemble d''endroits WindFinder révisé, par exemple, "Schilksee". |
|
| 1976 | +enterIdOfWindFinderReviewedSpotCollection=Entrez l''ID d''un ensemble d''endroits WindFinder révisé, par exemple, "Schilksee". |
|
| 1974 | 1977 | windFinderSpotCollectionsList=Ensemble d''endroits WindFinder |
| 1975 | 1978 | enterTagsForTheImage=Entrez des balises pour l''image. |
| 1976 | 1979 | unableToResolveWindFinderSpotId=Impossible de traiter l''endroit WindFinder ayant l''ID {0} : {1} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ja.properties
| ... | ... | @@ -1163,7 +1163,8 @@ racesScoredTooltip=このリーダーボードにおいて競技者が完了し |
| 1163 | 1163 | averageNumberOfOperationsPerMessage=メッセージごとの操作の平均数 |
| 1164 | 1164 | showUncorrectedTotalPoints=未修正総得点表示 |
| 1165 | 1165 | setStartTimeReceived=設定済スタート時刻を受信 |
| 1166 | -setStartTimeReceivedDescription=これにより、永続的でない選択した TrackedRace の startTimeReceived が設定されます。したがって、サーバが再起動された後は新規の値は忘れられます。 |
|
| 1166 | +setStartTimeReceivedDescription=選択した TrackedRace の startTimeReceived が指定した値に設定されます。値を空白のままにすると、現在設定されている startTimeReceived は削除されます。 |
|
| 1167 | +setStartTimeReceivedNotice=この変更は永続的なものではありません。つまり、新しい値はサーバが再起動したときに失われます。 |
|
| 1167 | 1168 | lastScoreCorrectionsTime=最終得点修正時刻 |
| 1168 | 1169 | lastScoreCorrectionsComment=最終得点修正コメント |
| 1169 | 1170 | setTimeToNow=時刻を ''現在'' に設定 |
| ... | ... | @@ -1275,11 +1276,13 @@ uploadSuccessful=正常にアップロード済 |
| 1275 | 1276 | fileUploadResult=ファイルアップロード: {0} {1}\nエラー発生の場合は、ファイルストレージサービスが適切に設定されていることを確認してください。 |
| 1276 | 1277 | removeUploadedFile=アップロード済ファイルの削除 |
| 1277 | 1278 | showCompetitorBoatColumn=競技者の艇 |
| 1279 | +showCompetitorSailIdColumn=セール ID |
|
| 1280 | +showCompetitorSailIdColumnTooltip=セール ID に加えて国旗または競技者画像を表示します。競技者画像が利用可能な場合はそれを国旗よりも優先させます。"{0}" が設定されている場合、両方のアイコンが表示されます。 |
|
| 1278 | 1281 | showCompetitorShortNameColumn=競技者の名前 (短) |
| 1279 | 1282 | showCompetitorShortNameColumnTooltip=名前 (短) に加えて国旗または競技者画像を表示します。競技者画像が利用可能な場合はそれを国旗よりも優先させます。"{0}" が設定されている場合、両方のアイコンが表示されます。 |
| 1280 | 1283 | showCompetitorFullNameColumn=競技者氏名 |
| 1281 | -showCompetitorNationalityColumn=競技者国籍を常に表示 |
|
| 1282 | -showCompetitorNationalityColumnTooltip=国旗と競技者画像 (利用可能な場合) の両方を表示 |
|
| 1284 | +alwaysShowCompetitorNationalityColumn=競技者国籍を常に表示 |
|
| 1285 | +alwaysShowCompetitorNationalityColumnTooltip=国旗と競技者画像 (利用可能な場合) の両方を表示 |
|
| 1283 | 1286 | loadingDimensionValues=次元値ロード中 |
| 1284 | 1287 | inviteBuoyTenders=ブイ入札の招待 |
| 1285 | 1288 | orMultipleEmails=または複数の電子メールをカンマで区切り |
| ... | ... | @@ -1970,7 +1973,7 @@ windFinderWindSourceTypeName=Windfinder |
| 1970 | 1973 | windFinderWindSourceTypeTooltip=www.windfinder.com の 1 つ以上のスポットから風を測定しました |
| 1971 | 1974 | windFinder=Windfinder |
| 1972 | 1975 | enterTagsForTheVideo=動画のタグを入力 |
| 1973 | -enterIdOfWindfinderReviewedSpotCollection=レビューする Windfinder スポットコレクションの ID を入力 (例: "schilksee") |
|
| 1976 | +enterIdOfWindFinderReviewedSpotCollection=レビューする Windfinder スポットコレクションの ID を入力 (例: "schilksee") |
|
| 1974 | 1977 | windFinderSpotCollectionsList=WindFinder スポットコレクション |
| 1975 | 1978 | enterTagsForTheImage=画像のタグを入力 |
| 1976 | 1979 | unableToResolveWindFinderSpotId=ID {0} で Windfinder スポットを決定できませんでした: {1} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_pt.properties
| ... | ... | @@ -1163,7 +1163,8 @@ racesScoredTooltip=Número de corridas que o competidor concluiu ou nas quais ob |
| 1163 | 1163 | averageNumberOfOperationsPerMessage=Número médio de operações por mensagem |
| 1164 | 1164 | showUncorrectedTotalPoints=Visualizar total de pontos não corrigidos |
| 1165 | 1165 | setStartTimeReceived=Definir hora de partida recebida |
| 1166 | -setStartTimeReceivedDescription=Isto define a hora de partida recebida da corrida rastreada selecionada que não é persistente. Isto significa que o novo valor será esquecido após a reinicialização do servidor. |
|
| 1166 | +setStartTimeReceivedDescription=Define a hora de partida recebida da corrida rastreada selecionada para o valor fornecido. Deixe o valor em branco para remover a hora de partida recebida definida atualmente. |
|
| 1167 | +setStartTimeReceivedNotice=Esta modificação não é persistente, ou seja, o novo valor será esquecido quando o servidor for reiniciado. |
|
| 1167 | 1168 | lastScoreCorrectionsTime=Hora de correção da última pontuação |
| 1168 | 1169 | lastScoreCorrectionsComment=Comentário de correção da última pontuação |
| 1169 | 1170 | setTimeToNow=Definir hora para ''agora'' |
| ... | ... | @@ -1275,11 +1276,13 @@ uploadSuccessful=Carregamento efetuado com êxito |
| 1275 | 1276 | fileUploadResult=Carregamento de arquivo: {0} {1}.\nEm caso de erro, verifique se seu serviço de armazenamento de arquivos está configurado de modo apropriado. |
| 1276 | 1277 | removeUploadedFile=Remover arquivo carregado |
| 1277 | 1278 | showCompetitorBoatColumn=Barco do competidor |
| 1279 | +showCompetitorSailIdColumn=ID da vela |
|
| 1280 | +showCompetitorSailIdColumnTooltip=Exibe o ID da vela mais a bandeira de nacionalidade ou a imagem do competidor. Se disponível, é priorizada uma imagem do competidor em relação a uma bandeira da nacionalidade. Se "{0}" estiver definido, ambos os ícones serão exibidos. |
|
| 1278 | 1281 | showCompetitorShortNameColumn=Nome abreviado do competidor |
| 1279 | 1282 | showCompetitorShortNameColumnTooltip=Exibe o nome abreviado mais a bandeira de nacionalidade ou a imagem do competidor. Se disponível, é priorizada uma imagem do competidor em relação a uma bandeira da nacionalidade. Se "{0}" estiver definido, ambos os ícones serão exibidos. |
| 1280 | 1283 | showCompetitorFullNameColumn=Nome completo do competidor |
| 1281 | -showCompetitorNationalityColumn=Exibir sempre a nacionalidade do competidor |
|
| 1282 | -showCompetitorNationalityColumnTooltip=Exibir ambos, bandeiras de nacionalidade e imagens do competidor, se disponíveis |
|
| 1284 | +alwaysShowCompetitorNationalityColumn=Exibir sempre a nacionalidade do competidor |
|
| 1285 | +alwaysShowCompetitorNationalityColumnTooltip=Exibir ambos, bandeiras de nacionalidade e imagens do competidor, se disponíveis |
|
| 1283 | 1286 | loadingDimensionValues=Carregando valores de dimensão |
| 1284 | 1287 | inviteBuoyTenders=Convidar navios-balizadores |
| 1285 | 1288 | orMultipleEmails=ou vários e-mails separados por vírgula |
| ... | ... | @@ -1970,7 +1973,7 @@ windFinderWindSourceTypeName=WindFinder |
| 1970 | 1973 | windFinderWindSourceTypeTooltip=Vento medido de um ou mais locais de www.windfinder.com |
| 1971 | 1974 | windFinder=WindFinder |
| 1972 | 1975 | enterTagsForTheVideo=Inserir etiquetas para o vídeo |
| 1973 | -enterIdOfWindfinderReviewedSpotCollection=Inserir ID de uma coleção revisada de locais do WindFinder, por exemplo, "schilksee" |
|
| 1976 | +enterIdOfWindFinderReviewedSpotCollection=Inserir ID de uma coleção revisada de locais do WindFinder, por exemplo, "schilksee" |
|
| 1974 | 1977 | windFinderSpotCollectionsList=Coleções de locais do WindFinder |
| 1975 | 1978 | enterTagsForTheImage=Inserir etiquetas para a imagem |
| 1976 | 1979 | unableToResolveWindFinderSpotId=Impossível resolver local do WindFinder com ID {0}: {1} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties
| ... | ... | @@ -1163,7 +1163,8 @@ racesScoredTooltip=Число гонок, которые участник зав |
| 1163 | 1163 | averageNumberOfOperationsPerMessage=Среднее число операций на сообщение |
| 1164 | 1164 | showUncorrectedTotalPoints=Показать неисправленный общий балл |
| 1165 | 1165 | setStartTimeReceived=Установить полученное время старта |
| 1166 | -setStartTimeReceivedDescription=Устанавливает полученное время старта для выбранной отслеживаемой гонки, которое не хранится постоянно. Это значит, что после перезагрузки сервера новое значение будет забыто. |
|
| 1166 | +setStartTimeReceivedDescription=Устанавливает введенное значение для полученного времени старта выбранной отслеживаемой гонки. Оставьте значение пустым, чтобы удалить текущее установленное полученное время старта. |
|
| 1167 | +setStartTimeReceivedNotice=Это изменение не хранится, т.е. новое значение будет забыто после перезагрузки сервера. |
|
| 1167 | 1168 | lastScoreCorrectionsTime=Время последнего исправления оценки |
| 1168 | 1169 | lastScoreCorrectionsComment=Комментарий последнего исправления оценки |
| 1169 | 1170 | setTimeToNow=Установить время ''сейчас'' |
| ... | ... | @@ -1275,11 +1276,13 @@ uploadSuccessful=Отправлено успешно |
| 1275 | 1276 | fileUploadResult=Отправка файла: {0} {1}.\nВ случае ошибки проверьте правильность конфигурации службы хранилища файлов. |
| 1276 | 1277 | removeUploadedFile=Удалить отправленный файл |
| 1277 | 1278 | showCompetitorBoatColumn=Лодка участника |
| 1279 | +showCompetitorSailIdColumn=Ид. паруса |
|
| 1280 | +showCompetitorSailIdColumnTooltip=Показывает ид. паруса плюс государственный флаг или изображение участника. Изображение участника, при наличии, имеет приоритет над государственным флагом. Если установлен параметр "{0}", будут отображены оба значка. |
|
| 1278 | 1281 | showCompetitorShortNameColumn=Краткое имя участника |
| 1279 | 1282 | showCompetitorShortNameColumnTooltip=Показывает краткое имя плюс государственный флаг или изображение участника. Изображение участника, при наличии, имеет приоритет над государственным флагом. Если установлен параметр "{0}", будут отображены оба значка. |
| 1280 | 1283 | showCompetitorFullNameColumn=Полное имя участника |
| 1281 | -showCompetitorNationalityColumn=Всегда показывать государственную принадлежность участника |
|
| 1282 | -showCompetitorNationalityColumnTooltip=Показывать и флаги государств, и изображения участников (при наличии) |
|
| 1284 | +alwaysShowCompetitorNationalityColumn=Всегда показывать государственную принадлежность участника |
|
| 1285 | +alwaysShowCompetitorNationalityColumnTooltip=Показывать и флаги государств, и изображения участников (при наличии) |
|
| 1283 | 1286 | loadingDimensionValues=Загрузка значений измерения |
| 1284 | 1287 | inviteBuoyTenders=Пригласить лоцманов |
| 1285 | 1288 | orMultipleEmails=или несколько адресов эл. почты через запятую |
| ... | ... | @@ -1970,7 +1973,7 @@ windFinderWindSourceTypeName=WindFinder |
| 1970 | 1973 | windFinderWindSourceTypeTooltip=Измерения ветра из одного или нескольких мест www.windfinder.com |
| 1971 | 1974 | windFinder=WindFinder |
| 1972 | 1975 | enterTagsForTheVideo=Введите теги для видео |
| 1973 | -enterIdOfWindfinderReviewedSpotCollection=Введите ид. просмотренной коллекции мест WindFinder (например, "schilksee") |
|
| 1976 | +enterIdOfWindFinderReviewedSpotCollection=Введите ид. просмотренной коллекции мест WindFinder (например, "schilksee") |
|
| 1974 | 1977 | windFinderSpotCollectionsList=Коллекции мест WindFinder |
| 1975 | 1978 | enterTagsForTheImage=Введите теги для изображения |
| 1976 | 1979 | unableToResolveWindFinderSpotId=Не удалось разрешить место WindFinder по ид. {0}: {1} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties
| ... | ... | @@ -1163,7 +1163,8 @@ racesScoredTooltip=参赛队完成并记录在此积分榜上的比赛轮次数 |
| 1163 | 1163 | averageNumberOfOperationsPerMessage=各消息操作的平均数 |
| 1164 | 1164 | showUncorrectedTotalPoints=显示未更正的总分 |
| 1165 | 1165 | setStartTimeReceived=设置接收的开始时间 |
| 1166 | -setStartTimeReceivedDescription=设置非持久的所选 TrackedRace 的 startTimeReceived。这意味着,重启服务器后,将忘记新值。 |
|
| 1166 | +setStartTimeReceivedDescription=将所选 TrackedRace 的 startTimeReceived 设置为提供的值。将此值留空,以移除当前设置的 startTimeReceived。 |
|
| 1167 | +setStartTimeReceivedNotice=此更改并不持久,即重启服务器后,新值将被忘记。 |
|
| 1167 | 1168 | lastScoreCorrectionsTime=上次得分更正时间 |
| 1168 | 1169 | lastScoreCorrectionsComment=上次得分更正评论 |
| 1169 | 1170 | setTimeToNow=将时间设为“现在” |
| ... | ... | @@ -1275,11 +1276,13 @@ uploadSuccessful=上传成功 |
| 1275 | 1276 | fileUploadResult=文件上传: {0} {1}。\n如果出错,请检查文件存储服务配置是否正确。 |
| 1276 | 1277 | removeUploadedFile=移除上传的文件 |
| 1277 | 1278 | showCompetitorBoatColumn=参赛队的船只 |
| 1279 | +showCompetitorSailIdColumn=帆号 |
|
| 1280 | +showCompetitorSailIdColumnTooltip=显示帆号和国籍旗帜或参赛队图像。如果可用,参赛队图像优先于国籍旗帜。如果设置 "{0}",将显示这两种图标。 |
|
| 1278 | 1281 | showCompetitorShortNameColumn=参赛队短名称 |
| 1279 | 1282 | showCompetitorShortNameColumnTooltip=显示短名称和国籍旗帜或参赛队图像。如果可用,参赛队图像优先于国籍旗帜。如果设置 "{0}",将显示这两种图标。 |
| 1280 | 1283 | showCompetitorFullNameColumn=参赛队全名 |
| 1281 | -showCompetitorNationalityColumn=始终显示参赛队国籍 |
|
| 1282 | -showCompetitorNationalityColumnTooltip=如果可用,显示两者:国籍旗帜和参赛队图像 |
|
| 1284 | +alwaysShowCompetitorNationalityColumn=始终显示参赛队国籍 |
|
| 1285 | +alwaysShowCompetitorNationalityColumnTooltip=如果可用,显示两者:国籍旗帜和参赛队图像 |
|
| 1283 | 1286 | loadingDimensionValues=正在加载尺寸值 |
| 1284 | 1287 | inviteBuoyTenders=邀请浮标供应船 |
| 1285 | 1288 | orMultipleEmails=或使用逗号隔开的多个电子邮件 |
| ... | ... | @@ -1970,7 +1973,7 @@ windFinderWindSourceTypeName=WindFinder |
| 1970 | 1973 | windFinderWindSourceTypeTooltip=Www.windfinder.com 中一个或多个地点的测量风力 |
| 1971 | 1974 | windFinder=WindFinder |
| 1972 | 1975 | enterTagsForTheVideo=为视频输入标记 |
| 1973 | -enterIdOfWindfinderReviewedSpotCollection=输入经检查的 WindFinder 地点集合的编号,例如 "schilksee" |
|
| 1976 | +enterIdOfWindFinderReviewedSpotCollection=输入经检查的 WindFinder 地点集合的编号,例如 "schilksee" |
|
| 1974 | 1977 | windFinderSpotCollectionsList=WindFinder 地点集合 |
| 1975 | 1978 | enterTagsForTheImage=为图像输入标记 |
| 1976 | 1979 | unableToResolveWindFinderSpotId=无法解析编号为{0}的 WindFinder 地点:{1} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/media/JSDownloadUtils.java
| ... | ... | @@ -10,6 +10,7 @@ import com.google.gwt.typedarrays.shared.Int8Array; |
| 10 | 10 | */ |
| 11 | 11 | public class JSDownloadUtils { |
| 12 | 12 | private static final Double REQUIRED_SIZE = 10000000.0; |
| 13 | + protected static final Double MAX_MEMORY_USAGE_FOR_DL = 1024 * 1024 * 1024 * 2d; |
|
| 13 | 14 | |
| 14 | 15 | public interface JSDownloadCallback { |
| 15 | 16 | void progress(Double current, Double total); |
| ... | ... | @@ -43,7 +44,7 @@ public class JSDownloadUtils { |
| 43 | 44 | getDataFast(url, callback, total, REQUIRED_SIZE); |
| 44 | 45 | } else { |
| 45 | 46 | //fallback will always work, if cors is supported, does not require any other server configuration |
| 46 | - getDataSlow(url, callback, REQUIRED_SIZE); |
|
| 47 | + getDataSlow(url, callback, REQUIRED_SIZE, MAX_MEMORY_USAGE_FOR_DL); |
|
| 47 | 48 | } |
| 48 | 49 | } |
| 49 | 50 | }); |
| ... | ... | @@ -53,75 +54,77 @@ public class JSDownloadUtils { |
| 53 | 54 | * Fast file download method based on range requests, only the first and the last REQUIRED_SIZE is loaded. |
| 54 | 55 | */ |
| 55 | 56 | private native static void getDataFast(String url, JSDownloadCallback callback, Double length, Double REQUIRED_SIZE) /*-{ |
| 56 | - try { |
|
| 57 | - var xhr = new XMLHttpRequest(); |
|
| 58 | - xhr.open("GET", url, true); |
|
| 59 | - xhr.setRequestHeader("Range", "bytes=0-" + REQUIRED_SIZE); |
|
| 60 | - xhr.responseType = "arraybuffer"; |
|
| 61 | - xhr.onprogress = function(evt) { |
|
| 62 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::progress(Ljava/lang/Double;Ljava/lang/Double;)(evt.loaded, evt.total); |
|
| 63 | - } |
|
| 64 | - xhr.error = function(error) { |
|
| 65 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
|
| 66 | - } |
|
| 67 | - |
|
| 68 | - xhr.onreadystatechange = function() { |
|
| 69 | - var state = xhr.readyState; |
|
| 70 | - if (state == 4) { |
|
| 71 | - if (xhr.response) { |
|
| 72 | - var startLength = xhr.response.byteLength; |
|
| 73 | - var start = new Int8Array(xhr.response); |
|
| 57 | + try { |
|
| 58 | + var xhr = new XMLHttpRequest(); |
|
| 59 | + xhr.open("GET", url, true); |
|
| 60 | + xhr.setRequestHeader("Range", "bytes=0-" + REQUIRED_SIZE); |
|
| 61 | + xhr.responseType = "arraybuffer"; |
|
| 62 | + xhr.onprogress = function(evt) { |
|
| 63 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::progress(Ljava/lang/Double;Ljava/lang/Double;)(evt.loaded, evt.total); |
|
| 64 | + } |
|
| 65 | + xhr.error = function(error) { |
|
| 66 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
|
| 67 | + } |
|
| 74 | 68 | |
| 75 | - try { |
|
| 76 | - var xhr2 = new XMLHttpRequest(); |
|
| 77 | - xhr2.open("GET", url, true); |
|
| 78 | - xhr2.setRequestHeader("Range", "bytes=" + (length - REQUIRED_SIZE)); |
|
| 79 | - xhr2.responseType = "arraybuffer"; |
|
| 80 | - xhr2.onprogress = function(evt) { |
|
| 81 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::progress(Ljava/lang/Double;Ljava/lang/Double;)(evt.loaded, evt.total); |
|
| 82 | - } |
|
| 83 | - xhr2.error = function(error) { |
|
| 69 | + xhr.onreadystatechange = function() { |
|
| 70 | + var state = xhr.readyState; |
|
| 71 | + if (state == 4) { |
|
| 72 | + if (xhr.response) { |
|
| 73 | + var startLength = xhr.response.byteLength; |
|
| 74 | + var start = new Int8Array(xhr.response); |
|
| 75 | + |
|
| 76 | + try { |
|
| 77 | + var xhr2 = new XMLHttpRequest(); |
|
| 78 | + xhr2.open("GET", url, true); |
|
| 79 | + xhr2.setRequestHeader("Range", "bytes=" |
|
| 80 | + + (length - REQUIRED_SIZE) + "-"); |
|
| 81 | + xhr2.responseType = "arraybuffer"; |
|
| 82 | + xhr2.onprogress = function(evt) { |
|
| 83 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::progress(Ljava/lang/Double;Ljava/lang/Double;)(evt.loaded, evt.total); |
|
| 84 | + } |
|
| 85 | + xhr2.error = function(error) { |
|
| 86 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + xhr2.onreadystatechange = function() { |
|
| 90 | + var state = xhr2.readyState; |
|
| 91 | + if (state == 4) { |
|
| 92 | + if (xhr2.response) { |
|
| 93 | + var endLength = xhr2.response.byteLength; |
|
| 94 | + var end = new Int8Array(xhr2.response); |
|
| 95 | + var sparse = length - startLength |
|
| 96 | + - endLength; |
|
| 97 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::complete(Lcom/google/gwt/typedarrays/shared/Int8Array;Lcom/google/gwt/typedarrays/shared/Int8Array;Ljava/lang/Double;)(start, end, sparse); |
|
| 98 | + } |
|
| 99 | + } |
|
| 100 | + }; |
|
| 101 | + xhr2.send(); |
|
| 102 | + } catch (error) { |
|
| 84 | 103 | callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
| 85 | 104 | } |
| 86 | - |
|
| 87 | - xhr2.onreadystatechange = function() { |
|
| 88 | - var state = xhr2.readyState; |
|
| 89 | - if (state == 4) { |
|
| 90 | - if (xhr2.response) { |
|
| 91 | - var endLength = xhr2.response.byteLength; |
|
| 92 | - var end = new Int8Array(xhr2.response); |
|
| 93 | - var sparse = length - startLength - endLength; |
|
| 94 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::complete(Lcom/google/gwt/typedarrays/shared/Int8Array;Lcom/google/gwt/typedarrays/shared/Int8Array;Ljava/lang/Double;)(start, end, sparse); |
|
| 95 | - } |
|
| 96 | - } |
|
| 97 | - }; |
|
| 98 | - xhr2.send(); |
|
| 99 | - } catch (error) { |
|
| 100 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
|
| 101 | 105 | } |
| 102 | 106 | } |
| 103 | - } |
|
| 104 | - }; |
|
| 105 | - xhr.send(); |
|
| 106 | - } catch (error) { |
|
| 107 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
|
| 108 | - } |
|
| 109 | -}-*/; |
|
| 107 | + }; |
|
| 108 | + xhr.send(); |
|
| 109 | + } catch (error) { |
|
| 110 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
|
| 111 | + } |
|
| 112 | + }-*/; |
|
| 110 | 113 | |
| 111 | 114 | /** |
| 112 | 115 | * Determines if a server can deliver a file with range requests, and if so returns the size of the file |
| 113 | 116 | */ |
| 114 | 117 | private native static void getFileSizeIfFastPath(String url, JSSizeCallback callback) /*-{ |
| 115 | - try { |
|
| 118 | + try { |
|
| 116 | 119 | var xhr = new XMLHttpRequest(); |
| 117 | 120 | xhr.open("HEAD", url, true); |
| 118 | 121 | xhr.responseType = "arraybuffer"; |
| 119 | 122 | xhr.error = function(error) { |
| 120 | 123 | callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSSizeCallback::size(Ljava/lang/Double;)(-1.0); |
| 121 | 124 | } |
| 122 | - |
|
| 125 | + |
|
| 123 | 126 | xhr.onreadystatechange = function() { |
| 124 | - var state = xhr.readyState; |
|
| 127 | + var state = xhr.readyState; |
|
| 125 | 128 | if (state == 4) { |
| 126 | 129 | if (xhr.response) { |
| 127 | 130 | var length = xhr.getResponseHeader("Content-Length"); |
| ... | ... | @@ -141,29 +144,36 @@ public class JSDownloadUtils { |
| 141 | 144 | /** |
| 142 | 145 | * If range requests are not possible, the whole file is downloaded and then slices to the required parts |
| 143 | 146 | */ |
| 144 | - private native static void getDataSlow(String url, JSDownloadCallback callback, Double REQUIRED_SIZE) /*-{ |
|
| 147 | + private native static void getDataSlow(String url, JSDownloadCallback callback, Double REQUIRED_SIZE, |
|
| 148 | + Double maxMemoryUsage) /*-{ |
|
| 145 | 149 | try { |
| 146 | 150 | var xhr = new XMLHttpRequest(); |
| 147 | 151 | xhr.open("GET", url, true); |
| 148 | 152 | xhr.responseType = "arraybuffer"; |
| 149 | 153 | xhr.onprogress = function(evt) { |
| 154 | + //ensure not more memory is used by the tab than commonly available in browsers |
|
| 155 | + if (evt.total > maxMemoryUsage || evt.loaded > maxMemoryUsage) { |
|
| 156 | + xhr.abort(); |
|
| 157 | + } |
|
| 150 | 158 | callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::progress(Ljava/lang/Double;Ljava/lang/Double;)(evt.loaded, evt.total); |
| 151 | 159 | } |
| 152 | 160 | xhr.error = function(error) { |
| 153 | 161 | callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)(error); |
| 154 | 162 | } |
| 155 | - |
|
| 163 | + |
|
| 156 | 164 | xhr.onreadystatechange = function() { |
| 157 | - var state = xhr.readyState; |
|
| 165 | + var state = xhr.readyState; |
|
| 158 | 166 | if (state == 4) { |
| 159 | 167 | if (xhr.response) { |
| 160 | 168 | var length = xhr.response.byteLength; |
| 161 | - var start = new Int8Array(xhr.response.slice(0, REQUIRED_SIZE)); |
|
| 162 | - var end = new Int8Array(xhr.response.slice(length - REQUIRED_SIZE)); |
|
| 169 | + var start = new Int8Array(xhr.response.slice(0, |
|
| 170 | + REQUIRED_SIZE)); |
|
| 171 | + var end = new Int8Array(xhr.response.slice(length |
|
| 172 | + - REQUIRED_SIZE)); |
|
| 163 | 173 | var sparse = length - 2 * REQUIRED_SIZE; |
| 164 | 174 | callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::complete(Lcom/google/gwt/typedarrays/shared/Int8Array;Lcom/google/gwt/typedarrays/shared/Int8Array;Ljava/lang/Double;)(start, end, sparse); |
| 165 | 175 | } else { |
| 166 | - callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)("No result"); |
|
| 176 | + callback.@com.sap.sailing.gwt.ui.client.media.JSDownloadUtils.JSDownloadCallback::error(Ljava/lang/Object;)("No result"); |
|
| 167 | 177 | } |
| 168 | 178 | } |
| 169 | 179 | }; |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/EditMarkPassingsPanel.java
| ... | ... | @@ -11,6 +11,7 @@ import com.google.gwt.cell.client.AbstractCell; |
| 11 | 11 | import com.google.gwt.event.dom.client.ClickEvent; |
| 12 | 12 | import com.google.gwt.event.dom.client.ClickHandler; |
| 13 | 13 | import com.google.gwt.i18n.client.DateTimeFormat; |
| 14 | +import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; |
|
| 14 | 15 | import com.google.gwt.safehtml.shared.SafeHtml; |
| 15 | 16 | import com.google.gwt.safehtml.shared.SafeHtmlBuilder; |
| 16 | 17 | import com.google.gwt.user.cellview.client.CellTable; |
| ... | ... | @@ -134,7 +135,7 @@ public class EditMarkPassingsPanel extends AbstractCompositeComponent<AbstractSe |
| 134 | 135 | }; |
| 135 | 136 | } |
| 136 | 137 | }, stringMessages.waypoint()); |
| 137 | - final DateTimeFormat timeFormat = DateTimeFormat.getFormat("HH:mm:ss"); |
|
| 138 | + final DateTimeFormat timeFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_TIME_FULL); |
|
| 138 | 139 | wayPointSelectionTable.addColumn(new Column<Util.Pair<Integer, Date>, SafeHtml>(new AnchorCell()) { |
| 139 | 140 | @Override |
| 140 | 141 | public SafeHtml getValue(final Pair<Integer, Date> object) { |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/EditMarkPositionPanel.java
| ... | ... | @@ -5,9 +5,11 @@ import java.util.Collection; |
| 5 | 5 | import java.util.Comparator; |
| 6 | 6 | import java.util.Date; |
| 7 | 7 | import java.util.HashMap; |
| 8 | +import java.util.HashSet; |
|
| 8 | 9 | import java.util.List; |
| 9 | 10 | import java.util.Map; |
| 10 | 11 | import java.util.Map.Entry; |
| 12 | +import java.util.Set; |
|
| 11 | 13 | import java.util.SortedMap; |
| 12 | 14 | import java.util.TreeMap; |
| 13 | 15 | |
| ... | ... | @@ -132,6 +134,8 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i |
| 132 | 134 | private final RaceIdentifierToLeaderboardRaceColumnAndFleetMapper raceIdentifierToLeaderboardRaceColumnAndFleetMapper; |
| 133 | 135 | protected boolean nonTrackingWarningWasDisplayed; |
| 134 | 136 | |
| 137 | + private final Set<MarkDTO> marksCurrentlyRequestedViaRemoteCall = new HashSet<>(); |
|
| 138 | + |
|
| 135 | 139 | public EditMarkPositionPanel(Component<?> parent, ComponentContext<?> context, final RaceMap raceMap, |
| 136 | 140 | final SingleRaceLeaderboardPanel leaderboardPanel, |
| 137 | 141 | RegattaAndRaceIdentifier selectedRaceIdentifier, String leaderboardName, final StringMessages stringMessages, |
| ... | ... | @@ -735,10 +739,7 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i |
| 735 | 739 | } |
| 736 | 740 | raceMap.unregisterAllCourseMarkInfoWindowClickHandlers(); |
| 737 | 741 | } else { |
| 738 | - if (currentFixPositionChooser != null) { |
|
| 739 | - currentFixPositionChooser.cancel(); |
|
| 740 | - currentFixPositionChooser = null; |
|
| 741 | - } |
|
| 742 | + cancelFixPositionChooserAndNotification(); |
|
| 742 | 743 | marksPanel.deselectMark(); |
| 743 | 744 | selectedMark = null; |
| 744 | 745 | if (sideBySideComponentViewer != null) { |
| ... | ... | @@ -754,6 +755,17 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i |
| 754 | 755 | super.setVisible(visible); |
| 755 | 756 | } |
| 756 | 757 | |
| 758 | + private void cancelFixPositionChooserAndNotification() { |
|
| 759 | + if (currentFixPositionChooser != null) { |
|
| 760 | + currentFixPositionChooser.cancel(); |
|
| 761 | + currentFixPositionChooser = null; |
|
| 762 | + if (notificationTimer.isRunning()) { |
|
| 763 | + notificationTimer.run(); |
|
| 764 | + notificationTimer.cancel(); |
|
| 765 | + } |
|
| 766 | + } |
|
| 767 | + } |
|
| 768 | + |
|
| 757 | 769 | private void checkIfTracking(Runnable continuation) { |
| 758 | 770 | if (nonTrackingWarningWasDisplayed) { |
| 759 | 771 | continuation.run(); |
| ... | ... | @@ -859,11 +871,10 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i |
| 859 | 871 | } |
| 860 | 872 | |
| 861 | 873 | private void selectMark(MarkDTO mark) { |
| 862 | - selectedMark = mark; |
|
| 863 | - if (currentFixPositionChooser != null) { |
|
| 864 | - currentFixPositionChooser.cancel(); |
|
| 865 | - currentFixPositionChooser = null; |
|
| 874 | + if (selectedMark != mark) { |
|
| 875 | + cancelFixPositionChooserAndNotification(); |
|
| 866 | 876 | } |
| 877 | + selectedMark = mark; |
|
| 867 | 878 | if (selectedMark != null) { |
| 868 | 879 | if (marksFromToTimes.get(selectedMark) != null) { |
| 869 | 880 | // For some reason the time slider does not change with this method only if you comment out line 430 and 432 in TimePanel it works |
| ... | ... | @@ -905,24 +916,43 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i |
| 905 | 916 | @Override |
| 906 | 917 | public void onSelectionChange(SelectionChangeEvent event) { |
| 907 | 918 | final MarkDTO mark = marksPanel.getSelectedMark(); |
| 919 | + retrieveAndSelectMarkIfNecessary(mark, null); |
|
| 920 | + } |
|
| 921 | + |
|
| 922 | + protected void retrieveAndSelectMarkIfNecessary(final MarkDTO mark, final Runnable callback) { |
|
| 908 | 923 | if (mark != null && (marks.get(mark) == null || marks.get(mark).isEmpty())) { |
| 909 | - if (mark != null) { |
|
| 910 | - markPositionService.getMarkTrack(raceIdentifierToLeaderboardRaceColumnAndFleetMapper.getLeaderboardNameAndRaceColumnNameAndFleetName(selectedRaceIdentifier), |
|
| 924 | + |
|
| 925 | + if (marksCurrentlyRequestedViaRemoteCall.add(mark)) { |
|
| 926 | + markPositionService.getMarkTrack( |
|
| 927 | + raceIdentifierToLeaderboardRaceColumnAndFleetMapper |
|
| 928 | + .getLeaderboardNameAndRaceColumnNameAndFleetName(selectedRaceIdentifier), |
|
| 911 | 929 | mark.getIdAsString(), new AsyncCallback<MarkTrackDTO>() { |
| 912 | 930 | @Override |
| 913 | 931 | public void onFailure(Throwable caught) { |
| 914 | - errorReporter.reportError(stringMessages.errorCommunicatingWithServer()+": "+caught.getMessage()); |
|
| 932 | + marksCurrentlyRequestedViaRemoteCall.remove(mark); |
|
| 933 | + errorReporter.reportError( |
|
| 934 | + stringMessages.errorCommunicatingWithServer() + ": " + caught.getMessage()); |
|
| 915 | 935 | } |
| 916 | - |
|
| 936 | + |
|
| 917 | 937 | @Override |
| 918 | 938 | public void onSuccess(MarkTrackDTO result) { |
| 939 | + marksCurrentlyRequestedViaRemoteCall.remove(mark); |
|
| 919 | 940 | createMarkTrackUi(mark, result.getFixes()); |
| 920 | 941 | selectMark(mark); |
| 942 | + if (callback != null) { |
|
| 943 | + callback.run(); |
|
| 944 | + } |
|
| 921 | 945 | } |
| 922 | 946 | }); |
| 923 | 947 | } |
| 948 | + else { |
|
| 949 | + // remote call of the same mark already in progress -> ignore this request |
|
| 950 | + } |
|
| 924 | 951 | } else { |
| 925 | 952 | selectMark(mark); |
| 953 | + if (callback != null) { |
|
| 954 | + callback.run(); |
|
| 955 | + } |
|
| 926 | 956 | } |
| 927 | 957 | } |
| 928 | 958 |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/MarksPanel.java
| ... | ... | @@ -85,22 +85,27 @@ public class MarksPanel extends AbstractCompositeComponent<AbstractSettings> { |
| 85 | 85 | @Override |
| 86 | 86 | public void update(int index, final MarkDTO mark, String value) { |
| 87 | 87 | final Date timePoint = parent.timer.getTime(); |
| 88 | - select(mark); |
|
| 89 | - if (parent.hasFixAtTimePoint(mark, timePoint)) { |
|
| 90 | - parent.showNotification(stringMessages.pleaseSelectOtherTimepoint(), NotificationType.ERROR); |
|
| 91 | - } else { |
|
| 92 | - parent.createFixPositionChooserToAddFixToMark(mark, new Callback<Position, Exception>() { |
|
| 93 | - @Override |
|
| 94 | - public void onFailure(Exception reason) { |
|
| 95 | - parent.resetCurrentFixPositionChooser(); |
|
| 88 | + parent.retrieveAndSelectMarkIfNecessary(mark, new Runnable() { |
|
| 89 | + |
|
| 90 | + @Override |
|
| 91 | + public void run() { |
|
| 92 | + if (parent.hasFixAtTimePoint(mark, timePoint)) { |
|
| 93 | + parent.showNotification(stringMessages.pleaseSelectOtherTimepoint(), NotificationType.ERROR); |
|
| 94 | + } else { |
|
| 95 | + parent.createFixPositionChooserToAddFixToMark(mark, new Callback<Position, Exception>() { |
|
| 96 | + @Override |
|
| 97 | + public void onFailure(final Exception reason) { |
|
| 98 | + parent.resetCurrentFixPositionChooser(); |
|
| 99 | + } |
|
| 100 | + @Override |
|
| 101 | + public void onSuccess(Position result) { |
|
| 102 | + parent.addMarkFix(mark, timePoint, result); |
|
| 103 | + parent.resetCurrentFixPositionChooser(); |
|
| 104 | + } |
|
| 105 | + }); |
|
| 96 | 106 | } |
| 97 | - @Override |
|
| 98 | - public void onSuccess(Position result) { |
|
| 99 | - parent.addMarkFix(mark, timePoint, result); |
|
| 100 | - parent.resetCurrentFixPositionChooser(); |
|
| 101 | - } |
|
| 102 | - }); |
|
| 103 | - } |
|
| 107 | + } |
|
| 108 | + }); |
|
| 104 | 109 | } |
| 105 | 110 | }); |
| 106 | 111 | markTable.addColumn(addFixColumn); |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/RaceMap.java
| ... | ... | @@ -622,116 +622,123 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme |
| 622 | 622 | loadLibraries.add(LoadLibrary.GEOMETRY); |
| 623 | 623 | |
| 624 | 624 | Runnable onLoad = new Runnable() { |
| 625 | - @Override |
|
| 626 | - public void run() { |
|
| 627 | - MapOptions mapOptions = getMapOptions(showMapControls, /* wind up */ false); |
|
| 628 | - map = new MapWidget(mapOptions); |
|
| 629 | - rootPanel.add(map, 0, 0); |
|
| 630 | - if (showHeaderPanel) { |
|
| 631 | - Image sapLogo = createSAPLogo(); |
|
| 632 | - rootPanel.add(sapLogo); |
|
| 633 | - } |
|
| 634 | - |
|
| 635 | - map.setControls(ControlPosition.LEFT_TOP, topLeftControlsWrapperPanel); |
|
| 636 | - adjustLeftControlsIndent(); |
|
| 637 | - |
|
| 638 | - RaceMap.this.raceMapImageManager.loadMapIcons(map); |
|
| 639 | - map.setSize("100%", "100%"); |
|
| 640 | - map.addZoomChangeHandler(new ZoomChangeMapHandler() { |
|
| 641 | - @Override |
|
| 642 | - public void onEvent(ZoomChangeMapEvent event) { |
|
| 643 | - if (!autoZoomIn && !autoZoomOut && !orientationChangeInProgress) { |
|
| 644 | - // stop automatic zoom after a manual zoom event; automatic zoom in zoomMapToNewBounds will restore old settings |
|
| 645 | - final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList(); |
|
| 646 | - RaceMapZoomSettings clearedZoomSettings = new RaceMapZoomSettings(emptyList, settings.getZoomSettings().isZoomToSelectedCompetitors()); |
|
| 647 | - settings = new RaceMapSettings(settings, clearedZoomSettings); |
|
| 648 | - } |
|
| 649 | - // TODO bug489 when in wind-up mode, avoid zooming out too far; perhaps zoom back in if zoomed out too far |
|
| 650 | - } |
|
| 651 | - }); |
|
| 652 | - map.addDragEndHandler(new DragEndMapHandler() { |
|
| 653 | - @Override |
|
| 654 | - public void onEvent(DragEndMapEvent event) { |
|
| 655 | - // stop automatic zoom after a manual drag event |
|
| 656 | - autoZoomIn = false; |
|
| 657 | - autoZoomOut = false; |
|
| 658 | - final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList(); |
|
| 659 | - RaceMapZoomSettings clearedZoomSettings = new RaceMapZoomSettings(emptyList, settings.getZoomSettings().isZoomToSelectedCompetitors()); |
|
| 660 | - settings = new RaceMapSettings(settings, clearedZoomSettings); |
|
| 661 | - } |
|
| 662 | - }); |
|
| 663 | - map.addIdleHandler(new IdleMapHandler() { |
|
| 664 | - @Override |
|
| 665 | - public void onEvent(IdleMapEvent event) { |
|
| 666 | - // the "idle"-event is raised at the end of map-animations |
|
| 667 | - if (autoZoomIn) { |
|
| 668 | - // finalize zoom-in that was started with panTo() in zoomMapToNewBounds() |
|
| 669 | - map.setZoom(autoZoomLevel); |
|
| 670 | - autoZoomIn = false; |
|
| 671 | - } |
|
| 672 | - if (autoZoomOut) { |
|
| 673 | - // finalize zoom-out that was started with setZoom() in zoomMapToNewBounds() |
|
| 674 | - map.panTo(autoZoomLatLngBounds.getCenter()); |
|
| 675 | - autoZoomOut = false; |
|
| 676 | - } |
|
| 677 | - } |
|
| 678 | - }); |
|
| 679 | - map.addBoundsChangeHandler(new BoundsChangeMapHandler() { |
|
| 680 | - @Override |
|
| 681 | - public void onEvent(BoundsChangeMapEvent event) { |
|
| 682 | - int newZoomLevel = map.getZoom(); |
|
| 683 | - if (!isAutoZoomInProgress() && (newZoomLevel != currentZoomLevel)) { |
|
| 684 | - removeTransitions(); |
|
| 685 | - } |
|
| 686 | - if ((streamletOverlay != null) && !map.getBounds().equals(currentMapBounds)) { |
|
| 687 | - streamletOverlay.onBoundsChanged(newZoomLevel != currentZoomLevel); |
|
| 688 | - } |
|
| 689 | - if ((simulationOverlay != null) && !map.getBounds().equals(currentMapBounds)) { |
|
| 690 | - simulationOverlay.onBoundsChanged(newZoomLevel != currentZoomLevel); |
|
| 691 | - } |
|
| 692 | - currentMapBounds = map.getBounds(); |
|
| 693 | - currentZoomLevel = newZoomLevel; |
|
| 694 | - headerPanel.getElement().getStyle().setWidth(map.getOffsetWidth(), Unit.PX); |
|
| 695 | - } |
|
| 696 | - }); |
|
| 697 | - |
|
| 698 | - // If there was a time change before the API was loaded, reset the time |
|
| 699 | - if (lastTimeChangeBeforeInitialization != null) { |
|
| 700 | - timeChanged(lastTimeChangeBeforeInitialization, null); |
|
| 701 | - lastTimeChangeBeforeInitialization = null; |
|
| 702 | - } |
|
| 703 | - // Initialize streamlet canvas for wind visualization; it shouldn't be doing anything unless it's visible |
|
| 704 | - streamletOverlay = new WindStreamletsRaceboardOverlay(getMap(), /* zIndex */ 0, |
|
| 705 | - timer, raceIdentifier, sailingService, asyncActionsExecutor, stringMessages, coordinateSystem); |
|
| 706 | - streamletOverlay.addToMap(); |
|
| 707 | - if (settings.isShowWindStreamletOverlay()) { |
|
| 708 | - streamletOverlay.setColors(settings.isShowWindStreamletColors()); |
|
| 709 | - streamletOverlay.setVisible(true); |
|
| 710 | - } |
|
| 711 | - |
|
| 712 | - if (isSimulationEnabled) { |
|
| 713 | - // determine availability of polar diagram |
|
| 714 | - setHasPolar(); |
|
| 715 | - // initialize simulation canvas |
|
| 716 | - simulationOverlay = new RaceSimulationOverlay(getMap(), /* zIndex */ 0, raceIdentifier, sailingService, stringMessages, asyncActionsExecutor, coordinateSystem); |
|
| 717 | - simulationOverlay.addToMap(); |
|
| 718 | - showSimulationOverlay(settings.isShowSimulationOverlay()); |
|
| 719 | - } |
|
| 720 | - if (showHeaderPanel) { |
|
| 721 | - createHeaderPanel(map); |
|
| 722 | - } |
|
| 723 | - if (showMapControls) { |
|
| 724 | - createSettingsButton(map); |
|
| 725 | - } |
|
| 726 | - // Data has been initialized |
|
| 727 | - RaceMap.this.isMapInitialized = true; |
|
| 728 | - RaceMap.this.redraw(); |
|
| 729 | - trueNorthIndicatorPanel.redraw(); |
|
| 730 | - showAdditionalControls(map); |
|
| 731 | - RaceMap.this.managedInfoWindow = new ManagedInfoWindow(map); |
|
| 732 | - } |
|
| 625 | + @Override |
|
| 626 | + public void run() { |
|
| 627 | + MapOptions mapOptions = getMapOptions(showMapControls, /* wind up */ false); |
|
| 628 | + map = new MapWidget(mapOptions); |
|
| 629 | + rootPanel.add(map, 0, 0); |
|
| 630 | + if (showHeaderPanel) { |
|
| 631 | + Image sapLogo = createSAPLogo(); |
|
| 632 | + rootPanel.add(sapLogo); |
|
| 633 | + } |
|
| 634 | + |
|
| 635 | + map.setControls(ControlPosition.LEFT_TOP, topLeftControlsWrapperPanel); |
|
| 636 | + adjustLeftControlsIndent(); |
|
| 637 | + |
|
| 638 | + RaceMap.this.raceMapImageManager.loadMapIcons(map); |
|
| 639 | + map.setSize("100%", "100%"); |
|
| 640 | + map.addZoomChangeHandler(new ZoomChangeMapHandler() { |
|
| 641 | + @Override |
|
| 642 | + public void onEvent(ZoomChangeMapEvent event) { |
|
| 643 | + if (!autoZoomIn && !autoZoomOut && !orientationChangeInProgress) { |
|
| 644 | + // stop automatic zoom after a manual zoom event; automatic zoom in zoomMapToNewBounds will |
|
| 645 | + // restore old settings |
|
| 646 | + final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList(); |
|
| 647 | + RaceMapZoomSettings clearedZoomSettings = new RaceMapZoomSettings(emptyList, |
|
| 648 | + settings.getZoomSettings().isZoomToSelectedCompetitors()); |
|
| 649 | + settings = new RaceMapSettings(settings, clearedZoomSettings); |
|
| 650 | + } |
|
| 651 | + // TODO bug489 when in wind-up mode, avoid zooming out too far; perhaps zoom back in if zoomed |
|
| 652 | + // out too far |
|
| 653 | + } |
|
| 654 | + }); |
|
| 655 | + map.addDragEndHandler(new DragEndMapHandler() { |
|
| 656 | + @Override |
|
| 657 | + public void onEvent(DragEndMapEvent event) { |
|
| 658 | + // stop automatic zoom after a manual drag event |
|
| 659 | + autoZoomIn = false; |
|
| 660 | + autoZoomOut = false; |
|
| 661 | + final List<RaceMapZoomSettings.ZoomTypes> emptyList = Collections.emptyList(); |
|
| 662 | + RaceMapZoomSettings clearedZoomSettings = new RaceMapZoomSettings(emptyList, |
|
| 663 | + settings.getZoomSettings().isZoomToSelectedCompetitors()); |
|
| 664 | + settings = new RaceMapSettings(settings, clearedZoomSettings); |
|
| 665 | + } |
|
| 666 | + }); |
|
| 667 | + map.addIdleHandler(new IdleMapHandler() { |
|
| 668 | + @Override |
|
| 669 | + public void onEvent(IdleMapEvent event) { |
|
| 670 | + // the "idle"-event is raised at the end of map-animations |
|
| 671 | + if (autoZoomIn) { |
|
| 672 | + // finalize zoom-in that was started with panTo() in zoomMapToNewBounds() |
|
| 673 | + map.setZoom(autoZoomLevel); |
|
| 674 | + autoZoomIn = false; |
|
| 675 | + } |
|
| 676 | + if (autoZoomOut) { |
|
| 677 | + // finalize zoom-out that was started with setZoom() in zoomMapToNewBounds() |
|
| 678 | + map.panTo(autoZoomLatLngBounds.getCenter()); |
|
| 679 | + autoZoomOut = false; |
|
| 680 | + } |
|
| 681 | + redraw(); |
|
| 682 | + } |
|
| 683 | + }); |
|
| 684 | + map.addBoundsChangeHandler(new BoundsChangeMapHandler() { |
|
| 685 | + @Override |
|
| 686 | + public void onEvent(BoundsChangeMapEvent event) { |
|
| 687 | + int newZoomLevel = map.getZoom(); |
|
| 688 | + if (!isAutoZoomInProgress() && (newZoomLevel != currentZoomLevel)) { |
|
| 689 | + removeTransitions(); |
|
| 690 | + } |
|
| 691 | + if ((streamletOverlay != null) && !map.getBounds().equals(currentMapBounds)) { |
|
| 692 | + streamletOverlay.onBoundsChanged(newZoomLevel != currentZoomLevel); |
|
| 693 | + } |
|
| 694 | + if ((simulationOverlay != null) && !map.getBounds().equals(currentMapBounds)) { |
|
| 695 | + simulationOverlay.onBoundsChanged(newZoomLevel != currentZoomLevel); |
|
| 696 | + } |
|
| 697 | + currentMapBounds = map.getBounds(); |
|
| 698 | + currentZoomLevel = newZoomLevel; |
|
| 699 | + headerPanel.getElement().getStyle().setWidth(map.getOffsetWidth(), Unit.PX); |
|
| 700 | + } |
|
| 701 | + }); |
|
| 702 | + |
|
| 703 | + // If there was a time change before the API was loaded, reset the time |
|
| 704 | + if (lastTimeChangeBeforeInitialization != null) { |
|
| 705 | + timeChanged(lastTimeChangeBeforeInitialization, null); |
|
| 706 | + lastTimeChangeBeforeInitialization = null; |
|
| 707 | + } |
|
| 708 | + // Initialize streamlet canvas for wind visualization; it shouldn't be doing anything unless it's |
|
| 709 | + // visible |
|
| 710 | + streamletOverlay = new WindStreamletsRaceboardOverlay(getMap(), /* zIndex */ 0, timer, raceIdentifier, |
|
| 711 | + sailingService, asyncActionsExecutor, stringMessages, coordinateSystem); |
|
| 712 | + streamletOverlay.addToMap(); |
|
| 713 | + if (settings.isShowWindStreamletOverlay()) { |
|
| 714 | + streamletOverlay.setColors(settings.isShowWindStreamletColors()); |
|
| 715 | + streamletOverlay.setVisible(true); |
|
| 716 | + } |
|
| 717 | + |
|
| 718 | + if (isSimulationEnabled) { |
|
| 719 | + // determine availability of polar diagram |
|
| 720 | + setHasPolar(); |
|
| 721 | + // initialize simulation canvas |
|
| 722 | + simulationOverlay = new RaceSimulationOverlay(getMap(), /* zIndex */ 0, raceIdentifier, |
|
| 723 | + sailingService, stringMessages, asyncActionsExecutor, coordinateSystem); |
|
| 724 | + simulationOverlay.addToMap(); |
|
| 725 | + showSimulationOverlay(settings.isShowSimulationOverlay()); |
|
| 726 | + } |
|
| 727 | + if (showHeaderPanel) { |
|
| 728 | + createHeaderPanel(map); |
|
| 729 | + } |
|
| 730 | + if (showMapControls) { |
|
| 731 | + createSettingsButton(map); |
|
| 732 | + } |
|
| 733 | + // Data has been initialized |
|
| 734 | + RaceMap.this.isMapInitialized = true; |
|
| 735 | + RaceMap.this.redraw(); |
|
| 736 | + trueNorthIndicatorPanel.redraw(); |
|
| 737 | + showAdditionalControls(map); |
|
| 738 | + RaceMap.this.managedInfoWindow = new ManagedInfoWindow(map); |
|
| 739 | + } |
|
| 733 | 740 | }; |
| 734 | - LoadApi.go(onLoad, loadLibraries, sensor, GoogleMapAPIKey.V3_PARAMS); |
|
| 741 | + LoadApi.go(onLoad, loadLibraries, sensor, GoogleMapAPIKey.V3_PARAMS); |
|
| 735 | 742 | } |
| 736 | 743 | |
| 737 | 744 | /** |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/maneuver/ManeuverTableData.java
| ... | ... | @@ -12,6 +12,7 @@ import com.sap.sailing.gwt.ui.shared.ManeuverDTO; |
| 12 | 12 | class ManeuverTableData { |
| 13 | 13 | |
| 14 | 14 | private final String competitorName; |
| 15 | + private final String competitorColor; |
|
| 15 | 16 | private final Date timePoint; |
| 16 | 17 | private final Date timePointBefore; |
| 17 | 18 | private final ManeuverType maneuverType; |
| ... | ... | @@ -24,8 +25,9 @@ class ManeuverTableData { |
| 24 | 25 | private final double directionChange; |
| 25 | 26 | private final boolean markPassing; |
| 26 | 27 | |
| 27 | - ManeuverTableData(final CompetitorDTO competitor, final ManeuverDTO maneuver) { |
|
| 28 | + ManeuverTableData(final CompetitorDTO competitor, final String competitorColor, final ManeuverDTO maneuver) { |
|
| 28 | 29 | this.competitorName = competitor.getName(); |
| 30 | + this.competitorColor = competitorColor; |
|
| 29 | 31 | this.timePoint = maneuver.getTimePoint(); |
| 30 | 32 | this.timePointBefore = maneuver.getTimePointBefore(); |
| 31 | 33 | this.maneuverType = maneuver.getType(); |
| ... | ... | @@ -43,6 +45,10 @@ class ManeuverTableData { |
| 43 | 45 | return competitorName; |
| 44 | 46 | } |
| 45 | 47 | |
| 48 | + public String getCompetitorColor() { |
|
| 49 | + return competitorColor; |
|
| 50 | + } |
|
| 51 | + |
|
| 46 | 52 | public Date getTimePoint() { |
| 47 | 53 | return timePoint; |
| 48 | 54 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/racemap/maneuver/ManeuverTablePanel.java
| ... | ... | @@ -38,8 +38,8 @@ import com.sap.sailing.domain.common.security.Permission; |
| 38 | 38 | import com.sap.sailing.domain.common.security.SailingPermissionsForRoleProvider; |
| 39 | 39 | import com.sap.sailing.gwt.ui.actions.GetManeuversForCompetitorsAction; |
| 40 | 40 | import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener; |
| 41 | -import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider; |
|
| 42 | 41 | import com.sap.sailing.gwt.ui.client.ManeuverTypeFormatter; |
| 42 | +import com.sap.sailing.gwt.ui.client.RaceCompetitorSelectionProvider; |
|
| 43 | 43 | import com.sap.sailing.gwt.ui.client.SailingServiceAsync; |
| 44 | 44 | import com.sap.sailing.gwt.ui.client.StringMessages; |
| 45 | 45 | import com.sap.sailing.gwt.ui.client.shared.controls.AbstractSortableColumnWithMinMax; |
| ... | ... | @@ -47,6 +47,7 @@ import com.sap.sailing.gwt.ui.client.shared.controls.SortableColumn; |
| 47 | 47 | import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel.LeaderBoardStyle; |
| 48 | 48 | import com.sap.sailing.gwt.ui.leaderboard.SortedCellTableWithStylableHeaders; |
| 49 | 49 | import com.sap.sailing.gwt.ui.shared.ManeuverDTO; |
| 50 | +import com.sap.sse.common.Color; |
|
| 50 | 51 | import com.sap.sse.common.TimeRange; |
| 51 | 52 | import com.sap.sse.common.Util; |
| 52 | 53 | import com.sap.sse.common.filter.Filter; |
| ... | ... | @@ -75,7 +76,8 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 75 | 76 | private final ManeuverTablePanelResources resources = GWT.create(ManeuverTablePanelResources.class); |
| 76 | 77 | |
| 77 | 78 | private final StringMessages stringMessages; |
| 78 | - private final CompetitorSelectionProvider competitorSelectionModel; |
|
| 79 | + private final RegattaAndRaceIdentifier raceIdentifier; |
|
| 80 | + private final RaceCompetitorSelectionProvider competitorSelectionModel; |
|
| 79 | 81 | |
| 80 | 82 | private final SimplePanel contentPanel = new SimplePanel(); |
| 81 | 83 | private final Label importantMessageLabel = new Label(); |
| ... | ... | @@ -89,7 +91,7 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 89 | 91 | public ManeuverTablePanel(final Component<?> parent, ComponentContext<?> context, |
| 90 | 92 | final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor, |
| 91 | 93 | final RegattaAndRaceIdentifier raceIdentifier, final StringMessages stringMessages, |
| 92 | - final CompetitorSelectionProvider competitorSelectionModel, final ErrorReporter errorReporter, |
|
| 94 | + final RaceCompetitorSelectionProvider competitorSelectionModel, final ErrorReporter errorReporter, |
|
| 93 | 95 | final Timer timer, final ManeuverTableSettings initialSettings, |
| 94 | 96 | final TimeRangeWithZoomModel timeRangeWithZoomProvider, final LeaderBoardStyle style, |
| 95 | 97 | final UserService userService) { |
| ... | ... | @@ -106,10 +108,11 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 106 | 108 | userStatusChangeHandler.onUserStatusChange(userService.getCurrentUser(), /* preAuthenticated */ true); |
| 107 | 109 | this.resources.css().ensureInjected(); |
| 108 | 110 | this.settings = initialSettings; |
| 111 | + this.raceIdentifier = raceIdentifier; |
|
| 109 | 112 | this.competitorSelectionModel = competitorSelectionModel; |
| 110 | 113 | this.stringMessages = stringMessages; |
| 111 | 114 | this.competitorDataProvider = new CachedManeuverTableDataProvider(timeRangeWithZoomProvider, timer, |
| 112 | - raceIdentifier, sailingService, asyncActionsExecutor); |
|
| 115 | + sailingService, asyncActionsExecutor); |
|
| 113 | 116 | this.competitorSelectionModel.addCompetitorSelectionChangeListener(this); |
| 114 | 117 | timer.addTimeListener(this); |
| 115 | 118 | final FlowPanel rootPanel = new FlowPanel(); |
| ... | ... | @@ -263,14 +266,23 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 263 | 266 | return column; |
| 264 | 267 | } |
| 265 | 268 | |
| 266 | - private SortableColumn<ManeuverTableData, String> createCompetitorColumn() { |
|
| 269 | + private SortableColumn<ManeuverTableData, ManeuverTableData> createCompetitorColumn() { |
|
| 267 | 270 | InvertibleComparator<ManeuverTableData> comparator = new InvertibleComparatorAdapter<ManeuverTableData>() { |
| 268 | 271 | @Override |
| 269 | 272 | public int compare(ManeuverTableData o1, ManeuverTableData o2) { |
| 270 | 273 | return o1.getCompetitorName().compareTo(o2.getCompetitorName()); |
| 271 | 274 | } |
| 272 | 275 | }; |
| 273 | - return new SortableColumn<ManeuverTableData, String>(new TextCell(), SortingOrder.ASCENDING) { |
|
| 276 | + return new SortableColumn<ManeuverTableData, ManeuverTableData>(new AbstractCell<ManeuverTableData>() { |
|
| 277 | + @Override |
|
| 278 | + public void render(Context context, ManeuverTableData data, SafeHtmlBuilder sb) { |
|
| 279 | + final String color = data.getCompetitorColor(); |
|
| 280 | + final String divStyle = color == null ? "border: none;" : "border-bottom: 2px solid " + color + ";"; |
|
| 281 | + sb.appendHtmlConstant("<div style=\"" + divStyle + "\">"); |
|
| 282 | + sb.appendEscaped(data.getCompetitorName()); |
|
| 283 | + sb.appendHtmlConstant("</div>"); |
|
| 284 | + } |
|
| 285 | + }, SortingOrder.ASCENDING) { |
|
| 274 | 286 | @Override |
| 275 | 287 | public InvertibleComparator<ManeuverTableData> getComparator() { |
| 276 | 288 | return comparator; |
| ... | ... | @@ -282,8 +294,8 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 282 | 294 | } |
| 283 | 295 | |
| 284 | 296 | @Override |
| 285 | - public String getValue(ManeuverTableData object) { |
|
| 286 | - return object.getCompetitorName(); |
|
| 297 | + public ManeuverTableData getValue(ManeuverTableData object) { |
|
| 298 | + return object; |
|
| 287 | 299 | } |
| 288 | 300 | }; |
| 289 | 301 | } |
| ... | ... | @@ -321,7 +333,8 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 321 | 333 | for (final Entry<CompetitorDTO, Iterable<ManeuverDTO>> entry : cachedData.entrySet()) { |
| 322 | 334 | for (ManeuverDTO maneuver : entry.getValue()) { |
| 323 | 335 | if (settings.getSelectedManeuverTypes().contains(maneuver.getType())) { |
| 324 | - data.add(new ManeuverTableData(entry.getKey(), maneuver)); |
|
| 336 | + final Color competitorColor = competitorSelectionModel.getColor(entry.getKey(), raceIdentifier); |
|
| 337 | + data.add(new ManeuverTableData(entry.getKey(), competitorColor.getAsHtml(), maneuver)); |
|
| 325 | 338 | } |
| 326 | 339 | } |
| 327 | 340 | } |
| ... | ... | @@ -429,15 +442,12 @@ public class ManeuverTablePanel extends AbstractCompositeComponent<ManeuverTable |
| 429 | 442 | |
| 430 | 443 | private class CachedManeuverTableDataProvider extends CachedRaceDataProvider<CompetitorDTO, ManeuverDTO> { |
| 431 | 444 | private final AsyncActionsExecutor asyncActionsExecutor; |
| 432 | - private final RegattaAndRaceIdentifier raceIdentifier; |
|
| 433 | 445 | private final SailingServiceAsync sailingService; |
| 434 | 446 | |
| 435 | 447 | private CachedManeuverTableDataProvider(final TimeRangeProvider timeRangeProvider, final Timer timer, |
| 436 | - final RegattaAndRaceIdentifier raceIdentifier, final SailingServiceAsync sailingService, |
|
| 437 | - final AsyncActionsExecutor asyncActionsExecutor) { |
|
| 448 | + final SailingServiceAsync sailingService, final AsyncActionsExecutor asyncActionsExecutor) { |
|
| 438 | 449 | super(timeRangeProvider, timer, m -> m.getTimePoint(), LOADING_OFFSET_TO_NEXT_MANEUVER_PROVIDER, true); |
| 439 | 450 | this.asyncActionsExecutor = asyncActionsExecutor; |
| 440 | - this.raceIdentifier = raceIdentifier; |
|
| 441 | 451 | this.sailingService = sailingService; |
| 442 | 452 | } |
| 443 | 453 |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/WinningLanesMode.java
| ... | ... | @@ -49,12 +49,10 @@ public class WinningLanesMode extends RaceBoardModeWithPerRaceCompetitors { |
| 49 | 49 | raceDetailsToShow.add(DetailType.RACE_TIME_TRAVELED); |
| 50 | 50 | final SingleRaceLeaderboardSettings additiveSettings = LeaderboardSettingsFactory.getInstance().createNewSettingsWithCustomRaceDetails(raceDetailsToShow); |
| 51 | 51 | ((RaceBoardComponentContext) leaderboardPanel.getComponentContext()).addModesPatching(leaderboardPanel, additiveSettings, new OnSettingsReloadedCallback<SingleRaceLeaderboardSettings>() { |
| 52 | - |
|
| 53 | 52 | @Override |
| 54 | 53 | public void onSettingsReloaded(SingleRaceLeaderboardSettings patchedSettings) { |
| 55 | 54 | leaderboardPanel.updateSettings(patchedSettings); |
| 56 | 55 | } |
| 57 | - |
|
| 58 | 56 | }); |
| 59 | 57 | } |
| 60 | 58 | |
| ... | ... | @@ -79,14 +77,11 @@ public class WinningLanesMode extends RaceBoardModeWithPerRaceCompetitors { |
| 79 | 77 | defaultSettings.isShowEstimatedDuration(), |
| 80 | 78 | defaultSettings.getStartCountDownFontSizeScaling(), |
| 81 | 79 | defaultSettings.isShowManeuverLossVisualization()); |
| 82 | - |
|
| 83 | 80 | ((RaceBoardComponentContext) raceMap.getComponentContext()).addModesPatching(raceMap, additiveSettings, new OnSettingsReloadedCallback<RaceMapSettings>() { |
| 84 | - |
|
| 85 | 81 | @Override |
| 86 | 82 | public void onSettingsReloaded(RaceMapSettings patchedSettings) { |
| 87 | 83 | raceMap.updateSettings(patchedSettings); |
| 88 | 84 | } |
| 89 | - |
|
| 90 | 85 | }); |
| 91 | 86 | } |
| 92 | 87 | |
| ... | ... | @@ -129,17 +124,16 @@ public class WinningLanesMode extends RaceBoardModeWithPerRaceCompetitors { |
| 129 | 124 | stopReceivingLeaderboard(); |
| 130 | 125 | adjustLeaderboardSettings(); |
| 131 | 126 | } |
| 132 | - if (adjustedLeaderboardSettings && tailLength != null) { |
|
| 133 | - adjustMapSettings(); |
|
| 134 | - } |
|
| 135 | 127 | if (getLeaderboardForSpecificTimePoint() == null && tailLength != null && getLeaderboard() != null && getRaceColumn() != null) { |
| 136 | 128 | loadLeaderboardForSpecificTimePoint(getLeaderboard().name, getRaceColumn().getName(), getTimer().getTime()); |
| 137 | 129 | } |
| 138 | 130 | if (!adjustedCompetitorSelection && getLeaderboardForSpecificTimePoint() != null && getCompetitorsInRace() != null) { |
| 139 | 131 | stopReceivingCompetitorsInRace(); |
| 140 | 132 | adjustedCompetitorSelection = true; |
| 133 | + updateCompetitorSelection(); |
|
| 134 | + } |
|
| 135 | + if (adjustedLeaderboardSettings && tailLength != null && adjustedCompetitorSelection) { |
|
| 136 | + adjustMapSettings(); |
|
| 141 | 137 | } |
| 142 | - updateCompetitorSelection(); |
|
| 143 | 138 | } |
| 144 | - |
|
| 145 | 139 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/MediaServiceImpl.java
| ... | ... | @@ -17,6 +17,7 @@ import java.net.URL; |
| 17 | 17 | import java.net.URLConnection; |
| 18 | 18 | import java.net.URLEncoder; |
| 19 | 19 | import java.nio.channels.Channels; |
| 20 | +import java.nio.channels.ReadableByteChannel; |
|
| 20 | 21 | import java.nio.charset.StandardCharsets; |
| 21 | 22 | import java.nio.file.Files; |
| 22 | 23 | import java.text.DateFormat; |
| ... | ... | @@ -221,13 +222,22 @@ public class MediaServiceImpl extends RemoteServiceServlet implements MediaServi |
| 221 | 222 | |
| 222 | 223 | private VideoMetadataDTO checkMetadataByFullFileDownload(URL input) |
| 223 | 224 | throws ParserConfigurationException, SAXException, IOException { |
| 224 | - try (IsoFile isof = new IsoFile(Channels.newChannel(input.openStream()))) { |
|
| 225 | - boolean canDownload = true; |
|
| 226 | - Date recordStartedTimer = determineRecordingStart(isof); |
|
| 227 | - Duration duration = determineDuration(isof); |
|
| 228 | - boolean spherical = determine360(isof); |
|
| 229 | - removeTempFiles(isof); |
|
| 230 | - return new VideoMetadataDTO(canDownload, duration, spherical, recordStartedTimer, ""); |
|
| 225 | + final File tmp = File.createTempFile("upload", "metadataCheck"); |
|
| 226 | + try { |
|
| 227 | + final ReadableByteChannel rbc = Channels.newChannel(input.openStream()); |
|
| 228 | + try (FileOutputStream fos = new FileOutputStream(tmp)) { |
|
| 229 | + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); |
|
| 230 | + try (IsoFile isof = new IsoFile(tmp)) { |
|
| 231 | + final boolean canDownload = true; |
|
| 232 | + final Date recordStartedTimer = determineRecordingStart(isof); |
|
| 233 | + final Duration duration = determineDuration(isof); |
|
| 234 | + final boolean spherical = determine360(isof); |
|
| 235 | + removeTempFiles(isof); |
|
| 236 | + return new VideoMetadataDTO(canDownload, duration, spherical, recordStartedTimer, ""); |
|
| 237 | + } |
|
| 238 | + } |
|
| 239 | + } finally { |
|
| 240 | + Files.delete(tmp.toPath()); |
|
| 231 | 241 | } |
| 232 | 242 | } |
| 233 | 243 | |
| ... | ... | @@ -276,8 +286,9 @@ public class MediaServiceImpl extends RemoteServiceServlet implements MediaServi |
| 276 | 286 | Field field = box.getClass().getDeclaredField("dataFile"); |
| 277 | 287 | field.setAccessible(true); |
| 278 | 288 | File data = (File) field.get(box); |
| 279 | - data.delete(); |
|
| 280 | - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { |
|
| 289 | + Files.delete(data.toPath()); |
|
| 290 | + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException |
|
| 291 | + | IOException e) { |
|
| 281 | 292 | logger.log(Level.WARNING, "Could not delete mp4 temp files", e); |
| 282 | 293 | } |
| 283 | 294 | } |
java/com.sap.sailing.polars.datamining.shared/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/BackendPolarsBoatClassRetrievalProcessor.java
| ... | ... | @@ -1,9 +1,11 @@ |
| 1 | 1 | package com.sap.sailing.polars.datamining.components; |
| 2 | 2 | |
| 3 | 3 | import java.util.Collection; |
| 4 | +import java.util.HashSet; |
|
| 5 | +import java.util.Set; |
|
| 4 | 6 | import java.util.concurrent.ExecutorService; |
| 5 | -import java.util.stream.Collectors; |
|
| 6 | 7 | |
| 8 | +import com.sap.sailing.domain.base.BoatClass; |
|
| 7 | 9 | import com.sap.sailing.domain.polars.PolarDataService; |
| 8 | 10 | import com.sap.sailing.polars.datamining.data.HasBackendPolarBoatClassContext; |
| 9 | 11 | import com.sap.sailing.polars.datamining.data.impl.BoatClassWithBackendPolarContext; |
| ... | ... | @@ -20,11 +22,15 @@ public class BackendPolarsBoatClassRetrievalProcessor extends AbstractRetrievalP |
| 20 | 22 | |
| 21 | 23 | @Override |
| 22 | 24 | protected Iterable<HasBackendPolarBoatClassContext> retrieveData(RacingEventService element) { |
| 25 | + Set<HasBackendPolarBoatClassContext> data = new HashSet<>(); |
|
| 23 | 26 | PolarDataService polarDataService = element.getPolarDataService(); |
| 24 | - return polarDataService.getAllBoatClassesWithPolarSheetsAvailable() |
|
| 25 | - .stream() |
|
| 26 | - .map(bc -> new BoatClassWithBackendPolarContext(bc, polarDataService)) |
|
| 27 | - .collect(Collectors.toSet()); |
|
| 27 | + for (BoatClass boatClass : polarDataService.getAllBoatClassesWithPolarSheetsAvailable()) { |
|
| 28 | + if (isAborted()) { |
|
| 29 | + break; |
|
| 30 | + } |
|
| 31 | + data.add(new BoatClassWithBackendPolarContext(boatClass, polarDataService)); |
|
| 32 | + } |
|
| 33 | + return data; |
|
| 28 | 34 | } |
| 29 | 35 | |
| 30 | 36 | } |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarCompetitorRetrievalProcessor.java
| ... | ... | @@ -25,6 +25,9 @@ public class PolarCompetitorRetrievalProcessor extends AbstractRetrievalProcesso |
| 25 | 25 | TrackedRace trackedRace = element.getTrackedRace(); |
| 26 | 26 | Set<HasCompetitorPolarContext> competitorWithContext = new HashSet<>(); |
| 27 | 27 | for (Competitor competitor : trackedRace.getRace().getCompetitors()) { |
| 28 | + if (isAborted()) { |
|
| 29 | + break; |
|
| 30 | + } |
|
| 28 | 31 | competitorWithContext.add(new CompetitorWithPolarContext(competitor, trackedRace, element.getLeg(), element)); |
| 29 | 32 | } |
| 30 | 33 | return competitorWithContext; |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarFleetRetrievalProcessor.java
| ... | ... | @@ -25,6 +25,9 @@ public class PolarFleetRetrievalProcessor extends AbstractRetrievalProcessor<Has |
| 25 | 25 | Set<HasFleetPolarContext> fleetWithContext = new HashSet<>(); |
| 26 | 26 | RaceColumn raceColumn = element.getRaceColumn(); |
| 27 | 27 | for (Fleet fleet : raceColumn.getFleets()) { |
| 28 | + if (isAborted()) { |
|
| 29 | + break; |
|
| 30 | + } |
|
| 28 | 31 | fleetWithContext.add(new FleetWithPolarContext(fleet, raceColumn, element)); |
| 29 | 32 | } |
| 30 | 33 | return fleetWithContext; |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarGPSFixRetrievalProcessor.java
| ... | ... | @@ -59,6 +59,9 @@ public class PolarGPSFixRetrievalProcessor extends AbstractRetrievalProcessor<Ha |
| 59 | 59 | try { |
| 60 | 60 | Iterable<GPSFixMoving> fixes = track.getFixes(startTime, true, finishTime, false); |
| 61 | 61 | for (GPSFixMoving fix : fixes) { |
| 62 | + if (isAborted()) { |
|
| 63 | + break; |
|
| 64 | + } |
|
| 62 | 65 | WindWithConfidence<Pair<Position, TimePoint>> wind = trackedRace.getWindWithConfidence( |
| 63 | 66 | fix.getPosition(), |
| 64 | 67 | fix.getTimePoint(), |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarLeaderboardGroupRetrievalProcessor.java
| ... | ... | @@ -1,9 +1,11 @@ |
| 1 | 1 | package com.sap.sailing.polars.datamining.components; |
| 2 | 2 | |
| 3 | 3 | import java.util.Collection; |
| 4 | +import java.util.HashSet; |
|
| 5 | +import java.util.Set; |
|
| 4 | 6 | import java.util.concurrent.ExecutorService; |
| 5 | -import java.util.stream.Collectors; |
|
| 6 | 7 | |
| 8 | +import com.sap.sailing.domain.leaderboard.LeaderboardGroup; |
|
| 7 | 9 | import com.sap.sailing.polars.datamining.data.HasLeaderboardGroupPolarContext; |
| 8 | 10 | import com.sap.sailing.polars.datamining.data.impl.LeaderboardGroupWithPolarContext; |
| 9 | 11 | import com.sap.sailing.server.RacingEventService; |
| ... | ... | @@ -19,11 +21,14 @@ public class PolarLeaderboardGroupRetrievalProcessor extends AbstractRetrievalPr |
| 19 | 21 | |
| 20 | 22 | @Override |
| 21 | 23 | protected Iterable<HasLeaderboardGroupPolarContext> retrieveData(RacingEventService element) { |
| 22 | - return element.getLeaderboardGroups() |
|
| 23 | - .values() |
|
| 24 | - .stream() |
|
| 25 | - .map(lg -> new LeaderboardGroupWithPolarContext(lg)) |
|
| 26 | - .collect(Collectors.toSet()); |
|
| 24 | + Set<HasLeaderboardGroupPolarContext> data = new HashSet<>(); |
|
| 25 | + for (LeaderboardGroup leaderboardGroup : element.getLeaderboardGroups().values()) { |
|
| 26 | + if (isAborted()) { |
|
| 27 | + break; |
|
| 28 | + } |
|
| 29 | + data.add(new LeaderboardGroupWithPolarContext(leaderboardGroup)); |
|
| 30 | + } |
|
| 31 | + return data; |
|
| 27 | 32 | } |
| 28 | 33 | |
| 29 | 34 | } |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarLeaderboardRetrievalProcessor.java
| ... | ... | @@ -23,6 +23,9 @@ public class PolarLeaderboardRetrievalProcessor extends AbstractRetrievalProcess |
| 23 | 23 | protected Iterable<HasLeaderboardPolarContext> retrieveData(HasLeaderboardGroupPolarContext element) { |
| 24 | 24 | Set<HasLeaderboardPolarContext> leaderboardsWithContext = new HashSet<>(); |
| 25 | 25 | for (Leaderboard leaderboard : element.getLeaderboardGroup().getLeaderboards()) { |
| 26 | + if (isAborted()) { |
|
| 27 | + break; |
|
| 28 | + } |
|
| 26 | 29 | leaderboardsWithContext.add(new LeaderboardWithPolarContext(leaderboard, element)); |
| 27 | 30 | } |
| 28 | 31 | return leaderboardsWithContext; |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarLegRetrievalProcessor.java
| ... | ... | @@ -35,6 +35,9 @@ public class PolarLegRetrievalProcessor extends AbstractRetrievalProcessor<HasFl |
| 35 | 35 | if (raceDefinition != null) { |
| 36 | 36 | Course course = raceDefinition.getCourse(); |
| 37 | 37 | for (Leg leg : course.getLegs()) { |
| 38 | + if (isAborted()) { |
|
| 39 | + break; |
|
| 40 | + } |
|
| 38 | 41 | legWithContext.add(new LegWithPolarContext(leg, trackedRace, element)); |
| 39 | 42 | } |
| 40 | 43 | } |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/PolarRaceColumnRetrievalProcessor.java
| ... | ... | @@ -25,6 +25,9 @@ public class PolarRaceColumnRetrievalProcessor extends AbstractRetrievalProcesso |
| 25 | 25 | Set<HasRaceColumnPolarContext> raceColumnWithContext = new HashSet<>(); |
| 26 | 26 | Leaderboard leaderboard = element.getLeaderboard(); |
| 27 | 27 | for (RaceColumn raceColumn : leaderboard.getRaceColumns()) { |
| 28 | + if (isAborted()) { |
|
| 29 | + break; |
|
| 30 | + } |
|
| 28 | 31 | raceColumnWithContext.add(new RaceColumnWithPolarContext(raceColumn, element)); |
| 29 | 32 | } |
| 30 | 33 | return raceColumnWithContext; |
java/com.sap.sailing.polars.datamining/src/com/sap/sailing/polars/datamining/components/aggregators/PolarBackendDataAggregationProcessor.java
| ... | ... | @@ -100,10 +100,17 @@ public class PolarBackendDataAggregationProcessor extends AbstractParallelGroupe |
| 100 | 100 | } catch (NotEnoughDataHasBeenAddedException e) { |
| 101 | 101 | hasDownwindAngleData = false; |
| 102 | 102 | } |
| 103 | + |
|
| 103 | 104 | for (int angleInDeg = 0; angleInDeg < 360; angleInDeg++) { |
| 105 | + if (isAborted()) { |
|
| 106 | + break; |
|
| 107 | + } |
|
| 104 | 108 | int convertedAngle = angleInDeg > 180 ? angleInDeg - 360 : angleInDeg ; |
| 105 | 109 | try { |
| 106 | 110 | for (int x = 0; x < 30; x++) { |
| 111 | + if (isAborted()) { |
|
| 112 | + break; |
|
| 113 | + } |
|
| 107 | 114 | SpeedWithConfidence<Void> speed = polarDataService.getSpeed(boatClass, new KnotSpeedImpl(x), new DegreeBearingImpl(convertedAngle)); |
| 108 | 115 | if (speed.getConfidence() > 0.1) { |
| 109 | 116 | hasDataForAngle[angleInDeg] = true; |
| ... | ... | @@ -127,6 +134,9 @@ public class PolarBackendDataAggregationProcessor extends AbstractParallelGroupe |
| 127 | 134 | |
| 128 | 135 | private void setArrayValuesForFunction(PolynomialFunction function, double[] yOverWindSpeed) { |
| 129 | 136 | for (int x = 0; x < 30; x++) { |
| 137 | + if (isAborted()) { |
|
| 138 | + break; |
|
| 139 | + } |
|
| 130 | 140 | yOverWindSpeed[x] = function.value(x); |
| 131 | 141 | } |
| 132 | 142 | } |
java/com.sap.sailing.polars/src/com/sap/sailing/polars/impl/PolarDataServiceImpl.java
| ... | ... | @@ -170,8 +170,10 @@ public class PolarDataServiceImpl implements ReplicablePolarService, ClearStateT |
| 170 | 170 | if (closestTwsTwa == null) { |
| 171 | 171 | result = new Pair<>(0.0, null); |
| 172 | 172 | } else { |
| 173 | - double minDiffDeg = Math.abs(Math.abs(Math.abs(closestTwsTwa.getObject().getBearing().getDegrees() * 2) |
|
| 174 | - - Math.abs(courseChangeDeg))); |
|
| 173 | + double targetManeuverAngle = getManeuverAngleInDegreesFromTwa( |
|
| 174 | + closestTwsTwa.getObject().getBearing().getDegrees(), maneuverType); |
|
| 175 | + double minDiffDeg = Math.abs(Math.abs(targetManeuverAngle) |
|
| 176 | + - Math.abs(courseChangeDeg)); |
|
| 175 | 177 | result = new Pair<>(1. / (1. + (minDiffDeg / 10.) * (minDiffDeg / 10.)), closestTwsTwa); |
| 176 | 178 | } |
| 177 | 179 | return result; |
| ... | ... | @@ -189,7 +191,7 @@ public class PolarDataServiceImpl implements ReplicablePolarService, ClearStateT |
| 189 | 191 | : courseChangeDeg >= 0 ? Tack.STARBOARD : Tack.PORT)) { |
| 190 | 192 | double targetManeuverAngle = getManeuverAngleInDegreesFromTwa( |
| 191 | 193 | trueWindSpeedAndAngle.getObject().getBearing().getDegrees(), type); |
| 192 | - double diff = Math.abs(targetManeuverAngle) - Math.abs(courseChangeDeg); |
|
| 194 | + double diff = Math.abs(Math.abs(targetManeuverAngle) - Math.abs(courseChangeDeg)); |
|
| 193 | 195 | if (diff < minDiff) { |
| 194 | 196 | minDiff = diff; |
| 195 | 197 | closestTwsTwa = trueWindSpeedAndAngle; |
java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarDataMiner.java
| ... | ... | @@ -288,7 +288,7 @@ public class PolarDataMiner { |
| 288 | 288 | } else if (legType.equals(LegType.DOWNWIND)) { |
| 289 | 289 | CubicEquation downWindEquation = new CubicEquation(0.0003, -0.0373, 1.5213, -2.1309 |
| 290 | 290 | - speedOverGround.getKnots()); |
| 291 | - int angle = 30 * tackFactor; |
|
| 291 | + int angle = 150 * tackFactor; |
|
| 292 | 292 | solveAndAddResults(resultSet, downWindEquation, angle); |
| 293 | 293 | } |
| 294 | 294 | return resultSet; |
java/com.sap.sailing.selenium.test/.classpath
| ... | ... | @@ -5,6 +5,5 @@ |
| 5 | 5 | <classpathentry kind="src" path="src"/> |
| 6 | 6 | <classpathentry kind="src" path="resources"/> |
| 7 | 7 | <classpathentry exported="true" kind="lib" path="lib/cglib-nodep-2.2.3.jar"/> |
| 8 | - <classpathentry kind="lib" path="/org.openqa.selenium.osgi/lib/commons-exec-1.1.jar"/> |
|
| 9 | 8 | <classpathentry kind="output" path="bin"/> |
| 10 | 9 | </classpath> |
java/com.sap.sailing.selenium.test/META-INF/MANIFEST.MF
| ... | ... | @@ -7,7 +7,7 @@ Bundle-Vendor: SAP |
| 7 | 7 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 |
| 8 | 8 | Require-Bundle: org.hamcrest;bundle-version="1.1.0", |
| 9 | 9 | org.junit;bundle-version="4.8.2", |
| 10 | - org.openqa.selenium.osgi;bundle-version="2.40.0", |
|
| 10 | + org.openqa.selenium.osgi;bundle-version="3.13.0", |
|
| 11 | 11 | com.sap.sse.mongodb;bundle-version="1.0.0", |
| 12 | 12 | org.mongodb.mongo-java-driver;bundle-version="2.13.0", |
| 13 | 13 | com.sap.sailing.domain.common, |
java/com.sap.sailing.selenium.test/ci-test-environment.xml
| ... | ... | @@ -44,12 +44,43 @@ |
| 44 | 44 | <name>webdriver.enable.native.events </name> |
| 45 | 45 | <value>true</value> |
| 46 | 46 | </system-property> |
| 47 | - <!-- |
|
| 47 | + <!-- |
|
| 48 | + You need chromedriver to be able to run Selenium tests on Chrome/Chromium. |
|
| 49 | + This is the path to chromedriver, not Chrome. |
|
| 50 | + The chromedriver download is linked on the official selenium download page: |
|
| 51 | + https://www.seleniumhq.org/download/ |
|
| 52 | + --> |
|
| 53 | + <!-- |
|
| 54 | + <system-property> |
|
| 55 | + <name>webdriver.chrome.driver</name> |
|
| 56 | + <value>/path/to/chromedriver</value> |
|
| 57 | + </system-property> |
|
| 58 | + --> |
|
| 59 | + |
|
| 60 | + <!-- |
|
| 61 | + You need geckodriver to be able to run Selenium tests on Firefox. |
|
| 62 | + This is the path to geckodriver, not Firefox. |
|
| 63 | + The geckodriver download is linked on the official selenium download page: |
|
| 64 | + https://www.seleniumhq.org/download/ |
|
| 65 | + --> |
|
| 66 | + <!-- |
|
| 67 | + <system-property> |
|
| 68 | + <name>webdriver.gecko.driver</name> |
|
| 69 | + <value>/path/to/geckodriver</value> |
|
| 70 | + </system-property> |
|
| 71 | + --> |
|
| 72 | + <!-- |
|
| 73 | + geckodriver automatically finds an installed version of Firefox. |
|
| 74 | + If no Firefox is installed on the system or another version should be used, |
|
| 75 | + the property "webdriver.firefox.bin" may be set to specify the path. |
|
| 76 | + The default on Windows is "C:\Program Files\Mozilla Firefox\firefox.exe" |
|
| 77 | + --> |
|
| 78 | + <!-- |
|
| 48 | 79 | <system-property> |
| 49 | 80 | <name>webdriver.firefox.bin</name> |
| 50 | - <value>[path to]\firefox.exe</value> |
|
| 81 | + <value>path/to/firefox</value> |
|
| 51 | 82 | </system-property> |
| 52 | - --> |
|
| 83 | + --> |
|
| 53 | 84 | </system-properties> |
| 54 | 85 | |
| 55 | 86 | <!-- |
| ... | ... | @@ -61,18 +92,28 @@ |
| 61 | 92 | pages mentioned above. |
| 62 | 93 | --> |
| 63 | 94 | <!-- --> |
| 95 | + <!-- |
|
| 64 | 96 | <driver-definition class="org.openqa.selenium.firefox.FirefoxDriver"> |
| 65 | - <!-- |
|
| 97 | + |
|
| 66 | 98 | <capabilities> |
| 67 | 99 | <capability> |
| 68 | 100 | <name>version</name> |
| 69 | 101 | <value>14.0.0</value> |
| 70 | 102 | </capability> |
| 71 | 103 | </capabilities> |
| 72 | - --> |
|
| 73 | 104 | </driver-definition> |
| 105 | + --> |
|
| 106 | + <!-- TODO: should we use headless Firefox instead of Xvfb on Hudson? --> |
|
| 107 | + <!-- |
|
| 108 | + <driver-definition class="com.sap.sailing.selenium.core.HeadlessFirefoxDriver"> |
|
| 109 | + </driver-definition> |
|
| 110 | + --> |
|
| 74 | 111 | |
| 75 | 112 | <!-- |
| 76 | 113 | <driver-definition class="org.openqa.selenium.chrome.ChromeDriver" /> |
| 77 | 114 | --> |
| 115 | + |
|
| 116 | + <driver-definition class="com.sap.sailing.selenium.core.HeadlessChromeDriver"> |
|
| 117 | + </driver-definition> |
|
| 118 | + |
|
| 78 | 119 | </test-environment> |
java/com.sap.sailing.selenium.test/com.sap.sailing.selenium.test (No Proxy, GWT Codesvr).launch
| ... | ... | @@ -14,13 +14,7 @@ |
| 14 | 14 | <booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> |
| 15 | 15 | <stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> |
| 16 | 16 | <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> |
| 17 | -<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> |
|
| 18 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" javaProject="com.sap.sailing.selenium.test" path="1" type="4"/> "/> |
|
| 19 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="com.sap.sailing.selenium.test"/> </runtimeClasspathEntry> "/> |
|
| 20 | -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.openqa.selenium.osgi/lib/commons-exec-1.1.jar" path="3" type="2"/> "/> |
|
| 21 | -</listAttribute> |
|
| 22 | -<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> |
|
| 23 | 17 | <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> |
| 24 | 18 | <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.selenium.test"/> |
| 25 | -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dselenium.test.environment.configuration=local-test-environment.xml -Dgwt.codesvr=127.0.0.1:9997 -Dwebdriver.firefox.profile=Selenium"/> |
|
| 19 | +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dselenium.test.environment.configuration=local-test-environment.xml -Dgwt.codesvr=127.0.0.1:9876"/> |
|
| 26 | 20 | </launchConfiguration> |
java/com.sap.sailing.selenium.test/com.sap.sailing.selenium.test (Proxy, GWT Codesvr).launch
| ... | ... | @@ -12,5 +12,5 @@ |
| 12 | 12 | <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> |
| 13 | 13 | <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> |
| 14 | 14 | <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.selenium.test"/> |
| 15 | -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dselenium.test.environment.configuration=local-test-environment.xml -Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -Dgwt.codesvr=127.0.0.1:9997 -Dwebdriver.firefox.profile=Selenium"/> |
|
| 15 | +<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Dselenium.test.environment.configuration=local-test-environment.xml -Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -Dgwt.codesvr=127.0.0.1:9876"/> |
|
| 16 | 16 | </launchConfiguration> |
java/com.sap.sailing.selenium.test/local-test-environment.xml
| ... | ... | @@ -28,22 +28,65 @@ |
| 28 | 28 | - http://code.google.com/p/selenium/wiki/SafariDriver |
| 29 | 29 | - http://code.google.com/p/selenium/wiki/RemoteWebDriverServer |
| 30 | 30 | |
| 31 | - NOTE: For the Chrome and the InternetExplorer driver an additional "server", which acts as a bridge between the |
|
| 31 | + NOTE: For the Chrome, Firefox and InternetExplorer driver an additional "server", which acts as a bridge between the |
|
| 32 | 32 | browser and the driver, is needed. |
| 33 | 33 | --> |
| 34 | 34 | <system-properties> |
| 35 | + <!-- |
|
| 36 | + You need chromedriver to be able to run Selenium tests on Chrome/Chromium. |
|
| 37 | + This is the path to chromedriver, not Chrome. |
|
| 38 | + The chromedriver download is linked on the official selenium download page: |
|
| 39 | + https://www.seleniumhq.org/download/ |
|
| 40 | + --> |
|
| 35 | 41 | <system-property> |
| 36 | 42 | <name>webdriver.chrome.driver</name> |
| 37 | 43 | <value>C:\apps\ChromeSeleniumDriver\chromedriver.exe</value> |
| 38 | 44 | </system-property> |
| 45 | + <!-- |
|
| 46 | + You need geckodriver to be able to run Selenium tests on Firefox. |
|
| 47 | + This is the path to geckodriver, not Firefox. |
|
| 48 | + The geckodriver download is linked on the official selenium download page: |
|
| 49 | + https://www.seleniumhq.org/download/ |
|
| 50 | + --> |
|
| 51 | + <system-property> |
|
| 52 | + <name>webdriver.gecko.driver</name> |
|
| 53 | + <value>/path/to/geckodriver.exe</value> |
|
| 54 | + </system-property> |
|
| 55 | + <!-- |
|
| 56 | + geckodriver automatically finds an installed version of Firefox. |
|
| 57 | + If no Firefox is installed on the system or another version should be used, |
|
| 58 | + the property "webdriver.firefox.bin" may be set to specify the path. |
|
| 59 | + The default on Windows is "C:\Program Files\Mozilla Firefox\firefox.exe" |
|
| 60 | + --> |
|
| 61 | + <!-- |
|
| 39 | 62 | <system-property> |
| 40 | 63 | <name>webdriver.firefox.bin</name> |
| 41 | - <!-- Default binary location on Windows: --> |
|
| 42 | - <value>c:\Program Files (x86)\Mozilla Firefox 24\firefox.exe</value> |
|
| 43 | - <!-- --> |
|
| 44 | - <!-- Default binary location on Linux: --> |
|
| 45 | - <!-- <value>/usr/bin/firefox</value> --> |
|
| 64 | + <value>/path/to/firefox.exe</value> |
|
| 65 | + </system-property> |
|
| 66 | + --> |
|
| 67 | + <!-- |
|
| 68 | + You need IEDriverServer.exe to successfully run selenium tests using IE 11. |
|
| 69 | + The download is listed on the official Selenium download page: |
|
| 70 | + https://www.seleniumhq.org/download/ |
|
| 71 | + This property needs to point to the downloaded and unzipped IEDriverServer.exe, not the ie.exe! |
|
| 72 | + |
|
| 73 | + With IE 10/11, only the 32Bit version works by the time of writing. |
|
| 74 | + |
|
| 75 | + In addition, versions 3.11 to 3.13 are known bad because these often fail with a |
|
| 76 | + org.openqa.selenium.ElementClickInterceptedException in case of modal GWT dialogs are shown. |
|
| 77 | + This is probably related to the following bug: https://github.com/SeleniumHQ/selenium/issues/5935 |
|
| 78 | + If you see suspicous ElementClickInterceptedExceptions, use IEDriverServer version 3.10: |
|
| 79 | + https://selenium-release.storage.googleapis.com/index.html?path=3.10/ |
|
| 80 | + |
|
| 81 | + Some further configuration steps may be required depending on the OS and IE version: |
|
| 82 | + https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver#required-configuration |
|
| 83 | + --> |
|
| 84 | + <!-- |
|
| 85 | + <system-property> |
|
| 86 | + <name>webdriver.ie.driver</name> |
|
| 87 | + <value>C:\path\to\IEDriverServer.exe</value> |
|
| 46 | 88 | </system-property> |
| 89 | + --> |
|
| 47 | 90 | </system-properties> |
| 48 | 91 | |
| 49 | 92 | |
| ... | ... | @@ -61,4 +104,16 @@ |
| 61 | 104 | <driver-definition class="org.openqa.selenium.chrome.ChromeDriver"> |
| 62 | 105 | </driver-definition> |
| 63 | 106 | --> |
| 107 | + <!-- <driver-definition class="org.openqa.selenium.ie.InternetExplorerDriver"> |
|
| 108 | + <capabilities> |
|
| 109 | + <capability> |
|
| 110 | + <name>ignoreZoomSetting</name> |
|
| 111 | + <value>true</value> |
|
| 112 | + </capability> |
|
| 113 | + </capabilities> |
|
| 114 | + </driver-definition> --> |
|
| 115 | + <!-- <driver-definition class="com.sap.sailing.selenium.core.HeadlessFirefoxDriver"> |
|
| 116 | + </driver-definition> --> |
|
| 117 | + <!-- <driver-definition class="com.sap.sailing.selenium.core.HeadlessChromeDriver"> |
|
| 118 | + </driver-definition> --> |
|
| 64 | 119 | </test-environment> |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/ElementSearchCondition.java
| ... | ... | @@ -1,8 +1,8 @@ |
| 1 | 1 | package com.sap.sailing.selenium.core; |
| 2 | 2 | |
| 3 | -import org.openqa.selenium.SearchContext; |
|
| 3 | +import java.util.function.Function; |
|
| 4 | 4 | |
| 5 | -import com.google.common.base.Function; |
|
| 5 | +import org.openqa.selenium.SearchContext; |
|
| 6 | 6 | |
| 7 | 7 | /** |
| 8 | 8 | * <p>Models a condition that might reasonably be expected to eventually evaluate to something that is neither |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/HeadlessChromeDriver.java
| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | +package com.sap.sailing.selenium.core; |
|
| 2 | + |
|
| 3 | +import org.openqa.selenium.Capabilities; |
|
| 4 | +import org.openqa.selenium.chrome.ChromeDriver; |
|
| 5 | +import org.openqa.selenium.chrome.ChromeDriverService; |
|
| 6 | +import org.openqa.selenium.chrome.ChromeOptions; |
|
| 7 | + |
|
| 8 | +/** |
|
| 9 | + *Specific {@link ChromeDriver} that is configured to start Chrome in headless mode. In theory, you do not need a |
|
| 10 | + * specific subclass of {@link ChromeDriver} but we currently can't apply specific command line options using XML based |
|
| 11 | + * configuration using {@link TestEnvironmentConfiguration}. So this is currently just a simple workaround but not a |
|
| 12 | + * long-term solution. |
|
| 13 | + */ |
|
| 14 | +public class HeadlessChromeDriver extends ChromeDriver { |
|
| 15 | + |
|
| 16 | + public HeadlessChromeDriver(Capabilities capabilities) { |
|
| 17 | + super(ChromeDriverService.createDefaultService(), constructChromeOptions(capabilities)); |
|
| 18 | + } |
|
| 19 | + |
|
| 20 | + private static ChromeOptions constructChromeOptions(Capabilities capabilities) { |
|
| 21 | + final ChromeOptions chromeOptions = new ChromeOptions(); |
|
| 22 | + chromeOptions.merge(capabilities); |
|
| 23 | + chromeOptions.addArguments("--headless", "--window-size=1440,900"); |
|
| 24 | + return chromeOptions; |
|
| 25 | + } |
|
| 26 | +} |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/HeadlessFirefoxDriver.java
| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | +package com.sap.sailing.selenium.core; |
|
| 2 | + |
|
| 3 | +import java.util.Objects; |
|
| 4 | + |
|
| 5 | +import org.openqa.selenium.Capabilities; |
|
| 6 | +import org.openqa.selenium.firefox.FirefoxBinary; |
|
| 7 | +import org.openqa.selenium.firefox.FirefoxDriver; |
|
| 8 | +import org.openqa.selenium.firefox.FirefoxOptions; |
|
| 9 | + |
|
| 10 | +/** |
|
| 11 | + * Specific {@link FirefoxDriver} that is configured to start Firefox in headless mode. In theory, you do not need a |
|
| 12 | + * specific subclass of {@link FirefoxDriver} but we currently can't apply specific command line options using XML based |
|
| 13 | + * configuration using {@link TestEnvironmentConfiguration}. So this is currently just a simple workaround but not a |
|
| 14 | + * long-term solution. |
|
| 15 | + */ |
|
| 16 | +public class HeadlessFirefoxDriver extends FirefoxDriver { |
|
| 17 | + |
|
| 18 | + public HeadlessFirefoxDriver(Capabilities desiredCapabilities) { |
|
| 19 | + super(constructFirefoxOptions(desiredCapabilities)); |
|
| 20 | + |
|
| 21 | + } |
|
| 22 | + |
|
| 23 | + private static FirefoxOptions constructFirefoxOptions(Capabilities desiredCapabilities) { |
|
| 24 | + final FirefoxOptions firefoxOptions = new FirefoxOptions(Objects.requireNonNull(desiredCapabilities, "No capabilities seen")); |
|
| 25 | + FirefoxBinary firefoxBinary = new FirefoxBinary(); |
|
| 26 | + // Window size is currently being ignored in headless mode |
|
| 27 | + // Documentation says it should work: https://developer.mozilla.org/en-US/Firefox/Headless_mode |
|
| 28 | + firefoxBinary.addCommandLineOptions("-headless"/*, "--window-size=1440,900"*/); |
|
| 29 | + firefoxOptions.setBinary(firefoxBinary); |
|
| 30 | + return firefoxOptions; |
|
| 31 | + } |
|
| 32 | +} |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/SeleniumElementLocator.java
| ... | ... | @@ -1,8 +1,9 @@ |
| 1 | 1 | package com.sap.sailing.selenium.core; |
| 2 | 2 | |
| 3 | 3 | import java.lang.reflect.Field; |
| 4 | +import java.time.Duration; |
|
| 4 | 5 | import java.util.List; |
| 5 | -import java.util.concurrent.TimeUnit; |
|
| 6 | +import java.util.function.Function; |
|
| 6 | 7 | |
| 7 | 8 | import org.openqa.selenium.By; |
| 8 | 9 | import org.openqa.selenium.NoSuchElementException; |
| ... | ... | @@ -11,8 +12,6 @@ import org.openqa.selenium.WebElement; |
| 11 | 12 | import org.openqa.selenium.support.pagefactory.ElementLocator; |
| 12 | 13 | import org.openqa.selenium.support.ui.FluentWait; |
| 13 | 14 | |
| 14 | -import com.google.common.base.Function; |
|
| 15 | - |
|
| 16 | 15 | /** |
| 17 | 16 | * <p>An element locator, which will lazily locate and wait for an element or an element list to appear, by polling the |
| 18 | 17 | * UI on a regular basis. It is possible to define the maximum amount of time to wait for the element or the list of |
| ... | ... | @@ -66,8 +65,8 @@ public class SeleniumElementLocator implements ElementLocator { |
| 66 | 65 | this.context = context; |
| 67 | 66 | |
| 68 | 67 | this.wait = new FluentWait<>(this.context); |
| 69 | - this.wait.withTimeout(timeOutSeconds, TimeUnit.SECONDS); |
|
| 70 | - this.wait.pollingEvery(intervalMillis, TimeUnit.MILLISECONDS); |
|
| 68 | + this.wait.withTimeout(Duration.ofSeconds(timeOutSeconds)); |
|
| 69 | + this.wait.pollingEvery(Duration.ofMillis(intervalMillis)); |
|
| 71 | 70 | this.wait.ignoring(NoSuchElementException.class); |
| 72 | 71 | |
| 73 | 72 | Annotations annotations = new Annotations(field); |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/SeleniumFieldDecorator.java
| ... | ... | @@ -9,8 +9,7 @@ import java.lang.reflect.Type; |
| 9 | 9 | import java.util.List; |
| 10 | 10 | |
| 11 | 11 | import org.openqa.selenium.WebElement; |
| 12 | - |
|
| 13 | -import org.openqa.selenium.internal.Locatable; |
|
| 12 | +import org.openqa.selenium.interactions.internal.Locatable; |
|
| 14 | 13 | import org.openqa.selenium.internal.WrapsElement; |
| 15 | 14 | |
| 16 | 15 | import org.openqa.selenium.support.pagefactory.ElementLocator; |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/WindowManager.java
| ... | ... | @@ -1,10 +1,11 @@ |
| 1 | 1 | package com.sap.sailing.selenium.core; |
| 2 | 2 | |
| 3 | 3 | import java.util.Set; |
| 4 | +import java.util.function.BiConsumer; |
|
| 4 | 5 | |
| 6 | +import org.openqa.selenium.Dimension; |
|
| 5 | 7 | import org.openqa.selenium.JavascriptExecutor; |
| 6 | 8 | import org.openqa.selenium.WebDriver; |
| 7 | -import org.openqa.selenium.WebDriver.TargetLocator; |
|
| 8 | 9 | |
| 9 | 10 | /** |
| 10 | 11 | * <p></p> |
| ... | ... | @@ -25,20 +26,8 @@ public class WindowManager { |
| 25 | 26 | */ |
| 26 | 27 | public WindowManager(WebDriver driver) { |
| 27 | 28 | this.driver = driver; |
| 28 | - } |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * <p></p> |
|
| 32 | - * |
|
| 33 | - * @param url |
|
| 34 | - */ |
|
| 35 | - public void switchTo(String url) { |
|
| 36 | - WebDriverWindow window = findWindow(url); |
|
| 37 | - |
|
| 38 | - if(window == null) |
|
| 39 | - throw new RuntimeException("Window not found"); |
|
| 40 | 29 | |
| 41 | - window.switchToWindow(); |
|
| 30 | + setWindowMaximized(); |
|
| 42 | 31 | } |
| 43 | 32 | |
| 44 | 33 | /** |
| ... | ... | @@ -47,60 +36,24 @@ public class WindowManager { |
| 47 | 36 | * @return |
| 48 | 37 | * |
| 49 | 38 | */ |
| 50 | - public WebDriverWindow getCurrentWindow() { |
|
| 39 | + private WebDriverWindow getCurrentWindow() { |
|
| 51 | 40 | return new WebDriverWindow(this.driver, this.driver.getWindowHandle()); |
| 52 | 41 | } |
| 53 | 42 | |
| 54 | 43 | /** |
| 55 | 44 | * <p></p> |
| 56 | 45 | * |
| 57 | - * <p>Note: If no window is found with the specified URL, </p> |
|
| 58 | - * |
|
| 59 | - * @param url |
|
| 60 | - * |
|
| 61 | 46 | * @return |
| 62 | - * |
|
| 63 | 47 | */ |
| 64 | - public WebDriverWindow findWindow(String url) { |
|
| 65 | - if(url == null) |
|
| 66 | - throw new IllegalArgumentException(); |
|
| 67 | - |
|
| 68 | - TargetLocator locator = this.driver.switchTo(); |
|
| 69 | - |
|
| 70 | - for(String handle : this.driver.getWindowHandles()) { |
|
| 71 | - locator.window(handle); |
|
| 72 | - |
|
| 73 | - if(url.equals(this.driver.getCurrentUrl())) |
|
| 74 | - return new WebDriverWindow(this.driver, handle); |
|
| 75 | - } |
|
| 76 | - |
|
| 77 | - return null; |
|
| 78 | - } |
|
| 79 | - |
|
| 80 | - /** |
|
| 81 | - * <p></p> |
|
| 82 | - * |
|
| 83 | - * @return |
|
| 84 | - */ |
|
| 85 | - public WebDriverWindow openNewWindow() { |
|
| 48 | + private WebDriverWindow openNewWindow() { |
|
| 86 | 49 | return openNewWindow(false); |
| 87 | 50 | } |
| 88 | 51 | |
| 89 | - public WebDriverWindow openNewWindow(boolean focus) { |
|
| 52 | + private WebDriverWindow openNewWindow(boolean focus) { |
|
| 90 | 53 | return openNewWindow("", focus); |
| 91 | 54 | } |
| 92 | 55 | |
| 93 | - /** |
|
| 94 | - * <p></p> |
|
| 95 | - * |
|
| 96 | - * @param url |
|
| 97 | - * @return |
|
| 98 | - */ |
|
| 99 | - public WebDriverWindow openNewWindow(String url) { |
|
| 100 | - return openNewWindow(url, false); |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - public WebDriverWindow openNewWindow(String url, boolean focus) { |
|
| 56 | + private WebDriverWindow openNewWindow(String url, boolean focus) { |
|
| 104 | 57 | WebDriverWindow window = new WebDriverWindow(this.driver, createWindow(url)); |
| 105 | 58 | |
| 106 | 59 | if(focus) { |
| ... | ... | @@ -134,4 +87,37 @@ public class WindowManager { |
| 134 | 87 | |
| 135 | 88 | return null; |
| 136 | 89 | } |
| 90 | + |
|
| 91 | + public void withExtraWindow(BiConsumer<WebDriverWindow, WebDriverWindow> defaultAndExtraWindow) { |
|
| 92 | + final WebDriverWindow defaultWindow = getCurrentWindow(); |
|
| 93 | + final WebDriverWindow extraWindow = openNewWindow(); |
|
| 94 | + extraWindow.switchToWindow(); |
|
| 95 | + setWindowMaximized(); |
|
| 96 | + defaultWindow.switchToWindow(); |
|
| 97 | + try { |
|
| 98 | + defaultAndExtraWindow.accept(defaultWindow, extraWindow); |
|
| 99 | + } finally { |
|
| 100 | + try { |
|
| 101 | + extraWindow.close(); |
|
| 102 | + } catch (Exception e) { |
|
| 103 | + // This call may fail depending on the WebDriver being used |
|
| 104 | + } |
|
| 105 | + defaultWindow.switchToWindow(); |
|
| 106 | + } |
|
| 107 | + } |
|
| 108 | + |
|
| 109 | + private void setWindowMaximized() { |
|
| 110 | + try { |
|
| 111 | + driver.manage().window().maximize(); |
|
| 112 | + } catch (Exception e) { |
|
| 113 | + // Depending on the combination of OS and WebDriver implementation this may fail |
|
| 114 | + // e.g. chrome with xvfb can't do this successfully. |
|
| 115 | + try { |
|
| 116 | + // Trying to set a proper screen size as fallback that should usable with all modern screens |
|
| 117 | + driver.manage().window().setSize(new Dimension(1440, 900)); |
|
| 118 | + } catch (Exception exc) { |
|
| 119 | + // In this case we just can't change the window |
|
| 120 | + } |
|
| 121 | + } |
|
| 122 | + } |
|
| 137 | 123 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/HostPage.java
| ... | ... | @@ -3,6 +3,7 @@ package com.sap.sailing.selenium.pages; |
| 3 | 3 | import java.net.URI; |
| 4 | 4 | import java.net.URISyntaxException; |
| 5 | 5 | |
| 6 | +import org.openqa.selenium.JavascriptExecutor; |
|
| 6 | 7 | import org.openqa.selenium.WebDriver; |
| 7 | 8 | |
| 8 | 9 | /** |
| ... | ... | @@ -18,9 +19,9 @@ public abstract class HostPage extends PageObject { |
| 18 | 19 | protected static final String NO_CODE_SERVER_PARAMTER_VALUE = ""; //$NON-NLS-1$ |
| 19 | 20 | |
| 20 | 21 | /** |
| 21 | - * </p>The default timeout of 60 seconds for the initialization of the page object.</p> |
|
| 22 | + * </p>The default timeout of 120 seconds for the initialization of the page object.</p> |
|
| 22 | 23 | */ |
| 23 | - protected static final int DEFAULT_PAGE_LOAD_TIMEOUT = 120; |
|
| 24 | + protected static final int DEFAULT_PAGE_LOAD_TIMEOUT_IN_SECONDS = 120; |
|
| 24 | 25 | |
| 25 | 26 | public static final String getGWTCodeServerAndLocale() { |
| 26 | 27 | StringBuilder queryBuilder = new StringBuilder("locale=en"); |
| ... | ... | @@ -64,13 +65,12 @@ public abstract class HostPage extends PageObject { |
| 64 | 65 | */ |
| 65 | 66 | @Override |
| 66 | 67 | protected void initElements() { |
| 67 | - waitForAjaxRequests(getPageLoadTimeOut(), 5); |
|
| 68 | - |
|
| 68 | + waitForAjaxRequests(getPageLoadTimeOutInSeconds(), 5 /* seconds */); |
|
| 69 | 69 | super.initElements(); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | - protected int getPageLoadTimeOut() { |
|
| 73 | - return DEFAULT_PAGE_LOAD_TIMEOUT; |
|
| 72 | + protected int getPageLoadTimeOutInSeconds() { |
|
| 73 | + return DEFAULT_PAGE_LOAD_TIMEOUT_IN_SECONDS; |
|
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | protected interface HostPageSupplier<T extends HostPage> { |
| ... | ... | @@ -80,4 +80,8 @@ public abstract class HostPage extends PageObject { |
| 80 | 80 | public String getCurrentUrl() { |
| 81 | 81 | return driver.getCurrentUrl(); |
| 82 | 82 | } |
| 83 | + |
|
| 84 | + protected void scrollToTop() { |
|
| 85 | + ((JavascriptExecutor) driver).executeScript("window.scrollTo(0, 0);"); |
|
| 86 | + } |
|
| 83 | 87 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/PageObject.java
| ... | ... | @@ -1,18 +1,19 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages; |
| 2 | 2 | |
| 3 | 3 | import java.text.MessageFormat; |
| 4 | +import java.time.Duration; |
|
| 4 | 5 | import java.util.Arrays; |
| 5 | 6 | import java.util.Collection; |
| 6 | 7 | import java.util.Collections; |
| 7 | 8 | import java.util.List; |
| 8 | -import java.util.concurrent.TimeUnit; |
|
| 9 | 9 | import java.util.function.BooleanSupplier; |
| 10 | +import java.util.function.Function; |
|
| 10 | 11 | import java.util.logging.Level; |
| 11 | 12 | import java.util.logging.Logger; |
| 12 | 13 | |
| 13 | 14 | import org.openqa.selenium.Alert; |
| 14 | 15 | import org.openqa.selenium.By; |
| 15 | -import org.openqa.selenium.NoAlertPresentException; |
|
| 16 | +import org.openqa.selenium.JavascriptExecutor; |
|
| 16 | 17 | import org.openqa.selenium.SearchContext; |
| 17 | 18 | import org.openqa.selenium.WebDriver; |
| 18 | 19 | import org.openqa.selenium.WebElement; |
| ... | ... | @@ -21,8 +22,6 @@ import org.openqa.selenium.support.ui.ExpectedConditions; |
| 21 | 22 | import org.openqa.selenium.support.ui.FluentWait; |
| 22 | 23 | import org.openqa.selenium.support.ui.WebDriverWait; |
| 23 | 24 | |
| 24 | -import com.google.common.base.Function; |
|
| 25 | -import com.google.common.base.Predicate; |
|
| 26 | 25 | import com.sap.sailing.selenium.core.AjaxCallsComplete; |
| 27 | 26 | import com.sap.sailing.selenium.core.AjaxCallsExecuted; |
| 28 | 27 | import com.sap.sailing.selenium.core.BySeleniumId; |
| ... | ... | @@ -60,7 +59,7 @@ public class PageObject { |
| 60 | 59 | |
| 61 | 60 | public static final int DEFAULT_WAIT_TIMEOUT_SECONDS = 120; |
| 62 | 61 | |
| 63 | - public static final int DEFAULT_POLLING_INTERVAL = 5; |
|
| 62 | + public static final int DEFAULT_POLLING_INTERVAL = 1; |
|
| 64 | 63 | |
| 65 | 64 | private static final MessageFormat TAB_PANEL_EXPRESSION = new MessageFormat( |
| 66 | 65 | ".//div[contains(@class, \"gwt-TabBarItem\")]/div[text()=\"{0}\"]/.."); |
| ... | ... | @@ -132,15 +131,15 @@ public class PageObject { |
| 132 | 131 | * |
| 133 | 132 | * @param input |
| 134 | 133 | * |
| 135 | - * @param timeout |
|
| 134 | + * @param timeoutInSeconds |
|
| 136 | 135 | * |
| 137 | - * @param polling |
|
| 136 | + * @param pollingEverySoManySeconds |
|
| 138 | 137 | * |
| 139 | 138 | * @return |
| 140 | 139 | * |
| 141 | 140 | */ |
| 142 | - public static <T> FluentWait<T> createFluentWait(T input, int timeout, int polling) { |
|
| 143 | - return createFluentWait(input, timeout, polling, Collections.<Class<? extends Throwable>>emptyList()); |
|
| 141 | + public static <T> FluentWait<T> createFluentWait(T input, int timeoutInSeconds, int pollingEverySoManySeconds) { |
|
| 142 | + return createFluentWait(input, timeoutInSeconds, pollingEverySoManySeconds, Collections.<Class<? extends Throwable>>emptyList()); |
|
| 144 | 143 | } |
| 145 | 144 | |
| 146 | 145 | /** |
| ... | ... | @@ -168,20 +167,20 @@ public class PageObject { |
| 168 | 167 | * |
| 169 | 168 | * @param input |
| 170 | 169 | * |
| 171 | - * @param timeout |
|
| 170 | + * @param timeoutInSeconds |
|
| 172 | 171 | * |
| 173 | - * @param polling |
|
| 172 | + * @param pollingEverySoManySeconds |
|
| 174 | 173 | * |
| 175 | 174 | * @param exceptions |
| 176 | 175 | * |
| 177 | 176 | * @return |
| 178 | 177 | * |
| 179 | 178 | */ |
| 180 | - public static <T> FluentWait<T> createFluentWait(T input, int timeout, int polling, |
|
| 179 | + public static <T> FluentWait<T> createFluentWait(T input, int timeoutInSeconds, int pollingEverySoManySeconds, |
|
| 181 | 180 | Collection<Class<? extends Throwable>> exceptions) { |
| 182 | 181 | FluentWait<T> wait = new FluentWait<>(input); |
| 183 | - wait.withTimeout(timeout, TimeUnit.SECONDS); |
|
| 184 | - wait.pollingEvery(polling, TimeUnit.SECONDS); |
|
| 182 | + wait.withTimeout(Duration.ofSeconds(timeoutInSeconds)); |
|
| 183 | + wait.pollingEvery(Duration.ofSeconds(pollingEverySoManySeconds)); |
|
| 185 | 184 | wait.ignoreAll(exceptions); |
| 186 | 185 | |
| 187 | 186 | return wait; |
| ... | ... | @@ -223,7 +222,7 @@ public class PageObject { |
| 223 | 222 | |
| 224 | 223 | /** |
| 225 | 224 | * <p>Initialize the page object. The default implementation use a factory to lazily initialize the elements |
| 226 | - * (annotated fields) of the page object using the timeout duration returned by {@link #getPageLoadTimeOut()}. |
|
| 225 | + * (annotated fields) of the page object using the timeout duration returned by {@link #getPageLoadTimeOutInSeconds()}. |
|
| 227 | 226 | * To get a field lazily initialized you have to annotate the field either with {@link FindBy} or with |
| 228 | 227 | * {@link FindBys}. If the element never changes (that is, that the same instance in the DOM can always be used) |
| 229 | 228 | * it is also possible to use a cache for the lookup by using the annotation {@code CacheLookup} in addition.</p> |
| ... | ... | @@ -431,15 +430,15 @@ public class PageObject { |
| 431 | 430 | * and polling interval. In reality, the interval may be greater as the cost of actually evaluating the condition |
| 432 | 431 | * is not factored in.</p> |
| 433 | 432 | * |
| 434 | - * @param timeout |
|
| 435 | - * The timeout duration for the waiting. |
|
| 436 | - * @param polling |
|
| 437 | - * The interval in which the check should be performed. |
|
| 433 | + * @param timeoutInSeconds |
|
| 434 | + * The timeout duration for the waiting in seconds. |
|
| 435 | + * @param pollingEverySoManySeconds |
|
| 436 | + * The interval in seconds in which the check should be performed. |
|
| 438 | 437 | * @throws org.openqa.selenium.TimeoutException |
| 439 | 438 | * if the timeout expires. |
| 440 | 439 | */ |
| 441 | - protected void waitForAjaxRequests(int timeout, int polling) { |
|
| 442 | - waitForAjaxRequests(AjaxCallsComplete.CATEGORY_GLOBAL, timeout, polling); |
|
| 440 | + protected void waitForAjaxRequests(int timeoutInSeconds, int pollingEverySoManySeconds) { |
|
| 441 | + waitForAjaxRequests(AjaxCallsComplete.CATEGORY_GLOBAL, timeoutInSeconds, pollingEverySoManySeconds); |
|
| 443 | 442 | } |
| 444 | 443 | |
| 445 | 444 | /** |
| ... | ... | @@ -449,15 +448,15 @@ public class PageObject { |
| 449 | 448 | * |
| 450 | 449 | * @param category |
| 451 | 450 | * The category of Ajax requests to wait for. |
| 452 | - * @param timeout |
|
| 453 | - * The timeout duration for the waiting. |
|
| 454 | - * @param polling |
|
| 455 | - * The interval in which the check should be performed. |
|
| 451 | + * @param timeoutInSeconds |
|
| 452 | + * The timeout duration for the waiting in seconds. |
|
| 453 | + * @param pollingEverySoManySeconds |
|
| 454 | + * The interval in seconds in which the check should be performed. |
|
| 456 | 455 | * @throws org.openqa.selenium.TimeoutException |
| 457 | 456 | * if the timeout expires. |
| 458 | 457 | */ |
| 459 | - protected void waitForAjaxRequests(String category, int timeout, int polling) { |
|
| 460 | - FluentWait<WebDriver> wait = createFluentWait(this.driver, timeout, polling); |
|
| 458 | + protected void waitForAjaxRequests(String category, int timeoutInSeconds, int pollingEverySoManySeconds) { |
|
| 459 | + FluentWait<WebDriver> wait = createFluentWait(this.driver, timeoutInSeconds, pollingEverySoManySeconds); |
|
| 461 | 460 | |
| 462 | 461 | wait.until(new AjaxCallsComplete(category)); |
| 463 | 462 | } |
| ... | ... | @@ -484,7 +483,7 @@ public class PageObject { |
| 484 | 483 | webDriverWait.until(ExpectedConditions.presenceOfElementLocated(new BySeleniumId(seleniumId))); |
| 485 | 484 | } |
| 486 | 485 | |
| 487 | - protected void waitUntil(Predicate<WebDriver> predicate) { |
|
| 486 | + protected void waitUntil(Function<WebDriver, Boolean> predicate) { |
|
| 488 | 487 | WebDriverWait webDriverWait = new WebDriverWait(driver, DEFAULT_LOOKUP_TIMEOUT); |
| 489 | 488 | webDriverWait.until(predicate); |
| 490 | 489 | } |
| ... | ... | @@ -579,57 +578,67 @@ public class PageObject { |
| 579 | 578 | /** |
| 580 | 579 | * Waits for an alert box to appear and accepts the alert. If no alert shows up, an Exception is thrown. |
| 581 | 580 | */ |
| 582 | - protected void waitForAlertAndAccept() throws InterruptedException { |
|
| 581 | + protected void waitForAlertAndAccept() { |
|
| 583 | 582 | waitForAlertAndAccept(DEFAULT_WAIT_TIMEOUT_SECONDS); |
| 584 | 583 | } |
| 585 | 584 | |
| 586 | 585 | /** |
| 587 | 586 | * Waits for an alert box to appear and accepts the alert. If no alert shows up, an Exception is thrown. |
| 588 | 587 | */ |
| 589 | - protected void waitForAlertAndAccept(int timeoutInSeconds) throws InterruptedException { |
|
| 590 | - int i = 0; |
|
| 591 | - while (i < timeoutInSeconds) { |
|
| 592 | - i++; |
|
| 593 | - try { |
|
| 594 | - Alert alert = driver.switchTo().alert(); |
|
| 595 | - alert.accept(); |
|
| 596 | - return; |
|
| 597 | - } catch (NoAlertPresentException e) { |
|
| 598 | - Thread.sleep(1000); |
|
| 599 | - } |
|
| 600 | - } |
|
| 601 | - throw new NoAlertPresentException(); |
|
| 588 | + protected void waitForAlertAndAccept(int timeoutInSeconds) { |
|
| 589 | + final Alert expectedAlert = new WebDriverWait(driver, timeoutInSeconds).until(ExpectedConditions.alertIsPresent()); |
|
| 590 | + expectedAlert.accept(); |
|
| 602 | 591 | } |
| 603 | 592 | |
| 604 | 593 | /** |
| 605 | - * Waits for an notification to appear and dismisses the notification by clicking on it. If no notification shows up, an Exception is thrown. |
|
| 594 | + * Waits for a notification to appear and dismisses the notification by clicking on it. If no notification shows up, an Exception is thrown. |
|
| 606 | 595 | */ |
| 607 | - protected void waitForNotificationAndDismiss() throws InterruptedException { |
|
| 608 | - waitForNotificationAndDismiss(DEFAULT_WAIT_TIMEOUT_SECONDS); |
|
| 596 | + protected void waitForNotificationAndDismiss() { |
|
| 597 | + waitForNotificationAndDismiss(DEFAULT_WAIT_TIMEOUT_SECONDS, null); |
|
| 598 | + } |
|
| 599 | + |
|
| 600 | + /** |
|
| 601 | + * Waits for a specific notification to appear and dismisses the notification by clicking on it. If no notification shows up, an Exception is thrown. |
|
| 602 | + */ |
|
| 603 | + protected void waitForNotificationAndDismiss(String expectedNotificationMessage) { |
|
| 604 | + waitForNotificationAndDismiss(DEFAULT_WAIT_TIMEOUT_SECONDS, expectedNotificationMessage); |
|
| 609 | 605 | } |
| 610 | 606 | |
| 611 | 607 | /** |
| 612 | 608 | * Waits for an notification to appear and dismisses the notification by clicking on it. If no notification shows up, an Exception is thrown. |
| 613 | 609 | */ |
| 614 | - protected void waitForNotificationAndDismiss(int timeoutInSeconds) throws InterruptedException { |
|
| 615 | - int i = 0; |
|
| 616 | - while (i < timeoutInSeconds) { |
|
| 617 | - i++; |
|
| 618 | - try { |
|
| 619 | - List<WebElement> notifications = driver.findElements(By.id("notificationBar")); |
|
| 620 | - if (notifications.size() > 0) { |
|
| 621 | - notifications.get(0).findElements(By.cssSelector("*")) |
|
| 622 | - .forEach(notification -> notification.click()); |
|
| 623 | - ; |
|
| 624 | - return; |
|
| 625 | - } else { |
|
| 626 | - throw new NoAlertPresentException(); |
|
| 610 | + protected void waitForNotificationAndDismiss(int timeoutInSeconds, String expectedNotificationMessage) { |
|
| 611 | + WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds); |
|
| 612 | + wait.until(new Function<WebDriver, Boolean>() { |
|
| 613 | + |
|
| 614 | + @Override |
|
| 615 | + public Boolean apply(WebDriver t) { |
|
| 616 | + boolean clickedNotifications = false; |
|
| 617 | + try { |
|
| 618 | + List<WebElement> notificationBar = driver.findElements(By.id("notificationBar")); |
|
| 619 | + if (!notificationBar.isEmpty()) { |
|
| 620 | + // we got the enclosing panel |
|
| 621 | + List<WebElement> notifications = notificationBar.get(0).findElements(By.cssSelector("*")); |
|
| 622 | + if (!notifications.isEmpty()) { |
|
| 623 | + for (WebElement messageElement : notifications) { |
|
| 624 | + if (expectedNotificationMessage == null |
|
| 625 | + || messageElement.getText().contains(expectedNotificationMessage)) { |
|
| 626 | + messageElement.click(); |
|
| 627 | + clickedNotifications = true; |
|
| 628 | + } |
|
| 629 | + } |
|
| 630 | + } |
|
| 631 | + } |
|
| 632 | + } catch (Exception e) { |
|
| 633 | + // This call can fail temporarily while notifications are being updated |
|
| 627 | 634 | } |
| 628 | - } catch (NoAlertPresentException e) { |
|
| 629 | - Thread.sleep(1000); |
|
| 635 | + return clickedNotifications; |
|
| 630 | 636 | } |
| 631 | - } |
|
| 632 | - throw new NoAlertPresentException(); |
|
| 637 | + }); |
|
| 638 | + } |
|
| 639 | + |
|
| 640 | + protected void scrollToView(WebElement webElement) { |
|
| 641 | + ((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(false);", webElement); |
|
| 633 | 642 | } |
| 634 | 643 | |
| 635 | 644 | public boolean isElementEntirelyVisible(WebElement element) { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/ActionsHelper.java
| ... | ... | @@ -1,5 +1,7 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.adminconsole; |
| 2 | 2 | |
| 3 | +import java.util.function.Function; |
|
| 4 | + |
|
| 3 | 5 | import org.openqa.selenium.Alert; |
| 4 | 6 | import org.openqa.selenium.By; |
| 5 | 7 | import org.openqa.selenium.NoAlertPresentException; |
| ... | ... | @@ -9,7 +11,6 @@ import org.openqa.selenium.WebDriver.TargetLocator; |
| 9 | 11 | import org.openqa.selenium.WebElement; |
| 10 | 12 | import org.openqa.selenium.support.ui.FluentWait; |
| 11 | 13 | |
| 12 | -import com.google.common.base.Function; |
|
| 13 | 14 | import com.sap.sailing.selenium.pages.PageObject; |
| 14 | 15 | |
| 15 | 16 | public class ActionsHelper { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/igtimi/IgtimiAccountsManagementPanelPO.java
| ... | ... | @@ -41,6 +41,6 @@ public class IgtimiAccountsManagementPanelPO extends PageArea { |
| 41 | 41 | addIgtimiAccountDialog.setPassword(password); |
| 42 | 42 | addIgtimiAccountDialog.pressOk(); |
| 43 | 43 | |
| 44 | - waitForNotificationAndDismiss(10); |
|
| 44 | + waitForNotificationAndDismiss(); |
|
| 45 | 45 | } |
| 46 | 46 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java
| ... | ... | @@ -1,15 +1,16 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.adminconsole.regatta; |
| 2 | 2 | |
| 3 | +import java.util.Arrays; |
|
| 4 | +import java.util.Collections; |
|
| 5 | +import java.util.List; |
|
| 6 | + |
|
| 3 | 7 | import org.openqa.selenium.WebDriver; |
| 4 | 8 | import org.openqa.selenium.WebElement; |
| 5 | 9 | |
| 6 | 10 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 7 | 11 | import com.sap.sailing.selenium.core.FindBy; |
| 8 | - |
|
| 9 | 12 | import com.sap.sailing.selenium.pages.PageArea; |
| 10 | - |
|
| 11 | 13 | import com.sap.sailing.selenium.pages.adminconsole.ActionsHelper; |
| 12 | - |
|
| 13 | 14 | import com.sap.sailing.selenium.pages.gwt.CellTablePO; |
| 14 | 15 | import com.sap.sailing.selenium.pages.gwt.DataEntryPO; |
| 15 | 16 | import com.sap.sailing.selenium.pages.gwt.GenericCellTablePO; |
| ... | ... | @@ -85,4 +86,17 @@ public class RegattaDetailsCompositePO extends PageArea { |
| 85 | 86 | private CellTablePO<DataEntryPO> getSeriesTable() { |
| 86 | 87 | return new GenericCellTablePO<>(this.driver, this.seriesTable, DataEntryPO.class); |
| 87 | 88 | } |
| 89 | + |
|
| 90 | + public List<String> getRaceNames(String seriesName) { |
|
| 91 | + final DataEntryPO seriesEntry = findSeries(seriesName); |
|
| 92 | + final String racesColumnContent = seriesEntry.getColumnContent("Races"); |
|
| 93 | + if (racesColumnContent != null && ! racesColumnContent.isEmpty()) { |
|
| 94 | + return Arrays.asList(racesColumnContent.split(", ")); |
|
| 95 | + } |
|
| 96 | + return Collections.emptyList(); |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + public void waitForRacesOfSeries(final String series, final List<String> races) { |
|
| 100 | + waitUntil(() -> getRaceNames(series).equals(races)); |
|
| 101 | + } |
|
| 88 | 102 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaStructureManagementPanelPO.java
| ... | ... | @@ -1,7 +1,10 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.adminconsole.regatta; |
| 2 | 2 | |
| 3 | +import java.util.function.Function; |
|
| 4 | + |
|
| 3 | 5 | import org.openqa.selenium.WebDriver; |
| 4 | 6 | import org.openqa.selenium.WebElement; |
| 7 | +import org.openqa.selenium.support.ui.WebDriverWait; |
|
| 5 | 8 | |
| 6 | 9 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 7 | 10 | import com.sap.sailing.selenium.core.FindBy; |
| ... | ... | @@ -64,7 +67,7 @@ public class RegattaStructureManagementPanelPO extends PageArea { |
| 64 | 67 | } |
| 65 | 68 | |
| 66 | 69 | private DefaultRegattaLeaderboardCreateDialogPO createDefaultRegattaLeaderboard() { |
| 67 | - WebElement dialog = findElementBySeleniumId(this.driver, "CreateDefaultRegattaLeaderboardDialog"); //$NON-NLS-1$ |
|
| 70 | + final WebElement dialog = waitForElementBySeleniumId(this.driver, "CreateDefaultRegattaLeaderboardDialog", 10); //$NON-NLS-1$ |
|
| 68 | 71 | return new DefaultRegattaLeaderboardCreateDialogPO(this.driver, dialog); |
| 69 | 72 | } |
| 70 | 73 | |
| ... | ... | @@ -80,9 +83,14 @@ public class RegattaStructureManagementPanelPO extends PageArea { |
| 80 | 83 | } |
| 81 | 84 | |
| 82 | 85 | public RegattaDetailsCompositePO getRegattaDetails() { |
| 83 | - if (this.regattaDetails.isDisplayed()) { |
|
| 84 | - return new RegattaDetailsCompositePO(this.driver, this.regattaDetails); |
|
| 85 | - } |
|
| 86 | - return null; |
|
| 86 | + return new WebDriverWait(driver, DEFAULT_WAIT_TIMEOUT_SECONDS).until(new Function<WebDriver, RegattaDetailsCompositePO>() { |
|
| 87 | + @Override |
|
| 88 | + public RegattaDetailsCompositePO apply(WebDriver t) { |
|
| 89 | + if (regattaDetails.isDisplayed()) { |
|
| 90 | + return new RegattaDetailsCompositePO(driver, regattaDetails); |
|
| 91 | + } |
|
| 92 | + return null; |
|
| 93 | + } |
|
| 94 | + }); |
|
| 87 | 95 | } |
| 88 | 96 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/SeriesEditDialogPO.java
| ... | ... | @@ -6,6 +6,7 @@ import java.util.List; |
| 6 | 6 | import org.openqa.selenium.By; |
| 7 | 7 | import org.openqa.selenium.WebDriver; |
| 8 | 8 | import org.openqa.selenium.WebElement; |
| 9 | +import org.openqa.selenium.interactions.Actions; |
|
| 9 | 10 | import org.openqa.selenium.support.ui.Select; |
| 10 | 11 | |
| 11 | 12 | import com.sap.sailing.selenium.core.BySeleniumId; |
| ... | ... | @@ -121,9 +122,12 @@ public class SeriesEditDialogPO extends DataEntryDialogPO { |
| 121 | 122 | for(WebElement editorRow : getRaceNameEditors()) { |
| 122 | 123 | WebElement valueTextBox = findElementBySeleniumId(editorRow, "ValueTextBox"); |
| 123 | 124 | |
| 124 | - if(races.contains(valueTextBox.getAttribute("value"))) { |
|
| 125 | + if (races.contains(valueTextBox.getAttribute("value"))) { |
|
| 125 | 126 | WebElement removeButton = findElementBySeleniumId(editorRow, "RemoveButton"); |
| 126 | - removeButton.click(); |
|
| 127 | + // A simple "removeButton.click();" does not work on GeckoDriver here. |
|
| 128 | + // This only presses the button down but a click isn't detected. |
|
| 129 | + // It seems that the mouseup event isn't correctly fired, why we use this workaround. |
|
| 130 | + new Actions(driver).sendKeys(removeButton, "\13").perform(); |
|
| 127 | 131 | } |
| 128 | 132 | } |
| 129 | 133 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/tracking/TrackedRacesListPO.java
| ... | ... | @@ -6,13 +6,13 @@ import java.util.Collections; |
| 6 | 6 | import java.util.Iterator; |
| 7 | 7 | import java.util.List; |
| 8 | 8 | import java.util.Objects; |
| 9 | +import java.util.function.Function; |
|
| 9 | 10 | |
| 10 | 11 | import org.openqa.selenium.TimeoutException; |
| 11 | 12 | import org.openqa.selenium.WebDriver; |
| 12 | 13 | import org.openqa.selenium.WebElement; |
| 13 | 14 | import org.openqa.selenium.support.ui.FluentWait; |
| 14 | 15 | |
| 15 | -import com.google.common.base.Function; |
|
| 16 | 16 | import com.sap.sailing.domain.common.BoatClassMasterdata; |
| 17 | 17 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 18 | 18 | import com.sap.sailing.selenium.core.FindBy; |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/tractrac/TracTracEventManagementPanelPO.java
| ... | ... | @@ -1,16 +1,17 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.adminconsole.tractrac; |
| 2 | 2 | |
| 3 | 3 | import java.util.ArrayList; |
| 4 | +import java.util.Collection; |
|
| 5 | +import java.util.Collections; |
|
| 6 | +import java.util.HashSet; |
|
| 4 | 7 | import java.util.LinkedList; |
| 5 | 8 | import java.util.List; |
| 6 | 9 | import java.util.Objects; |
| 10 | +import java.util.Set; |
|
| 7 | 11 | |
| 8 | -import org.openqa.selenium.Alert; |
|
| 9 | 12 | import org.openqa.selenium.By; |
| 10 | 13 | import org.openqa.selenium.WebDriver; |
| 11 | 14 | import org.openqa.selenium.WebElement; |
| 12 | -import org.openqa.selenium.support.ui.ExpectedCondition; |
|
| 13 | -import org.openqa.selenium.support.ui.ExpectedConditions; |
|
| 14 | 15 | import org.openqa.selenium.support.ui.Select; |
| 15 | 16 | |
| 16 | 17 | import com.sap.sailing.domain.common.BoatClassMasterdata; |
| ... | ... | @@ -45,7 +46,7 @@ public class TracTracEventManagementPanelPO extends PageArea { |
| 45 | 46 | |
| 46 | 47 | @Override |
| 47 | 48 | public int hashCode() { |
| 48 | - return Objects.hash(this.boatClass, this.eventName, this.raceName); |
|
| 49 | + return Objects.hash(BoatClassMasterdata.resolveBoatClass(this.boatClass), this.eventName, this.raceName); |
|
| 49 | 50 | } |
| 50 | 51 | |
| 51 | 52 | @Override |
| ... | ... | @@ -228,44 +229,53 @@ public class TracTracEventManagementPanelPO extends PageArea { |
| 228 | 229 | } |
| 229 | 230 | |
| 230 | 231 | public void startTrackingForRace(TrackableRaceDescriptor race) { |
| 231 | - //startTrackingForRaces(Arrays.asList(race)); |
|
| 232 | - CellTablePO<DataEntryPO> table = getTrackableRacesTable(); |
|
| 233 | - DataEntryPO entryToSelect = null; |
|
| 234 | - for (DataEntryPO entry : table.getEntries()) { |
|
| 235 | - TrackableRaceDescriptor entryDiscribtor = new TrackableRaceDescriptor(entry.getColumnContent("Event"), |
|
| 236 | - entry.getColumnContent("Race"), entry.getColumnContent("Boat Class")); |
|
| 237 | - if (race.equals(entryDiscribtor)) { |
|
| 238 | - entryToSelect = entry; |
|
| 239 | - break; |
|
| 240 | - } |
|
| 241 | - } |
|
| 242 | - table.selectEntry(entryToSelect); |
|
| 243 | - startTrackingAndWaitForAjaxRequests(); |
|
| 232 | + startTrackingForRacesInternal(Collections.singletonList(race), null, false); |
|
| 244 | 233 | } |
| 245 | 234 | |
| 246 | - public void startTrackingForRaces(List<TrackableRaceDescriptor> races) { |
|
| 247 | - List<TrackableRaceDescriptor> racesToProcess = new ArrayList<>(races); |
|
| 248 | - CellTablePO<DataEntryPO> table = getTrackableRacesTable(); |
|
| 235 | + public void startTrackingForRacesAndAcceptDefaultRegattaWarning(TrackableRaceDescriptor race) { |
|
| 236 | + startTrackingForRacesInternal(Collections.singletonList(race), null, true); |
|
| 237 | + } |
|
| 238 | + |
|
| 239 | + public void startTrackingForRaceAndAwaitBoatClassError(TrackableRaceDescriptor race, String expectedBoatClass) { |
|
| 240 | + startTrackingForRacesInternal(Collections.singletonList(race), expectedBoatClass, false); |
|
| 241 | + } |
|
| 242 | + |
|
| 243 | + public void startTrackingForRaces(Collection<TrackableRaceDescriptor> races) { |
|
| 244 | + startTrackingForRacesInternal(races, null, false); |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + private void startTrackingForRacesInternal(Collection<TrackableRaceDescriptor> races, |
|
| 248 | + String expectedBoatClassErrorOrNull, boolean awaitDefaultRegattaAlert) { |
|
| 249 | + final Set<TrackableRaceDescriptor> racesToProcess = new HashSet<>(races); |
|
| 250 | + final CellTablePO<DataEntryPO> table = getTrackableRacesTable(); |
|
| 249 | 251 | table.selectEntries(e -> racesToProcess.remove(new TrackableRaceDescriptor(e.getColumnContent("Event"), |
| 250 | - e.getColumnContent("Race"), e.getColumnContent("Boat Class")))); |
|
| 251 | - if(!racesToProcess.isEmpty()) { |
|
| 252 | + e.getColumnContent("Race"), e.getColumnContent("Boat Class"))), racesToProcess::isEmpty); |
|
| 253 | + if (!racesToProcess.isEmpty()) { |
|
| 252 | 254 | throw new IllegalStateException("Not all given races where selected"); |
| 253 | 255 | } |
| 254 | - startTrackingAndWaitForAjaxRequests(); |
|
| 256 | + startTrackingForSelectedRaces(expectedBoatClassErrorOrNull, awaitDefaultRegattaAlert); |
|
| 255 | 257 | } |
| 256 | 258 | |
| 257 | 259 | public void startTrackingForAllRaces() { |
| 258 | 260 | getTrackableRacesTable().selectAllEntries(); |
| 259 | - startTrackingAndWaitForAjaxRequests(); |
|
| 261 | + startTrackingForSelectedRaces(null, false); |
|
| 260 | 262 | } |
| 261 | 263 | |
| 262 | - private void startTrackingAndWaitForAjaxRequests() { |
|
| 263 | - this.startTrackingButton.click(); |
|
| 264 | - ExpectedCondition<Alert> condition = ExpectedConditions.alertIsPresent(); |
|
| 265 | - if (condition.apply(this.driver) == null) { |
|
| 264 | + private void startTrackingForSelectedRaces(String expectedBoatClassErrorOrNull, boolean awaitDefaultRegattaAlert) { |
|
| 265 | + this.startTracking(); |
|
| 266 | + |
|
| 267 | + if (awaitDefaultRegattaAlert) { |
|
| 268 | + waitForAlertAndAccept(); |
|
| 269 | + } else if (expectedBoatClassErrorOrNull == null) { |
|
| 266 | 270 | waitForAjaxRequests(); |
| 271 | + } else { |
|
| 272 | + waitForSelectedRacesContainDifferentBoatClassesError(expectedBoatClassErrorOrNull); |
|
| 267 | 273 | } |
| 268 | 274 | } |
| 275 | + |
|
| 276 | + private void startTracking() { |
|
| 277 | + this.startTrackingButton.click(); |
|
| 278 | + } |
|
| 269 | 279 | |
| 270 | 280 | public TrackedRacesListPO getTrackedRacesList() { |
| 271 | 281 | return new TrackedRacesListPO(this.driver, this.trackedRacesListComposite); |
| ... | ... | @@ -281,4 +291,11 @@ public class TracTracEventManagementPanelPO extends PageArea { |
| 281 | 291 | if(input.isSelected() != selected) |
| 282 | 292 | input.click(); |
| 283 | 293 | } |
| 294 | + |
|
| 295 | + private void waitForSelectedRacesContainDifferentBoatClassesError(String boatClass) { |
|
| 296 | + String message = String.format("The selected races contain boat classes which are not the same as " |
|
| 297 | + + "the boat class '%s' of the selected regatta.", boatClass); |
|
| 298 | + |
|
| 299 | + waitForNotificationAndDismiss(message); |
|
| 300 | + } |
|
| 284 | 301 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/wind/WindPanelPO.java
| ... | ... | @@ -1,11 +1,12 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.adminconsole.wind; |
| 2 | 2 | |
| 3 | +import java.util.function.Function; |
|
| 4 | + |
|
| 3 | 5 | import org.openqa.selenium.TimeoutException; |
| 4 | 6 | import org.openqa.selenium.WebDriver; |
| 5 | 7 | import org.openqa.selenium.WebElement; |
| 6 | 8 | import org.openqa.selenium.support.ui.FluentWait; |
| 7 | 9 | |
| 8 | -import com.google.common.base.Function; |
|
| 9 | 10 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 10 | 11 | import com.sap.sailing.selenium.core.FindBy; |
| 11 | 12 | import com.sap.sailing.selenium.pages.PageArea; |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/autoplay/AutoPlayConfiguration.java
| ... | ... | @@ -2,9 +2,7 @@ package com.sap.sailing.selenium.pages.autoplay; |
| 2 | 2 | |
| 3 | 3 | import org.openqa.selenium.WebDriver; |
| 4 | 4 | import org.openqa.selenium.WebElement; |
| 5 | -import org.openqa.selenium.support.ui.WebDriverWait; |
|
| 6 | 5 | |
| 7 | -import com.google.common.base.Predicate; |
|
| 8 | 6 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 9 | 7 | import com.sap.sailing.selenium.core.FindBy; |
| 10 | 8 | import com.sap.sailing.selenium.pages.PageArea; |
| ... | ... | @@ -31,15 +29,8 @@ public class AutoPlayConfiguration extends PageArea { |
| 31 | 29 | ListBoxPO.create(driver, configurationSelectionBox).selectOptionByLabel(mode); |
| 32 | 30 | ListBoxPO.create(driver, eventSelectionBox).selectOptionByLabel(event); |
| 33 | 31 | ListBoxPO.create(driver, leaderboardSelectionBox).selectOptionByLabel(leaderboard); |
| 34 | - WebDriverWait wait = new WebDriverWait(driver, 10); |
|
| 35 | 32 | //wait till the page processed the changes |
| 36 | - wait.until(new Predicate<WebDriver>() { |
|
| 37 | - |
|
| 38 | - @Override |
|
| 39 | - public boolean apply(WebDriver arg0) { |
|
| 40 | - return getConfiguredUrl() != null && !getConfiguredUrl().isEmpty(); |
|
| 41 | - } |
|
| 42 | - }); |
|
| 33 | + waitUntil(() -> getConfiguredUrl() != null && !getConfiguredUrl().isEmpty()); |
|
| 43 | 34 | } |
| 44 | 35 | |
| 45 | 36 | public String getConfiguredUrl() { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/autoplay/AutoPlayUpcomingView.java
| ... | ... | @@ -1,13 +1,13 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.autoplay; |
| 2 | 2 | |
| 3 | 3 | import java.util.List; |
| 4 | +import java.util.function.Function; |
|
| 4 | 5 | |
| 5 | 6 | import org.openqa.selenium.StaleElementReferenceException; |
| 6 | 7 | import org.openqa.selenium.WebDriver; |
| 7 | 8 | import org.openqa.selenium.WebElement; |
| 8 | 9 | import org.openqa.selenium.support.ui.WebDriverWait; |
| 9 | 10 | |
| 10 | -import com.google.common.base.Function; |
|
| 11 | 11 | import com.sap.sailing.selenium.pages.PageArea; |
| 12 | 12 | |
| 13 | 13 | public class AutoPlayUpcomingView extends PageArea { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/common/DataEntryDialogPO.java
| ... | ... | @@ -1,10 +1,14 @@ |
| 1 | 1 | package com.sap.sailing.selenium.pages.common; |
| 2 | 2 | |
| 3 | +import java.util.function.BooleanSupplier; |
|
| 4 | + |
|
| 3 | 5 | import org.openqa.selenium.Alert; |
| 6 | +import org.openqa.selenium.JavascriptExecutor; |
|
| 7 | +import org.openqa.selenium.StaleElementReferenceException; |
|
| 4 | 8 | import org.openqa.selenium.WebDriver; |
| 5 | 9 | import org.openqa.selenium.WebElement; |
| 6 | -import org.openqa.selenium.support.ui.ExpectedCondition; |
|
| 7 | 10 | import org.openqa.selenium.support.ui.ExpectedConditions; |
| 11 | +import org.openqa.selenium.support.ui.WebDriverWait; |
|
| 8 | 12 | |
| 9 | 13 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 10 | 14 | import com.sap.sailing.selenium.core.FindBy; |
| ... | ... | @@ -25,6 +29,9 @@ public abstract class DataEntryDialogPO extends PageArea { |
| 25 | 29 | |
| 26 | 30 | protected DataEntryDialogPO(WebDriver driver, WebElement element) { |
| 27 | 31 | super(driver, element); |
| 32 | + |
|
| 33 | + // This ensures that we wait until the dialog is opened and not just attached to the DOM |
|
| 34 | + waitUntil(element::isDisplayed); |
|
| 28 | 35 | } |
| 29 | 36 | |
| 30 | 37 | @Override |
| ... | ... | @@ -52,23 +59,41 @@ public abstract class DataEntryDialogPO extends PageArea { |
| 52 | 59 | } |
| 53 | 60 | |
| 54 | 61 | public void pressOk() { |
| 55 | - pressOk(false); |
|
| 62 | + pressOk(false, true); |
|
| 56 | 63 | } |
| 57 | 64 | |
| 58 | - public void pressOk(boolean accept) { |
|
| 59 | - this.okButton.click(); |
|
| 65 | + public void pressOk(boolean acceptAlert, boolean waitForAjaxRequests) { |
|
| 66 | + // This generically triggers revalidation in dialogs to ensure that the ok button gets enabled |
|
| 67 | + ((JavascriptExecutor) driver).executeScript("!!document.activeElement ? document.activeElement.blur() : 0"); |
|
| 60 | 68 | |
| 61 | - ExpectedCondition<Alert> condition = ExpectedConditions.alertIsPresent(); |
|
| 62 | - Alert alert = condition.apply(this.driver); |
|
| 69 | + scrollToView(this.okButton); |
|
| 70 | + // Browsers may use smooth scrolling |
|
| 71 | + waitUntil(() -> isElementEntirelyVisible(this.okButton) && this.okButton.isEnabled()); |
|
| 72 | + this.okButton.click(); |
|
| 63 | 73 | |
| 64 | - if(alert != null && accept) { |
|
| 74 | + if (acceptAlert) { |
|
| 75 | + final Alert alert = new WebDriverWait(driver, DEFAULT_WAIT_TIMEOUT_SECONDS) |
|
| 76 | + .until(ExpectedConditions.alertIsPresent()); |
|
| 65 | 77 | alert.accept(); |
| 66 | 78 | } |
| 67 | 79 | |
| 68 | - if(alert == null || accept) { |
|
| 80 | + if (waitForAjaxRequests) { |
|
| 69 | 81 | // Wait, since we do a callback usually |
| 70 | 82 | waitForAjaxRequests(); |
| 71 | 83 | } |
| 84 | + |
|
| 85 | + // This waits until the dialog is physically closed to make sure further don't fail because the dialog still covers other elements |
|
| 86 | + waitUntil(new BooleanSupplier() { |
|
| 87 | + @Override |
|
| 88 | + public boolean getAsBoolean() { |
|
| 89 | + try { |
|
| 90 | + return !((WebElement) context).isDisplayed(); |
|
| 91 | + } catch (StaleElementReferenceException e) { |
|
| 92 | + // When the element was removed from the DOM, it isn't displayed anymore |
|
| 93 | + return true; |
|
| 94 | + } |
|
| 95 | + } |
|
| 96 | + }); |
|
| 72 | 97 | } |
| 73 | 98 | |
| 74 | 99 | public void pressCancel() { |
| ... | ... | @@ -78,15 +103,7 @@ public abstract class DataEntryDialogPO extends PageArea { |
| 78 | 103 | public void pressMakeDefault() { |
| 79 | 104 | WebElement element = findElementBySeleniumId(ID_MAKE_DEFAULT_BUTTON); |
| 80 | 105 | element.click(); |
| 81 | - ExpectedCondition<Alert> condition = ExpectedConditions.alertIsPresent(); |
|
| 82 | - Alert alert = condition.apply(this.driver); |
|
| 83 | - |
|
| 84 | - if(alert != null) { |
|
| 85 | - alert.accept(); |
|
| 86 | - } else { |
|
| 87 | - waitForAjaxRequests(); |
|
| 88 | - } |
|
| 89 | - |
|
| 106 | + waitForNotificationAndDismiss(); |
|
| 90 | 107 | } |
| 91 | 108 | |
| 92 | 109 | public boolean isMakeDefaultButtonVisible() { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/gwt/CellTablePO.java
| ... | ... | @@ -4,6 +4,7 @@ import java.util.ArrayList; |
| 4 | 4 | import java.util.Iterator; |
| 5 | 5 | import java.util.List; |
| 6 | 6 | import java.util.Objects; |
| 7 | +import java.util.function.BooleanSupplier; |
|
| 7 | 8 | import java.util.function.Predicate; |
| 8 | 9 | import java.util.function.Supplier; |
| 9 | 10 | import java.util.stream.Stream; |
| ... | ... | @@ -11,9 +12,7 @@ import java.util.stream.Stream; |
| 11 | 12 | import org.openqa.selenium.By; |
| 12 | 13 | import org.openqa.selenium.WebDriver; |
| 13 | 14 | import org.openqa.selenium.WebElement; |
| 14 | -import org.openqa.selenium.support.ui.WebDriverWait; |
|
| 15 | 15 | |
| 16 | -import com.google.common.base.Function; |
|
| 17 | 16 | import com.sap.sailing.selenium.pages.PageArea; |
| 18 | 17 | import com.sap.sailing.selenium.pages.common.CSSConstants; |
| 19 | 18 | |
| ... | ... | @@ -260,13 +259,16 @@ public abstract class CellTablePO<T extends DataEntryPO> extends PageArea { |
| 260 | 259 | * |
| 261 | 260 | * <p>Note: If an entry is not contained in the table it will not be selected.</p> |
| 262 | 261 | */ |
| 263 | - public void selectEntries(Predicate<T> toSelectPredicate) { |
|
| 262 | + public void selectEntries(Predicate<T> toSelectPredicate, BooleanSupplier canAbort) { |
|
| 264 | 263 | for (T entry : getEntries()) { |
| 265 | 264 | if(toSelectPredicate.test(entry)) { |
| 266 | 265 | entry.appendToSelection(); |
| 267 | 266 | } else { |
| 268 | 267 | entry.deselect(); |
| 269 | 268 | } |
| 269 | + if (canAbort.getAsBoolean()) { |
|
| 270 | + break; |
|
| 271 | + } |
|
| 270 | 272 | } |
| 271 | 273 | } |
| 272 | 274 | |
| ... | ... | @@ -276,7 +278,7 @@ public abstract class CellTablePO<T extends DataEntryPO> extends PageArea { |
| 276 | 278 | * <p>Note: If an entry is not contained in the table it will not be selected.</p> |
| 277 | 279 | */ |
| 278 | 280 | public void selectAllEntries() { |
| 279 | - selectEntries(e -> true); |
|
| 281 | + selectEntries(e -> true, Boolean.FALSE::booleanValue); |
|
| 280 | 282 | } |
| 281 | 283 | |
| 282 | 284 | /** |
| ... | ... | @@ -347,11 +349,6 @@ public abstract class CellTablePO<T extends DataEntryPO> extends PageArea { |
| 347 | 349 | } |
| 348 | 350 | |
| 349 | 351 | public void waitForTableToShowData() { |
| 350 | - new WebDriverWait(driver, 30).until(new Function<WebDriver, Boolean>() { |
|
| 351 | - @Override |
|
| 352 | - public Boolean apply(WebDriver driver) { |
|
| 353 | - return !getRows().isEmpty(); |
|
| 354 | - } |
|
| 355 | - }); |
|
| 352 | + waitUntil(() -> !getRows().isEmpty()); |
|
| 356 | 353 | } |
| 357 | 354 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/gwt/DataEntryPO.java
| ... | ... | @@ -4,16 +4,12 @@ import java.util.List; |
| 4 | 4 | |
| 5 | 5 | import org.openqa.selenium.By; |
| 6 | 6 | import org.openqa.selenium.By.ByXPath; |
| 7 | +import org.openqa.selenium.Dimension; |
|
| 7 | 8 | import org.openqa.selenium.Keys; |
| 8 | 9 | import org.openqa.selenium.WebElement; |
| 9 | 10 | import org.openqa.selenium.interactions.Action; |
| 10 | 11 | import org.openqa.selenium.interactions.Actions; |
| 11 | 12 | import org.openqa.selenium.interactions.CompositeAction; |
| 12 | -import org.openqa.selenium.interactions.HasInputDevices; |
|
| 13 | -import org.openqa.selenium.interactions.KeyDownAction; |
|
| 14 | -import org.openqa.selenium.interactions.KeyUpAction; |
|
| 15 | -import org.openqa.selenium.interactions.Keyboard; |
|
| 16 | -import org.openqa.selenium.interactions.Mouse; |
|
| 17 | 13 | |
| 18 | 14 | import com.sap.sailing.selenium.core.FindBy; |
| 19 | 15 | import com.sap.sailing.selenium.pages.common.AttributeHelper; |
| ... | ... | @@ -82,11 +78,33 @@ public class DataEntryPO extends CellTableRowPO { |
| 82 | 78 | } |
| 83 | 79 | |
| 84 | 80 | protected Action getSelectAction() { |
| 85 | - Actions actions = new Actions(this.driver); |
|
| 86 | - actions.moveToElement(getElementForSelect(), 1, 1); |
|
| 81 | + final Actions actions = new Actions(this.driver); |
|
| 82 | + final WebElement elementForSelect = getElementForSelect(); |
|
| 83 | + moveToUpperLeftCorner(actions, elementForSelect); |
|
| 87 | 84 | actions.click(); |
| 88 | 85 | |
| 89 | - return actions.build(); |
|
| 86 | + final CompositeAction compositeAction = new CompositeAction(); |
|
| 87 | + compositeAction.addAction(new Action() { |
|
| 88 | + @Override |
|
| 89 | + public void perform() { |
|
| 90 | + scrollToView(elementForSelect); |
|
| 91 | + } |
|
| 92 | + }); |
|
| 93 | + compositeAction.addAction(actions.build()); |
|
| 94 | + return compositeAction; |
|
| 95 | + } |
|
| 96 | + |
|
| 97 | + /** |
|
| 98 | + * It seems that the JavaDoc of {@link Actions#moveToElement(WebElement, int, int)} is not consistent to the |
|
| 99 | + * WebDriver specification. The specification says the int params are relative to the center of the element, while |
|
| 100 | + * the JavaDoc says it's relative to the upper-left corner. GeckoDriver implements the specification. This method |
|
| 101 | + * ensures consistent behavior no matter if the implementation is a legacy one or one that conforms to the |
|
| 102 | + * specification. |
|
| 103 | + */ |
|
| 104 | + private void moveToUpperLeftCorner(Actions actions, WebElement webElement) { |
|
| 105 | + actions.moveToElement(webElement); |
|
| 106 | + final Dimension size = webElement.getSize(); |
|
| 107 | + actions.moveByOffset(-size.width / 2 + 1, -size.height / 2 + 1); |
|
| 90 | 108 | } |
| 91 | 109 | |
| 92 | 110 | /** |
| ... | ... | @@ -110,35 +128,49 @@ public class DataEntryPO extends CellTableRowPO { |
| 110 | 128 | |
| 111 | 129 | protected Action getModifiedSelectAction() { |
| 112 | 130 | Actions actions = new Actions(this.driver); |
| 131 | + final WebElement elementToSelect; |
|
| 132 | + final boolean controlClick; |
|
| 113 | 133 | if (table.getColumnHeaders().get(0).equals("\u2713")) { |
| 114 | 134 | // it's a checkbox column |
| 115 | - actions.moveToElement(this.columns.isEmpty() ? getWebElement() : this.columns.get(0)); |
|
| 116 | - actions.click(); |
|
| 135 | + elementToSelect = this.columns.isEmpty() ? getWebElement() : this.columns.get(0); |
|
| 136 | + controlClick = false; |
|
| 117 | 137 | } else { |
| 138 | + elementToSelect = getElementForSelect(); |
|
| 139 | + controlClick = true; |
|
| 140 | + } |
|
| 141 | + if (controlClick) { |
|
| 118 | 142 | actions.keyDown(Keys.CONTROL); |
| 119 | - actions.moveToElement(getElementForSelect(), 1, 1); |
|
| 120 | - actions.click(); |
|
| 143 | + } |
|
| 144 | + moveToUpperLeftCorner(actions, elementToSelect); |
|
| 145 | + actions.moveToElement(elementToSelect, 1, 1); |
|
| 146 | + actions.click(); |
|
| 147 | + if (controlClick) { |
|
| 121 | 148 | actions.keyUp(Keys.CONTROL); |
| 122 | 149 | } |
| 123 | - return actions.build(); |
|
| 150 | + final CompositeAction compositeAction = new CompositeAction(); |
|
| 151 | + compositeAction.addAction(new Action() { |
|
| 152 | + @Override |
|
| 153 | + public void perform() { |
|
| 154 | + scrollToView(elementToSelect); |
|
| 155 | + } |
|
| 156 | + }); |
|
| 157 | + compositeAction.addAction(actions.build()); |
|
| 158 | + return compositeAction; |
|
| 124 | 159 | } |
| 125 | 160 | |
| 126 | 161 | protected CompositeAction getModifiedCompositeActionAction() { |
| 127 | - HasInputDevices devices = (HasInputDevices) this.driver; |
|
| 128 | - |
|
| 129 | - final Mouse mouse = devices.getMouse(); |
|
| 130 | - final Keyboard keyboard = devices.getKeyboard(); |
|
| 131 | - |
|
| 132 | 162 | return new CompositeAction() { |
| 133 | 163 | @Override |
| 134 | 164 | public void perform() { |
| 135 | - Action pressControl = new KeyDownAction(keyboard, mouse, Keys.CONTROL); |
|
| 136 | - pressControl.perform(); |
|
| 165 | + Actions actions = new Actions(driver); |
|
| 166 | + actions.keyDown(Keys.CONTROL); |
|
| 167 | + actions.perform(); |
|
| 137 | 168 | |
| 138 | 169 | super.perform(); |
| 139 | 170 | |
| 140 | - Action releaseControl = new KeyUpAction(keyboard, mouse, Keys.CONTROL); |
|
| 141 | - releaseControl.perform(); |
|
| 171 | + actions = new Actions(driver); |
|
| 172 | + actions.keyUp(Keys.CONTROL); |
|
| 173 | + actions.perform(); |
|
| 142 | 174 | } |
| 143 | 175 | }; |
| 144 | 176 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/gwt/DateAndTimeInputPO.java
| ... | ... | @@ -4,11 +4,11 @@ import java.text.DateFormat; |
| 4 | 4 | import java.text.SimpleDateFormat; |
| 5 | 5 | import java.util.Date; |
| 6 | 6 | |
| 7 | +import org.openqa.selenium.JavascriptExecutor; |
|
| 7 | 8 | import org.openqa.selenium.WebDriver; |
| 8 | 9 | import org.openqa.selenium.WebElement; |
| 9 | 10 | |
| 10 | 11 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 11 | -import com.sap.sailing.selenium.core.FindBy; |
|
| 12 | 12 | import com.sap.sailing.selenium.pages.PageArea; |
| 13 | 13 | |
| 14 | 14 | public class DateAndTimeInputPO extends PageArea { |
| ... | ... | @@ -16,15 +16,17 @@ public class DateAndTimeInputPO extends PageArea { |
| 16 | 16 | private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMM d, y"); |
| 17 | 17 | private static final DateFormat TIME_FORMAT_MINUTES = new SimpleDateFormat("h:mm a"); |
| 18 | 18 | private static final DateFormat TIME_FORMAT_SECONDS = new SimpleDateFormat("h:mm:ss a"); |
| 19 | + private static final DateFormat ISO_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); |
|
| 20 | + private static final DateFormat ISO_TIME_FORMAT_MINUTES = new SimpleDateFormat("HH:mm"); |
|
| 21 | + private static final DateFormat ISO_TIME_FORMAT_SECONDS = new SimpleDateFormat("HH:mm:ss"); |
|
| 22 | + private static final DateFormat ISO_DATE_TIME_FORMAT_MINUTES = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm"); |
|
| 23 | + private static final DateFormat ISO_DATE_TIME_FORMAT_SECONDS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); |
|
| 19 | 24 | |
| 20 | - @FindBy(how = BySeleniumId.class, using = "dateInput") |
|
| 21 | - private WebElement dateInput; |
|
| 22 | - |
|
| 23 | - @FindBy(how = BySeleniumId.class, using = "timeInput") |
|
| 24 | - private WebElement timeInput; |
|
| 25 | + private final WebElement element; |
|
| 25 | 26 | |
| 26 | 27 | private DateAndTimeInputPO(WebDriver driver, WebElement element) { |
| 27 | 28 | super(driver, element); |
| 29 | + this.element = element; |
|
| 28 | 30 | } |
| 29 | 31 | |
| 30 | 32 | /** |
| ... | ... | @@ -39,8 +41,27 @@ public class DateAndTimeInputPO extends PageArea { |
| 39 | 41 | * @see WebElement#sendKeys(CharSequence...) |
| 40 | 42 | */ |
| 41 | 43 | public void setValue(Date date, boolean enterSeconds) { |
| 42 | - this.setValue(dateInput, date, DATE_FORMAT); |
|
| 43 | - this.setValue(timeInput, date, enterSeconds ? TIME_FORMAT_SECONDS : TIME_FORMAT_MINUTES); |
|
| 44 | + if (isFieldOfType(element, "datetime-local")) { |
|
| 45 | + this.setValueNative(element, date, enterSeconds ? ISO_DATE_TIME_FORMAT_SECONDS : ISO_DATE_TIME_FORMAT_MINUTES); |
|
| 46 | + } else { |
|
| 47 | + final WebElement dateInput = element.findElement(new BySeleniumId("dateInput")); |
|
| 48 | + final WebElement timeInput = element.findElement(new BySeleniumId("timeInput")); |
|
| 49 | + if (isFieldOfType(dateInput, "date")) { |
|
| 50 | + this.setValueNative(dateInput, date, ISO_DATE_FORMAT); |
|
| 51 | + } else { |
|
| 52 | + this.setValue(dateInput, date, DATE_FORMAT); |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + if (isFieldOfType(timeInput, "time")) { |
|
| 56 | + this.setValueNative(timeInput, date, enterSeconds ? ISO_TIME_FORMAT_SECONDS : ISO_TIME_FORMAT_MINUTES); |
|
| 57 | + } else { |
|
| 58 | + this.setValue(timeInput, date, enterSeconds ? TIME_FORMAT_SECONDS : TIME_FORMAT_MINUTES); |
|
| 59 | + } |
|
| 60 | + } |
|
| 61 | + } |
|
| 62 | + |
|
| 63 | + private boolean isFieldOfType(WebElement inputToCheck, String type) { |
|
| 64 | + return type.equals(inputToCheck.getAttribute("type")); |
|
| 44 | 65 | } |
| 45 | 66 | |
| 46 | 67 | private void setValue(WebElement input, Date date, DateFormat format) { |
| ... | ... | @@ -49,6 +70,12 @@ public class DateAndTimeInputPO extends PageArea { |
| 49 | 70 | input.sendKeys(value); |
| 50 | 71 | input.sendKeys("\t"); // ensure popup closing! |
| 51 | 72 | } |
| 73 | + |
|
| 74 | + private void setValueNative(WebElement input, Date date, DateFormat format) { |
|
| 75 | + final String value = format.format(date); |
|
| 76 | + final JavascriptExecutor javascriptExecutor = ((JavascriptExecutor) driver); |
|
| 77 | + javascriptExecutor.executeScript("arguments[0].value = arguments[1];", input, value); |
|
| 78 | + } |
|
| 52 | 79 | |
| 53 | 80 | public static DateAndTimeInputPO create(WebDriver driver, WebElement element) { |
| 54 | 81 | return new DateAndTimeInputPO(driver, element); |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/leaderboard/LeaderboardPage.java
| ... | ... | @@ -129,6 +129,7 @@ public class LeaderboardPage extends HostPage { |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | public LeaderboardSettingsDialogPO getLeaderboardSettings() { |
| 132 | + scrollToTop(); |
|
| 132 | 133 | this.leaderboardSettingsButton.click(); |
| 133 | 134 | return new LeaderboardSettingsDialogPO(this.driver, |
| 134 | 135 | findElementBySeleniumId(this.driver, "LeaderboardSettingsDialog")); |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/raceboard/RaceBoardPage.java
| ... | ... | @@ -3,9 +3,11 @@ package com.sap.sailing.selenium.pages.raceboard; |
| 3 | 3 | import java.io.UnsupportedEncodingException; |
| 4 | 4 | import java.net.URLEncoder; |
| 5 | 5 | import java.util.function.BooleanSupplier; |
| 6 | +import java.util.function.Function; |
|
| 6 | 7 | |
| 7 | 8 | import org.openqa.selenium.WebDriver; |
| 8 | 9 | import org.openqa.selenium.WebElement; |
| 10 | +import org.openqa.selenium.support.ui.WebDriverWait; |
|
| 9 | 11 | |
| 10 | 12 | import com.sap.sailing.selenium.core.BySeleniumId; |
| 11 | 13 | import com.sap.sailing.selenium.core.FindBy; |
| ... | ... | @@ -20,6 +22,7 @@ public class RaceBoardPage extends HostPageWithAuthentication { |
| 20 | 22 | |
| 21 | 23 | @FindBy(how = BySeleniumId.class, using = "raceMapSettingsButton") |
| 22 | 24 | private WebElement raceMapSettingsButton; |
| 25 | + private boolean doneInit; |
|
| 23 | 26 | |
| 24 | 27 | /** |
| 25 | 28 | * Navigates to the given home URL and provides the corresponding {@link PageObject}. |
| ... | ... | @@ -42,20 +45,60 @@ public class RaceBoardPage extends HostPageWithAuthentication { |
| 42 | 45 | private RaceBoardPage(WebDriver driver) { |
| 43 | 46 | super(driver); |
| 44 | 47 | } |
| 48 | + |
|
| 49 | + @Override |
|
| 50 | + protected void waitForAjaxRequests(int timeout, int polling) { |
|
| 51 | + // since the raceboard continually loads new data, we cannot wait for it to finish initially |
|
| 52 | + if (doneInit) { |
|
| 53 | + super.waitForAjaxRequests(timeout, polling); |
|
| 54 | + } |
|
| 55 | + } |
|
| 56 | + |
|
| 57 | + @Override |
|
| 58 | + protected void initElements() { |
|
| 59 | + super.initElements(); |
|
| 60 | + doneInit = true; |
|
| 61 | + |
|
| 62 | + // wait untill initial rendering of racemap & compilation ect, as default ajax based wait won't work here |
|
| 63 | + WebDriverWait webDriverWait = new WebDriverWait(driver, 300); |
|
| 64 | + webDriverWait.until(new Function<WebDriver, Boolean>() { |
|
| 65 | + @Override |
|
| 66 | + public Boolean apply(WebDriver t) { |
|
| 67 | + try { |
|
| 68 | + return raceMapSettingsButton.isDisplayed() && raceMapSettingsButton.getLocation().y > 100; |
|
| 69 | + } catch (Exception e) { |
|
| 70 | + // RaceMap cause multiple reflows and the element may temporarily not be in the viewport |
|
| 71 | + return false; |
|
| 72 | + } |
|
| 73 | + } |
|
| 74 | + }); |
|
| 75 | + } |
|
| 76 | + |
|
| 45 | 77 | public MapSettingsPO openMapSettings() { |
| 78 | + waitUntil(new BooleanSupplier() { |
|
| 79 | + @Override |
|
| 80 | + public boolean getAsBoolean() { |
|
| 81 | + try { |
|
| 82 | + return raceMapSettingsButton.isDisplayed() && raceMapSettingsButton.getLocation().y > 100; |
|
| 83 | + } catch (Exception e) { |
|
| 84 | + // RaceMap cause multiple reflows and the element may temporarily not be in the viewport |
|
| 85 | + return false; |
|
| 86 | + } |
|
| 87 | + } |
|
| 88 | + }); |
|
| 46 | 89 | raceMapSettingsButton.click(); |
| 47 | 90 | waitUntil(new BooleanSupplier() { |
| 48 | - |
|
| 49 | 91 | @Override |
| 50 | 92 | public boolean getAsBoolean() { |
| 51 | 93 | WebElement settingsDialog = null; |
| 52 | 94 | try { |
| 53 | 95 | settingsDialog = findElementBySeleniumId("raceMapSettings"); |
| 96 | + boolean exists = settingsDialog != null; |
|
| 97 | + // exists, and was actually rendered (to apply the values) |
|
| 98 | + return (exists && settingsDialog.isDisplayed()); |
|
| 54 | 99 | } catch(Exception e) { |
| 55 | 100 | } |
| 56 | - boolean exists = settingsDialog != null; |
|
| 57 | - // exists, and was actually rendered (to apply the values) |
|
| 58 | - return (exists && settingsDialog.getSize().height > 50); |
|
| 101 | + return false; |
|
| 59 | 102 | } |
| 60 | 103 | }); |
| 61 | 104 | return new MapSettingsPO(driver, findElementBySeleniumId("raceMapSettings")); |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/AbstractSeleniumTest.java
| ... | ... | @@ -18,20 +18,23 @@ import org.junit.Rule; |
| 18 | 18 | import org.junit.rules.TestWatchman; |
| 19 | 19 | import org.junit.runner.RunWith; |
| 20 | 20 | import org.junit.runners.model.FrameworkMethod; |
| 21 | +import org.openqa.selenium.By; |
|
| 21 | 22 | import org.openqa.selenium.Cookie; |
| 22 | -import org.openqa.selenium.JavascriptExecutor; |
|
| 23 | +import org.openqa.selenium.Keys; |
|
| 23 | 24 | import org.openqa.selenium.OutputType; |
| 24 | 25 | import org.openqa.selenium.TakesScreenshot; |
| 25 | 26 | import org.openqa.selenium.WebDriver; |
| 27 | +import org.openqa.selenium.html5.WebStorage; |
|
| 26 | 28 | import org.openqa.selenium.remote.Augmenter; |
| 27 | 29 | import org.openqa.selenium.remote.RemoteWebDriver; |
| 28 | 30 | |
| 29 | -import com.sap.sse.common.Duration; |
|
| 30 | -import com.sap.sse.common.impl.MillisecondsTimePoint; |
|
| 31 | 31 | import com.sap.sailing.selenium.core.Managed; |
| 32 | 32 | import com.sap.sailing.selenium.core.SeleniumRunner; |
| 33 | 33 | import com.sap.sailing.selenium.core.TestEnvironment; |
| 34 | 34 | import com.sap.sailing.selenium.core.WindowManager; |
| 35 | +import com.sap.sailing.selenium.pages.PageObject; |
|
| 36 | +import com.sap.sse.common.Duration; |
|
| 37 | +import com.sap.sse.common.impl.MillisecondsTimePoint; |
|
| 35 | 38 | |
| 36 | 39 | /** |
| 37 | 40 | * <p>Abstract base class for unit tests with Selenium. This class is already annotated as required to get executed |
| ... | ... | @@ -83,16 +86,37 @@ public abstract class AbstractSeleniumTest { |
| 83 | 86 | } catch (IOException exception) { |
| 84 | 87 | throw new RuntimeException(exception); |
| 85 | 88 | } |
| 86 | - // clear local storage |
|
| 89 | + |
|
| 90 | + // To be able to access LocalStorage we need to load a page having the target origin |
|
| 87 | 91 | getWebDriver().get(contextRoot); |
| 88 | - ((JavascriptExecutor)getWebDriver()).executeScript("window.localStorage.clear();"); |
|
| 92 | + |
|
| 93 | + // clear local storage |
|
| 94 | + final WebStorage webStorage = (WebStorage)getWebDriver(); |
|
| 95 | + webStorage.getLocalStorage().clear(); |
|
| 96 | + |
|
| 97 | + // extending the timeout of notifications to 100s to prevent timing failures |
|
| 98 | + webStorage.getLocalStorage().setItem("sse.notification.customTimeOutInSeconds", |
|
| 99 | + Integer.toString(PageObject.DEFAULT_WAIT_TIMEOUT_SECONDS)); |
|
| 100 | + |
|
| 101 | + try { |
|
| 102 | + // In IE 11 we sometimes see the problem that IE somehow automatically changes the zoom level to 75%. |
|
| 103 | + // Selenium tests with InternetExplorerDriver fail if the zoom level is not set to 100% due to the fact that coordinates determined aren't correct. |
|
| 104 | + // With this we enforce a zoom level of 100% before running a test. |
|
| 105 | + // To make this work correctly you also need to set InternetExplorerDriver.IGNORE_ZOOM_SETTING to true (this should be pre-configured in local-test-environment.xml when activating IE driver) |
|
| 106 | + getWebDriver().findElement(By.tagName("html")).sendKeys(Keys.chord(Keys.CONTROL, "0")); |
|
| 107 | + } catch (Exception e) { |
|
| 108 | + } |
|
| 89 | 109 | } |
| 90 | 110 | |
| 91 | 111 | protected void setUpAuthenticatedSession() { |
| 112 | + // To be able to set a cookie we need to load a page having the target origin |
|
| 113 | + getWebDriver().get(getContextRoot()); |
|
| 114 | + |
|
| 92 | 115 | logger.info("Authenticating session..."); |
| 93 | 116 | Cookie sessionCookie = authenticate(getContextRoot()); |
| 94 | 117 | getWebDriver().get(getContextRoot() + "index.html"); // initialize web driver so setting a cookie for the local domain is possible |
| 95 | - getWebDriver().manage().addCookie(sessionCookie); |
|
| 118 | + final Cookie cookieWithoutDomain = new Cookie(sessionCookie.getName(), sessionCookie.getValue(), null, sessionCookie.getPath(), sessionCookie.getExpiry(), sessionCookie.isSecure(), sessionCookie.isHttpOnly()); |
|
| 119 | + getWebDriver().manage().addCookie(cookieWithoutDomain); |
|
| 96 | 120 | logger.info("...obtained session cookie "+sessionCookie); |
| 97 | 121 | } |
| 98 | 122 |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestRefreshableSelectionModel.java
| ... | ... | @@ -13,8 +13,6 @@ import org.openqa.selenium.WebDriver; |
| 13 | 13 | import org.openqa.selenium.support.ui.ExpectedCondition; |
| 14 | 14 | import org.openqa.selenium.support.ui.WebDriverWait; |
| 15 | 15 | |
| 16 | -import com.sap.sailing.selenium.core.WebDriverWindow; |
|
| 17 | -import com.sap.sailing.selenium.core.WindowManager; |
|
| 18 | 16 | import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage; |
| 19 | 17 | import com.sap.sailing.selenium.pages.adminconsole.connectors.SmartphoneTrackingEventManagementPanelPO; |
| 20 | 18 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardConfigurationPanelPO; |
| ... | ... | @@ -36,10 +34,6 @@ import com.sap.sailing.selenium.pages.gwt.DataEntryPO; |
| 36 | 34 | import com.sap.sailing.selenium.test.AbstractSeleniumTest; |
| 37 | 35 | |
| 38 | 36 | public class TestRefreshableSelectionModel extends AbstractSeleniumTest { |
| 39 | - private static WindowManager manager; |
|
| 40 | - private static WebDriverWindow windowForEdit; |
|
| 41 | - private static WebDriverWindow windowForSelection; |
|
| 42 | - |
|
| 43 | 37 | // TestMaintenanceOfSelectionAfterDataChanges |
| 44 | 38 | private CompetitorEntry competitorEntry; |
| 45 | 39 | private CompetitorEntry competitorEntryToSelect; |
| ... | ... | @@ -66,9 +60,6 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest { |
| 66 | 60 | @Before |
| 67 | 61 | public void setUp() { |
| 68 | 62 | clearState(getContextRoot()); |
| 69 | - manager = this.environment.getWindowManager(); |
|
| 70 | - windowForEdit = manager.getCurrentWindow(); |
|
| 71 | - windowForSelection = manager.openNewWindow(); |
|
| 72 | 63 | super.setUp(); |
| 73 | 64 | } |
| 74 | 65 | |
| ... | ... | @@ -80,85 +71,87 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest { |
| 80 | 71 | |
| 81 | 72 | @Test |
| 82 | 73 | public void testMaintenanceOfSelectionAfterDataChanges() { |
| 83 | - windowForEdit.switchToWindow(); |
|
| 84 | - final TrackedRacesCompetitorsPanelPO competitorsPanel = goToCompetitorsPanel(); |
|
| 85 | - |
|
| 86 | - for (int i = 0; i < 2; i++) { |
|
| 74 | + this.environment.getWindowManager().withExtraWindow((windowForSelection, windowForEdit) -> { |
|
| 75 | + windowForEdit.switchToWindow(); |
|
| 76 | + final TrackedRacesCompetitorsPanelPO competitorsPanel = goToCompetitorsPanel(); |
|
| 77 | + |
|
| 78 | + for (int i = 0; i < 2; i++) { |
|
| 79 | + TrackedRacesCompetitorEditDialogPO dialog = competitorsPanel.pushAddCompetitorButton(); |
|
| 80 | + dialog.setNameTextBox("" + System.currentTimeMillis()); |
|
| 81 | + dialog.setShortNameTextBox("" + System.currentTimeMillis()); |
|
| 82 | + dialog.pressOk(); |
|
| 83 | + } |
|
| 84 | + |
|
| 87 | 85 | TrackedRacesCompetitorEditDialogPO dialog = competitorsPanel.pushAddCompetitorButton(); |
| 88 | - dialog.setNameTextBox("" + System.currentTimeMillis()); |
|
| 89 | - dialog.setShortNameTextBox("" + System.currentTimeMillis()); |
|
| 86 | + final String name = "" + System.currentTimeMillis(); |
|
| 87 | + dialog.setNameTextBox(name); |
|
| 88 | + final String shortName = "" + System.currentTimeMillis(); |
|
| 89 | + dialog.setShortNameTextBox(shortName); |
|
| 90 | 90 | dialog.pressOk(); |
| 91 | - } |
|
| 92 | - |
|
| 93 | - TrackedRacesCompetitorEditDialogPO dialog = competitorsPanel.pushAddCompetitorButton(); |
|
| 94 | - final String name = "" + System.currentTimeMillis(); |
|
| 95 | - dialog.setNameTextBox(name); |
|
| 96 | - final String shortName = "" + System.currentTimeMillis(); |
|
| 97 | - dialog.setShortNameTextBox(shortName); |
|
| 98 | - dialog.pressOk(); |
|
| 99 | - |
|
| 100 | - boolean found = false; |
|
| 101 | - for (final CompetitorEntry it : competitorsPanel.getCompetitorTable().getEntries()) { |
|
| 102 | - String itName = it.getName(); |
|
| 103 | - if (itName.equals(name)) { |
|
| 104 | - found = true; |
|
| 105 | - competitorEntry = it; |
|
| 106 | - break; |
|
| 91 | + |
|
| 92 | + boolean found = false; |
|
| 93 | + for (final CompetitorEntry it : competitorsPanel.getCompetitorTable().getEntries()) { |
|
| 94 | + String itName = it.getName(); |
|
| 95 | + if (itName.equals(name)) { |
|
| 96 | + found = true; |
|
| 97 | + competitorEntry = it; |
|
| 98 | + break; |
|
| 99 | + } |
|
| 107 | 100 | } |
| 108 | - } |
|
| 109 | - assertTrue(found); |
|
| 110 | - |
|
| 111 | - windowForSelection.switchToWindow(); |
|
| 112 | - TrackedRacesCompetitorsPanelPO competitorPanelForSelection = goToCompetitorsPanel(); |
|
| 113 | - found = false; |
|
| 114 | - for (final CompetitorEntry it : competitorPanelForSelection.getCompetitorTable().getEntries()) { |
|
| 115 | - String itName = it.getName(); |
|
| 116 | - if (itName.equals(name)) { |
|
| 117 | - found = true; |
|
| 118 | - competitorEntryToSelect = it; |
|
| 119 | - break; |
|
| 101 | + assertTrue(found); |
|
| 102 | + |
|
| 103 | + windowForSelection.switchToWindow(); |
|
| 104 | + TrackedRacesCompetitorsPanelPO competitorPanelForSelection = goToCompetitorsPanel(); |
|
| 105 | + found = false; |
|
| 106 | + for (final CompetitorEntry it : competitorPanelForSelection.getCompetitorTable().getEntries()) { |
|
| 107 | + String itName = it.getName(); |
|
| 108 | + if (itName.equals(name)) { |
|
| 109 | + found = true; |
|
| 110 | + competitorEntryToSelect = it; |
|
| 111 | + break; |
|
| 112 | + } |
|
| 120 | 113 | } |
| 121 | - } |
|
| 122 | - assertTrue(found); |
|
| 123 | - competitorPanelForSelection.getCompetitorTable().selectEntry(competitorEntryToSelect); |
|
| 124 | - |
|
| 125 | - assertEquals(1, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().size()); |
|
| 126 | - assertEquals(name, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getName()); |
|
| 127 | - assertEquals(shortName, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getShortName()); |
|
| 128 | - // change competitor |
|
| 129 | - windowForEdit.switchToWindow(); |
|
| 130 | - dialog = competitorEntry.clickEditButton(); |
|
| 131 | - final String changedName = "" + System.currentTimeMillis(); |
|
| 132 | - dialog.setNameTextBox(changedName); |
|
| 133 | - final String changedShortName = "" + System.currentTimeMillis(); |
|
| 134 | - dialog.setShortNameTextBox(changedShortName); |
|
| 135 | - dialog.pressOk(); |
|
| 136 | - |
|
| 137 | - // assert selection |
|
| 138 | - windowForSelection.switchToWindow(); |
|
| 139 | - |
|
| 140 | - competitorPanelForSelection.pushRefreshButton(); |
|
| 141 | - WebDriverWait waitTimer = new WebDriverWait(competitorPanelForSelection.driver, 10); |
|
| 142 | - ExpectedCondition<Boolean> condition = new ExpectedCondition<Boolean>() { |
|
| 143 | - @Override |
|
| 144 | - public Boolean apply(WebDriver arg0) { |
|
| 145 | - return competitorPanelForSelection.getCompetitorTable().getSelectedEntries().size() == 1; |
|
| 146 | - } |
|
| 147 | - }; |
|
| 148 | - waitTimer.until(condition); |
|
| 149 | - |
|
| 150 | - assertEquals(1, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().size()); |
|
| 151 | - for (final CompetitorEntry it : competitorPanelForSelection.getCompetitorTable().getEntries()) { |
|
| 152 | - String itName = it.getName(); |
|
| 153 | - if (itName.equals(changedName)) { |
|
| 154 | - found = true; |
|
| 155 | - competitorEntryToSelect = it; |
|
| 156 | - break; |
|
| 114 | + assertTrue(found); |
|
| 115 | + competitorPanelForSelection.getCompetitorTable().selectEntry(competitorEntryToSelect); |
|
| 116 | + |
|
| 117 | + assertEquals(1, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().size()); |
|
| 118 | + assertEquals(name, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getName()); |
|
| 119 | + assertEquals(shortName, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getShortName()); |
|
| 120 | + // change competitor |
|
| 121 | + windowForEdit.switchToWindow(); |
|
| 122 | + dialog = competitorEntry.clickEditButton(); |
|
| 123 | + final String changedName = "" + System.currentTimeMillis(); |
|
| 124 | + dialog.setNameTextBox(changedName); |
|
| 125 | + final String changedShortName = "" + System.currentTimeMillis(); |
|
| 126 | + dialog.setShortNameTextBox(changedShortName); |
|
| 127 | + dialog.pressOk(); |
|
| 128 | + |
|
| 129 | + // assert selection |
|
| 130 | + windowForSelection.switchToWindow(); |
|
| 131 | + |
|
| 132 | + competitorPanelForSelection.pushRefreshButton(); |
|
| 133 | + WebDriverWait waitTimer = new WebDriverWait(competitorPanelForSelection.driver, 10); |
|
| 134 | + ExpectedCondition<Boolean> condition = new ExpectedCondition<Boolean>() { |
|
| 135 | + @Override |
|
| 136 | + public Boolean apply(WebDriver arg0) { |
|
| 137 | + return competitorPanelForSelection.getCompetitorTable().getSelectedEntries().size() == 1; |
|
| 138 | + } |
|
| 139 | + }; |
|
| 140 | + waitTimer.until(condition); |
|
| 141 | + |
|
| 142 | + assertEquals(1, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().size()); |
|
| 143 | + for (final CompetitorEntry it : competitorPanelForSelection.getCompetitorTable().getEntries()) { |
|
| 144 | + String itName = it.getName(); |
|
| 145 | + if (itName.equals(changedName)) { |
|
| 146 | + found = true; |
|
| 147 | + competitorEntryToSelect = it; |
|
| 148 | + break; |
|
| 149 | + } |
|
| 157 | 150 | } |
| 158 | - } |
|
| 159 | - assertTrue(found); |
|
| 160 | - assertEquals(changedName, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getName()); |
|
| 161 | - assertEquals(changedShortName, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getShortName()); |
|
| 151 | + assertTrue(found); |
|
| 152 | + assertEquals(changedName, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getName()); |
|
| 153 | + assertEquals(changedShortName, competitorPanelForSelection.getCompetitorTable().getSelectedEntries().get(0).getShortName()); |
|
| 154 | + }); |
|
| 162 | 155 | } |
| 163 | 156 | |
| 164 | 157 | private void setUpTestRefreshOfDependingUIElements() { |
| ... | ... | @@ -201,62 +194,63 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest { |
| 201 | 194 | |
| 202 | 195 | @Test |
| 203 | 196 | public void testRefreshOfDependingUIElements() { |
| 204 | - windowForSelection.switchToWindow(); |
|
| 205 | - setUpTestRefreshOfDependingUIElements(); |
|
| 206 | - AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 207 | - SmartphoneTrackingEventManagementPanelPO smartphoneTrackingPanel = adminConsole.goToSmartphoneTrackingPanel(); |
|
| 208 | - CellTablePO<DataEntryPO> leaderboards = smartphoneTrackingPanel.getLeaderboardTable(); |
|
| 209 | - // select leaderboard |
|
| 210 | - DataEntryPO entryToSelect = null; |
|
| 211 | - for(DataEntryPO entry : leaderboards.getEntries()) { |
|
| 212 | - if(entry.getColumnContent("Name").equals(LEADERBOARD)) { |
|
| 213 | - entryToSelect = entry; |
|
| 214 | - break; |
|
| 197 | + this.environment.getWindowManager().withExtraWindow((windowForSelection, windowForEdit) -> { |
|
| 198 | + windowForSelection.switchToWindow(); |
|
| 199 | + setUpTestRefreshOfDependingUIElements(); |
|
| 200 | + AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 201 | + SmartphoneTrackingEventManagementPanelPO smartphoneTrackingPanel = adminConsole.goToSmartphoneTrackingPanel(); |
|
| 202 | + CellTablePO<DataEntryPO> leaderboards = smartphoneTrackingPanel.getLeaderboardTable(); |
|
| 203 | + // select leaderboard |
|
| 204 | + DataEntryPO entryToSelect = null; |
|
| 205 | + for(DataEntryPO entry : leaderboards.getEntries()) { |
|
| 206 | + if(entry.getColumnContent("Name").equals(LEADERBOARD)) { |
|
| 207 | + entryToSelect = entry; |
|
| 208 | + break; |
|
| 209 | + } |
|
| 215 | 210 | } |
| 216 | - } |
|
| 217 | - assertNotNull(entryToSelect); |
|
| 218 | - leaderboards.selectEntry(entryToSelect); |
|
| 219 | - |
|
| 220 | - RaceColumnTableWrapperPO raceColumnTableWrapper = smartphoneTrackingPanel.getRaceColumnTableWrapper(); |
|
| 221 | - CellTablePO<DataEntryPO> raceColumnTable = raceColumnTableWrapper.getRaceColumnTable(); |
|
| 222 | - final int anzRaceColumns = raceColumnTable.getEntries().size(); |
|
| 223 | - assertEquals(5, anzRaceColumns); |
|
| 224 | - |
|
| 225 | - // Open a second window & setup second window |
|
| 226 | - windowForEdit.switchToWindow(); |
|
| 227 | - |
|
| 228 | - AdminConsolePage adminConsoleForEdit = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 229 | - RegattaStructureManagementPanelPO regattaStructure = adminConsoleForEdit.goToRegattaStructure(); |
|
| 230 | - |
|
| 231 | - RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta); |
|
| 232 | - SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME); |
|
| 233 | - seriesDialog.addRaces(6, 7); |
|
| 234 | - seriesDialog.pressOk(); |
|
| 235 | - |
|
| 236 | - windowForSelection.switchToWindow(); |
|
| 237 | - adminConsole.goToTracTracEvents(); |
|
| 238 | - smartphoneTrackingPanel = adminConsole.goToSmartphoneTrackingPanel(); |
|
| 239 | - leaderboards = smartphoneTrackingPanel.getLeaderboardTable(); |
|
| 240 | - // select leaderboard |
|
| 241 | - entryToSelect = null; |
|
| 242 | - for(DataEntryPO entry : leaderboards.getEntries()) { |
|
| 243 | - if(entry.getColumnContent("Name").equals(LEADERBOARD)) { |
|
| 244 | - entryToSelect = entry; |
|
| 245 | - break; |
|
| 211 | + assertNotNull(entryToSelect); |
|
| 212 | + leaderboards.selectEntry(entryToSelect); |
|
| 213 | + |
|
| 214 | + RaceColumnTableWrapperPO raceColumnTableWrapper = smartphoneTrackingPanel.getRaceColumnTableWrapper(); |
|
| 215 | + CellTablePO<DataEntryPO> raceColumnTable = raceColumnTableWrapper.getRaceColumnTable(); |
|
| 216 | + final int anzRaceColumns = raceColumnTable.getEntries().size(); |
|
| 217 | + assertEquals(5, anzRaceColumns); |
|
| 218 | + |
|
| 219 | + // Open a second window & setup second window |
|
| 220 | + windowForEdit.switchToWindow(); |
|
| 221 | + |
|
| 222 | + AdminConsolePage adminConsoleForEdit = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 223 | + RegattaStructureManagementPanelPO regattaStructure = adminConsoleForEdit.goToRegattaStructure(); |
|
| 224 | + |
|
| 225 | + RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta); |
|
| 226 | + SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME); |
|
| 227 | + seriesDialog.addRaces(6, 7); |
|
| 228 | + seriesDialog.pressOk(); |
|
| 229 | + |
|
| 230 | + windowForSelection.switchToWindow(); |
|
| 231 | + adminConsole.goToTracTracEvents(); |
|
| 232 | + smartphoneTrackingPanel = adminConsole.goToSmartphoneTrackingPanel(); |
|
| 233 | + leaderboards = smartphoneTrackingPanel.getLeaderboardTable(); |
|
| 234 | + // select leaderboard |
|
| 235 | + entryToSelect = null; |
|
| 236 | + for(DataEntryPO entry : leaderboards.getEntries()) { |
|
| 237 | + if(entry.getColumnContent("Name").equals(LEADERBOARD)) { |
|
| 238 | + entryToSelect = entry; |
|
| 239 | + break; |
|
| 240 | + } |
|
| 246 | 241 | } |
| 247 | - } |
|
| 248 | - assertNotNull(entryToSelect); |
|
| 249 | - leaderboards.selectEntry(entryToSelect); |
|
| 250 | - |
|
| 251 | - raceColumnTableWrapper = smartphoneTrackingPanel.getRaceColumnTableWrapper(); |
|
| 252 | - raceColumnTable = raceColumnTableWrapper.getRaceColumnTable(); |
|
| 253 | - final int newAnzRaceColumns = raceColumnTable.getEntries().size(); |
|
| 254 | - assertEquals(7, newAnzRaceColumns); |
|
| 242 | + assertNotNull(entryToSelect); |
|
| 243 | + leaderboards.selectEntry(entryToSelect); |
|
| 244 | + |
|
| 245 | + raceColumnTableWrapper = smartphoneTrackingPanel.getRaceColumnTableWrapper(); |
|
| 246 | + raceColumnTable = raceColumnTableWrapper.getRaceColumnTable(); |
|
| 247 | + final int newAnzRaceColumns = raceColumnTable.getEntries().size(); |
|
| 248 | + assertEquals(7, newAnzRaceColumns); |
|
| 249 | + }); |
|
| 255 | 250 | } |
| 256 | 251 | |
| 257 | 252 | @Test |
| 258 | 253 | public void testMaintenanceOfSelectionAfterFilteringTrackedracesOnLeaderboardConfigPanel() { |
| 259 | - windowForSelection.switchToWindow(); |
|
| 260 | 254 | setUpTestRefreshOfDependingUIElements(); |
| 261 | 255 | AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
| 262 | 256 | LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
| ... | ... | @@ -267,12 +261,7 @@ public class TestRefreshableSelectionModel extends AbstractSeleniumTest { |
| 267 | 261 | tracTracEvents.listTrackableRaces(IDM_5O5_2013_JSON_URL); |
| 268 | 262 | tracTracEvents.setReggataForTracking(this.regatta); |
| 269 | 263 | tracTracEvents.setTrackSettings(false, false, false); |
| 270 | - // TODO: There exists a bug in Selenium with key modifiers (Issue 3734 and 6817), so we can't use multi |
|
| 271 | - // selection (Firefox on Windows) |
|
| 272 | - //tracTracEvents.startTrackingForRaces(this.trackableRaces); |
|
| 273 | - for(int i =0; i<2;i++) { |
|
| 274 | - tracTracEvents.startTrackingForRace(trackableRaces.get(i)); |
|
| 275 | - } |
|
| 264 | + tracTracEvents.startTrackingForRaces(this.trackableRaces); |
|
| 276 | 265 | |
| 277 | 266 | leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
| 278 | 267 | LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestSmartphoneTrackingEventManagementPanel.java
| ... | ... | @@ -15,9 +15,9 @@ import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardConfig |
| 15 | 15 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardDetailsPanelPO; |
| 16 | 16 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardDetailsPanelPO.RaceDescriptor; |
| 17 | 17 | import com.sap.sailing.selenium.pages.adminconsole.regatta.RegattaDetailsCompositePO; |
| 18 | +import com.sap.sailing.selenium.pages.adminconsole.regatta.RegattaListCompositePO.RegattaDescriptor; |
|
| 18 | 19 | import com.sap.sailing.selenium.pages.adminconsole.regatta.RegattaStructureManagementPanelPO; |
| 19 | 20 | import com.sap.sailing.selenium.pages.adminconsole.regatta.SeriesEditDialogPO; |
| 20 | -import com.sap.sailing.selenium.pages.adminconsole.regatta.RegattaListCompositePO.RegattaDescriptor; |
|
| 21 | 21 | import com.sap.sailing.selenium.pages.adminconsole.tracking.RaceColumnTableWrapperPO; |
| 22 | 22 | import com.sap.sailing.selenium.pages.adminconsole.tracking.TrackedRacesListPO; |
| 23 | 23 | import com.sap.sailing.selenium.pages.adminconsole.tracking.TrackedRacesListPO.TrackedRaceDescriptor; |
| ... | ... | @@ -132,11 +132,6 @@ public class TestSmartphoneTrackingEventManagementPanel extends AbstractSelenium |
| 132 | 132 | tracTracEvents.listTrackableRaces(IDM_5O5_2013_JSON_URL); |
| 133 | 133 | tracTracEvents.setReggataForTracking(this.regatta); |
| 134 | 134 | tracTracEvents.setTrackSettings(false, false, false); |
| 135 | - // TODO: There exists a bug in Selenium with key modifiers (Issue 3734 and 6817), so we can't use multi |
|
| 136 | - // selection (Firefox on Windows) |
|
| 137 | - //tracTracEvents.startTrackingForRaces(this.trackableRaces); |
|
| 138 | - for(TrackableRaceDescriptor race : this.trackableRaces) { |
|
| 139 | - tracTracEvents.startTrackingForRace(race); |
|
| 140 | - } |
|
| 135 | + tracTracEvents.startTrackingForRaces(this.trackableRaces); |
|
| 141 | 136 | } |
| 142 | 137 | } |
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestStartAndStopTrackingForTracTracEvents.java
| ... | ... | @@ -1,16 +1,10 @@ |
| 1 | 1 | package com.sap.sailing.selenium.test.adminconsole; |
| 2 | 2 | |
| 3 | -import static org.hamcrest.Matchers.containsString; |
|
| 4 | 3 | import static org.hamcrest.Matchers.equalTo; |
| 5 | 4 | import static org.junit.Assert.assertThat; |
| 6 | -import static org.junit.Assert.assertTrue; |
|
| 7 | 5 | |
| 8 | 6 | import org.junit.Before; |
| 9 | 7 | import org.junit.Test; |
| 10 | -import org.openqa.selenium.Alert; |
|
| 11 | -import org.openqa.selenium.By; |
|
| 12 | -import org.openqa.selenium.WebDriver.TargetLocator; |
|
| 13 | -import org.openqa.selenium.WebElement; |
|
| 14 | 8 | |
| 15 | 9 | import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage; |
| 16 | 10 | import com.sap.sailing.selenium.pages.adminconsole.regatta.RegattaListCompositePO.RegattaDescriptor; |
| ... | ... | @@ -90,14 +84,7 @@ public class TestStartAndStopTrackingForTracTracEvents extends AbstractSeleniumT |
| 90 | 84 | tracTracEvents.listTrackableRaces(BMW_CUP_JSON_URL); |
| 91 | 85 | tracTracEvents.setReggataForTracking(DEFAULT_REGATTA); |
| 92 | 86 | tracTracEvents.setTrackSettings(false, false, false); |
| 93 | - tracTracEvents.startTrackingForRace(this.trackableRace); |
|
| 94 | - |
|
| 95 | - TargetLocator locator = getWebDriver().switchTo(); |
|
| 96 | - Alert alert = locator.alert(); |
|
| 97 | - String text = alert.getText(); |
|
| 98 | - alert.dismiss(); |
|
| 99 | - String message = "There is at least one regatta for the selected boat classes."; |
|
| 100 | - assertThat(text, containsString(message)); |
|
| 87 | + tracTracEvents.startTrackingForRacesAndAcceptDefaultRegattaWarning(this.trackableRace); |
|
| 101 | 88 | } |
| 102 | 89 | |
| 103 | 90 | @Test |
| ... | ... | @@ -112,17 +99,6 @@ public class TestStartAndStopTrackingForTracTracEvents extends AbstractSeleniumT |
| 112 | 99 | tracTracEvents.listTrackableRaces(BMW_CUP_JSON_URL); |
| 113 | 100 | tracTracEvents.setReggataForTracking(idm2013Descriptor); |
| 114 | 101 | tracTracEvents.setTrackSettings(false, false, false); |
| 115 | - tracTracEvents.startTrackingForRace(this.trackableRace); |
|
| 116 | - |
|
| 117 | - String message = String.format("The selected races contain boat classes which are not the same as " |
|
| 118 | - + "the boat class '%s' of the selected regatta.", IDM_2013_BOAT_CLASS); |
|
| 119 | - for (WebElement element : getWebDriver().findElement(By.id("notificationBar")).findElements(By.cssSelector("*"))) { |
|
| 120 | - if (element.getText().contains(message)) { |
|
| 121 | - element.click(); |
|
| 122 | - assertTrue(true); |
|
| 123 | - return; |
|
| 124 | - } |
|
| 125 | - } |
|
| 126 | - assertTrue("Could not find error notification.", false); |
|
| 102 | + tracTracEvents.startTrackingForRaceAndAwaitBoatClassError(this.trackableRace, IDM_2013_BOAT_CLASS); |
|
| 127 | 103 | } |
| 128 | 104 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/autoplay/TestAutoPlay.java
| ... | ... | @@ -6,6 +6,7 @@ import static org.junit.Assert.assertTrue; |
| 6 | 6 | |
| 7 | 7 | import java.util.Date; |
| 8 | 8 | import java.util.List; |
| 9 | +import java.util.function.Function; |
|
| 9 | 10 | |
| 10 | 11 | import javax.xml.bind.DatatypeConverter; |
| 11 | 12 | |
| ... | ... | @@ -15,7 +16,6 @@ import org.junit.Test; |
| 15 | 16 | import org.openqa.selenium.WebDriver; |
| 16 | 17 | import org.openqa.selenium.support.ui.WebDriverWait; |
| 17 | 18 | |
| 18 | -import com.google.common.base.Function; |
|
| 19 | 19 | import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage; |
| 20 | 20 | import com.sap.sailing.selenium.pages.adminconsole.event.EventConfigurationPanelPO; |
| 21 | 21 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardConfigurationPanelPO; |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/leaderboard/TestLeaderboardConfiguration.java
| ... | ... | @@ -11,8 +11,6 @@ import org.junit.Before; |
| 11 | 11 | import org.junit.Ignore; |
| 12 | 12 | import org.junit.Test; |
| 13 | 13 | |
| 14 | -import com.sap.sailing.selenium.core.WebDriverWindow; |
|
| 15 | -import com.sap.sailing.selenium.core.WindowManager; |
|
| 16 | 14 | import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage; |
| 17 | 15 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardConfigurationPanelPO; |
| 18 | 16 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardDetailsPanelPO; |
| ... | ... | @@ -73,117 +71,113 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest { |
| 73 | 71 | |
| 74 | 72 | @Test |
| 75 | 73 | public void testDynamicRaceLinking() { |
| 76 | - // Open a second window which we use for the leaderboard later |
|
| 77 | - WindowManager manager = this.environment.getWindowManager(); |
|
| 78 | - WebDriverWindow leaderboardWindow = manager.getCurrentWindow(); |
|
| 79 | - WebDriverWindow adminConsoleWindow = manager.openNewWindow(); |
|
| 80 | - |
|
| 81 | - // Open the leaderboard and check for "empty" leaderboard |
|
| 82 | - LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false); |
|
| 83 | - LeaderboardTablePO table = leaderboard.getLeaderboardTable(); |
|
| 84 | - List<String> races = table.getRaceNames(); |
|
| 85 | - |
|
| 86 | - assertThat(races.size(), equalTo(5)); |
|
| 87 | - assertThat(table.getEntries().size(), equalTo(28)); // the regatta already has the races linked; regatta leaderboard obtains competitors from regatta |
|
| 88 | - adminConsoleWindow.switchToWindow(); |
|
| 89 | - AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 90 | - LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
|
| 91 | - LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
|
| 92 | - |
|
| 93 | - Integer[] expectedPointsForFindelJens = new Integer[] {2, 18, 12, 4, 7}; |
|
| 94 | - Integer[] expectedRankForFindelJens = new Integer[] {2, 9, 11, 7, 6}; // Bogacki with no score in R1 expected to end up at end of leaderboard |
|
| 95 | - |
|
| 96 | - // Link the races and check the leaderboard again |
|
| 97 | - for (int i = 0; i < 5; i++) { |
|
| 98 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(i), this.trackedRaces.get(i)); |
|
| 99 | - leaderboardWindow.switchToWindow(); |
|
| 100 | - leaderboard.refresh(); |
|
| 101 | - List<LeaderboardEntry> allEntries = table.getEntries(); |
|
| 102 | - LeaderboardEntry findelJens = table.getEntry("8875"); |
|
| 103 | - Integer points = findelJens.getPointsForRace(String.format("D%s", i + 1)); |
|
| 104 | - Integer rank = findelJens.getTotalRank(); |
|
| 105 | - // Assertions |
|
| 106 | - assertThat("Number of competitors does not match", |
|
| 107 | - allEntries.size(), equalTo(28)); |
|
| 108 | - assertThat("Points for race 'D" + (i + 1) + "' do not match for competitor '8875' (Findel, Jens)", |
|
| 109 | - points, equalTo(expectedPointsForFindelJens[i])); |
|
| 110 | - assertThat("Total rank after " + (i + 1) + " race(s) does not match for competitor '8875' (Findel, Jens)", |
|
| 111 | - rank, equalTo(expectedRankForFindelJens[i])); |
|
| 74 | + this.environment.getWindowManager().withExtraWindow((leaderboardWindow, adminConsoleWindow) -> { |
|
| 75 | + // Open the leaderboard and check for "empty" leaderboard |
|
| 76 | + LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false); |
|
| 77 | + LeaderboardTablePO table = leaderboard.getLeaderboardTable(); |
|
| 78 | + List<String> races = table.getRaceNames(); |
|
| 79 | + |
|
| 80 | + assertThat(races.size(), equalTo(5)); |
|
| 81 | + assertThat(table.getEntries().size(), equalTo(28)); // the regatta already has the races linked; regatta leaderboard obtains competitors from regatta |
|
| 112 | 82 | adminConsoleWindow.switchToWindow(); |
| 113 | - } |
|
| 83 | + AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 84 | + LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
|
| 85 | + LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
|
| 86 | + |
|
| 87 | + Integer[] expectedPointsForFindelJens = new Integer[] {2, 18, 12, 4, 7}; |
|
| 88 | + Integer[] expectedRankForFindelJens = new Integer[] {2, 9, 11, 7, 6}; // Bogacki with no score in R1 expected to end up at end of leaderboard |
|
| 89 | + |
|
| 90 | + // Link the races and check the leaderboard again |
|
| 91 | + for (int i = 0; i < 5; i++) { |
|
| 92 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(i), this.trackedRaces.get(i)); |
|
| 93 | + leaderboardWindow.switchToWindow(); |
|
| 94 | + leaderboard.refresh(); |
|
| 95 | + List<LeaderboardEntry> allEntries = table.getEntries(); |
|
| 96 | + LeaderboardEntry findelJens = table.getEntry("8875"); |
|
| 97 | + Integer points = findelJens.getPointsForRace(String.format("D%s", i + 1)); |
|
| 98 | + Integer rank = findelJens.getTotalRank(); |
|
| 99 | + // Assertions |
|
| 100 | + assertThat("Number of competitors does not match", |
|
| 101 | + allEntries.size(), equalTo(28)); |
|
| 102 | + assertThat("Points for race 'D" + (i + 1) + "' do not match for competitor '8875' (Findel, Jens)", |
|
| 103 | + points, equalTo(expectedPointsForFindelJens[i])); |
|
| 104 | + assertThat("Total rank after " + (i + 1) + " race(s) does not match for competitor '8875' (Findel, Jens)", |
|
| 105 | + rank, equalTo(expectedRankForFindelJens[i])); |
|
| 106 | + adminConsoleWindow.switchToWindow(); |
|
| 107 | + } |
|
| 108 | + }); |
|
| 114 | 109 | } |
| 115 | 110 | |
| 116 | 111 | @Test |
| 117 | 112 | public void testDynamicRaceDeletion() { |
| 118 | - WindowManager manager = this.environment.getWindowManager(); |
|
| 119 | - WebDriverWindow adminConsoleWindow = manager.getCurrentWindow(); |
|
| 120 | - WebDriverWindow leaderboardWindow = manager.openNewWindow(); |
|
| 121 | - // Go to the administration console and link all 5 races |
|
| 122 | - AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 123 | - LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
|
| 124 | - LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
|
| 125 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(0), this.trackedRaces.get(0)); |
|
| 126 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(1), this.trackedRaces.get(1)); |
|
| 127 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(2), this.trackedRaces.get(2)); |
|
| 128 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(3), this.trackedRaces.get(3)); |
|
| 129 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(4), this.trackedRaces.get(4)); |
|
| 130 | - // Open the leaderboard in our second window |
|
| 131 | - leaderboardWindow.switchToWindow(); |
|
| 132 | - LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false); |
|
| 133 | - LeaderboardTablePO table = leaderboard.getLeaderboardTable(); |
|
| 134 | - // Go back to the administration console and delete third race |
|
| 135 | - adminConsoleWindow.switchToWindow(); |
|
| 136 | - RegattaStructureManagementPanelPO regattaStructure = adminConsole.goToRegattaStructure(); |
|
| 137 | - RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta); |
|
| 138 | - SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME); |
|
| 139 | - seriesDialog.deleteRace("D3"); |
|
| 140 | - seriesDialog.pressOk(true); |
|
| 141 | - // Now we can check the result with our expectation |
|
| 142 | - leaderboardWindow.switchToWindow(); |
|
| 143 | - leaderboard.refresh(); |
|
| 144 | - assertThat("Race names do not match after deletion of race 'D3'", |
|
| 145 | - table.getRaceNames(), equalTo(Arrays.asList("D1", "D2", "D4", "D5"))); |
|
| 113 | + this.environment.getWindowManager().withExtraWindow((adminConsoleWindow, leaderboardWindow) -> { |
|
| 114 | + // Go to the administration console and link all 5 races |
|
| 115 | + AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 116 | + LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
|
| 117 | + LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
|
| 118 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(0), this.trackedRaces.get(0)); |
|
| 119 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(1), this.trackedRaces.get(1)); |
|
| 120 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(2), this.trackedRaces.get(2)); |
|
| 121 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(3), this.trackedRaces.get(3)); |
|
| 122 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(4), this.trackedRaces.get(4)); |
|
| 123 | + // Open the leaderboard in our second window |
|
| 124 | + leaderboardWindow.switchToWindow(); |
|
| 125 | + LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false); |
|
| 126 | + LeaderboardTablePO table = leaderboard.getLeaderboardTable(); |
|
| 127 | + // Go back to the administration console and delete third race |
|
| 128 | + adminConsoleWindow.switchToWindow(); |
|
| 129 | + RegattaStructureManagementPanelPO regattaStructure = adminConsole.goToRegattaStructure(); |
|
| 130 | + RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta); |
|
| 131 | + SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME); |
|
| 132 | + seriesDialog.deleteRace("D3"); |
|
| 133 | + seriesDialog.pressOk(true, false); |
|
| 134 | + final List<String> expectedRaces = Arrays.asList("D1", "D2", "D4", "D5"); |
|
| 135 | + regattaDetails.waitForRacesOfSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME, expectedRaces); |
|
| 136 | + // Now we can check the result with our expectation |
|
| 137 | + leaderboardWindow.switchToWindow(); |
|
| 138 | + leaderboard.refresh(); |
|
| 139 | + assertThat("Race names do not match after deletion of race 'D3'", table.getRaceNames(), |
|
| 140 | + equalTo(expectedRaces)); |
|
| 141 | + }); |
|
| 146 | 142 | } |
| 147 | 143 | |
| 148 | 144 | @Ignore("This test belongs to bug 1892 and currently fails. It is currently enabled on branch bug1892.") |
| 149 | 145 | @Test |
| 150 | 146 | public void testDynamicRenamingOfRace() { |
| 151 | - WindowManager manager = this.environment.getWindowManager(); |
|
| 152 | - WebDriverWindow adminConsoleWindow = manager.getCurrentWindow(); |
|
| 153 | - WebDriverWindow leaderboardWindow = manager.openNewWindow(); |
|
| 154 | - |
|
| 155 | - // Go to the administration console and link all 5 races |
|
| 156 | - AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 157 | - LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
|
| 158 | - LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
|
| 159 | - |
|
| 160 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(0), this.trackedRaces.get(0)); |
|
| 161 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(1), this.trackedRaces.get(1)); |
|
| 162 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(2), this.trackedRaces.get(2)); |
|
| 163 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(3), this.trackedRaces.get(3)); |
|
| 164 | - leaderboardDetails.linkRace(this.leaderboardRaces.get(4), this.trackedRaces.get(4)); |
|
| 165 | - |
|
| 166 | - // Open the leaderboard in our second window |
|
| 167 | - leaderboardWindow.switchToWindow(); |
|
| 168 | - |
|
| 169 | - LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false); |
|
| 170 | - LeaderboardTablePO table = leaderboard.getLeaderboardTable(); |
|
| 171 | - |
|
| 172 | - // Go back to the administration console and rename the first race |
|
| 173 | - adminConsoleWindow.switchToWindow(); |
|
| 174 | - |
|
| 175 | - RegattaStructureManagementPanelPO regattaStructure = adminConsole.goToRegattaStructure(); |
|
| 176 | - RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta); |
|
| 177 | - SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME); |
|
| 178 | - seriesDialog.renameRace("D1", "Q"); |
|
| 179 | - seriesDialog.pressOk(true); |
|
| 180 | - |
|
| 181 | - // Now we can check the result with our expectation |
|
| 182 | - leaderboardWindow.switchToWindow(); |
|
| 183 | - leaderboard.refresh(); |
|
| 184 | - List<String> races = table.getRaceNames(); |
|
| 185 | - assertThat("Race names do not match after renaming race 'D1' to 'Q'", |
|
| 186 | - races, equalTo(Arrays.asList("Q", "D2", "D3", "D4", "D5"))); |
|
| 147 | + this.environment.getWindowManager().withExtraWindow((adminConsoleWindow, leaderboardWindow) -> { |
|
| 148 | + // Go to the administration console and link all 5 races |
|
| 149 | + AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot()); |
|
| 150 | + LeaderboardConfigurationPanelPO leaderboardConfiguration = adminConsole.goToLeaderboardConfiguration(); |
|
| 151 | + LeaderboardDetailsPanelPO leaderboardDetails = leaderboardConfiguration.getLeaderboardDetails(this.regatta.toString()); |
|
| 152 | + |
|
| 153 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(0), this.trackedRaces.get(0)); |
|
| 154 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(1), this.trackedRaces.get(1)); |
|
| 155 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(2), this.trackedRaces.get(2)); |
|
| 156 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(3), this.trackedRaces.get(3)); |
|
| 157 | + leaderboardDetails.linkRace(this.leaderboardRaces.get(4), this.trackedRaces.get(4)); |
|
| 158 | + |
|
| 159 | + // Open the leaderboard in our second window |
|
| 160 | + leaderboardWindow.switchToWindow(); |
|
| 161 | + |
|
| 162 | + LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, false); |
|
| 163 | + LeaderboardTablePO table = leaderboard.getLeaderboardTable(); |
|
| 164 | + |
|
| 165 | + // Go back to the administration console and rename the first race |
|
| 166 | + adminConsoleWindow.switchToWindow(); |
|
| 167 | + |
|
| 168 | + RegattaStructureManagementPanelPO regattaStructure = adminConsole.goToRegattaStructure(); |
|
| 169 | + RegattaDetailsCompositePO regattaDetails = regattaStructure.getRegattaDetails(this.regatta); |
|
| 170 | + SeriesEditDialogPO seriesDialog = regattaDetails.editSeries(RegattaStructureManagementPanelPO.DEFAULT_SERIES_NAME); |
|
| 171 | + seriesDialog.renameRace("D1", "Q"); |
|
| 172 | + seriesDialog.pressOk(true, false); |
|
| 173 | + |
|
| 174 | + // Now we can check the result with our expectation |
|
| 175 | + leaderboardWindow.switchToWindow(); |
|
| 176 | + leaderboard.refresh(); |
|
| 177 | + List<String> races = table.getRaceNames(); |
|
| 178 | + assertThat("Race names do not match after renaming race 'D1' to 'Q'", |
|
| 179 | + races, equalTo(Arrays.asList("Q", "D2", "D3", "D4", "D5"))); |
|
| 180 | + }); |
|
| 187 | 181 | } |
| 188 | 182 | |
| 189 | 183 | private void configureLeaderboard() { |
| ... | ... | @@ -209,20 +203,10 @@ public class TestLeaderboardConfiguration extends AbstractSeleniumTest { |
| 209 | 203 | tracTracEvents.listTrackableRaces(IDM_5O5_2013_JSON_URL); |
| 210 | 204 | tracTracEvents.setReggataForTracking(this.regatta); |
| 211 | 205 | tracTracEvents.setTrackSettings(false, false, false); |
| 212 | - // TODO: There exists a bug in Selenium with key modifiers (Issue 3734 and 6817), so we can't use multi |
|
| 213 | - // selection (Firefox on Windows) |
|
| 214 | - //tracTracEvents.startTrackingForRaces(this.trackableRaces); |
|
| 215 | - for(TrackableRaceDescriptor race : this.trackableRaces) { |
|
| 216 | - tracTracEvents.startTrackingForRace(race); |
|
| 217 | - } |
|
| 206 | + tracTracEvents.startTrackingForRaces(trackableRaces); |
|
| 218 | 207 | |
| 219 | 208 | TrackedRacesListPO trackedRacesList = tracTracEvents.getTrackedRacesList(); |
| 220 | 209 | trackedRacesList.waitForTrackedRaces(this.trackedRaces, Status.FINISHED); // TracAPI puts REPLAY races into FINISHED mode when done loading |
| 221 | - // TODO: There exists a bug in Selenium with key modifiers (Issue 3734 and 6817), so we can't use multi |
|
| 222 | - // selection (Firefox on Windows) |
|
| 223 | - //trackedRacesList.stopTracking(this.trackedRaces); |
|
| 224 | - for (TrackedRaceDescriptor race : this.trackedRaces) { |
|
| 225 | - trackedRacesList.stopTracking(race); |
|
| 226 | - } |
|
| 210 | + trackedRacesList.stopTracking(this.trackedRaces); |
|
| 227 | 211 | } |
| 228 | 212 | } |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/leaderboard/TestSwitchingOffStartOfRaceInference.java
| ... | ... | @@ -11,8 +11,6 @@ import java.util.List; |
| 11 | 11 | import org.junit.Before; |
| 12 | 12 | import org.junit.Test; |
| 13 | 13 | |
| 14 | -import com.sap.sailing.selenium.core.WebDriverWindow; |
|
| 15 | -import com.sap.sailing.selenium.core.WindowManager; |
|
| 16 | 14 | import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage; |
| 17 | 15 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardConfigurationPanelPO; |
| 18 | 16 | import com.sap.sailing.selenium.pages.adminconsole.leaderboard.LeaderboardDetailsPanelPO; |
| ... | ... | @@ -62,33 +60,31 @@ public class TestSwitchingOffStartOfRaceInference extends AbstractSeleniumTest { |
| 62 | 60 | |
| 63 | 61 | @Test |
| 64 | 62 | public void testCorrectDisplayOfRaceColumnWithAndWithoutStartTimeInference() { |
| 65 | - WindowManager manager = this.environment.getWindowManager(); |
|
| 66 | - WebDriverWindow adminConsoleWindow = manager.getCurrentWindow(); |
|
| 67 | - WebDriverWindow leaderboardWindow = manager.openNewWindow(); |
|
| 68 | - leaderboardWindow.switchToWindow(); |
|
| 69 | - LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, /* race details */ false); |
|
| 70 | - LeaderboardTablePO leaderboardTable = leaderboard.getLeaderboardTable(); |
|
| 71 | - List<String> races = leaderboardTable.getRaceNames(); |
|
| 72 | - assertThat("Expected only D3", races, equalTo(Arrays.asList("D3"))); |
|
| 73 | - int d3ColumnIndex = leaderboardTable.getColumnIndex("D3"); |
|
| 74 | - for (LeaderboardEntry e : leaderboardTable.getEntries()) { |
|
| 75 | - String raceColumnContent = e.getColumnContent(d3ColumnIndex); |
|
| 76 | - assertTrue(Integer.parseInt(raceColumnContent) > 0); // all competitors have a positive score in R3 |
|
| 77 | - } |
|
| 78 | - adminConsoleWindow.switchToWindow(); |
|
| 79 | - // Go to the administration console and unset the "useStartTimeInference" flag |
|
| 80 | - RegattaStructureManagementPanelPO regattaManagementPanel = adminConsole.goToRegattaStructure(); |
|
| 81 | - RegattaListCompositePO regattaList = regattaManagementPanel.getRegattaList(); |
|
| 82 | - RegattaEditDialogPO regattaEditDialog = regattaList.editRegatta(regatta); |
|
| 83 | - regattaEditDialog.setUseStartTimeInference(false); |
|
| 84 | - regattaEditDialog.pressOk(); |
|
| 85 | - leaderboardWindow.switchToWindow(); |
|
| 86 | - leaderboard.refresh(); |
|
| 87 | - for (LeaderboardEntry e : leaderboardTable.getEntries()) { |
|
| 88 | - String raceColumnContent = e.getColumnContent(d3ColumnIndex); |
|
| 89 | - assertEquals("", raceColumnContent); // all competitors have an empty score because there is no start time anymore |
|
| 90 | - } |
|
| 91 | - leaderboardWindow.close(); |
|
| 63 | + this.environment.getWindowManager().withExtraWindow((adminConsoleWindow, leaderboardWindow) -> { |
|
| 64 | + leaderboardWindow.switchToWindow(); |
|
| 65 | + LeaderboardPage leaderboard = LeaderboardPage.goToPage(getWebDriver(), getContextRoot(), LEADERBOARD, /* race details */ false); |
|
| 66 | + LeaderboardTablePO leaderboardTable = leaderboard.getLeaderboardTable(); |
|
| 67 | + List<String> races = leaderboardTable.getRaceNames(); |
|
| 68 | + assertThat("Expected only D3", races, equalTo(Arrays.asList("D3"))); |
|
| 69 | + int d3ColumnIndex = leaderboardTable.getColumnIndex("D3"); |
|
| 70 | + for (LeaderboardEntry e : leaderboardTable.getEntries()) { |
|
| 71 | + String raceColumnContent = e.getColumnContent(d3ColumnIndex); |
|
| 72 | + assertTrue(Integer.parseInt(raceColumnContent) > 0); // all competitors have a positive score in R3 |
|
| 73 | + } |
|
| 74 | + adminConsoleWindow.switchToWindow(); |
|
| 75 | + // Go to the administration console and unset the "useStartTimeInference" flag |
|
| 76 | + RegattaStructureManagementPanelPO regattaManagementPanel = adminConsole.goToRegattaStructure(); |
|
| 77 | + RegattaListCompositePO regattaList = regattaManagementPanel.getRegattaList(); |
|
| 78 | + RegattaEditDialogPO regattaEditDialog = regattaList.editRegatta(regatta); |
|
| 79 | + regattaEditDialog.setUseStartTimeInference(false); |
|
| 80 | + regattaEditDialog.pressOk(); |
|
| 81 | + leaderboardWindow.switchToWindow(); |
|
| 82 | + leaderboard.refresh(); |
|
| 83 | + for (LeaderboardEntry e : leaderboardTable.getEntries()) { |
|
| 84 | + String raceColumnContent = e.getColumnContent(d3ColumnIndex); |
|
| 85 | + assertEquals("", raceColumnContent); // all competitors have an empty score because there is no start time anymore |
|
| 86 | + } |
|
| 87 | + }); |
|
| 92 | 88 | } |
| 93 | 89 | |
| 94 | 90 | private AdminConsolePage configureRegattaAndLeaderboard() { |
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/raceboard/SettingsTest.java
| ... | ... | @@ -77,7 +77,6 @@ public class SettingsTest extends AbstractSeleniumTest { |
| 77 | 77 | // Modes settings were formerly patched on the user defaults but are now patched on top of the system defaults. |
| 78 | 78 | // In addition, there are now different settigns keys per mode so that settigns for one mode do not have an effect on other modes. |
| 79 | 79 | // To verify this, there are new tests below but these do not test ReceBoard's embedded Leaderboard. |
| 80 | - // FIXME uncomment leaderboard test code when selenium infrastructure gets an upgrade |
|
| 81 | 80 | /** |
| 82 | 81 | * Verifies the settings storage of the raceboard. Checks the precedences of url, context specific settings, mode |
| 83 | 82 | * settings and global settings. |
| ... | ... | @@ -95,35 +94,29 @@ public class SettingsTest extends AbstractSeleniumTest { |
| 95 | 94 | RaceBoardPage raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA, |
| 96 | 95 | BMW_CUP_REGATTA, String.format(BMW_RACE, 1), "PLAYER"); |
| 97 | 96 | |
| 98 | - //FIXME uncomment the leaderboard code when selenium on remote build server displays the raceboard properly |
|
| 99 | - |
|
| 100 | -// DetailCheckboxInfo[] detailsToSelect = new DetailCheckboxInfo[] { |
|
| 101 | -// // Overall details |
|
| 102 | -// |
|
| 103 | -// // Race details |
|
| 104 | -// DetailCheckboxInfo.RACE_GAP_TO_LEADER, |
|
| 105 | -// DetailCheckboxInfo.RACE_CURRENT_SPEED_OVER_GROUND, |
|
| 106 | -// DetailCheckboxInfo.DISPLAY_LEGS, |
|
| 107 | -// |
|
| 108 | -// // Race Start Analysis |
|
| 109 | -// |
|
| 110 | -// // Leg Details |
|
| 111 | -// DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 112 | -// |
|
| 113 | -// // Maneuvers |
|
| 114 | -// DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, |
|
| 115 | -// DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 116 | -// |
|
| 117 | -// }; |
|
| 118 | -// |
|
| 119 | -// LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 120 | -// LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = |
|
| 121 | -// leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 122 | -// DetailCheckboxInfo[] selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 123 | -// Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 124 | -// leaderboardSettingsPanelPO.setRefreshInterval(2); |
|
| 125 | -// leaderboardSettingsDialog.pressMakeDefault(); |
|
| 126 | -// leaderboardSettingsDialog.pressCancel(); |
|
| 97 | + DetailCheckboxInfo[] detailsToSelect = new DetailCheckboxInfo[] { |
|
| 98 | + // Overall details |
|
| 99 | + |
|
| 100 | + // Race details |
|
| 101 | + DetailCheckboxInfo.RACE_GAP_TO_LEADER, DetailCheckboxInfo.RACE_CURRENT_SPEED_OVER_GROUND, |
|
| 102 | + DetailCheckboxInfo.DISPLAY_LEGS, |
|
| 103 | + |
|
| 104 | + // Leg Details |
|
| 105 | + DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 106 | + |
|
| 107 | + // Maneuvers |
|
| 108 | + DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 109 | + |
|
| 110 | + }; |
|
| 111 | + |
|
| 112 | + LeaderboardSettingsDialogPO leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 113 | + LeaderboardSettingsPanelPO leaderboardSettingsPanelPO = leaderboardSettingsDialog |
|
| 114 | + .getLeaderboardSettingsPanelPO(); |
|
| 115 | + DetailCheckboxInfo[] selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 116 | + Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 117 | + leaderboardSettingsPanelPO.setRefreshInterval(2); |
|
| 118 | + leaderboardSettingsDialog.pressMakeDefault(); |
|
| 119 | + leaderboardSettingsDialog.pressCancel(); |
|
| 127 | 120 | |
| 128 | 121 | MapSettingsPO mapSettings = raceboard.openMapSettings(); |
| 129 | 122 | // Verify initial mode settings |
| ... | ... | @@ -136,58 +129,38 @@ public class SettingsTest extends AbstractSeleniumTest { |
| 136 | 129 | raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA, BMW_CUP_REGATTA, |
| 137 | 130 | String.format(BMW_RACE, 1), "WINNING_LANES"); |
| 138 | 131 | |
| 139 | -// detailsToSelect = new DetailCheckboxInfo[] { |
|
| 140 | -// // Overall details |
|
| 141 | -// |
|
| 142 | -// // Race details |
|
| 143 | -// DetailCheckboxInfo.RACE_GAP_TO_LEADER, //merged from user settings |
|
| 144 | -// DetailCheckboxInfo.RACE_DISTANCE, |
|
| 145 | -// DetailCheckboxInfo.RACE_TIME, |
|
| 146 | -// DetailCheckboxInfo.RACE_CURRENT_SPEED_OVER_GROUND, //merged from user settings |
|
| 147 | -// DetailCheckboxInfo.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR, |
|
| 148 | -// DetailCheckboxInfo.RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR, |
|
| 149 | -// |
|
| 150 | -// // Race Start Analysis |
|
| 151 | -// |
|
| 152 | -// // Leg Details |
|
| 153 | -// DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 154 | -// |
|
| 155 | -// // Maneuvers |
|
| 156 | -// DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, |
|
| 157 | -// DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 158 | -// |
|
| 159 | -// }; |
|
| 160 | -// |
|
| 161 | -// |
|
| 162 | -// leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 163 | -// leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 164 | -// selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 165 | -// Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 166 | -// |
|
| 167 | -// detailsToSelect = new DetailCheckboxInfo[] { |
|
| 168 | -// // Overall details |
|
| 169 | -// |
|
| 170 | -// // Race details |
|
| 171 | -// DetailCheckboxInfo.RACE_GAP_TO_LEADER, |
|
| 172 | -// DetailCheckboxInfo.RACE_DISTANCE, |
|
| 173 | -// DetailCheckboxInfo.RACE_TIME, |
|
| 174 | -// DetailCheckboxInfo.RACE_CURRENT_SPEED_OVER_GROUND, |
|
| 175 | -// DetailCheckboxInfo.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL, //new value |
|
| 176 | -// DetailCheckboxInfo.DISPLAY_LEGS, //new value which should override mode settings |
|
| 177 | -// |
|
| 178 | -// // Race Start Analysis |
|
| 179 | -// |
|
| 180 | -// // Leg Details |
|
| 181 | -// DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 182 | -// |
|
| 183 | -// // Maneuvers |
|
| 184 | -// DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, |
|
| 185 | -// DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 186 | -// |
|
| 187 | -// }; |
|
| 188 | -// leaderboardSettingsPanelPO.selectDetailsAndDeselectOther(detailsToSelect); |
|
| 189 | -// leaderboardSettingsPanelPO.setRefreshInterval(1); |
|
| 190 | -// leaderboardSettingsDialog.pressOk(); |
|
| 132 | + detailsToSelect = new DetailCheckboxInfo[] { |
|
| 133 | + // Race details |
|
| 134 | + DetailCheckboxInfo.RACE_DISTANCE, DetailCheckboxInfo.RACE_TIME, |
|
| 135 | + DetailCheckboxInfo.RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR, |
|
| 136 | + DetailCheckboxInfo.RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR, |
|
| 137 | + // Leg Details |
|
| 138 | + DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 139 | + // Maneuvers |
|
| 140 | + DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 141 | + |
|
| 142 | + }; |
|
| 143 | + |
|
| 144 | + leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 145 | + leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 146 | + selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 147 | + Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 148 | + |
|
| 149 | + detailsToSelect = new DetailCheckboxInfo[] { |
|
| 150 | + // Race details |
|
| 151 | + DetailCheckboxInfo.RACE_GAP_TO_LEADER, DetailCheckboxInfo.RACE_DISTANCE, DetailCheckboxInfo.RACE_TIME, |
|
| 152 | + DetailCheckboxInfo.RACE_CURRENT_SPEED_OVER_GROUND, |
|
| 153 | + DetailCheckboxInfo.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL, |
|
| 154 | + DetailCheckboxInfo.DISPLAY_LEGS, |
|
| 155 | + // Leg Details |
|
| 156 | + DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 157 | + // Maneuvers |
|
| 158 | + DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 159 | + |
|
| 160 | + }; |
|
| 161 | + leaderboardSettingsPanelPO.selectDetailsAndDeselectOther(detailsToSelect); |
|
| 162 | + leaderboardSettingsPanelPO.setRefreshInterval(1); |
|
| 163 | + leaderboardSettingsDialog.pressOk(false, false); |
|
| 191 | 164 | |
| 192 | 165 | mapSettings = raceboard.openMapSettings(); |
| 193 | 166 | // verify default mode settings override custom user settings |
| ... | ... | @@ -198,21 +171,22 @@ public class SettingsTest extends AbstractSeleniumTest { |
| 198 | 171 | Assert.assertFalse(mapSettings.isTransparentHoverlines()); |
| 199 | 172 | mapSettings.setWindUp(false); |
| 200 | 173 | mapSettings.setTransparentHoverlines(false); |
| 201 | - mapSettings.pressOk(); |
|
| 174 | + |
|
| 175 | + mapSettings.pressOk(false, false); |
|
| 202 | 176 | |
| 203 | 177 | raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA, BMW_CUP_REGATTA, |
| 204 | 178 | String.format(BMW_RACE, 1), "WINNING_LANES"); |
| 205 | 179 | |
| 206 | -// leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 207 | -// leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 208 | -// selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 209 | -// |
|
| 210 | -// //verify highest precedence of document settings |
|
| 211 | -// Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 212 | -// //verify that document settings are able to override custom user settings by a system default value |
|
| 213 | -// Assert.assertEquals(1, leaderboardSettingsPanelPO.getRefreshInterval()); |
|
| 214 | -// |
|
| 215 | -// leaderboardSettingsDialog.pressCancel(); |
|
| 180 | + leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 181 | + leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 182 | + selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 183 | + |
|
| 184 | + // verify highest precedence of document settings |
|
| 185 | + Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 186 | + // verify that document settings are able to override custom user settings by a system default value |
|
| 187 | + Assert.assertEquals(1, leaderboardSettingsPanelPO.getRefreshInterval()); |
|
| 188 | + |
|
| 189 | + leaderboardSettingsDialog.pressCancel(); |
|
| 216 | 190 | |
| 217 | 191 | mapSettings = raceboard.openMapSettings(); |
| 218 | 192 | // Verify that mode settings are overridden by document settings |
| ... | ... | @@ -222,35 +196,29 @@ public class SettingsTest extends AbstractSeleniumTest { |
| 222 | 196 | |
| 223 | 197 | //FIXME uncomment when START_ANALYSIS mode can be handled by remote CI server |
| 224 | 198 | // verify that custom document settings override mode settings of other modes |
| 225 | -// raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA, |
|
| 226 | -// BMW_CUP_REGATTA, |
|
| 227 | -// String.format(BMW_RACE, 1), "START_ANALYSIS"); |
|
| 228 | -// leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 229 | -// leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 230 | -// selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 231 | -// |
|
| 232 | -// detailsToSelect = new DetailCheckboxInfo[] { |
|
| 233 | -// DetailCheckboxInfo.RACE_GAP_TO_LEADER, //start analysis mode |
|
| 234 | -// DetailCheckboxInfo.RACE_CURRENT_SPEED_OVER_GROUND, //user settings |
|
| 235 | -// DetailCheckboxInfo.DISPLAY_LEGS, //document settings which override mode settings |
|
| 236 | -// DetailCheckboxInfo.RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL, //document settings |
|
| 237 | -// DetailCheckboxInfo.RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_START, //start analysis mode |
|
| 238 | -// DetailCheckboxInfo.RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START, //start analysis mode |
|
| 239 | -// DetailCheckboxInfo.DISTANCE_TO_START_AT_RACE_START, //start analysis mode |
|
| 240 | -// DetailCheckboxInfo.SPEED_OVER_GROUND_AT_RACE_START, //start analysis mode |
|
| 241 | -// DetailCheckboxInfo.SPEED_OVER_GROUND_WHEN_STARTING, //start analysis mode |
|
| 242 | -// DetailCheckboxInfo.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_STARTING, //start analysis mode |
|
| 243 | -// DetailCheckboxInfo.START_TACK, //start analysis mode |
|
| 244 | -// |
|
| 245 | -// DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 246 | -// |
|
| 247 | -// DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, DetailCheckboxInfo.PENALTY_CIRCLE |
|
| 248 | -// }; |
|
| 249 | -// Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 250 | -// leaderboardSettingsDialog.pressCancel(); |
|
| 251 | -// |
|
| 252 | -// mapSettings = raceboard.openMapSettings(); |
|
| 253 | -// Assert.assertFalse(mapSettings.isWindUp()); |
|
| 199 | + raceboard = RaceBoardPage.goToRaceboardUrl(getWebDriver(), getContextRoot(), BMW_CUP_REGATTA, BMW_CUP_REGATTA, |
|
| 200 | + String.format(BMW_RACE, 1), "START_ANALYSIS"); |
|
| 201 | + leaderboardSettingsDialog = raceboard.openLeaderboardSettingsDialog(); |
|
| 202 | + leaderboardSettingsPanelPO = leaderboardSettingsDialog.getLeaderboardSettingsPanelPO(); |
|
| 203 | + selectedDetails = leaderboardSettingsPanelPO.getSelectedDetails(); |
|
| 204 | + |
|
| 205 | + detailsToSelect = new DetailCheckboxInfo[] { DetailCheckboxInfo.RACE_GAP_TO_LEADER, // start analysis mode |
|
| 206 | + DetailCheckboxInfo.RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_START, // start analysis mode |
|
| 207 | + DetailCheckboxInfo.RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START, // start analysis mode |
|
| 208 | + DetailCheckboxInfo.DISTANCE_TO_START_AT_RACE_START, // start analysis mode |
|
| 209 | + DetailCheckboxInfo.SPEED_OVER_GROUND_AT_RACE_START, // start analysis mode |
|
| 210 | + DetailCheckboxInfo.SPEED_OVER_GROUND_WHEN_STARTING, // start analysis mode |
|
| 211 | + DetailCheckboxInfo.DISTANCE_TO_STARBOARD_END_OF_STARTLINE_WHEN_STARTING, // start analysis mode |
|
| 212 | + DetailCheckboxInfo.START_TACK, // start analysis mode |
|
| 213 | + |
|
| 214 | + DetailCheckboxInfo.AVERAGE_SPEED_OVER_GROUND, DetailCheckboxInfo.DISTANCE, DetailCheckboxInfo.RANK_GAIN, |
|
| 215 | + |
|
| 216 | + DetailCheckboxInfo.TACK, DetailCheckboxInfo.JIBE, DetailCheckboxInfo.PENALTY_CIRCLE }; |
|
| 217 | + Assert.assertArrayEquals(detailsToSelect, selectedDetails); |
|
| 218 | + leaderboardSettingsDialog.pressCancel(); |
|
| 219 | + |
|
| 220 | + mapSettings = raceboard.openMapSettings(); |
|
| 221 | + Assert.assertTrue(mapSettings.isWindUp()); |
|
| 254 | 222 | } |
| 255 | 223 | |
| 256 | 224 | /** |
| ... | ... | @@ -687,7 +655,7 @@ public class SettingsTest extends AbstractSeleniumTest { |
| 687 | 655 | |
| 688 | 656 | // open settings dialog of configurated leaderboard with default values |
| 689 | 657 | LeaderboardSettingsDialogPO leaderboardSettingsDialog = leaderboardPage.getLeaderboardSettings(); |
| 690 | - LeaderboardSettingsPanelPO leaderboardSettingsPanel = leaderboardPage.getLeaderboardSettings() |
|
| 658 | + LeaderboardSettingsPanelPO leaderboardSettingsPanel = leaderboardSettingsDialog |
|
| 691 | 659 | .getLeaderboardSettingsPanelPO(); |
| 692 | 660 | |
| 693 | 661 | // store default values for checks later |
java/com.sap.sailing.server.gateway.serialization.test/src/com/sap/sailing/server/gateway/serialization/test/EstimationDataSerializationDeserializationTest.java
| ... | ... | @@ -130,14 +130,14 @@ public class EstimationDataSerializationDeserializationTest { |
| 130 | 130 | Bearing relativeBearingToNextMarkAfterManeuver = new DegreeBearingImpl(10.01); |
| 131 | 131 | boolean markPassing = true; |
| 132 | 132 | Distance closestDistanceToMark = new MeterDistance(3.0); |
| 133 | - Double deviationFromTargetTackAngle = 23.30; |
|
| 134 | - Double deviationFromTargetJibeAngle = 22.30; |
|
| 133 | + Double targetTackAngle = 23.30; |
|
| 134 | + Double targetJibeAngle = 22.30; |
|
| 135 | 135 | |
| 136 | 136 | CompleteManeuverCurveWithEstimationData toSerialize = new CompleteManeuverCurveWithEstimationDataImpl( |
| 137 | 137 | maneuverPosition, mainCurve, curve, wind, tackingCount, jibingCount, |
| 138 | 138 | maneuverStartsByRunningAwayFromWind, relativeBearingToNextMarkBeforeManeuver, |
| 139 | - relativeBearingToNextMarkAfterManeuver, markPassing, closestDistanceToMark, |
|
| 140 | - deviationFromTargetTackAngle, deviationFromTargetJibeAngle); |
|
| 139 | + relativeBearingToNextMarkAfterManeuver, markPassing, closestDistanceToMark, targetTackAngle, |
|
| 140 | + targetJibeAngle); |
|
| 141 | 141 | CompleteManeuverCurveWithEstimationDataJsonSerializer serializer = new CompleteManeuverCurveWithEstimationDataJsonSerializer( |
| 142 | 142 | new ManeuverMainCurveWithEstimationDataJsonSerializer(), |
| 143 | 143 | new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(), |
| ... | ... | @@ -149,10 +149,8 @@ public class EstimationDataSerializationDeserializationTest { |
| 149 | 149 | new ManeuverWindJsonDeserializer(), new PositionJsonDeserializer()); |
| 150 | 150 | CompleteManeuverCurveWithEstimationData deserialized = deserializer.deserialize(json); |
| 151 | 151 | |
| 152 | - assertEquals(deviationFromTargetJibeAngle, |
|
| 153 | - deserialized.getDeviationOfManeuverAngleFromTargetJibeAngleInDegrees()); |
|
| 154 | - assertEquals(deviationFromTargetTackAngle, |
|
| 155 | - deserialized.getDeviationOfManeuverAngleFromTargetTackAngleInDegrees()); |
|
| 152 | + assertEquals(targetJibeAngle, deserialized.getTargetJibeAngleInDegrees()); |
|
| 153 | + assertEquals(targetTackAngle, deserialized.getTargetTackAngleInDegrees()); |
|
| 156 | 154 | assertEquals(closestDistanceToMark, deserialized.getDistanceToClosestMark()); |
| 157 | 155 | assertEquals(maneuverPosition, deserialized.getPosition()); |
| 158 | 156 | assertEquals(tackingCount, deserialized.getTackingCount()); |
| ... | ... | @@ -310,14 +308,14 @@ public class EstimationDataSerializationDeserializationTest { |
| 310 | 308 | boolean markPassing = false; |
| 311 | 309 | DegreePosition maneuverPosition = new DegreePosition(50.325246, 11.148556); |
| 312 | 310 | Distance closestDistanceToMark = null; |
| 313 | - Double deviationFromTargetTackAngle = null; |
|
| 314 | - Double deviationFromTargetJibeAngle = null; |
|
| 311 | + Double targetTackAngle = null; |
|
| 312 | + Double targetJibeAngle = null; |
|
| 315 | 313 | |
| 316 | 314 | CompleteManeuverCurveWithEstimationData toSerialize = new CompleteManeuverCurveWithEstimationDataImpl( |
| 317 | 315 | maneuverPosition, mainCurve, curve, wind, tackingCount, jibingCount, |
| 318 | 316 | maneuverStartsByRunningAwayFromWind, relativeBearingToNextMarkBeforeManeuver, |
| 319 | - relativeBearingToNextMarkAfterManeuver, markPassing, closestDistanceToMark, |
|
| 320 | - deviationFromTargetTackAngle, deviationFromTargetJibeAngle); |
|
| 317 | + relativeBearingToNextMarkAfterManeuver, markPassing, closestDistanceToMark, targetTackAngle, |
|
| 318 | + targetJibeAngle); |
|
| 321 | 319 | CompleteManeuverCurveWithEstimationDataJsonSerializer serializer = new CompleteManeuverCurveWithEstimationDataJsonSerializer( |
| 322 | 320 | new ManeuverMainCurveWithEstimationDataJsonSerializer(), |
| 323 | 321 | new ManeuverCurveWithUnstableCourseAndSpeedWithEstimationDataJsonSerializer(), |
| ... | ... | @@ -329,10 +327,8 @@ public class EstimationDataSerializationDeserializationTest { |
| 329 | 327 | new ManeuverWindJsonDeserializer(), new PositionJsonDeserializer()); |
| 330 | 328 | CompleteManeuverCurveWithEstimationData deserialized = deserializer.deserialize(json); |
| 331 | 329 | |
| 332 | - assertEquals(deviationFromTargetJibeAngle, |
|
| 333 | - deserialized.getDeviationOfManeuverAngleFromTargetJibeAngleInDegrees()); |
|
| 334 | - assertEquals(deviationFromTargetTackAngle, |
|
| 335 | - deserialized.getDeviationOfManeuverAngleFromTargetTackAngleInDegrees()); |
|
| 330 | + assertEquals(targetJibeAngle, deserialized.getTargetJibeAngleInDegrees()); |
|
| 331 | + assertEquals(targetTackAngle, deserialized.getTargetTackAngleInDegrees()); |
|
| 336 | 332 | assertEquals(closestDistanceToMark, deserialized.getDistanceToClosestMark()); |
| 337 | 333 | assertEquals(maneuverPosition, deserialized.getPosition()); |
| 338 | 334 | assertEquals(tackingCount, deserialized.getTackingCount()); |
java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CompleteManeuverCurveWithEstimationDataJsonDeserializer.java
| ... | ... | @@ -67,16 +67,15 @@ public class CompleteManeuverCurveWithEstimationDataJsonDeserializer |
| 67 | 67 | CompleteManeuverCurveWithEstimationDataJsonSerializer.RELATIVE_BEARING_TO_NEXT_MARK_AFTER_MANEUVER); |
| 68 | 68 | Double closestDistanceToMarkInMeters = (Double) object |
| 69 | 69 | .get(CompleteManeuverCurveWithEstimationDataJsonSerializer.CLOSEST_DISTANCE_TO_MARK); |
| 70 | - Double deviationFromTargetTackAngle = (Double) object |
|
| 71 | - .get(CompleteManeuverCurveWithEstimationDataJsonSerializer.DEVIATION_FROM_TARGET_TACK_ANGLE); |
|
| 72 | - Double deviationFromTargetJibeAngle = (Double) object |
|
| 73 | - .get(CompleteManeuverCurveWithEstimationDataJsonSerializer.DEVIATION_FROM_TARGET_JIBE_ANGLE); |
|
| 70 | + Double targetTackAngle = (Double) object |
|
| 71 | + .get(CompleteManeuverCurveWithEstimationDataJsonSerializer.TARGET_TACK_ANGLE); |
|
| 72 | + Double targetJibeAngle = (Double) object |
|
| 73 | + .get(CompleteManeuverCurveWithEstimationDataJsonSerializer.TARGET_JIBE_ANGLE); |
|
| 74 | 74 | return new CompleteManeuverCurveWithEstimationDataImpl(position, mainCurve, curveWithUnstableCourseAndSpeed, |
| 75 | 75 | wind, tackingCount, jibingCount, maneuverStartsByRunningAwayFromWind, |
| 76 | 76 | convertBearing(relativeBearingToNextMarkBeforeManeuver), |
| 77 | 77 | convertBearing(relativeBearingToNextMarkAfterManeuver), markPassing, |
| 78 | - convertDistance(closestDistanceToMarkInMeters), deviationFromTargetTackAngle, |
|
| 79 | - deviationFromTargetJibeAngle); |
|
| 78 | + convertDistance(closestDistanceToMarkInMeters), targetTackAngle, targetJibeAngle); |
|
| 80 | 79 | } |
| 81 | 80 | |
| 82 | 81 | private Bearing convertBearing(Double degrees) { |
java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompetitorTrackWithEstimationDataJsonSerializer.java
| ... | ... | @@ -26,7 +26,7 @@ import com.sap.sse.common.impl.MillisecondsDurationImpl; |
| 26 | 26 | * |
| 27 | 27 | */ |
| 28 | 28 | public class CompetitorTrackWithEstimationDataJsonSerializer extends AbstractTrackedRaceDataJsonSerializer { |
| 29 | - public static final String elements = "elements"; |
|
| 29 | + public static final String ELEMENTS = "elements"; |
|
| 30 | 30 | public static final String BOAT_CLASS = "boatClass"; |
| 31 | 31 | public static final String COMPETITOR_NAME = "competitorName"; |
| 32 | 32 | public static final String AVG_INTERVAL_BETWEEN_FIXES_IN_SECONDS = "avgIntervalBetweenFixesInSeconds"; |
| ... | ... | @@ -67,27 +67,27 @@ public class CompetitorTrackWithEstimationDataJsonSerializer extends AbstractTra |
| 67 | 67 | for (Competitor competitor : trackedRace.getRace().getCompetitors()) { |
| 68 | 68 | ManeuverDetectorImpl maneuverDetector = new ManeuverDetectorImpl(trackedRace, competitor); |
| 69 | 69 | TrackTimeInfo trackTimeInfo = maneuverDetector.getTrackTimeInfo(); |
| 70 | - TimePoint from = null; |
|
| 71 | - TimePoint to = null; |
|
| 72 | - if (startBeforeStartLineInSeconds != null) { |
|
| 73 | - from = trackTimeInfo.getTrackStartTimePoint() |
|
| 74 | - .minus(new MillisecondsDurationImpl(startBeforeStartLineInSeconds * 1000L)); |
|
| 75 | - } else if (startAfterFinishLineInSeconds != null) { |
|
| 76 | - from = trackTimeInfo.getTrackEndTimePoint() |
|
| 77 | - .plus(new MillisecondsDurationImpl(startAfterFinishLineInSeconds * 1000L)); |
|
| 78 | - } else { |
|
| 79 | - from = trackTimeInfo.getTrackStartTimePoint(); |
|
| 80 | - } |
|
| 81 | - if (endAfterFinishLineInSeconds != null) { |
|
| 82 | - to = trackTimeInfo.getTrackEndTimePoint() |
|
| 83 | - .plus(new MillisecondsDurationImpl(endAfterFinishLineInSeconds * 1000L)); |
|
| 84 | - } else if (endBeforeStartLineInSeconds != null) { |
|
| 85 | - to = trackTimeInfo.getTrackStartTimePoint() |
|
| 86 | - .minus(new MillisecondsDurationImpl(endBeforeStartLineInSeconds * 1000L)); |
|
| 87 | - } else { |
|
| 88 | - to = trackTimeInfo.getTrackEndTimePoint(); |
|
| 89 | - } |
|
| 90 | 70 | if (trackTimeInfo != null) { |
| 71 | + TimePoint from = null; |
|
| 72 | + TimePoint to = null; |
|
| 73 | + if (startBeforeStartLineInSeconds != null) { |
|
| 74 | + from = trackTimeInfo.getTrackStartTimePoint() |
|
| 75 | + .minus(new MillisecondsDurationImpl(startBeforeStartLineInSeconds * 1000L)); |
|
| 76 | + } else if (startAfterFinishLineInSeconds != null) { |
|
| 77 | + from = trackTimeInfo.getTrackEndTimePoint() |
|
| 78 | + .plus(new MillisecondsDurationImpl(startAfterFinishLineInSeconds * 1000L)); |
|
| 79 | + } else { |
|
| 80 | + from = trackTimeInfo.getTrackStartTimePoint(); |
|
| 81 | + } |
|
| 82 | + if (endAfterFinishLineInSeconds != null) { |
|
| 83 | + to = trackTimeInfo.getTrackEndTimePoint() |
|
| 84 | + .plus(new MillisecondsDurationImpl(endAfterFinishLineInSeconds * 1000L)); |
|
| 85 | + } else if (endBeforeStartLineInSeconds != null) { |
|
| 86 | + to = trackTimeInfo.getTrackStartTimePoint() |
|
| 87 | + .minus(new MillisecondsDurationImpl(endBeforeStartLineInSeconds * 1000L)); |
|
| 88 | + } else { |
|
| 89 | + to = trackTimeInfo.getTrackEndTimePoint(); |
|
| 90 | + } |
|
| 91 | 91 | final JSONObject forCompetitorJson = new JSONObject(); |
| 92 | 92 | byCompetitorJson.add(forCompetitorJson); |
| 93 | 93 | forCompetitorJson.put(COMPETITOR_NAME, competitor.getName()); |
| ... | ... | @@ -111,7 +111,7 @@ public class CompetitorTrackWithEstimationDataJsonSerializer extends AbstractTra |
| 111 | 111 | : trackTimeInfo.getTrackEndTimePoint().asMillis()); |
| 112 | 112 | forCompetitorJson.put(MARK_PASSINGS_COUNT, getMarkPassingsCount(trackedRace, competitor)); |
| 113 | 113 | forCompetitorJson.put(WAYPOINTS_COUNT, getWaypointsCount(trackedRace)); |
| 114 | - forCompetitorJson.put(elements, |
|
| 114 | + forCompetitorJson.put(ELEMENTS, |
|
| 115 | 115 | elementsJsonSerializer.serialize(trackedRace, competitor, from, to, trackTimeInfo)); |
| 116 | 116 | } |
| 117 | 117 | } |
java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CompleteManeuverCurveWithEstimationDataJsonSerializer.java
| ... | ... | @@ -24,8 +24,8 @@ public class CompleteManeuverCurveWithEstimationDataJsonSerializer |
| 24 | 24 | public static final String RELATIVE_BEARING_TO_NEXT_MARK_BEFORE_MANEUVER = "relativeBearingToNextMarkBeforeManeuver"; |
| 25 | 25 | public static final String RELATIVE_BEARING_TO_NEXT_MARK_AFTER_MANEUVER = "relativeBearingToNextMarkAfterManeuver"; |
| 26 | 26 | public static final String CLOSEST_DISTANCE_TO_MARK = "closestDistanceToMarkInMeters"; |
| 27 | - public static final String DEVIATION_FROM_TARGET_TACK_ANGLE = "deviationFromTargetTackAngleInDegrees"; |
|
| 28 | - public static final String DEVIATION_FROM_TARGET_JIBE_ANGLE = "deviationFromTargetJibeAngleInDegrees"; |
|
| 27 | + public static final String TARGET_TACK_ANGLE = "targetTackAngleInDegrees"; |
|
| 28 | + public static final String TARGET_JIBE_ANGLE = "targetJibeAngleInDegrees"; |
|
| 29 | 29 | |
| 30 | 30 | private final ManeuverCurveBoundariesJsonSerializer mainCurveSerializer; |
| 31 | 31 | private final ManeuverCurveBoundariesJsonSerializer curveWithUnstableCourseAndSpeedSerializer; |
| ... | ... | @@ -64,10 +64,8 @@ public class CompleteManeuverCurveWithEstimationDataJsonSerializer |
| 64 | 64 | : maneuverWithEstimationData.getRelativeBearingToNextMarkAfterManeuver().getDegrees()); |
| 65 | 65 | result.put(CLOSEST_DISTANCE_TO_MARK, maneuverWithEstimationData.getDistanceToClosestMark() == null ? null |
| 66 | 66 | : maneuverWithEstimationData.getDistanceToClosestMark().getMeters()); |
| 67 | - result.put(DEVIATION_FROM_TARGET_TACK_ANGLE, |
|
| 68 | - maneuverWithEstimationData.getDeviationOfManeuverAngleFromTargetTackAngleInDegrees()); |
|
| 69 | - result.put(DEVIATION_FROM_TARGET_JIBE_ANGLE, |
|
| 70 | - maneuverWithEstimationData.getDeviationOfManeuverAngleFromTargetJibeAngleInDegrees()); |
|
| 67 | + result.put(TARGET_TACK_ANGLE, maneuverWithEstimationData.getTargetTackAngleInDegrees()); |
|
| 68 | + result.put(TARGET_JIBE_ANGLE, maneuverWithEstimationData.getTargetJibeAngleInDegrees()); |
|
| 71 | 69 | return result; |
| 72 | 70 | } |
| 73 | 71 |
java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/GPSFixMovingJsonSerializer.java
| ... | ... | @@ -2,19 +2,25 @@ package com.sap.sailing.server.gateway.serialization.impl; |
| 2 | 2 | |
| 3 | 3 | import org.json.simple.JSONObject; |
| 4 | 4 | |
| 5 | +import com.sap.sailing.domain.common.SpeedWithBearing; |
|
| 5 | 6 | import com.sap.sailing.domain.common.tracking.GPSFixMoving; |
| 6 | 7 | import com.sap.sailing.server.gateway.deserialization.TypeBasedJsonDeserializer; |
| 7 | 8 | import com.sap.sailing.server.gateway.deserialization.impl.GPSFixMovingJsonDeserializer; |
| 8 | 9 | import com.sap.sailing.server.gateway.serialization.JsonSerializer; |
| 9 | 10 | |
| 10 | 11 | public class GPSFixMovingJsonSerializer implements JsonSerializer<GPSFixMoving> { |
| 12 | + |
|
| 11 | 13 | @Override |
| 12 | 14 | public JSONObject serialize(GPSFixMoving object) { |
| 15 | + return serialize(object, object.getSpeed()); |
|
| 16 | + } |
|
| 17 | + |
|
| 18 | + public JSONObject serialize(GPSFixMoving object, SpeedWithBearing speedWithCourse) { |
|
| 13 | 19 | JSONObject result = new GPSFixJsonSerializer().serialize(object); |
| 14 | 20 | |
| 15 | 21 | result.put(TypeBasedJsonDeserializer.FIELD_TYPE, GPSFixMovingJsonDeserializer.TYPE); |
| 16 | - result.put(GPSFixMovingJsonDeserializer.FIELD_BEARING_DEG, object.getSpeed().getBearing().getDegrees()); |
|
| 17 | - result.put(GPSFixMovingJsonDeserializer.FIELD_SPEED_KNOTS, object.getSpeed().getKnots()); |
|
| 22 | + result.put(GPSFixMovingJsonDeserializer.FIELD_BEARING_DEG, speedWithCourse.getBearing().getDegrees()); |
|
| 23 | + result.put(GPSFixMovingJsonDeserializer.FIELD_SPEED_KNOTS, speedWithCourse.getKnots()); |
|
| 18 | 24 | |
| 19 | 25 | return result; |
| 20 | 26 | } |
java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/GpsFixesWithEstimationDataJsonSerializer.java
| ... | ... | @@ -60,7 +60,9 @@ public class GpsFixesWithEstimationDataJsonSerializer implements CompetitorTrack |
| 60 | 60 | track.lockForRead(); |
| 61 | 61 | try { |
| 62 | 62 | for (GPSFixMoving gpsFix : track.getFixes(from, true, to, true)) { |
| 63 | - JSONObject serializedGpsFix = gpsFixMovingJsonSerializer.serialize(gpsFix); |
|
| 63 | + SpeedWithBearing speedWithBearing = smoothFixes ? track.getEstimatedSpeed(gpsFix.getTimePoint()) |
|
| 64 | + : gpsFix.getSpeed(); |
|
| 65 | + JSONObject serializedGpsFix = gpsFixMovingJsonSerializer.serialize(gpsFix, speedWithBearing); |
|
| 64 | 66 | if (addWind) { |
| 65 | 67 | Wind wind = trackedRace.getWind(gpsFix.getPosition(), gpsFix.getTimePoint()); |
| 66 | 68 | JSONObject serializedWind = wind == null ? null : windJsonSerializer.serialize(wind); |
| ... | ... | @@ -69,8 +71,6 @@ public class GpsFixesWithEstimationDataJsonSerializer implements CompetitorTrack |
| 69 | 71 | if (addNextWaypoint) { |
| 70 | 72 | Distance closestDistanceToMark = estimationDataSupportDecoratorImpl |
| 71 | 73 | .getClosestDistanceToMark(gpsFix.getTimePoint()); |
| 72 | - SpeedWithBearing speedWithBearing = smoothFixes ? track.getEstimatedSpeed(gpsFix.getTimePoint()) |
|
| 73 | - : gpsFix.getSpeed(); |
|
| 74 | 74 | Bearing relativeBearingToNextMark = speedWithBearing == null ? null |
| 75 | 75 | : estimationDataSupportDecoratorImpl.getRelativeBearingToNextMark(gpsFix.getTimePoint(), |
| 76 | 76 | speedWithBearing.getBearing()); |
java/com.sap.sailing.simulator.test/.project
| ... | ... | @@ -22,12 +22,12 @@ |
| 22 | 22 | </arguments> |
| 23 | 23 | </buildCommand> |
| 24 | 24 | <buildCommand> |
| 25 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 26 | 26 | <arguments> |
| 27 | 27 | </arguments> |
| 28 | 28 | </buildCommand> |
| 29 | 29 | <buildCommand> |
| 30 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 31 | 31 | <arguments> |
| 32 | 32 | </arguments> |
| 33 | 33 | </buildCommand> |
| ... | ... | @@ -35,6 +35,6 @@ |
| 35 | 35 | <natures> |
| 36 | 36 | <nature>org.eclipse.pde.PluginNature</nature> |
| 37 | 37 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 38 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 39 | 39 | </natures> |
| 40 | 40 | </projectDescription> |
java/com.sap.sailing.simulator/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sailing.www/release_notes_admin.html
| ... | ... | @@ -24,6 +24,11 @@ |
| 24 | 24 | |
| 25 | 25 | <h2 class="articleSubheadline">July 2018</h2> |
| 26 | 26 | <ul class="bulletList"> |
| 27 | + <li>The mark passing editor now uses a full date/time format for the mark passing time points.</li> |
|
| 28 | + </ul> |
|
| 29 | + |
|
| 30 | + <h2 class="articleSubheadline">July 2018</h2> |
|
| 31 | + <ul class="bulletList"> |
|
| 27 | 32 | <li>When adding a YouTube video for tracked races ("Manage Media" in <tt>RaceBoard.html</tt> or "Tracked Races > Audio & Video" in <tt>AdminConsole.html</tt>) the respective video metadata is now read using YouTube API v3. |
| 28 | 33 | This functionality used to work some years ago using API v2 but was broken since this API version was discontinued some time ago. |
| 29 | 34 | Due to limitations of the new API we can't read the start timepoint of videos by now. You still need to provide this value manually.</li> |
| ... | ... | @@ -45,6 +50,10 @@ |
| 45 | 50 | For any non-medal series, the standard low point rules apply.</li> |
| 46 | 51 | </ul> |
| 47 | 52 | </li> |
| 53 | + <li>A TracAPI upgrade from version 3.10.1 to 3.11.0 unifies the handling of course updates and solves an issue |
|
| 54 | + observed with updating mark passing instructions.</li> |
|
| 55 | + <li>Bug fix for mark position editor, now providing consistent behavior during adding of new mark fixes</li> |
|
| 56 | + <li>Data Mining now more aggressively terminates running queries if needed.</li> |
|
| 48 | 57 | </ul> |
| 49 | 58 | |
| 50 | 59 | <h2 class="articleSubheadline">June 2018</h2> |
java/com.sap.sse.common/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestAbortingHeavyLoadQuery.java
| ... | ... | @@ -0,0 +1,524 @@ |
| 1 | +package com.sap.sse.datamining.impl; |
|
| 2 | + |
|
| 3 | +import static org.hamcrest.Matchers.is; |
|
| 4 | +import static org.junit.Assert.assertFalse; |
|
| 5 | +import static org.junit.Assert.assertThat; |
|
| 6 | +import static org.junit.Assert.assertTrue; |
|
| 7 | + |
|
| 8 | +import java.lang.reflect.Method; |
|
| 9 | +import java.text.SimpleDateFormat; |
|
| 10 | +import java.util.ArrayList; |
|
| 11 | +import java.util.Collection; |
|
| 12 | +import java.util.Collections; |
|
| 13 | +import java.util.Date; |
|
| 14 | +import java.util.HashSet; |
|
| 15 | +import java.util.Map; |
|
| 16 | +import java.util.Set; |
|
| 17 | +import java.util.concurrent.ConcurrentHashMap; |
|
| 18 | +import java.util.concurrent.ConcurrentLinkedQueue; |
|
| 19 | +import java.util.concurrent.ExecutionException; |
|
| 20 | +import java.util.concurrent.ExecutorService; |
|
| 21 | +import java.util.concurrent.FutureTask; |
|
| 22 | +import java.util.concurrent.RunnableFuture; |
|
| 23 | +import java.util.concurrent.TimeUnit; |
|
| 24 | +import java.util.function.Consumer; |
|
| 25 | + |
|
| 26 | +import org.junit.After; |
|
| 27 | +import org.junit.Before; |
|
| 28 | +import org.junit.Test; |
|
| 29 | + |
|
| 30 | +import com.sap.sse.datamining.Query; |
|
| 31 | +import com.sap.sse.datamining.QueryState; |
|
| 32 | +import com.sap.sse.datamining.components.AdditionalResultDataBuilder; |
|
| 33 | +import com.sap.sse.datamining.components.Processor; |
|
| 34 | +import com.sap.sse.datamining.components.ProcessorInstruction; |
|
| 35 | +import com.sap.sse.datamining.components.ProcessorInstructionHandler; |
|
| 36 | +import com.sap.sse.datamining.data.QueryResult; |
|
| 37 | +import com.sap.sse.datamining.impl.components.AbstractParallelProcessor; |
|
| 38 | +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; |
|
| 39 | +import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor; |
|
| 40 | +import com.sap.sse.datamining.impl.components.GroupedDataEntry; |
|
| 41 | +import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; |
|
| 42 | +import com.sap.sse.datamining.impl.components.aggregators.ParallelGroupedDataCollectingAsSetProcessor; |
|
| 43 | +import com.sap.sse.datamining.shared.GroupKey; |
|
| 44 | +import com.sap.sse.datamining.shared.data.QueryResultState; |
|
| 45 | +import com.sap.sse.datamining.shared.impl.GenericGroupKey; |
|
| 46 | +import com.sap.sse.datamining.test.util.components.StatefulBlockingInstruction; |
|
| 47 | +import com.sap.sse.datamining.test.util.components.StatefulProcessorInstruction; |
|
| 48 | + |
|
| 49 | +/** |
|
| 50 | + * Integration test aborting a query with simulated heavy load instructions. Uses a highly customized processor chain |
|
| 51 | + * (based on the processors/instructions used in production) that allows detailed introspection and logging of the |
|
| 52 | + * execution process. The test is used to verify the behavior of processors, if such a heavy load query is aborted |
|
| 53 | + * during the process. For example that no instructions are scheduled after the query was aborted and the behavior of |
|
| 54 | + * already scheduled instructions that may or may not have been started.<br> |
|
| 55 | + * <br> |
|
| 56 | + * The test is configurable regarding the number of threads for the executor, the number of data elements/heavy load |
|
| 57 | + * instructions, the duration of heavy load instructions, the time to wait before the query is aborted and the time |
|
| 58 | + * given to the executor to finish the remaining instructions. Note that the test can fail for some configurations, due |
|
| 59 | + * to race conditions that would be very hard to check for.<br> |
|
| 60 | + * <br> |
|
| 61 | + * The test optionally records the process in order of the execution (using a concurrent message queue), which is |
|
| 62 | + * printed to the console before assertions are performed. This isn't used by the assertions, but can be used to get a |
|
| 63 | + * better understanding of what happens during the execution.<br> |
|
| 64 | + * <br> |
|
| 65 | + * See {@link #initialize()} for more details about the processor chain. |
|
| 66 | + * |
|
| 67 | + * @author Lennart Hensler |
|
| 68 | + */ |
|
| 69 | +public class TestAbortingHeavyLoadQuery { |
|
| 70 | + |
|
| 71 | + // Test Configuration ---------------------------------------------------------------------------------------- |
|
| 72 | + /** |
|
| 73 | + * Number of threads in the executor. Determines the number of elements (and thus heavy load instructions) |
|
| 74 | + * retrieved for each group. This means that each group should have a runtime of {@value #HeavyLoadInstructionTotalDuration}ms, |
|
| 75 | + * since the single instructions are executed concurrently. |
|
| 76 | + */ |
|
| 77 | + private static final int ExecutorPoolSize = Math.max(3, Runtime.getRuntime().availableProcessors()); |
|
| 78 | + |
|
| 79 | + /** The number of groups contained in the initial data source. */ |
|
| 80 | + private static final int DataSourceSize = 2000; |
|
| 81 | + private static final String GroupKeyPrefix = "G"; |
|
| 82 | + |
|
| 83 | + /** The time a step of a heavy load instruction blocks the executing thread (using {@link Thread#sleep(long)}). */ |
|
| 84 | + private static final long HeavyLoadInstructionStepDuration = 50; |
|
| 85 | + /** The number of steps a heavy load instruction performs */ |
|
| 86 | + private static final int HeavyLoadInstructionNumberOfSteps = 10; |
|
| 87 | + /** The total time a heavy load instruction blocks the executing thread (using {@link Thread#sleep(long)}). */ |
|
| 88 | + private static final long HeavyLoadInstructionTotalDuration = HeavyLoadInstructionStepDuration * HeavyLoadInstructionNumberOfSteps; |
|
| 89 | + |
|
| 90 | + /** The number of milliseconds to wait before {@link Query#abort()} is called. */ |
|
| 91 | + private static final long AbortQueryDelay = (long) (HeavyLoadInstructionTotalDuration * 5.45); |
|
| 92 | + /** The time given to the executor to complete all unfinished instructions */ |
|
| 93 | + private static final long TerminationTimeout = HeavyLoadInstructionStepDuration * 2; |
|
| 94 | + //------------------------------------------------------------------------------------------------------------ |
|
| 95 | + |
|
| 96 | + // Execution Recording Configuration ------------------------------------------------------------------------- |
|
| 97 | + /** Enables concurrent logging of the query execution and prints the current record before assertions. */ |
|
| 98 | + private static final boolean RecordExecution = true; |
|
| 99 | + private static final SimpleDateFormat DateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); |
|
| 100 | + private ConcurrentLinkedQueue<String> executionRecord; |
|
| 101 | + //------------------------------------------------------------------------------------------------------------ |
|
| 102 | + |
|
| 103 | + // Test State - Initialized in initialize() ------------------------------------------------------------------ |
|
| 104 | + private ExecutorService executor; |
|
| 105 | + private Query<HashSet<Integer>> query; |
|
| 106 | + private Collection<Processor<?, ?>> processors; |
|
| 107 | + private Set<StatefulProcessorInstruction<?>> unfinishedInstructions; |
|
| 108 | + //------------------------------------------------------------------------------------------------------------ |
|
| 109 | + |
|
| 110 | + @Test |
|
| 111 | + public void testAbortingHeavyLoadQuery() throws InterruptedException, ExecutionException { |
|
| 112 | + // Executing query in separate thread |
|
| 113 | + RunnableFuture<QueryResult<HashSet<Integer>>> queryTask = new FutureTask<>(() -> { |
|
| 114 | + logExecution("Starting query execution"); |
|
| 115 | + long start = System.currentTimeMillis(); |
|
| 116 | + QueryResult<HashSet<Integer>> result = query.run(); |
|
| 117 | + long duration = System.currentTimeMillis() - start; |
|
| 118 | + logExecution("Finished query in " + duration + "ms"); |
|
| 119 | + return result; |
|
| 120 | + }); |
|
| 121 | + Thread worker = new Thread(queryTask, "Worker"); |
|
| 122 | + worker.start(); |
|
| 123 | + do { |
|
| 124 | + Thread.sleep(10); |
|
| 125 | + } while (query.getState() != QueryState.RUNNING); |
|
| 126 | + |
|
| 127 | + // Aborting query and waiting for completion |
|
| 128 | + Thread.sleep(AbortQueryDelay); |
|
| 129 | + logExecution("Aborting query"); |
|
| 130 | + query.abort(); |
|
| 131 | + QueryResult<HashSet<Integer>> result = queryTask.get(); |
|
| 132 | + |
|
| 133 | + // The query execution returned, so all processors are aborted (checked below). |
|
| 134 | + // The number of unfinished instructions mustn't change after this point |
|
| 135 | + int unfinishedInstructionsCount = unfinishedInstructions.size(); |
|
| 136 | + boolean unfinishedInstructionWasFinished = false; |
|
| 137 | + Set<StatefulProcessorInstruction<?>> runningInstructions = new HashSet<>(); |
|
| 138 | + Set<StatefulProcessorInstruction<?>> notStartedInstructions = new HashSet<>(); |
|
| 139 | + for (StatefulProcessorInstruction<?> instruction : unfinishedInstructions) { |
|
| 140 | + if (instruction.runWasCalled()) { |
|
| 141 | + runningInstructions.add(instruction); |
|
| 142 | + } else { |
|
| 143 | + notStartedInstructions.add(instruction); |
|
| 144 | + } |
|
| 145 | + unfinishedInstructionWasFinished |= instruction.computeResultWasFinished(); |
|
| 146 | + } |
|
| 147 | + logExecution(unfinishedInstructionsCount + " unfinished instructions left - " + |
|
| 148 | + runningInstructions.size() + " running, " + notStartedInstructions.size() + " not started"); |
|
| 149 | + printExecutionRecord(); |
|
| 150 | + assertThat("Number of unfinished instructions changed", runningInstructions.size() + notStartedInstructions.size(), is(unfinishedInstructionsCount)); |
|
| 151 | + assertFalse("Unfinished instructions expected, but at least one was completed", unfinishedInstructionWasFinished); |
|
| 152 | + |
|
| 153 | + // Checking query, result and processor chain state |
|
| 154 | + assertThat(query.getState(), is(QueryState.ABORTED)); |
|
| 155 | + assertThat(result.getState(), is(QueryResultState.ABORTED)); |
|
| 156 | + assertTrue("The result is not empty", result.isEmpty()); |
|
| 157 | + for (Processor<?, ?> processor : processors) { |
|
| 158 | + assertTrue("Processor wasn't aborted", processor.isAborted()); |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + // Execution of unfinished instructions |
|
| 162 | + executor.shutdown(); |
|
| 163 | + boolean terminated = executor.awaitTermination(TerminationTimeout, TimeUnit.MILLISECONDS); |
|
| 164 | + printExecutionRecord(); |
|
| 165 | + assertTrue("The executor didn't terminate in the given time", terminated); |
|
| 166 | + |
|
| 167 | + // Verify that the collection of unfinished instructions didn't change |
|
| 168 | + assertThat("Number of unfinished instructions changed", unfinishedInstructions.size(), is(unfinishedInstructionsCount)); |
|
| 169 | + for (StatefulProcessorInstruction<?> instruction : unfinishedInstructions) { |
|
| 170 | + boolean previouslyContained = runningInstructions.contains(instruction) || notStartedInstructions.contains(instruction); |
|
| 171 | + assertTrue("A new instruction has been scheduled after aborting the query", previouslyContained); |
|
| 172 | + } |
|
| 173 | + for (StatefulProcessorInstruction<?> instruction : runningInstructions) { |
|
| 174 | + assertTrue("A previously running instruction was removed from unfinished instructions", unfinishedInstructions.contains(instruction)); |
|
| 175 | + } |
|
| 176 | + for (StatefulProcessorInstruction<?> instruction : notStartedInstructions) { |
|
| 177 | + assertTrue("A previously unstarted instruction was removed from unfinished instructions", unfinishedInstructions.contains(instruction)); |
|
| 178 | + } |
|
| 179 | + |
|
| 180 | + // Checking state of unfinished instructions |
|
| 181 | + for (StatefulProcessorInstruction<?> instruction : runningInstructions) { |
|
| 182 | + assertTrue("computeResult() of a running unfinished instruction wasn't called", instruction.computeResultWasCalled()); |
|
| 183 | + assertTrue("computeResult() of a running unfinished instruction didn't finish", instruction.computeResultWasFinished()); |
|
| 184 | + if (instruction instanceof StatefulBlockingInstruction) { |
|
| 185 | + StatefulBlockingInstruction<?> blockingInstruction = (StatefulBlockingInstruction<?>) instruction; |
|
| 186 | + assertTrue("computeResult() of a running heavy load instruction wasn't aborted", blockingInstruction.computeResultWasAborted()); |
|
| 187 | + } |
|
| 188 | + } |
|
| 189 | + for (StatefulProcessorInstruction<?> instruction : notStartedInstructions) { |
|
| 190 | + assertTrue("run() of an unstarted unfinished instruction wasn't called", instruction.runWasCalled()); |
|
| 191 | + |
|
| 192 | + assertFalse("computeResult() of an unstarted unfinished instruction was called", instruction.computeResultWasCalled()); |
|
| 193 | + assertFalse("computeResult() of an unstarted unfinished instruction was finished", instruction.computeResultWasFinished()); |
|
| 194 | + } |
|
| 195 | + } |
|
| 196 | + |
|
| 197 | + private void printExecutionRecord() { |
|
| 198 | + if (RecordExecution) { |
|
| 199 | + Collection<String> snapshot = new ArrayList<>(executionRecord); |
|
| 200 | + executionRecord.clear(); |
|
| 201 | + for (String string : snapshot) { |
|
| 202 | + System.out.println(string); |
|
| 203 | + } |
|
| 204 | + } |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + private void logExecution(String message) { |
|
| 208 | + if (RecordExecution) { |
|
| 209 | + String timeString = DateFormatter.format(new Date()); |
|
| 210 | + executionRecord.add(timeString + " - " + Thread.currentThread().getName() + ": " + message); |
|
| 211 | + } |
|
| 212 | + } |
|
| 213 | + |
|
| 214 | + /** |
|
| 215 | + * Initializes the {@link ExecutorService}, the execution record, helper collections (e.g. the processors in the |
|
| 216 | + * chain or the unfinished instructions) and most importantly the processor chain for the query, which works as |
|
| 217 | + * follows: |
|
| 218 | + * <ol> |
|
| 219 | + * <li> |
|
| 220 | + * The initial data source is a collection of strings from {@value #GroupKeyPrefix}<code>n</code> to |
|
| 221 | + * {@value #GroupKeyPrefix}<code>n-1</code>, denoting a group. <code>n</code> is specified in {@link #DataSourceSize}. |
|
| 222 | + * </li> |
|
| 223 | + * <li> |
|
| 224 | + * <code>x</code> (specified by {@link #ExecutorPoolSize}) {@link Element elements} are retrieved for each |
|
| 225 | + * group, where the elements name is set to the received string and the elements value is the current value |
|
| 226 | + * of <code>x</code>. |
|
| 227 | + * </li> |
|
| 228 | + * <li> |
|
| 229 | + * A heavy load instruction for each element is scheduled, which blocks the running thread for |
|
| 230 | + * {@value #HeavyLoadInstructionTotalDuration}ms. |
|
| 231 | + * </li> |
|
| 232 | + * <li> |
|
| 233 | + * Each element is grouped by its name and its value is used as value for the {@link GroupedDataEntry}. |
|
| 234 | + * </li> |
|
| 235 | + * <li>The grouped data is collected as set.</li> |
|
| 236 | + * </ol> |
|
| 237 | + * This results in <code>n * x</code> data elements (and heavy load instructions), with <code>x</code> instructions |
|
| 238 | + * executed concurrently.<br> |
|
| 239 | + * <br> |
|
| 240 | + * Each processor creates {@link StatefulProcessorInstruction} or uses {@link StatefulInstructionWrapper}, which allows |
|
| 241 | + * to verify if <code>instruction.run()</code> was called, its computation started and its computation finished.<br> |
|
| 242 | + * <br> |
|
| 243 | + * A concurrent set ({@link ConcurrentHashMap#newKeySet()}) is used to track the unfinished instructions. An instruction |
|
| 244 | + * is added to the set upon its construction and is removed when the instruction finished callback method is called. |
|
| 245 | + */ |
|
| 246 | + @Before |
|
| 247 | + @SuppressWarnings("unchecked") |
|
| 248 | + public void initialize() { |
|
| 249 | + if (RecordExecution) { |
|
| 250 | + executionRecord = new ConcurrentLinkedQueue<>(); |
|
| 251 | + } |
|
| 252 | + |
|
| 253 | + executor = new DataMiningExecutorService(ExecutorPoolSize); |
|
| 254 | +// executor = new ThreadPoolExecutor(ExecutorPoolSize, ExecutorPoolSize, 0, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<>()); |
|
| 255 | +// executor = new ThreadPoolExecutor(ExecutorPoolSize, ExecutorPoolSize, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); |
|
| 256 | + processors = new ArrayList<>(); |
|
| 257 | + unfinishedInstructions = ConcurrentHashMap.newKeySet(); |
|
| 258 | + |
|
| 259 | + Class<Iterable<String>> dataSourceType = (Class<Iterable<String>>)(Class<?>) Iterable.class; |
|
| 260 | + Class<GroupedDataEntry<Integer>> groupedType = (Class<GroupedDataEntry<Integer>>)(Class<?>) GroupedDataEntry.class; |
|
| 261 | + Class<HashSet<Integer>> resultType = (Class<HashSet<Integer>>)(Class<?>) HashSet.class; |
|
| 262 | + |
|
| 263 | + Collection<String> dataSource = new ArrayList<>(DataSourceSize); |
|
| 264 | + for (int i = 0; i < DataSourceSize; i++) { |
|
| 265 | + dataSource.add(GroupKeyPrefix + i); |
|
| 266 | + } |
|
| 267 | + query = new ProcessorQuery<HashSet<Integer>, Iterable<String>>(dataSource, resultType) { |
|
| 268 | + @Override |
|
| 269 | + protected Processor<Iterable<String>, ?> createChainAndReturnFirstProcessor(Processor<Map<GroupKey, HashSet<Integer>>, Void> resultReceiver) { |
|
| 270 | + Processor<GroupedDataEntry<Integer>, Map<GroupKey, HashSet<Integer>>> aggregator = new ParallelGroupedDataCollectingAsSetProcessor<Integer>(executor, Collections.singleton(resultReceiver)) { |
|
| 271 | + @Override |
|
| 272 | + protected ProcessorInstruction<Map<GroupKey, HashSet<Integer>>> createInstruction(GroupedDataEntry<Integer> element) { |
|
| 273 | + AbstractProcessorInstruction<Map<GroupKey, HashSet<Integer>>> instruction = (AbstractProcessorInstruction<Map<GroupKey, HashSet<Integer>>>) super.createInstruction(element); |
|
| 274 | + StatefulProcessorInstruction<Map<GroupKey, HashSet<Integer>>> statefulInstruction = new StatefulInstructionWrapper<>(instruction); |
|
| 275 | + unfinishedInstructions.add(statefulInstruction); |
|
| 276 | + return statefulInstruction; |
|
| 277 | + } |
|
| 278 | + |
|
| 279 | + @Override |
|
| 280 | + protected void storeElement(GroupedDataEntry<Integer> element) { |
|
| 281 | + logExecution("Storing " + element); |
|
| 282 | + super.storeElement(element); |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + @Override |
|
| 286 | + public void afterInstructionFinished(ProcessorInstruction<Map<GroupKey, HashSet<Integer>>> instruction) { |
|
| 287 | + super.afterInstructionFinished(instruction); |
|
| 288 | + if(canProcessElements()) unfinishedInstructions.remove(instruction); |
|
| 289 | + } |
|
| 290 | + }; |
|
| 291 | + |
|
| 292 | + Processor<Element, GroupedDataEntry<Integer>> grouper = new AbstractParallelProcessor<Element, GroupedDataEntry<Integer>>(Element.class, groupedType, executor, Collections.singleton(aggregator)) { |
|
| 293 | + @Override |
|
| 294 | + protected ProcessorInstruction<GroupedDataEntry<Integer>> createInstruction(Element element) { |
|
| 295 | + StatefulProcessorInstruction<GroupedDataEntry<Integer>> instruction = new StatefulProcessorInstruction<GroupedDataEntry<Integer>>(this, ProcessorInstructionPriority.Grouping) { |
|
| 296 | + @Override |
|
| 297 | + protected GroupedDataEntry<Integer> internalComputeResult() throws Exception { |
|
| 298 | + logExecution("Grouping " + element); |
|
| 299 | + return new GroupedDataEntry<>(new GenericGroupKey<>(element.getName()), element.getValue()); |
|
| 300 | + } |
|
| 301 | + }; |
|
| 302 | + unfinishedInstructions.add(instruction); |
|
| 303 | + return instruction; |
|
| 304 | + } |
|
| 305 | + |
|
| 306 | + @Override |
|
| 307 | + public void afterInstructionFinished(ProcessorInstruction<GroupedDataEntry<Integer>> instruction) { |
|
| 308 | + super.afterInstructionFinished(instruction); |
|
| 309 | + if(canProcessElements()) unfinishedInstructions.remove(instruction); |
|
| 310 | + } |
|
| 311 | + |
|
| 312 | + @Override |
|
| 313 | + protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) { } |
|
| 314 | + }; |
|
| 315 | + |
|
| 316 | + Processor<Element, Element> heavyLoadProcessor = new AbstractParallelProcessor<Element, Element>(Element.class, Element.class, executor, Collections.singleton(grouper)) { |
|
| 317 | + @Override |
|
| 318 | + protected ProcessorInstruction<Element> createInstruction(Element element) { |
|
| 319 | + StatefulProcessorInstruction<Element> instruction = new HeavyLoadInstruction(this, |
|
| 320 | + ProcessorInstructionPriority.Extraction, HeavyLoadInstructionStepDuration, |
|
| 321 | + HeavyLoadInstructionNumberOfSteps, element, TestAbortingHeavyLoadQuery.this::logExecution); |
|
| 322 | + unfinishedInstructions.add(instruction); |
|
| 323 | + return instruction; |
|
| 324 | + } |
|
| 325 | + |
|
| 326 | + @Override |
|
| 327 | + public void afterInstructionFinished(ProcessorInstruction<Element> instruction) { |
|
| 328 | + super.afterInstructionFinished(instruction); |
|
| 329 | + if(canProcessElements()) unfinishedInstructions.remove(instruction); |
|
| 330 | + } |
|
| 331 | + |
|
| 332 | + @Override |
|
| 333 | + protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) { } |
|
| 334 | + }; |
|
| 335 | + |
|
| 336 | + Processor<String, Element> retriever1 = new AbstractRetrievalProcessor<String, Element>(String.class, Element.class, executor, Collections.singleton(heavyLoadProcessor), 1) { |
|
| 337 | + @Override |
|
| 338 | + protected ProcessorInstruction<Element> createInstruction(String element) { |
|
| 339 | + AbstractProcessorInstruction<Element> instruction = (AbstractProcessorInstruction<Element>) super.createInstruction(element); |
|
| 340 | + StatefulProcessorInstruction<Element> statefulInstruction = new StatefulInstructionWrapper<>(instruction); |
|
| 341 | + unfinishedInstructions.add(statefulInstruction); |
|
| 342 | + return statefulInstruction; |
|
| 343 | + } |
|
| 344 | + |
|
| 345 | + @Override |
|
| 346 | + protected Iterable<Element> retrieveData(String element) { |
|
| 347 | + int count = ExecutorPoolSize; |
|
| 348 | + logExecution("Retrieving " + count + " elements for " + element); |
|
| 349 | + Collection<Element> data = new ArrayList<>(); |
|
| 350 | + for (int i = 0; i < count; i++) { |
|
| 351 | + data.add(new Element(element, i)); |
|
| 352 | + } |
|
| 353 | + return data; |
|
| 354 | + } |
|
| 355 | + |
|
| 356 | + @Override |
|
| 357 | + public void instructionSucceeded(Element result) { |
|
| 358 | + logExecution("Group retrieval finished"); |
|
| 359 | + super.instructionSucceeded(result); |
|
| 360 | + } |
|
| 361 | + |
|
| 362 | + @Override |
|
| 363 | + public void afterInstructionFinished(ProcessorInstruction<Element> instruction) { |
|
| 364 | + super.afterInstructionFinished(instruction); |
|
| 365 | + if(canProcessElements()) unfinishedInstructions.remove(instruction); |
|
| 366 | + } |
|
| 367 | + }; |
|
| 368 | + Processor<Iterable<String>, String> retriever0 = new AbstractRetrievalProcessor<Iterable<String>, String>(dataSourceType, String.class, executor, Collections.singleton(retriever1), 0) { |
|
| 369 | + @Override |
|
| 370 | + protected ProcessorInstruction<String> createInstruction(Iterable<String> element) { |
|
| 371 | + AbstractProcessorInstruction<String> instruction = (AbstractProcessorInstruction<String>) super.createInstruction(element); |
|
| 372 | + StatefulProcessorInstruction<String> statefulInstruction = new StatefulInstructionWrapper<>(instruction); |
|
| 373 | + unfinishedInstructions.add(statefulInstruction); |
|
| 374 | + return statefulInstruction; |
|
| 375 | + } |
|
| 376 | + |
|
| 377 | + @Override |
|
| 378 | + protected Iterable<String> retrieveData(Iterable<String> element) { |
|
| 379 | + logExecution("Retrieving data from data source"); |
|
| 380 | + return element; |
|
| 381 | + } |
|
| 382 | + |
|
| 383 | + @Override |
|
| 384 | + public void instructionSucceeded(String result) { |
|
| 385 | + logExecution("Data source retrieval finished"); |
|
| 386 | + super.instructionSucceeded(result); |
|
| 387 | + } |
|
| 388 | + |
|
| 389 | + @Override |
|
| 390 | + public void afterInstructionFinished(ProcessorInstruction<String> instruction) { |
|
| 391 | + super.afterInstructionFinished(instruction); |
|
| 392 | + if(canProcessElements()) unfinishedInstructions.remove(instruction); |
|
| 393 | + } |
|
| 394 | + }; |
|
| 395 | + |
|
| 396 | + processors.add(retriever0); |
|
| 397 | + processors.add(retriever1); |
|
| 398 | + processors.add(heavyLoadProcessor); |
|
| 399 | + processors.add(grouper); |
|
| 400 | + processors.add(aggregator); |
|
| 401 | + |
|
| 402 | + return retriever0; |
|
| 403 | + } |
|
| 404 | + }; |
|
| 405 | + } |
|
| 406 | + |
|
| 407 | + private static class HeavyLoadInstruction extends StatefulBlockingInstruction<Element> { |
|
| 408 | + |
|
| 409 | + private final Consumer<String> recorder; |
|
| 410 | + |
|
| 411 | + public HeavyLoadInstruction(ProcessorInstructionHandler<Element> handler, ProcessorInstructionPriority priority, |
|
| 412 | + long stepDuration, int numberOfSteps, Element result, Consumer<String> recorder) { |
|
| 413 | + super(handler, priority, stepDuration, numberOfSteps, result); |
|
| 414 | + this.recorder = recorder; |
|
| 415 | + } |
|
| 416 | + |
|
| 417 | + @Override |
|
| 418 | + public void run() { |
|
| 419 | + recorder.accept("Executing heavy load instruction for " + result); |
|
| 420 | + super.run(); |
|
| 421 | + } |
|
| 422 | + |
|
| 423 | + @Override |
|
| 424 | + protected void actionBeforeBlock() { |
|
| 425 | + recorder.accept("Starting work for heavy load instruction for " + result); |
|
| 426 | + } |
|
| 427 | + |
|
| 428 | + @Override |
|
| 429 | + protected void actionBeforeAbort() { |
|
| 430 | + recorder.accept("Aborting heavy load instruction for " + result); |
|
| 431 | + } |
|
| 432 | + |
|
| 433 | + @Override |
|
| 434 | + protected void actionAfterBlock() { |
|
| 435 | + recorder.accept("Finished heavy load instruction for " + result); |
|
| 436 | + } |
|
| 437 | + |
|
| 438 | + } |
|
| 439 | + |
|
| 440 | + private static class StatefulInstructionWrapper<ResultType> extends StatefulProcessorInstruction<ResultType> { |
|
| 441 | + |
|
| 442 | + private static Method computeResult; |
|
| 443 | + |
|
| 444 | + private final AbstractProcessorInstruction<ResultType> instruction; |
|
| 445 | + |
|
| 446 | + public StatefulInstructionWrapper(AbstractProcessorInstruction<ResultType> instruction) { |
|
| 447 | + super(instruction.getHandler(), instruction.getPriority()); |
|
| 448 | + this.instruction = instruction; |
|
| 449 | + } |
|
| 450 | + |
|
| 451 | + @Override |
|
| 452 | + @SuppressWarnings("unchecked") |
|
| 453 | + protected ResultType internalComputeResult() throws Exception { |
|
| 454 | + if (computeResult == null) { |
|
| 455 | + computeResult = AbstractProcessorInstruction.class.getDeclaredMethod("computeResult"); |
|
| 456 | + computeResult.setAccessible(true); |
|
| 457 | + } |
|
| 458 | + return (ResultType) computeResult.invoke(instruction); |
|
| 459 | + } |
|
| 460 | + |
|
| 461 | + } |
|
| 462 | + |
|
| 463 | + @After |
|
| 464 | + public void resetComputeResultAccessibility() throws SecurityException, NoSuchMethodException { |
|
| 465 | + AbstractProcessorInstruction.class.getDeclaredMethod("computeResult").setAccessible(false); |
|
| 466 | + } |
|
| 467 | + |
|
| 468 | + /** |
|
| 469 | + * Simple data type consisting of a name and value. |
|
| 470 | + */ |
|
| 471 | + private static class Element { |
|
| 472 | + |
|
| 473 | + private final String name; |
|
| 474 | + private final int value; |
|
| 475 | + |
|
| 476 | + public Element(String name, int value) { |
|
| 477 | + this.name = name; |
|
| 478 | + this.value = value; |
|
| 479 | + } |
|
| 480 | + |
|
| 481 | + public String getName() { |
|
| 482 | + return name; |
|
| 483 | + } |
|
| 484 | + |
|
| 485 | + public int getValue() { |
|
| 486 | + return value; |
|
| 487 | + } |
|
| 488 | + |
|
| 489 | + @Override |
|
| 490 | + public String toString() { |
|
| 491 | + return getName() + "-" + getValue(); |
|
| 492 | + } |
|
| 493 | + |
|
| 494 | + @Override |
|
| 495 | + public int hashCode() { |
|
| 496 | + final int prime = 31; |
|
| 497 | + int result = 1; |
|
| 498 | + result = prime * result + ((name == null) ? 0 : name.hashCode()); |
|
| 499 | + result = prime * result + value; |
|
| 500 | + return result; |
|
| 501 | + } |
|
| 502 | + |
|
| 503 | + @Override |
|
| 504 | + public boolean equals(Object obj) { |
|
| 505 | + if (this == obj) |
|
| 506 | + return true; |
|
| 507 | + if (obj == null) |
|
| 508 | + return false; |
|
| 509 | + if (getClass() != obj.getClass()) |
|
| 510 | + return false; |
|
| 511 | + Element other = (Element) obj; |
|
| 512 | + if (name == null) { |
|
| 513 | + if (other.name != null) |
|
| 514 | + return false; |
|
| 515 | + } else if (!name.equals(other.name)) |
|
| 516 | + return false; |
|
| 517 | + if (value != other.value) |
|
| 518 | + return false; |
|
| 519 | + return true; |
|
| 520 | + } |
|
| 521 | + |
|
| 522 | + } |
|
| 523 | + |
|
| 524 | +} |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java
| ... | ... | @@ -63,7 +63,7 @@ public class TestProcessorQuery { |
| 63 | 63 | Collection<Processor<Double, ?>> resultReceivers = new ArrayList<>(); |
| 64 | 64 | resultReceivers.add(new AbortResultReceiver(resultReceiver)); |
| 65 | 65 | return new BlockingProcessor<Iterable<Number>, Double>((Class<Iterable<Number>>)(Class<?>) Iterable.class, Double.class, |
| 66 | - ConcurrencyTestsUtil.getExecutor(), resultReceivers, 1000) { |
|
| 66 | + ConcurrencyTestsUtil.getSharedExecutor(), resultReceivers, 1000) { |
|
| 67 | 67 | @Override |
| 68 | 68 | protected Double createResult(Iterable<Number> element) { |
| 69 | 69 | return 0.0; |
| ... | ... | @@ -101,7 +101,7 @@ public class TestProcessorQuery { |
| 101 | 101 | Collection<Processor<Double, ?>> resultReceivers = new ArrayList<>(); |
| 102 | 102 | resultReceivers.add(new AbortResultReceiver(resultReceiver)); |
| 103 | 103 | return new BlockingProcessor<Iterable<Number>, Double>((Class<Iterable<Number>>)(Class<?>) Iterable.class, Double.class, |
| 104 | - ConcurrencyTestsUtil.getExecutor(), resultReceivers, 1000) { |
|
| 104 | + ConcurrencyTestsUtil.getSharedExecutor(), resultReceivers, 1000) { |
|
| 105 | 105 | @Override |
| 106 | 106 | protected Double createResult(Iterable<Number> element) { |
| 107 | 107 | return 0.0; |
| ... | ... | @@ -168,7 +168,7 @@ public class TestProcessorQuery { |
| 168 | 168 | resultReceivers.add(resultReceiver); |
| 169 | 169 | return new AbstractParallelProcessor<Iterable<Number>, Map<GroupKey, Double>>((Class<Iterable<Number>>)(Class<?>) Iterable.class, |
| 170 | 170 | (Class<Map<GroupKey, Double>>)(Class<?>) Map.class, |
| 171 | - ConcurrencyTestsUtil.getExecutor(), |
|
| 171 | + ConcurrencyTestsUtil.getSharedExecutor(), |
|
| 172 | 172 | resultReceivers) { |
| 173 | 173 | @Override |
| 174 | 174 | protected ProcessorInstruction<Map<GroupKey, Double>> createInstruction(final Iterable<Number> element) { |
| ... | ... | @@ -242,7 +242,7 @@ public class TestProcessorQuery { |
| 242 | 242 | resultReceivers.add(resultReceiver); |
| 243 | 243 | return new AbstractParallelProcessor<Double, Map<GroupKey, Double>>(Double.class, |
| 244 | 244 | (Class<Map<GroupKey, Double>>)(Class<?>) Map.class, |
| 245 | - ConcurrencyTestsUtil.getExecutor(), |
|
| 245 | + ConcurrencyTestsUtil.getSharedExecutor(), |
|
| 246 | 246 | resultReceivers) { |
| 247 | 247 | @Override |
| 248 | 248 | protected ProcessorInstruction<Map<GroupKey, Double>> createInstruction(Double element) { |
| ... | ... | @@ -282,7 +282,7 @@ public class TestProcessorQuery { |
| 282 | 282 | resultReceivers.add(resultReceiver); |
| 283 | 283 | return new AbstractParallelProcessor<Double, Map<GroupKey, Double>>(Double.class, |
| 284 | 284 | (Class<Map<GroupKey, Double>>)(Class<?>) Map.class, |
| 285 | - ConcurrencyTestsUtil.getExecutor(), |
|
| 285 | + ConcurrencyTestsUtil.getSharedExecutor(), |
|
| 286 | 286 | resultReceivers) { |
| 287 | 287 | @Override |
| 288 | 288 | protected ProcessorInstruction<Map<GroupKey, Double>> createInstruction(Double element) { |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorElementProcessing.java
| ... | ... | @@ -0,0 +1,152 @@ |
| 1 | +package com.sap.sse.datamining.impl.components; |
|
| 2 | + |
|
| 3 | +import static org.hamcrest.Matchers.is; |
|
| 4 | +import static org.junit.Assert.assertFalse; |
|
| 5 | +import static org.junit.Assert.assertThat; |
|
| 6 | +import static org.junit.Assert.assertTrue; |
|
| 7 | + |
|
| 8 | +import java.util.ArrayList; |
|
| 9 | +import java.util.Collections; |
|
| 10 | +import java.util.List; |
|
| 11 | +import java.util.concurrent.LinkedBlockingQueue; |
|
| 12 | +import java.util.concurrent.ThreadPoolExecutor; |
|
| 13 | +import java.util.concurrent.TimeUnit; |
|
| 14 | + |
|
| 15 | +import org.junit.Before; |
|
| 16 | +import org.junit.Test; |
|
| 17 | + |
|
| 18 | +import com.sap.sse.common.Util.Pair; |
|
| 19 | +import com.sap.sse.datamining.components.AdditionalResultDataBuilder; |
|
| 20 | +import com.sap.sse.datamining.components.Processor; |
|
| 21 | +import com.sap.sse.datamining.components.ProcessorInstruction; |
|
| 22 | +import com.sap.sse.datamining.test.util.ConcurrencyTestsUtil; |
|
| 23 | +import com.sap.sse.datamining.test.util.components.StatefulBlockingInstruction; |
|
| 24 | + |
|
| 25 | +public class TestAbstractParallelProcessorElementProcessing { |
|
| 26 | + |
|
| 27 | + private ThreadPoolExecutor executor; |
|
| 28 | + private Processor<Pair<Long, Integer>, Object> processor; |
|
| 29 | + private List<StatefulBlockingInstruction<?>> createdInstructions; |
|
| 30 | + |
|
| 31 | + @Before |
|
| 32 | + public void initialize() { |
|
| 33 | + int corePoolSize = Runtime.getRuntime().availableProcessors(); |
|
| 34 | + executor = new ThreadPoolExecutor(corePoolSize, corePoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); |
|
| 35 | + createdInstructions = new ArrayList<>(); |
|
| 36 | + |
|
| 37 | + @SuppressWarnings("unchecked") |
|
| 38 | + Class<Pair<Long, Integer>> inputType = (Class<Pair<Long, Integer>>)(Class<?>) Pair.class; |
|
| 39 | + processor = new AbstractParallelProcessor<Pair<Long, Integer>, Object>(inputType, Object.class, executor, Collections.emptySet()) { |
|
| 40 | + @Override |
|
| 41 | + protected ProcessorInstruction<Object> createInstruction(Pair<Long, Integer> sleepTime) { |
|
| 42 | + StatefulBlockingInstruction<Object> instruction = new StatefulBlockingInstruction<>(this, sleepTime.getA(), sleepTime.getB()); |
|
| 43 | + createdInstructions.add(instruction); |
|
| 44 | + return instruction; |
|
| 45 | + } |
|
| 46 | + @Override |
|
| 47 | + protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) { } |
|
| 48 | + }; |
|
| 49 | + } |
|
| 50 | + |
|
| 51 | + @Test |
|
| 52 | + public void testSimpleProcessing() throws InterruptedException { |
|
| 53 | + long stepDuration = 10; |
|
| 54 | + int numberOfSteps = 1; |
|
| 55 | + Pair<Long, Integer> input = new Pair<Long, Integer>(stepDuration, numberOfSteps); |
|
| 56 | + int elementCount = executor.getMaximumPoolSize() * 2; |
|
| 57 | + for (int i = 0; i < elementCount; i++) { |
|
| 58 | + processor.processElement(input); |
|
| 59 | + } |
|
| 60 | + |
|
| 61 | + assertThat("Unexpected amount of created instructions", createdInstructions.size(), is(elementCount)); |
|
| 62 | + double executionTime = Math.ceil((double) elementCount / executor.getMaximumPoolSize()) * stepDuration * numberOfSteps; |
|
| 63 | + executor.shutdown(); |
|
| 64 | + assertTrue("Executor couldn't terminate", executor.awaitTermination((long) (executionTime * 1.2), TimeUnit.SECONDS)); |
|
| 65 | + for (StatefulBlockingInstruction<?> instruction : createdInstructions) { |
|
| 66 | + assertTrue("run wasn't called", instruction.runWasCalled()); |
|
| 67 | + assertTrue("computeResult wasn't called", instruction.computeResultWasCalled()); |
|
| 68 | + assertTrue("computeResult didn't finish", instruction.computeResultWasFinished()); |
|
| 69 | + assertFalse("computeResult was aborted", instruction.computeResultWasAborted()); |
|
| 70 | + } |
|
| 71 | + } |
|
| 72 | + |
|
| 73 | + @Test |
|
| 74 | + public void testProcessingAfterFinish() throws InterruptedException { |
|
| 75 | + long stepDuration = 10; |
|
| 76 | + int numberOfSteps = 5; |
|
| 77 | + Pair<Long, Integer> input = new Pair<Long, Integer>(stepDuration, numberOfSteps); |
|
| 78 | + int elementCount = executor.getMaximumPoolSize() + 1; // Last instruction will be queued |
|
| 79 | + for (int i = 0; i < elementCount; i++) { |
|
| 80 | + processor.processElement(input); |
|
| 81 | + } |
|
| 82 | + assertThat("Unexpected amount of created instructions", createdInstructions.size(), is(elementCount)); |
|
| 83 | + |
|
| 84 | + Thread.sleep(stepDuration); // Giving some time to ensure execution of unqueued instructions |
|
| 85 | + Thread finishingThread = ConcurrencyTestsUtil.tryToFinishTheProcessorInAnotherThread(processor); |
|
| 86 | + do { |
|
| 87 | + Thread.sleep(1); |
|
| 88 | + } while (!finishingThread.isAlive()); |
|
| 89 | + assertFalse("Processor is already finished", processor.isFinished()); |
|
| 90 | + // Processor not yet finished. New elements will be accepted |
|
| 91 | + processor.processElement(input); |
|
| 92 | + elementCount++; |
|
| 93 | + assertThat("Unexpected amount of created instructions", createdInstructions.size(), is(elementCount)); |
|
| 94 | + |
|
| 95 | + finishingThread.join(); |
|
| 96 | + assertTrue("Processor isn't finished", processor.isFinished()); |
|
| 97 | + processor.processElement(input); |
|
| 98 | + assertThat("Unexpected amount of created instructions", createdInstructions.size(), is(elementCount)); |
|
| 99 | + |
|
| 100 | + for (StatefulBlockingInstruction<?> instruction : createdInstructions) { |
|
| 101 | + assertTrue("run wasn't called", instruction.runWasCalled()); |
|
| 102 | + assertTrue("computeResult wasn't called", instruction.computeResultWasCalled()); |
|
| 103 | + assertTrue("computeResult didn't finish", instruction.computeResultWasFinished()); |
|
| 104 | + assertFalse("computeResult was aborted", instruction.computeResultWasAborted()); |
|
| 105 | + } |
|
| 106 | + } |
|
| 107 | + |
|
| 108 | + @Test |
|
| 109 | + public void testProcessingAfterAbort() throws InterruptedException { |
|
| 110 | + long stepDuration = 10; |
|
| 111 | + int numberOfSteps = 5; |
|
| 112 | + Pair<Long, Integer> input = new Pair<Long, Integer>(stepDuration, numberOfSteps); |
|
| 113 | + int elementCount = executor.getMaximumPoolSize() // Set of finished instructions |
|
| 114 | + + executor.getMaximumPoolSize() // Set of started, but not yet finished instructions |
|
| 115 | + + 1; // Scheduled instruction |
|
| 116 | + for (int i = 0; i < elementCount; i++) { |
|
| 117 | + processor.processElement(input); |
|
| 118 | + } |
|
| 119 | + assertThat("Unexpected amount of created instructions", createdInstructions.size(), is(elementCount)); |
|
| 120 | + |
|
| 121 | + long instructionDuration = stepDuration * numberOfSteps; |
|
| 122 | + Thread.sleep(instructionDuration + stepDuration); // Time to finish first set and start second set |
|
| 123 | + processor.abort(); |
|
| 124 | + processor.processElement(new Pair<>(0L, 0)); |
|
| 125 | + assertThat("Unexpected amount of created instructions", createdInstructions.size(), is(elementCount)); |
|
| 126 | + |
|
| 127 | + executor.shutdown(); |
|
| 128 | + assertTrue("Executor couldn't terminate", executor.awaitTermination(2 * stepDuration, TimeUnit.MILLISECONDS)); |
|
| 129 | + for (int i = 0; i < createdInstructions.size(); i++) { |
|
| 130 | + StatefulBlockingInstruction<?> instruction = createdInstructions.get(i); |
|
| 131 | + // run should be called for all instructions |
|
| 132 | + assertTrue("run wasn't called", instruction.runWasCalled()); |
|
| 133 | + if (i < executor.getMaximumPoolSize()) { |
|
| 134 | + // First set of instructions should be processed normally |
|
| 135 | + assertTrue("computeResult wasn't called", instruction.computeResultWasCalled()); |
|
| 136 | + assertTrue("computeResult didn't finish", instruction.computeResultWasFinished()); |
|
| 137 | + assertFalse("computeResult was aborted", instruction.computeResultWasAborted()); |
|
| 138 | + } else if (i < executor.getMaximumPoolSize() * 2) { |
|
| 139 | + // Second set of instructions was running when the processor was aborted. computeResult should be aborted |
|
| 140 | + assertTrue("computeResult wasn't called", instruction.computeResultWasCalled()); |
|
| 141 | + assertTrue("computeResult didn't finish", instruction.computeResultWasFinished()); |
|
| 142 | + assertTrue("computeResult wasn't aborted", instruction.computeResultWasAborted()); |
|
| 143 | + } else { |
|
| 144 | + // Last instructions was still scheduled when the processor was aborted. computeResult should not be called |
|
| 145 | + assertFalse("computeResult of last instruction was called", instruction.computeResultWasCalled()); |
|
| 146 | + assertFalse("computeResult of last instruction finished", instruction.computeResultWasFinished()); |
|
| 147 | + assertFalse("computeResult was aborted", instruction.computeResultWasAborted()); |
|
| 148 | + } |
|
| 149 | + } |
|
| 150 | + } |
|
| 151 | + |
|
| 152 | +} |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorFinishing.java
| ... | ... | @@ -68,7 +68,7 @@ public class TestAbstractParallelProcessorFinishing { |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | 70 | private AbstractParallelProcessor<Integer, Integer> createProcessor(Collection<Processor<Integer, ?>> receivers) { |
| 71 | - return new AbstractParallelProcessor<Integer, Integer>(Integer.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), receivers) { |
|
| 71 | + return new AbstractParallelProcessor<Integer, Integer>(Integer.class, Integer.class, ConcurrencyTestsUtil.getSharedExecutor(), receivers) { |
|
| 72 | 72 | @Override |
| 73 | 73 | protected ProcessorInstruction<Integer> createInstruction(Integer partialElement) { |
| 74 | 74 | return new AbstractProcessorInstruction<Integer>(this) { |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorWithManySimpleInstructions.java
| ... | ... | @@ -37,7 +37,7 @@ public class TestAbstractParallelProcessorWithManySimpleInstructions { |
| 37 | 37 | |
| 38 | 38 | Collection<Processor<Integer, ?>> receivers = new ArrayList<>(); |
| 39 | 39 | receivers.add(receiver); |
| 40 | - processor = new AbstractParallelProcessor<Integer, Integer>(Integer.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), receivers) { |
|
| 40 | + processor = new AbstractParallelProcessor<Integer, Integer>(Integer.class, Integer.class, ConcurrencyTestsUtil.getSharedExecutor(), receivers) { |
|
| 41 | 41 | @Override |
| 42 | 42 | protected ProcessorInstruction<Integer> createInstruction(final Integer element) { |
| 43 | 43 | return new AbstractProcessorInstruction<Integer>(this) { |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestDataRetrieverChainCreation.java
| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | package com.sap.sse.datamining.impl.components; |
| 2 | 2 | |
| 3 | -import static com.sap.sse.datamining.test.util.ConcurrencyTestsUtil.getExecutor; |
|
| 3 | +import static com.sap.sse.datamining.test.util.ConcurrencyTestsUtil.getSharedExecutor; |
|
| 4 | 4 | import static org.hamcrest.Matchers.is; |
| 5 | 5 | import static org.hamcrest.Matchers.not; |
| 6 | 6 | import static org.junit.Assert.assertThat; |
| ... | ... | @@ -90,12 +90,12 @@ public class TestDataRetrieverChainCreation { |
| 90 | 90 | |
| 91 | 91 | assertThat(chainClone, not(dataRetrieverChainDefinition)); |
| 92 | 92 | |
| 93 | - chainClone.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 93 | + chainClone.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | @Test |
| 97 | 97 | public void testThatTheDataRetrieverChainBuilderHasToBeInitialized() { |
| 98 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 98 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 99 | 99 | |
| 100 | 100 | try { |
| 101 | 101 | chainBuilder.getCurrentRetrievedDataType(); |
| ... | ... | @@ -126,7 +126,7 @@ public class TestDataRetrieverChainCreation { |
| 126 | 126 | |
| 127 | 127 | @Test |
| 128 | 128 | public void testStepByStepDataRetrieverChainCreation() throws InterruptedException { |
| 129 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 129 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 130 | 130 | chainBuilder.stepFurther(); //Initialization |
| 131 | 131 | |
| 132 | 132 | assertThat(chainBuilder.getCurrentRetrievedDataType().equals(Test_Regatta.class), is(true)); |
| ... | ... | @@ -206,7 +206,7 @@ public class TestDataRetrieverChainCreation { |
| 206 | 206 | |
| 207 | 207 | @Test(expected=IllegalArgumentException.class) |
| 208 | 208 | public void testSettingAFilterWithWrongElementType() { |
| 209 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 209 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 210 | 210 | chainBuilder.stepFurther(); //Initialization |
| 211 | 211 | |
| 212 | 212 | chainBuilder.setFilter(raceFilter); |
| ... | ... | @@ -214,7 +214,7 @@ public class TestDataRetrieverChainCreation { |
| 214 | 214 | |
| 215 | 215 | @Test(expected=IllegalArgumentException.class) |
| 216 | 216 | public void testSettingAResultReceiverWithWrongInputType() { |
| 217 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 217 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 218 | 218 | chainBuilder.stepFurther(); //Initialization |
| 219 | 219 | |
| 220 | 220 | chainBuilder.addResultReceiver(legReceiver); |
| ... | ... | @@ -253,12 +253,12 @@ public class TestDataRetrieverChainCreation { |
| 253 | 253 | raceRetrieverClass, |
| 254 | 254 | Test_HasRaceContext.class, "race"); |
| 255 | 255 | |
| 256 | - dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 256 | + dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | @Test(expected=IllegalStateException.class) |
| 260 | 260 | public void testSteppingToFar() { |
| 261 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 261 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 262 | 262 | while (chainBuilder.canStepFurther()) { |
| 263 | 263 | chainBuilder.stepFurther(); |
| 264 | 264 | } |
| ... | ... | @@ -272,7 +272,7 @@ public class TestDataRetrieverChainCreation { |
| 272 | 272 | chainWithSettings.endWith(TestLegOfCompetitorWithContextRetrievalProcessor.class, Test_RetrievalProcessorWithSettings.class, Test_HasLegOfCompetitorContext.class, |
| 273 | 273 | Test_RetrievalProcessorSettings.class, new Test_RetrievalProcessorSettings("Default Settings"), "legOfCompetitor"); |
| 274 | 274 | |
| 275 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = chainWithSettings.startBuilding(getExecutor()); |
|
| 275 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = chainWithSettings.startBuilding(getSharedExecutor()); |
|
| 276 | 276 | while (chainBuilder.canStepFurther()) { |
| 277 | 277 | chainBuilder.stepFurther(); |
| 278 | 278 | } |
| ... | ... | @@ -311,7 +311,7 @@ public class TestDataRetrieverChainCreation { |
| 311 | 311 | chainWithSettings.endWith(TestLegOfCompetitorWithContextRetrievalProcessor.class, Test_RetrievalProcessorWithSettings.class, Test_HasLegOfCompetitorContext.class, |
| 312 | 312 | Test_RetrievalProcessorSettings.class, new Test_RetrievalProcessorSettings("Default Settings"), "legOfCompetitor"); |
| 313 | 313 | |
| 314 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = chainWithSettings.startBuilding(getExecutor()); |
|
| 314 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = chainWithSettings.startBuilding(getSharedExecutor()); |
|
| 315 | 315 | while (chainBuilder.canStepFurther()) { |
| 316 | 316 | chainBuilder.stepFurther(); |
| 317 | 317 | } |
| ... | ... | @@ -320,7 +320,7 @@ public class TestDataRetrieverChainCreation { |
| 320 | 320 | |
| 321 | 321 | @Test(expected=IllegalStateException.class) |
| 322 | 322 | public void testRetrieverWithNoSettingsButSettedSettingsCreated() { |
| 323 | - DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getExecutor()); |
|
| 323 | + DataRetrieverChainBuilder<Collection<Test_Regatta>> chainBuilder = dataRetrieverChainDefinition.startBuilding(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 324 | 324 | chainBuilder.stepFurther(); // Initialization |
| 325 | 325 | chainBuilder.setSettings(new WrongSettings()); |
| 326 | 326 | } |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestFilteringProcessors.java
| ... | ... | @@ -34,7 +34,7 @@ public class TestFilteringProcessors { |
| 34 | 34 | return element % 2 == 0; |
| 35 | 35 | } |
| 36 | 36 | }; |
| 37 | - Processor<Integer, Integer> filteringProcessor = new ParallelFilteringProcessor<Integer>(Integer.class, ConcurrencyTestsUtil.getExecutor(), receivers, elementIsEvenCriteria); |
|
| 37 | + Processor<Integer, Integer> filteringProcessor = new ParallelFilteringProcessor<Integer>(Integer.class, ConcurrencyTestsUtil.getSharedExecutor(), receivers, elementIsEvenCriteria); |
|
| 38 | 38 | ConcurrencyTestsUtil.processElements(filteringProcessor, createElementsToProcess()); |
| 39 | 39 | ConcurrencyTestsUtil.sleepFor(100); // Giving the processor time to process the instructions |
| 40 | 40 |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestParallelExtractionProcessor.java
| ... | ... | @@ -63,7 +63,7 @@ public class TestParallelExtractionProcessor { |
| 63 | 63 | |
| 64 | 64 | @Test |
| 65 | 65 | public void testValueExtraction() { |
| 66 | - Processor<GroupedDataEntry<Number>, GroupedDataEntry<Integer>> processor = new ParallelGroupedElementsValueExtractionProcessor<Number, Integer>(ConcurrencyTestsUtil.getExecutor(), receivers, getCrossSumFunction); |
|
| 66 | + Processor<GroupedDataEntry<Number>, GroupedDataEntry<Integer>> processor = new ParallelGroupedElementsValueExtractionProcessor<Number, Integer>(ConcurrencyTestsUtil.getSharedExecutor(), receivers, getCrossSumFunction); |
|
| 67 | 67 | Collection<GroupedDataEntry<Number>> elements = createElements(); |
| 68 | 68 | ConcurrencyTestsUtil.processElements(processor, elements); |
| 69 | 69 | ConcurrencyTestsUtil.sleepFor(100); //Giving the processor time to finish the instructions |
| ... | ... | @@ -81,7 +81,7 @@ public class TestParallelExtractionProcessor { |
| 81 | 81 | |
| 82 | 82 | @Test |
| 83 | 83 | public void testValueExtractionWithInvalidFunction() { |
| 84 | - Processor<GroupedDataEntry<Number>, GroupedDataEntry<Integer>> processor = new ParallelGroupedElementsValueExtractionProcessor<Number, Integer>(ConcurrencyTestsUtil.getExecutor(), receivers, invalidFunction); |
|
| 84 | + Processor<GroupedDataEntry<Number>, GroupedDataEntry<Integer>> processor = new ParallelGroupedElementsValueExtractionProcessor<Number, Integer>(ConcurrencyTestsUtil.getSharedExecutor(), receivers, invalidFunction); |
|
| 85 | 85 | ConcurrencyTestsUtil.processElements(processor, createElements()); |
| 86 | 86 | ConcurrencyTestsUtil.sleepFor(100); //Giving the processor time to finish the instructions |
| 87 | 87 | assertThat("Values have been received, but the processor function is invalid.", receivedValues.isEmpty(), is(true)); |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestParallelMultiDimensionalGroupingProcessor.java
| ... | ... | @@ -57,7 +57,7 @@ public class TestParallelMultiDimensionalGroupingProcessor { |
| 57 | 57 | |
| 58 | 58 | @Test(expected=IllegalArgumentException.class) |
| 59 | 59 | public void testConstructionWithNullDimensions() { |
| 60 | - new ParallelMultiDimensionsValueNestingGroupingProcessor<>(Number.class, ConcurrencyTestsUtil.getExecutor(), receivers, null); |
|
| 60 | + new ParallelMultiDimensionsValueNestingGroupingProcessor<>(Number.class, ConcurrencyTestsUtil.getSharedExecutor(), receivers, null); |
|
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | @Test(expected=IllegalArgumentException.class) |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestRetrieverFilterProcessorChain.java
| ... | ... | @@ -72,7 +72,7 @@ public class TestRetrieverFilterProcessorChain { |
| 72 | 72 | resultReceivers.add(retrievalProcessor); |
| 73 | 73 | @SuppressWarnings("unchecked") |
| 74 | 74 | Processor<Iterable<Iterable<Integer>>, Iterable<Integer>> layeredRetrievalProcessor = new AbstractRetrievalProcessor<Iterable<Iterable<Integer>>, Iterable<Integer>>((Class<Iterable<Iterable<Integer>>>)(Class<?>) Iterable.class, (Class<Iterable<Integer>>)(Class<?>) Iterable.class, |
| 75 | - ConcurrencyTestsUtil.getExecutor(), resultReceivers, 0) { |
|
| 75 | + ConcurrencyTestsUtil.getSharedExecutor(), resultReceivers, 0) { |
|
| 76 | 76 | @Override |
| 77 | 77 | protected Iterable<Iterable<Integer>> retrieveData(Iterable<Iterable<Integer>> element) { |
| 78 | 78 | return element; |
| ... | ... | @@ -110,11 +110,11 @@ public class TestRetrieverFilterProcessorChain { |
| 110 | 110 | return element >= 0; |
| 111 | 111 | } |
| 112 | 112 | }; |
| 113 | - Processor<Integer, Integer> filtrationProcessor = new ParallelFilteringProcessor<>(Integer.class, ConcurrencyTestsUtil.getExecutor(), filtrationResultReceivers, elementGreaterZeroFilterCriteria); |
|
| 113 | + Processor<Integer, Integer> filtrationProcessor = new ParallelFilteringProcessor<>(Integer.class, ConcurrencyTestsUtil.getSharedExecutor(), filtrationResultReceivers, elementGreaterZeroFilterCriteria); |
|
| 114 | 114 | |
| 115 | 115 | Collection<Processor<Integer, ?>> retrievalResultReceivers = new ArrayList<>(); |
| 116 | 116 | retrievalResultReceivers.add(filtrationProcessor); |
| 117 | - retrievalProcessor = new AbstractRetrievalProcessor<Iterable<Integer>, Integer>((Class<Iterable<Integer>>)(Class<?>) Iterable.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), retrievalResultReceivers, 1) { |
|
| 117 | + retrievalProcessor = new AbstractRetrievalProcessor<Iterable<Integer>, Integer>((Class<Iterable<Integer>>)(Class<?>) Iterable.class, Integer.class, ConcurrencyTestsUtil.getSharedExecutor(), retrievalResultReceivers, 1) { |
|
| 118 | 118 | @Override |
| 119 | 119 | protected Iterable<Integer> retrieveData(Iterable<Integer> element) { |
| 120 | 120 | return element; |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/aggregators/TestAbstractStoringParallelAggregationProcessor.java
| ... | ... | @@ -48,7 +48,7 @@ public class TestAbstractStoringParallelAggregationProcessor { |
| 48 | 48 | |
| 49 | 49 | @Test |
| 50 | 50 | public void testAbstractAggregationHandling() throws InterruptedException { |
| 51 | - Processor<GroupedDataEntry<Integer>, Map<GroupKey, Integer>> processor = new AbstractParallelGroupedDataStoringAggregationProcessor<Integer, Integer>(ConcurrencyTestsUtil.getExecutor(), receivers, "Sum") { |
|
| 51 | + Processor<GroupedDataEntry<Integer>, Map<GroupKey, Integer>> processor = new AbstractParallelGroupedDataStoringAggregationProcessor<Integer, Integer>(ConcurrencyTestsUtil.getSharedExecutor(), receivers, "Sum") { |
|
| 52 | 52 | @Override |
| 53 | 53 | protected void storeElement(GroupedDataEntry<Integer> element) { |
| 54 | 54 | elementStore.add(element); |
| ... | ... | @@ -104,7 +104,7 @@ public class TestAbstractStoringParallelAggregationProcessor { |
| 104 | 104 | } |
| 105 | 105 | } |
| 106 | 106 | }); |
| 107 | - Processor<GroupedDataEntry<Integer>, Map<GroupKey, Integer>> processor = new AbstractParallelGroupedDataStoringAggregationProcessor<Integer, Integer>(ConcurrencyTestsUtil.getExecutor(), receivers, "Sum") { |
|
| 107 | + Processor<GroupedDataEntry<Integer>, Map<GroupKey, Integer>> processor = new AbstractParallelGroupedDataStoringAggregationProcessor<Integer, Integer>(ConcurrencyTestsUtil.getSharedExecutor(), receivers, "Sum") { |
|
| 108 | 108 | @Override |
| 109 | 109 | protected void storeElement(GroupedDataEntry<Integer> element) { |
| 110 | 110 | if (element.getDataEntry() < 0) { |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/aggregators/TestParallelAggregationProcessors.java
| ... | ... | @@ -16,7 +16,7 @@ public class TestParallelAggregationProcessors extends AbstractTestParallelAvera |
| 16 | 16 | |
| 17 | 17 | @Test |
| 18 | 18 | public void testSumAggregationProcessor() throws InterruptedException { |
| 19 | - Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> sumAggregationProcessor = ParallelGroupedNumberDataSumAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 19 | + Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> sumAggregationProcessor = ParallelGroupedNumberDataSumAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 20 | 20 | Collection<GroupedDataEntry<Number>> elements = createElements(); |
| 21 | 21 | ConcurrencyTestsUtil.processElements(sumAggregationProcessor, elements); |
| 22 | 22 | |
| ... | ... | @@ -27,7 +27,7 @@ public class TestParallelAggregationProcessors extends AbstractTestParallelAvera |
| 27 | 27 | |
| 28 | 28 | @Test |
| 29 | 29 | public void testMedianAggregationProcessor() throws InterruptedException { |
| 30 | - Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> medianAggregationProcessor = ParallelGroupedNumberDataMedianAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 30 | + Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> medianAggregationProcessor = ParallelGroupedNumberDataMedianAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 31 | 31 | Collection<GroupedDataEntry<Number>> elements = createElements(); |
| 32 | 32 | ConcurrencyTestsUtil.processElements(medianAggregationProcessor, elements); |
| 33 | 33 | |
| ... | ... | @@ -38,7 +38,7 @@ public class TestParallelAggregationProcessors extends AbstractTestParallelAvera |
| 38 | 38 | |
| 39 | 39 | @Test |
| 40 | 40 | public void testMaxAggregationProcessor() throws InterruptedException { |
| 41 | - Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> maxAggregationProcessor = ParallelGroupedNumberDataMaxAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 41 | + Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> maxAggregationProcessor = ParallelGroupedNumberDataMaxAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 42 | 42 | Collection<GroupedDataEntry<Number>> elements = createElements(); |
| 43 | 43 | ConcurrencyTestsUtil.processElements(maxAggregationProcessor, elements); |
| 44 | 44 | |
| ... | ... | @@ -49,7 +49,7 @@ public class TestParallelAggregationProcessors extends AbstractTestParallelAvera |
| 49 | 49 | |
| 50 | 50 | @Test |
| 51 | 51 | public void testMinAggregationProcessor() throws InterruptedException { |
| 52 | - Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> minAggregationProcessor = ParallelGroupedNumberDataMinAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 52 | + Processor<GroupedDataEntry<Number>, Map<GroupKey, Number>> minAggregationProcessor = ParallelGroupedNumberDataMinAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 53 | 53 | Collection<GroupedDataEntry<Number>> elements = createElements(); |
| 54 | 54 | ConcurrencyTestsUtil.processElements(minAggregationProcessor, elements); |
| 55 | 55 | |
| ... | ... | @@ -60,7 +60,7 @@ public class TestParallelAggregationProcessors extends AbstractTestParallelAvera |
| 60 | 60 | |
| 61 | 61 | @Test |
| 62 | 62 | public void testCountAggregationProcessor() throws InterruptedException { |
| 63 | - Processor<GroupedDataEntry<Object>, Map<GroupKey, Number>> countAggregationProcessor = ParallelGroupedDataCountAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 63 | + Processor<GroupedDataEntry<Object>, Map<GroupKey, Number>> countAggregationProcessor = ParallelGroupedDataCountAggregationProcessor.getDefinition().construct(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 64 | 64 | @SuppressWarnings("unchecked") |
| 65 | 65 | Collection<GroupedDataEntry<Object>> elements = (Collection<GroupedDataEntry<Object>>)(Collection<?>) createElements(); |
| 66 | 66 | ConcurrencyTestsUtil.processElements(countAggregationProcessor, elements); |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/aggregators/TestParallelAveragingProcessors.java
| ... | ... | @@ -19,7 +19,7 @@ public class TestParallelAveragingProcessors extends AbstractTestParallelAveragi |
| 19 | 19 | @Test |
| 20 | 20 | public void testAverageAggregationProcessor() throws InterruptedException { |
| 21 | 21 | Processor<GroupedDataEntry<Number>, Map<GroupKey, AverageWithStats<Number>>> averageAggregationProcessor = ParallelGroupedNumberDataAverageAggregationProcessor |
| 22 | - .getDefinition().construct(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 22 | + .getDefinition().construct(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 23 | 23 | Collection<GroupedDataEntry<Number>> elements = createElements(); |
| 24 | 24 | ConcurrencyTestsUtil.processElements(averageAggregationProcessor, elements); |
| 25 | 25 | averageAggregationProcessor.finish(); |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/aggregators/TestParallelGroupedDataCollectingAsSetProcessor.java
| ... | ... | @@ -37,7 +37,7 @@ public class TestParallelGroupedDataCollectingAsSetProcessor { |
| 37 | 37 | |
| 38 | 38 | @Test |
| 39 | 39 | public void testDataCollecting() throws InterruptedException { |
| 40 | - Processor<GroupedDataEntry<Double>, Map<GroupKey, HashSet<Double>>> collectingProcessor = new ParallelGroupedDataCollectingAsSetProcessor<Double>(ConcurrencyTestsUtil.getExecutor(), receivers); |
|
| 40 | + Processor<GroupedDataEntry<Double>, Map<GroupKey, HashSet<Double>>> collectingProcessor = new ParallelGroupedDataCollectingAsSetProcessor<Double>(ConcurrencyTestsUtil.getSharedExecutor(), receivers); |
|
| 41 | 41 | Collection<GroupedDataEntry<Double>> elements = createElements(); |
| 42 | 42 | |
| 43 | 43 | ConcurrencyTestsUtil.processElements(collectingProcessor, elements); |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/functions/TestFunctionManagerAsFunctionRegistry.java
| ... | ... | @@ -63,7 +63,7 @@ public class TestFunctionManagerAsFunctionRegistry { |
| 63 | 63 | DataRetrieverChainDefinitionRegistry dataRetrieverChainDefinitionRegistry = new DataRetrieverChainDefinitionManager(); |
| 64 | 64 | AggregationProcessorDefinitionRegistry aggregationProcessorDefinitionRegistry = new AggregationProcessorDefinitionManager(); |
| 65 | 65 | QueryDefinitionDTORegistry queryDefinitionRegistry = new QueryDefinitionDTOManager(); |
| 66 | - ModifiableDataMiningServer server = new DataMiningServerImpl(ConcurrencyTestsUtil.getExecutor(), functionManager, |
|
| 66 | + ModifiableDataMiningServer server = new DataMiningServerImpl(ConcurrencyTestsUtil.getSharedExecutor(), functionManager, |
|
| 67 | 67 | dataSourceProviderRegistry, |
| 68 | 68 | dataRetrieverChainDefinitionRegistry, |
| 69 | 69 | aggregationProcessorDefinitionRegistry, |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/ComponentTestsUtil.java
| ... | ... | @@ -22,7 +22,7 @@ import com.sap.sse.datamining.test.domain.impl.Test_TeamImpl; |
| 22 | 22 | |
| 23 | 23 | public final class ComponentTestsUtil { |
| 24 | 24 | |
| 25 | - private final static ProcessorFactory processorFactory = new ProcessorFactory(ConcurrencyTestsUtil.getExecutor()); |
|
| 25 | + private final static ProcessorFactory processorFactory = new ProcessorFactory(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 26 | 26 | |
| 27 | 27 | public static ProcessorFactory getProcessorFactory() { |
| 28 | 28 | return processorFactory; |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/ConcurrencyTestsUtil.java
| ... | ... | @@ -19,7 +19,7 @@ public class ConcurrencyTestsUtil extends TestsUtil { |
| 19 | 19 | private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3); |
| 20 | 20 | private static final ExecutorService executor = new DataMiningExecutorService(THREAD_POOL_SIZE); |
| 21 | 21 | |
| 22 | - public static ExecutorService getExecutor() { |
|
| 22 | + public static ExecutorService getSharedExecutor() { |
|
| 23 | 23 | return executor; |
| 24 | 24 | } |
| 25 | 25 | |
| ... | ... | @@ -47,7 +47,7 @@ public class ConcurrencyTestsUtil extends TestsUtil { |
| 47 | 47 | } |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | - public static void tryToFinishTheProcessorInAnotherThread(final Processor<?, ?> processor) { |
|
| 50 | + public static Thread tryToFinishTheProcessorInAnotherThread(final Processor<?, ?> processor) { |
|
| 51 | 51 | Thread finishingThread = new Thread(new Runnable() { |
| 52 | 52 | @Override |
| 53 | 53 | public void run() { |
| ... | ... | @@ -59,6 +59,7 @@ public class ConcurrencyTestsUtil extends TestsUtil { |
| 59 | 59 | } |
| 60 | 60 | }); |
| 61 | 61 | finishingThread.start(); |
| 62 | + return finishingThread; |
|
| 62 | 63 | } |
| 63 | 64 | |
| 64 | 65 | protected ConcurrencyTestsUtil() { |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/TestsUtil.java
| ... | ... | @@ -1,6 +1,7 @@ |
| 1 | 1 | package com.sap.sse.datamining.test.util; |
| 2 | 2 | |
| 3 | 3 | import java.nio.charset.StandardCharsets; |
| 4 | +import java.util.concurrent.ExecutorService; |
|
| 4 | 5 | |
| 5 | 6 | import com.sap.sse.datamining.ModifiableDataMiningServer; |
| 6 | 7 | import com.sap.sse.datamining.components.management.AggregationProcessorDefinitionRegistry; |
| ... | ... | @@ -55,12 +56,16 @@ public class TestsUtil { |
| 55 | 56 | } |
| 56 | 57 | |
| 57 | 58 | public static ModifiableDataMiningServer createNewServer() { |
| 59 | + return createNewServer(ConcurrencyTestsUtil.getSharedExecutor()); |
|
| 60 | + } |
|
| 61 | + |
|
| 62 | + public static ModifiableDataMiningServer createNewServer(ExecutorService executor) { |
|
| 58 | 63 | FunctionRegistry functionRegistry = new FunctionManager(); |
| 59 | 64 | DataSourceProviderRegistry dataSourceProviderRegistry = new DataSourceProviderManager(); |
| 60 | 65 | DataRetrieverChainDefinitionRegistry dataRetrieverChainDefinitionRegistry = new DataRetrieverChainDefinitionManager(); |
| 61 | 66 | AggregationProcessorDefinitionRegistry aggregationProcessorDefinitionRegistry = new AggregationProcessorDefinitionManager(); |
| 62 | 67 | QueryDefinitionDTORegistry queryDefinitionRegistry = new QueryDefinitionDTOManager(); |
| 63 | - return new DataMiningServerImpl(ConcurrencyTestsUtil.getExecutor(), functionRegistry, |
|
| 68 | + return new DataMiningServerImpl(executor, functionRegistry, |
|
| 64 | 69 | dataSourceProviderRegistry, |
| 65 | 70 | dataRetrieverChainDefinitionRegistry, |
| 66 | 71 | aggregationProcessorDefinitionRegistry, |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulBlockingInstruction.java
| ... | ... | @@ -0,0 +1,58 @@ |
| 1 | +package com.sap.sse.datamining.test.util.components; |
|
| 2 | + |
|
| 3 | +import com.sap.sse.datamining.components.ProcessorInstructionHandler; |
|
| 4 | +import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; |
|
| 5 | + |
|
| 6 | +public class StatefulBlockingInstruction<ResultType> extends StatefulProcessorInstruction<ResultType> { |
|
| 7 | + |
|
| 8 | + protected final long stepDuration; |
|
| 9 | + protected final int numberOfSteps; |
|
| 10 | + protected final ResultType result; |
|
| 11 | + |
|
| 12 | + private boolean computeResultWasAborted; |
|
| 13 | + |
|
| 14 | + public StatefulBlockingInstruction(ProcessorInstructionHandler<ResultType> handler, long stepDuration, int numberOfSteps) { |
|
| 15 | + this(handler, 0, stepDuration, numberOfSteps, null); |
|
| 16 | + } |
|
| 17 | + |
|
| 18 | + public StatefulBlockingInstruction(ProcessorInstructionHandler<ResultType> handler, ProcessorInstructionPriority priority, long stepDuration, int numberOfSteps, ResultType result) { |
|
| 19 | + this(handler, priority.asIntValue(), stepDuration, numberOfSteps, result); |
|
| 20 | + } |
|
| 21 | + |
|
| 22 | + public StatefulBlockingInstruction(ProcessorInstructionHandler<ResultType> handler, int priority, long stepDuration, int numberOfSteps, ResultType result) { |
|
| 23 | + super(handler, priority); |
|
| 24 | + this.stepDuration = stepDuration; |
|
| 25 | + this.numberOfSteps = numberOfSteps; |
|
| 26 | + this.result = result; |
|
| 27 | + } |
|
| 28 | + |
|
| 29 | + @Override |
|
| 30 | + protected ResultType internalComputeResult() throws Exception { |
|
| 31 | + if (getTotalBlockDuration() > 0) { |
|
| 32 | + actionBeforeBlock(); |
|
| 33 | + for (int i = 0; i < numberOfSteps; i++) { |
|
| 34 | + if (isAborted()) { |
|
| 35 | + actionBeforeAbort(); |
|
| 36 | + computeResultWasAborted = true; |
|
| 37 | + break; |
|
| 38 | + } |
|
| 39 | + Thread.sleep(stepDuration); |
|
| 40 | + } |
|
| 41 | + actionAfterBlock(); |
|
| 42 | + } |
|
| 43 | + return result; |
|
| 44 | + } |
|
| 45 | + |
|
| 46 | + protected void actionBeforeBlock() { } |
|
| 47 | + protected void actionBeforeAbort() { } |
|
| 48 | + protected void actionAfterBlock() { } |
|
| 49 | + |
|
| 50 | + public long getTotalBlockDuration() { |
|
| 51 | + return stepDuration * numberOfSteps; |
|
| 52 | + } |
|
| 53 | + |
|
| 54 | + public boolean computeResultWasAborted() { |
|
| 55 | + return computeResultWasAborted; |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | +} |
|
| ... | ... | \ No newline at end of file |
java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/StatefulProcessorInstruction.java
| ... | ... | @@ -0,0 +1,54 @@ |
| 1 | +package com.sap.sse.datamining.test.util.components; |
|
| 2 | + |
|
| 3 | +import com.sap.sse.datamining.components.ProcessorInstructionHandler; |
|
| 4 | +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; |
|
| 5 | +import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; |
|
| 6 | + |
|
| 7 | +public abstract class StatefulProcessorInstruction<ResultType> extends AbstractProcessorInstruction<ResultType> { |
|
| 8 | + |
|
| 9 | + private boolean runWasCalled; |
|
| 10 | + private boolean computeResultWasCalled; |
|
| 11 | + private boolean computeResultWasFinished; |
|
| 12 | + |
|
| 13 | + public StatefulProcessorInstruction(ProcessorInstructionHandler<ResultType> processor, int priority) { |
|
| 14 | + super(processor, priority); |
|
| 15 | + } |
|
| 16 | + |
|
| 17 | + public StatefulProcessorInstruction(ProcessorInstructionHandler<ResultType> handler, |
|
| 18 | + ProcessorInstructionPriority priority) { |
|
| 19 | + super(handler, priority); |
|
| 20 | + } |
|
| 21 | + |
|
| 22 | + public StatefulProcessorInstruction(ProcessorInstructionHandler<ResultType> handler) { |
|
| 23 | + super(handler); |
|
| 24 | + } |
|
| 25 | + |
|
| 26 | + @Override |
|
| 27 | + public void run() { |
|
| 28 | + runWasCalled = true; |
|
| 29 | + super.run(); |
|
| 30 | + } |
|
| 31 | + |
|
| 32 | + @Override |
|
| 33 | + protected ResultType computeResult() throws Exception { |
|
| 34 | + computeResultWasCalled = true; |
|
| 35 | + ResultType result = internalComputeResult(); |
|
| 36 | + computeResultWasFinished = true; |
|
| 37 | + return result; |
|
| 38 | + } |
|
| 39 | + |
|
| 40 | + protected abstract ResultType internalComputeResult() throws Exception; |
|
| 41 | + |
|
| 42 | + public boolean runWasCalled() { |
|
| 43 | + return runWasCalled; |
|
| 44 | + } |
|
| 45 | + |
|
| 46 | + public boolean computeResultWasCalled() { |
|
| 47 | + return computeResultWasCalled; |
|
| 48 | + } |
|
| 49 | + |
|
| 50 | + public boolean computeResultWasFinished() { |
|
| 51 | + return computeResultWasFinished; |
|
| 52 | + } |
|
| 53 | + |
|
| 54 | +} |
java/com.sap.sse.datamining.ui/.project
| ... | ... | @@ -21,12 +21,12 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 24 | + <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | 25 | <arguments> |
| 26 | 26 | </arguments> |
| 27 | 27 | </buildCommand> |
| 28 | 28 | <buildCommand> |
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 29 | + <name>com.gwtplugins.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | 30 | <arguments> |
| 31 | 31 | </arguments> |
| 32 | 32 | </buildCommand> |
| ... | ... | @@ -34,6 +34,6 @@ |
| 34 | 34 | <natures> |
| 35 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 36 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 37 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 38 | 38 | </natures> |
| 39 | 39 | </projectDescription> |
java/com.sap.sse.datamining.ui/META-INF/MANIFEST.MF
| ... | ... | @@ -17,7 +17,6 @@ Export-Package: com.sap.sse.datamining.ui.client, |
| 17 | 17 | com.sap.sse.datamining.ui.client.presentation, |
| 18 | 18 | com.sap.sse.datamining.ui.client.presentation.dataproviders, |
| 19 | 19 | com.sap.sse.datamining.ui.client.selection, |
| 20 | - com.sap.sse.datamining.ui.client.selection.filter, |
|
| 21 | 20 | com.sap.sse.datamining.ui.client.settings |
| 22 | 21 | Bundle-ActivationPolicy: lazy |
| 23 | 22 | Automatic-Module-Name: com.sap.sse.datamining.ui |
java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/DimensionFilterSelectionProvider.java
| ... | ... | @@ -0,0 +1,371 @@ |
| 1 | +package com.sap.sse.datamining.ui.client.selection; |
|
| 2 | + |
|
| 3 | +import java.io.Serializable; |
|
| 4 | +import java.util.ArrayList; |
|
| 5 | +import java.util.Collection; |
|
| 6 | +import java.util.Collections; |
|
| 7 | +import java.util.HashMap; |
|
| 8 | +import java.util.HashSet; |
|
| 9 | +import java.util.List; |
|
| 10 | +import java.util.Map; |
|
| 11 | +import java.util.Set; |
|
| 12 | + |
|
| 13 | +import com.google.gwt.cell.client.CheckboxCell; |
|
| 14 | +import com.google.gwt.core.client.Scheduler; |
|
| 15 | +import com.google.gwt.core.shared.GWT; |
|
| 16 | +import com.google.gwt.dom.client.BrowserEvents; |
|
| 17 | +import com.google.gwt.dom.client.NativeEvent; |
|
| 18 | +import com.google.gwt.dom.client.Style.TextAlign; |
|
| 19 | +import com.google.gwt.dom.client.Style.Unit; |
|
| 20 | +import com.google.gwt.i18n.client.LocaleInfo; |
|
| 21 | +import com.google.gwt.user.cellview.client.Column; |
|
| 22 | +import com.google.gwt.user.cellview.client.DataGrid; |
|
| 23 | +import com.google.gwt.user.cellview.client.TextColumn; |
|
| 24 | +import com.google.gwt.user.client.ui.DockLayoutPanel; |
|
| 25 | +import com.google.gwt.user.client.ui.HasHorizontalAlignment; |
|
| 26 | +import com.google.gwt.user.client.ui.HasVerticalAlignment; |
|
| 27 | +import com.google.gwt.user.client.ui.HorizontalPanel; |
|
| 28 | +import com.google.gwt.user.client.ui.Image; |
|
| 29 | +import com.google.gwt.user.client.ui.Label; |
|
| 30 | +import com.google.gwt.user.client.ui.LayoutPanel; |
|
| 31 | +import com.google.gwt.user.client.ui.ToggleButton; |
|
| 32 | +import com.google.gwt.user.client.ui.Widget; |
|
| 33 | +import com.google.gwt.view.client.CellPreviewEvent; |
|
| 34 | +import com.google.gwt.view.client.DefaultSelectionEventManager; |
|
| 35 | +import com.google.gwt.view.client.DefaultSelectionEventManager.EventTranslator; |
|
| 36 | +import com.google.gwt.view.client.DefaultSelectionEventManager.SelectAction; |
|
| 37 | +import com.google.gwt.view.client.ListDataProvider; |
|
| 38 | +import com.google.gwt.view.client.MultiSelectionModel; |
|
| 39 | +import com.google.gwt.view.client.SelectionChangeEvent; |
|
| 40 | +import com.sap.sse.common.settings.SerializableSettings; |
|
| 41 | +import com.sap.sse.common.util.NaturalComparator; |
|
| 42 | +import com.sap.sse.datamining.shared.DataMiningSession; |
|
| 43 | +import com.sap.sse.datamining.shared.GroupKey; |
|
| 44 | +import com.sap.sse.datamining.shared.impl.GenericGroupKey; |
|
| 45 | +import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; |
|
| 46 | +import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; |
|
| 47 | +import com.sap.sse.datamining.shared.impl.dto.QueryResultDTO; |
|
| 48 | +import com.sap.sse.datamining.ui.client.DataMiningServiceAsync; |
|
| 49 | +import com.sap.sse.datamining.ui.client.DataRetrieverChainDefinitionProvider; |
|
| 50 | +import com.sap.sse.datamining.ui.client.FilterSelectionChangedListener; |
|
| 51 | +import com.sap.sse.datamining.ui.client.FilterSelectionProvider; |
|
| 52 | +import com.sap.sse.datamining.ui.client.ManagedDataMiningQueriesCounter; |
|
| 53 | +import com.sap.sse.datamining.ui.client.execution.ManagedDataMiningQueryCallback; |
|
| 54 | +import com.sap.sse.datamining.ui.client.execution.SimpleManagedDataMiningQueriesCounter; |
|
| 55 | +import com.sap.sse.datamining.ui.client.resources.DataMiningDataGridResources; |
|
| 56 | +import com.sap.sse.datamining.ui.client.resources.DataMiningResources; |
|
| 57 | +import com.sap.sse.gwt.client.ErrorReporter; |
|
| 58 | +import com.sap.sse.gwt.client.controls.busyindicator.SimpleBusyIndicator; |
|
| 59 | +import com.sap.sse.gwt.client.panels.AbstractFilterablePanel; |
|
| 60 | +import com.sap.sse.gwt.client.shared.components.AbstractComponent; |
|
| 61 | +import com.sap.sse.gwt.client.shared.components.Component; |
|
| 62 | +import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; |
|
| 63 | +import com.sap.sse.gwt.client.shared.settings.ComponentContext; |
|
| 64 | + |
|
| 65 | +public class DimensionFilterSelectionProvider extends AbstractComponent<SerializableSettings> { |
|
| 66 | + |
|
| 67 | + private static final DataMiningResources resources = GWT.create(DataMiningResources.class); |
|
| 68 | + private static final NaturalComparator NaturalComparator = new NaturalComparator(); |
|
| 69 | + |
|
| 70 | + private final DataMiningServiceAsync dataMiningService; |
|
| 71 | + private final ErrorReporter errorReporter; |
|
| 72 | + private final DataMiningSession session; |
|
| 73 | + private final ManagedDataMiningQueriesCounter counter; |
|
| 74 | + private final Set<FilterSelectionChangedListener> listeners; |
|
| 75 | + |
|
| 76 | + private final DataRetrieverChainDefinitionProvider retrieverChainProvider; |
|
| 77 | + private final FilterSelectionProvider filterSelectionProvider; |
|
| 78 | + |
|
| 79 | + private final DataRetrieverLevelDTO retrieverLevel; |
|
| 80 | + private final FunctionDTO dimension; |
|
| 81 | + private final Set<Serializable> selectionToBeApplied; |
|
| 82 | + |
|
| 83 | + private final DockLayoutPanel mainPanel; |
|
| 84 | + private final AbstractFilterablePanel<Serializable> filterPanel; |
|
| 85 | + private final LayoutPanel contentContainer; |
|
| 86 | + private final SimpleBusyIndicator busyIndicator; |
|
| 87 | + |
|
| 88 | + private final ListDataProvider<Serializable> filteredData; |
|
| 89 | + private final MultiSelectionModel<Serializable> selectionModel; |
|
| 90 | + private final DataGrid<Serializable> dataGrid; |
|
| 91 | + private final Column<Serializable, Boolean> checkboxColumn; |
|
| 92 | + |
|
| 93 | + public DimensionFilterSelectionProvider(Component<?> parent, ComponentContext<?> componentContext, DataMiningServiceAsync dataMiningService, |
|
| 94 | + ErrorReporter errorReporter, DataMiningSession session, DataRetrieverChainDefinitionProvider retrieverChainProvider, |
|
| 95 | + FilterSelectionProvider filterSelectionProvider, DataRetrieverLevelDTO retrieverLevel, FunctionDTO dimension) { |
|
| 96 | + super(parent, componentContext); |
|
| 97 | + this.dataMiningService = dataMiningService; |
|
| 98 | + this.errorReporter = errorReporter; |
|
| 99 | + this.session = session; |
|
| 100 | + this.retrieverChainProvider = retrieverChainProvider; |
|
| 101 | + this.filterSelectionProvider = filterSelectionProvider; |
|
| 102 | + this.retrieverLevel = retrieverLevel; |
|
| 103 | + this.dimension = dimension; |
|
| 104 | + |
|
| 105 | + counter = new SimpleManagedDataMiningQueriesCounter(); |
|
| 106 | + listeners = new HashSet<>(); |
|
| 107 | + selectionToBeApplied = new HashSet<>(); |
|
| 108 | + |
|
| 109 | + DataMiningDataGridResources dataGridResources = GWT.create(DataMiningDataGridResources.class); |
|
| 110 | + dataGrid = new DataGrid<>(Integer.MAX_VALUE, dataGridResources); |
|
| 111 | + dataGrid.setAutoHeaderRefreshDisabled(true); |
|
| 112 | + dataGrid.setAutoFooterRefreshDisabled(true); |
|
| 113 | + dataGrid.addStyleName("dataMiningBorderTop"); |
|
| 114 | + |
|
| 115 | + filteredData = new ListDataProvider<Serializable>(this::elementAsString); |
|
| 116 | + filterPanel = new AbstractFilterablePanel<Serializable>(null, dataGrid, filteredData) { |
|
| 117 | + @Override |
|
| 118 | + public Iterable<String> getSearchableStrings(Serializable element) { |
|
| 119 | + return Collections.singleton(elementAsString(element)); |
|
| 120 | + } |
|
| 121 | + }; |
|
| 122 | + filterPanel.setWidth("100%"); |
|
| 123 | + filterPanel.setSpacing(1); |
|
| 124 | + filterPanel.getTextBox().setWidth("100%"); |
|
| 125 | + filterPanel.getAllListDataProvider().addDataDisplay(dataGrid); |
|
| 126 | + |
|
| 127 | + selectionModel = new MultiSelectionModel<>(this::elementAsString); |
|
| 128 | + selectionModel.addSelectionChangeHandler(this::selectionChanged); |
|
| 129 | + dataGrid.setSelectionModel(selectionModel, DefaultSelectionEventManager.createCustomManager(new CustomCheckboxEventTranslator())); |
|
| 130 | + |
|
| 131 | + checkboxColumn = new Column<Serializable, Boolean>(new CheckboxCell(true, false)) { |
|
| 132 | + @Override |
|
| 133 | + public Boolean getValue(Serializable object) { |
|
| 134 | + return selectionModel.isSelected(object); |
|
| 135 | + } |
|
| 136 | + }; |
|
| 137 | + dataGrid.addColumn(checkboxColumn); |
|
| 138 | + TextColumn<Serializable> contentColumn = new TextColumn<Serializable>() { |
|
| 139 | + @Override |
|
| 140 | + public String getValue(Serializable element) { |
|
| 141 | + return elementAsString(element); |
|
| 142 | + } |
|
| 143 | + }; |
|
| 144 | + contentColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); |
|
| 145 | + dataGrid.addColumn(contentColumn); |
|
| 146 | + |
|
| 147 | + busyIndicator = new SimpleBusyIndicator(false, 0.85f); |
|
| 148 | + busyIndicator.getElement().getStyle().setTextAlign(TextAlign.CENTER); |
|
| 149 | + |
|
| 150 | + contentContainer = new LayoutPanel(); |
|
| 151 | + contentContainer.add(busyIndicator); |
|
| 152 | + contentContainer.setWidgetTopBottom(busyIndicator, 10, Unit.PX, 10, Unit.PX); |
|
| 153 | + contentContainer.setWidgetLeftRight(busyIndicator, 10, Unit.PX, 10, Unit.PX); |
|
| 154 | + |
|
| 155 | + mainPanel = new DockLayoutPanel(Unit.PX); |
|
| 156 | + mainPanel.addNorth(createHeaderPanel(), 40); |
|
| 157 | + mainPanel.addNorth(filterPanel, 35); |
|
| 158 | + mainPanel.setWidgetHidden(filterPanel, true); |
|
| 159 | + mainPanel.add(contentContainer); |
|
| 160 | + |
|
| 161 | + updateContent(null); |
|
| 162 | + } |
|
| 163 | + |
|
| 164 | + private Widget createHeaderPanel() { |
|
| 165 | + HorizontalPanel headerPanel = new HorizontalPanel(); |
|
| 166 | + headerPanel.setSpacing(2); |
|
| 167 | + headerPanel.setWidth("100%"); |
|
| 168 | + headerPanel.setHeight("100%"); |
|
| 169 | + headerPanel.addStyleName("dimensionFilterSelectionHeader"); |
|
| 170 | + headerPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); |
|
| 171 | + |
|
| 172 | + Label headerLabel = new Label(dimension.getDisplayName()); |
|
| 173 | + headerPanel.add(headerLabel); |
|
| 174 | + headerPanel.setCellWidth(headerLabel, "100%"); |
|
| 175 | + headerPanel.setCellHorizontalAlignment(headerLabel, HasHorizontalAlignment.ALIGN_CENTER); |
|
| 176 | + |
|
| 177 | + ToggleButton toggleFilterButton = new ToggleButton(new Image(resources.searchIcon())); |
|
| 178 | + toggleFilterButton.addClickHandler(e -> { |
|
| 179 | + boolean enabled = toggleFilterButton.isDown(); |
|
| 180 | + mainPanel.setWidgetHidden(filterPanel, !enabled); |
|
| 181 | + if (enabled) { |
|
| 182 | + Scheduler.get().scheduleDeferred(() -> { |
|
| 183 | + filterPanel.getTextBox().setFocus(true); |
|
| 184 | + filterPanel.getTextBox().selectAll(); |
|
| 185 | + }); |
|
| 186 | + } |
|
| 187 | + |
|
| 188 | + ListDataProvider<Serializable> oldProvider = enabled ? filterPanel.getAllListDataProvider(): filteredData; |
|
| 189 | + ListDataProvider<Serializable> newProvider = enabled ? filteredData : filterPanel.getAllListDataProvider(); |
|
| 190 | + oldProvider.removeDataDisplay(dataGrid); |
|
| 191 | + newProvider.addDataDisplay(dataGrid); |
|
| 192 | + }); |
|
| 193 | + headerPanel.add(toggleFilterButton); |
|
| 194 | + headerPanel.setCellHorizontalAlignment(toggleFilterButton, HasHorizontalAlignment.ALIGN_RIGHT); |
|
| 195 | + |
|
| 196 | + return headerPanel; |
|
| 197 | + } |
|
| 198 | + |
|
| 199 | + public void updateContent(Runnable callback) { |
|
| 200 | + HashMap<DataRetrieverLevelDTO,SerializableSettings> retrieverSettings = retrieverChainProvider.getRetrieverSettings(); |
|
| 201 | + HashMap<DataRetrieverLevelDTO, HashMap<FunctionDTO, HashSet<? extends Serializable>>> filterSelection = filterSelectionProvider.getSelection(); |
|
| 202 | + if (filterSelection.containsKey(retrieverLevel)) { |
|
| 203 | + filterSelection.get(retrieverLevel).remove(dimension); |
|
| 204 | + } |
|
| 205 | + HashSet<FunctionDTO> dimensions = new HashSet<>(); |
|
| 206 | + dimensions.add(dimension); |
|
| 207 | + |
|
| 208 | + counter.increase(); |
|
| 209 | + contentContainer.remove(dataGrid); |
|
| 210 | + busyIndicator.setBusy(true); |
|
| 211 | + dataMiningService.getDimensionValuesFor(session, retrieverChainProvider.getDataRetrieverChainDefinition(), retrieverLevel, dimensions, |
|
| 212 | + retrieverSettings, filterSelection, LocaleInfo.getCurrentLocale().getLocaleName(), new ManagedDataMiningQueryCallback<HashSet<Object>>(counter) { |
|
| 213 | + @SuppressWarnings("unchecked") |
|
| 214 | + @Override |
|
| 215 | + protected void handleSuccess(QueryResultDTO<HashSet<Object>> result) { |
|
| 216 | + Map<GroupKey, HashSet<Object>> results = result.getResults(); |
|
| 217 | + List<Serializable> content = new ArrayList<>(); |
|
| 218 | + |
|
| 219 | + if (!results.isEmpty()) { |
|
| 220 | + GroupKey contentKey = new GenericGroupKey<FunctionDTO>(dimension); |
|
| 221 | + content.addAll((Collection<? extends Serializable>) results.get(contentKey)); |
|
| 222 | + content.sort((o1, o2) -> NaturalComparator.compare(o1.toString(), o2.toString())); |
|
| 223 | + } |
|
| 224 | + |
|
| 225 | + busyIndicator.setBusy(false); |
|
| 226 | + filterPanel.updateAll(content); |
|
| 227 | + contentContainer.add(dataGrid); |
|
| 228 | + |
|
| 229 | + internalSetSelection(!selectionToBeApplied.isEmpty() ? selectionToBeApplied : selectionModel.getSelectedSet()); |
|
| 230 | + selectionToBeApplied.clear(); |
|
| 231 | + |
|
| 232 | + if (callback != null) { |
|
| 233 | + callback.run(); |
|
| 234 | + } |
|
| 235 | + } |
|
| 236 | + @Override |
|
| 237 | + protected void handleFailure(Throwable caught) { |
|
| 238 | + errorReporter.reportError("Error fetching the dimension values of " + dimension + ": " + caught.getMessage()); |
|
| 239 | + } |
|
| 240 | + }); |
|
| 241 | + } |
|
| 242 | + |
|
| 243 | + private String elementAsString(Object element) { |
|
| 244 | + return element.toString(); |
|
| 245 | + } |
|
| 246 | + |
|
| 247 | + private void selectionChanged(SelectionChangeEvent event) { |
|
| 248 | + notifyListeners(); |
|
| 249 | + } |
|
| 250 | + |
|
| 251 | + public HashSet<? extends Serializable> getSelection() { |
|
| 252 | + return new HashSet<>(selectionModel.getSelectedSet()); |
|
| 253 | + } |
|
| 254 | + |
|
| 255 | + public void setSelection(Iterable<? extends Serializable> items) { |
|
| 256 | + selectionToBeApplied.clear(); |
|
| 257 | + for (Serializable item : items) { |
|
| 258 | + selectionToBeApplied.add(item); |
|
| 259 | + } |
|
| 260 | + |
|
| 261 | + if (!busyIndicator.isBusy()) { |
|
| 262 | + internalSetSelection(selectionToBeApplied); |
|
| 263 | + selectionToBeApplied.clear(); |
|
| 264 | + } |
|
| 265 | + } |
|
| 266 | + |
|
| 267 | + private void internalSetSelection(Set<? extends Serializable> selection) { |
|
| 268 | + clearSelection(); |
|
| 269 | + if (!selection.isEmpty()) { |
|
| 270 | + for (Serializable item : filterPanel.getAll()) { |
|
| 271 | + if (selection.contains(item)) { |
|
| 272 | + selectionModel.setSelected(item, true); |
|
| 273 | + } |
|
| 274 | + } |
|
| 275 | + } |
|
| 276 | + } |
|
| 277 | + |
|
| 278 | + public void clearSelection() { |
|
| 279 | + selectionModel.clear(); |
|
| 280 | + } |
|
| 281 | + |
|
| 282 | + public void addListener(FilterSelectionChangedListener listener) { |
|
| 283 | + listeners.add(listener); |
|
| 284 | + } |
|
| 285 | + |
|
| 286 | + private void notifyListeners() { |
|
| 287 | + for (FilterSelectionChangedListener listener : listeners) { |
|
| 288 | + listener.selectionChanged(); |
|
| 289 | + } |
|
| 290 | + } |
|
| 291 | + |
|
| 292 | + @Override |
|
| 293 | + public Widget getEntryWidget() { |
|
| 294 | + return mainPanel; |
|
| 295 | + } |
|
| 296 | + |
|
| 297 | + @Override |
|
| 298 | + public String getId() { |
|
| 299 | + return "DimensionFilterSelectionProvider"; |
|
| 300 | + } |
|
| 301 | + |
|
| 302 | + @Override |
|
| 303 | + public String getLocalizedShortName() { |
|
| 304 | + return getClass().getSimpleName(); |
|
| 305 | + } |
|
| 306 | + |
|
| 307 | + @Override |
|
| 308 | + public boolean isVisible() { |
|
| 309 | + return getEntryWidget().isVisible(); |
|
| 310 | + } |
|
| 311 | + |
|
| 312 | + @Override |
|
| 313 | + public void setVisible(boolean visibility) { |
|
| 314 | + getEntryWidget().setVisible(visibility); |
|
| 315 | + } |
|
| 316 | + |
|
| 317 | + @Override |
|
| 318 | + public boolean hasSettings() { |
|
| 319 | + return false; |
|
| 320 | + } |
|
| 321 | + |
|
| 322 | + @Override |
|
| 323 | + public SettingsDialogComponent<SerializableSettings> getSettingsDialogComponent(SerializableSettings settings) { |
|
| 324 | + return null; |
|
| 325 | + } |
|
| 326 | + |
|
| 327 | + @Override |
|
| 328 | + public SerializableSettings getSettings() { |
|
| 329 | + return null; |
|
| 330 | + } |
|
| 331 | + |
|
| 332 | + @Override |
|
| 333 | + public void updateSettings(SerializableSettings newSettings) { |
|
| 334 | + // no-op |
|
| 335 | + } |
|
| 336 | + |
|
| 337 | + @Override |
|
| 338 | + public String getDependentCssClassName() { |
|
| 339 | + return "dimensionFilterSelectionProvider"; |
|
| 340 | + } |
|
| 341 | + |
|
| 342 | + private class CustomCheckboxEventTranslator implements EventTranslator<Serializable> { |
|
| 343 | + |
|
| 344 | + @Override |
|
| 345 | + public boolean clearCurrentSelection(CellPreviewEvent<Serializable> event) { |
|
| 346 | + return !isCheckboxColumn(event.getColumn()); |
|
| 347 | + } |
|
| 348 | + |
|
| 349 | + @Override |
|
| 350 | + public SelectAction translateSelectionEvent(CellPreviewEvent<Serializable> event) { |
|
| 351 | + NativeEvent nativeEvent = event.getNativeEvent(); |
|
| 352 | + if (BrowserEvents.CLICK.equals(nativeEvent.getType())) { |
|
| 353 | + if (nativeEvent.getCtrlKey()) { |
|
| 354 | + Serializable value = event.getValue(); |
|
| 355 | + selectionModel.setSelected(value, !selectionModel.isSelected(value)); |
|
| 356 | + return SelectAction.IGNORE; |
|
| 357 | + } |
|
| 358 | + if (!selectionModel.getSelectedSet().isEmpty() && !isCheckboxColumn(event.getColumn())) { |
|
| 359 | + return SelectAction.DEFAULT; |
|
| 360 | + } |
|
| 361 | + } |
|
| 362 | + return SelectAction.TOGGLE; |
|
| 363 | + } |
|
| 364 | + |
|
| 365 | + private boolean isCheckboxColumn(int columnIndex) { |
|
| 366 | + return columnIndex == dataGrid.getColumnIndex(checkboxColumn); |
|
| 367 | + } |
|
| 368 | + |
|
| 369 | + } |
|
| 370 | + |
|
| 371 | +} |
java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/HierarchicalDimensionListFilterSelectionProvider.java
| ... | ... | @@ -0,0 +1,618 @@ |
| 1 | +package com.sap.sse.datamining.ui.client.selection; |
|
| 2 | + |
|
| 3 | +import java.io.Serializable; |
|
| 4 | +import java.util.ArrayList; |
|
| 5 | +import java.util.Collection; |
|
| 6 | +import java.util.Collections; |
|
| 7 | +import java.util.HashMap; |
|
| 8 | +import java.util.HashSet; |
|
| 9 | +import java.util.Iterator; |
|
| 10 | +import java.util.List; |
|
| 11 | +import java.util.Map; |
|
| 12 | +import java.util.Map.Entry; |
|
| 13 | +import java.util.Objects; |
|
| 14 | +import java.util.Set; |
|
| 15 | +import java.util.stream.Collectors; |
|
| 16 | + |
|
| 17 | +import com.google.gwt.cell.client.CheckboxCell; |
|
| 18 | +import com.google.gwt.core.client.GWT; |
|
| 19 | +import com.google.gwt.dom.builder.shared.TableCellBuilder; |
|
| 20 | +import com.google.gwt.dom.builder.shared.TableRowBuilder; |
|
| 21 | +import com.google.gwt.dom.client.Element; |
|
| 22 | +import com.google.gwt.dom.client.NativeEvent; |
|
| 23 | +import com.google.gwt.dom.client.NodeList; |
|
| 24 | +import com.google.gwt.dom.client.Style.Unit; |
|
| 25 | +import com.google.gwt.dom.client.TableCellElement; |
|
| 26 | +import com.google.gwt.dom.client.TableRowElement; |
|
| 27 | +import com.google.gwt.i18n.client.LocaleInfo; |
|
| 28 | +import com.google.gwt.user.cellview.client.AbstractCellTable; |
|
| 29 | +import com.google.gwt.user.cellview.client.Column; |
|
| 30 | +import com.google.gwt.user.cellview.client.DataGrid; |
|
| 31 | +import com.google.gwt.user.cellview.client.RowHoverEvent; |
|
| 32 | +import com.google.gwt.user.cellview.client.TextColumn; |
|
| 33 | +import com.google.gwt.user.client.rpc.AsyncCallback; |
|
| 34 | +import com.google.gwt.user.client.ui.DockLayoutPanel; |
|
| 35 | +import com.google.gwt.user.client.ui.Label; |
|
| 36 | +import com.google.gwt.user.client.ui.ScrollPanel; |
|
| 37 | +import com.google.gwt.user.client.ui.Widget; |
|
| 38 | +import com.google.gwt.view.client.CellPreviewEvent; |
|
| 39 | +import com.google.gwt.view.client.DefaultSelectionEventManager; |
|
| 40 | +import com.google.gwt.view.client.DefaultSelectionEventManager.EventTranslator; |
|
| 41 | +import com.google.gwt.view.client.DefaultSelectionEventManager.SelectAction; |
|
| 42 | +import com.google.gwt.view.client.ListDataProvider; |
|
| 43 | +import com.google.gwt.view.client.MultiSelectionModel; |
|
| 44 | +import com.google.gwt.view.client.SelectionChangeEvent; |
|
| 45 | +import com.sap.sse.common.settings.SerializableSettings; |
|
| 46 | +import com.sap.sse.datamining.shared.DataMiningSession; |
|
| 47 | +import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO; |
|
| 48 | +import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO; |
|
| 49 | +import com.sap.sse.datamining.shared.impl.dto.DataRetrieverLevelDTO; |
|
| 50 | +import com.sap.sse.datamining.shared.impl.dto.FunctionDTO; |
|
| 51 | +import com.sap.sse.datamining.shared.impl.dto.ReducedDimensionsDTO; |
|
| 52 | +import com.sap.sse.datamining.ui.client.DataMiningServiceAsync; |
|
| 53 | +import com.sap.sse.datamining.ui.client.DataRetrieverChainDefinitionProvider; |
|
| 54 | +import com.sap.sse.datamining.ui.client.FilterSelectionChangedListener; |
|
| 55 | +import com.sap.sse.datamining.ui.client.FilterSelectionPresenter; |
|
| 56 | +import com.sap.sse.datamining.ui.client.FilterSelectionProvider; |
|
| 57 | +import com.sap.sse.datamining.ui.client.StringMessages; |
|
| 58 | +import com.sap.sse.datamining.ui.client.presentation.PlainFilterSelectionPresenter; |
|
| 59 | +import com.sap.sse.datamining.ui.client.resources.DataMiningDataGridResources; |
|
| 60 | +import com.sap.sse.datamining.ui.client.resources.DataMiningDataGridResources.DataMiningDataGridStyle; |
|
| 61 | +import com.sap.sse.gwt.client.ErrorReporter; |
|
| 62 | +import com.sap.sse.gwt.client.celltable.BaseCellTableBuilder; |
|
| 63 | +import com.sap.sse.gwt.client.panels.AbstractFilterablePanel; |
|
| 64 | +import com.sap.sse.gwt.client.shared.components.AbstractComponent; |
|
| 65 | +import com.sap.sse.gwt.client.shared.components.Component; |
|
| 66 | +import com.sap.sse.gwt.client.shared.components.SettingsDialogComponent; |
|
| 67 | +import com.sap.sse.gwt.client.shared.settings.ComponentContext; |
|
| 68 | + |
|
| 69 | +public class HierarchicalDimensionListFilterSelectionProvider extends AbstractComponent<SerializableSettings> implements FilterSelectionProvider { |
|
| 70 | + |
|
| 71 | + private final static String DimensionListSubheaderAttribute = "subheader"; |
|
| 72 | + |
|
| 73 | + private static final Unit LayoutUnit = Unit.PX; |
|
| 74 | + private static final double SelectionPresenterHeight = 100; |
|
| 75 | + private static final double DimensionSelectionWidth = 300; |
|
| 76 | + private static final double DimensionSelectionHeaderHeight = 40; |
|
| 77 | + private static final double FilterSelectionTableWidth = 250; |
|
| 78 | + |
|
| 79 | + private final DataMiningSession session; |
|
| 80 | + private final DataMiningServiceAsync dataMiningService; |
|
| 81 | + private final ErrorReporter errorReporter; |
|
| 82 | + private final DataRetrieverChainDefinitionProvider retrieverChainProvider; |
|
| 83 | + private final Set<FilterSelectionChangedListener> listeners; |
|
| 84 | + |
|
| 85 | + private boolean isAwaitingReload; |
|
| 86 | + private DataRetrieverChainDefinitionDTO retrieverChain; |
|
| 87 | + private ReducedDimensionsDTO reducedDimensions; |
|
| 88 | + private final List<DimensionWithContext> allFilterDimensions; |
|
| 89 | + private final ListDataProvider<DimensionWithContext> filteredFilterDimensions; |
|
| 90 | + |
|
| 91 | + private final DockLayoutPanel mainPanel; |
|
| 92 | + |
|
| 93 | + private final AbstractFilterablePanel<DimensionWithContext> filterFilterDimensionsPanel; |
|
| 94 | + private final MultiSelectionModel<DimensionWithContext> filterDimensionSelectionModel; |
|
| 95 | + private final DataGrid<DimensionWithContext> filterDimensionsList; |
|
| 96 | + private final Column<DimensionWithContext, Boolean> checkboxColumn; |
|
| 97 | + |
|
| 98 | + private final DockLayoutPanel dimensionFilterSelectionProvidersPanel; |
|
| 99 | + private final Map<DimensionWithContext, DimensionFilterSelectionProvider> dimensionFilterSelectionProviders; |
|
| 100 | + private boolean updateInProgress; |
|
| 101 | + |
|
| 102 | + private final FilterSelectionPresenter filterSelectionPresenter; |
|
| 103 | + private final ScrollPanel filterSelectionPresenterContainer; |
|
| 104 | + |
|
| 105 | + public HierarchicalDimensionListFilterSelectionProvider(Component<?> parent, ComponentContext<?> context, |
|
| 106 | + DataMiningSession session, StringMessages stringMessages, |
|
| 107 | + DataMiningServiceAsync dataMiningService, ErrorReporter errorReporter, |
|
| 108 | + DataRetrieverChainDefinitionProvider retrieverChainProvider) { |
|
| 109 | + super(parent, context); |
|
| 110 | + this.session = session; |
|
| 111 | + this.dataMiningService = dataMiningService; |
|
| 112 | + this.errorReporter = errorReporter; |
|
| 113 | + this.retrieverChainProvider = retrieverChainProvider; |
|
| 114 | + retrieverChainProvider.addDataRetrieverChainDefinitionChangedListener(this); |
|
| 115 | + |
|
| 116 | + listeners = new HashSet<>(); |
|
| 117 | + isAwaitingReload = false; |
|
| 118 | + retrieverChain = null; |
|
| 119 | + allFilterDimensions = new ArrayList<>(); |
|
| 120 | + filteredFilterDimensions = new ListDataProvider<>(); |
|
| 121 | + |
|
| 122 | + Label filterDimensionsSelectionTitleLabel = new Label(stringMessages.selectDimensionsToFilterBy()); |
|
| 123 | + filterDimensionsSelectionTitleLabel.addStyleName("emphasizedLabel"); |
|
| 124 | + filterDimensionsSelectionTitleLabel.addStyleName("dataMiningMarginLeft"); |
|
| 125 | + filterDimensionsSelectionTitleLabel.addStyleName("filterDimensionsTitleLabel"); |
|
| 126 | + |
|
| 127 | + DataMiningDataGridResources resources = GWT.create(DataMiningDataGridResources.class); |
|
| 128 | + filterDimensionsList = new DataGrid<>(Integer.MAX_VALUE, resources); |
|
| 129 | + filterDimensionsList.setAutoHeaderRefreshDisabled(true); |
|
| 130 | + filterDimensionsList.setAutoFooterRefreshDisabled(true); |
|
| 131 | + filterDimensionsList.setTableBuilder(new FilterDimensionsListBuilder(filterDimensionsList, resources.dataGridStyle())); |
|
| 132 | + filteredFilterDimensions.addDataDisplay(filterDimensionsList); |
|
| 133 | + |
|
| 134 | + filterFilterDimensionsPanel = new AbstractFilterablePanel<DimensionWithContext>( |
|
| 135 | + null, filterDimensionsList, filteredFilterDimensions) |
|
| 136 | + { |
|
| 137 | + @Override |
|
| 138 | + public Iterable<String> getSearchableStrings(DimensionWithContext dimension) { |
|
| 139 | + return dimension.getMatchingStrings(); |
|
| 140 | + } |
|
| 141 | + }; |
|
| 142 | + filterFilterDimensionsPanel.addStyleName("filterFilterDimensionsPanel"); |
|
| 143 | + filterFilterDimensionsPanel.setSpacing(2); |
|
| 144 | + filterFilterDimensionsPanel.setWidth("100%"); |
|
| 145 | + filterFilterDimensionsPanel.setHeight("100%"); |
|
| 146 | + filterFilterDimensionsPanel.getTextBox().setWidth("100%"); |
|
| 147 | + filterFilterDimensionsPanel.getTextBox().getElement().setPropertyString("placeholder", stringMessages.filterShownDimensions()); |
|
| 148 | + |
|
| 149 | + filterDimensionSelectionModel = new MultiSelectionModel<>(); |
|
| 150 | + filterDimensionSelectionModel.addSelectionChangeHandler(this::selectedFilterDimensionsChanged); |
|
| 151 | + filterDimensionsList.setSelectionModel(filterDimensionSelectionModel, DefaultSelectionEventManager.createCustomManager(new CustomCheckboxEventTranslator())); |
|
| 152 | + |
|
| 153 | + checkboxColumn = new Column<DimensionWithContext, Boolean>(new CheckboxCell(true, false)) { |
|
| 154 | + @Override |
|
| 155 | + public Boolean getValue(DimensionWithContext object) { |
|
| 156 | + return filterDimensionSelectionModel.isSelected(object); |
|
| 157 | + } |
|
| 158 | + }; |
|
| 159 | + filterDimensionsList.addColumn(checkboxColumn); |
|
| 160 | + TextColumn<DimensionWithContext> dimensionColumn = new TextColumn<DimensionWithContext>() { |
|
| 161 | + @Override |
|
| 162 | + public String getValue(DimensionWithContext object) { |
|
| 163 | + return object.getDimension().getDisplayName(); |
|
| 164 | + } |
|
| 165 | + }; |
|
| 166 | + filterDimensionsList.addColumn(dimensionColumn); |
|
| 167 | + |
|
| 168 | + DockLayoutPanel filterDimensionsSelectionPanel = new DockLayoutPanel(LayoutUnit); |
|
| 169 | + filterDimensionsSelectionPanel.addNorth(filterDimensionsSelectionTitleLabel, 20); |
|
| 170 | + filterDimensionsSelectionPanel.addNorth(filterFilterDimensionsPanel, DimensionSelectionHeaderHeight); |
|
| 171 | + filterDimensionsSelectionPanel.add(filterDimensionsList); |
|
| 172 | + |
|
| 173 | + dimensionFilterSelectionProviders = new HashMap<>(); |
|
| 174 | + dimensionFilterSelectionProvidersPanel = new DockLayoutPanel(LayoutUnit); |
|
| 175 | + dimensionFilterSelectionProvidersPanel.addStyleName("dimensionFilterSelectionTablesContainer"); |
|
| 176 | + dimensionFilterSelectionProvidersPanel.addStyleName("dataMiningBorderLeft"); |
|
| 177 | + |
|
| 178 | + filterSelectionPresenter = new PlainFilterSelectionPresenter(this, context, stringMessages, retrieverChainProvider, this); |
|
| 179 | + filterSelectionPresenter.getEntryWidget().addStyleName("dataMiningMarginLeft"); |
|
| 180 | + filterSelectionPresenterContainer = new ScrollPanel(filterSelectionPresenter.getEntryWidget()); |
|
| 181 | + filterSelectionPresenterContainer.addStyleName("dataMiningBorderTop"); |
|
| 182 | + |
|
| 183 | + mainPanel = new DockLayoutPanel(LayoutUnit); |
|
| 184 | + mainPanel.addSouth(filterSelectionPresenterContainer, SelectionPresenterHeight); |
|
| 185 | + mainPanel.setWidgetHidden(filterSelectionPresenterContainer, true); |
|
| 186 | + mainPanel.addWest(filterDimensionsSelectionPanel, DimensionSelectionWidth); |
|
| 187 | + mainPanel.add(dimensionFilterSelectionProvidersPanel); |
|
| 188 | + } |
|
| 189 | + |
|
| 190 | + @Override |
|
| 191 | + public void awaitReloadComponents() { |
|
| 192 | + isAwaitingReload = true; |
|
| 193 | + } |
|
| 194 | + |
|
| 195 | + @Override |
|
| 196 | + public boolean isAwaitingReload() { |
|
| 197 | + return isAwaitingReload; |
|
| 198 | + } |
|
| 199 | + |
|
| 200 | + @Override |
|
| 201 | + public void reloadComponents() { |
|
| 202 | + updateFilterDimensions(); |
|
| 203 | + isAwaitingReload = false; |
|
| 204 | + notifyListeners(); |
|
| 205 | + } |
|
| 206 | + |
|
| 207 | + @Override |
|
| 208 | + public void dataRetrieverChainDefinitionChanged(DataRetrieverChainDefinitionDTO newDataRetrieverChainDefinition) { |
|
| 209 | + if (!Objects.equals(retrieverChain, newDataRetrieverChainDefinition)) { |
|
| 210 | + retrieverChain = newDataRetrieverChainDefinition; |
|
| 211 | + if (!isAwaitingReload && retrieverChain != null) { |
|
| 212 | + updateFilterDimensions(); |
|
| 213 | + } else if (!isAwaitingReload) { |
|
| 214 | + clearContent(); |
|
| 215 | + } |
|
| 216 | + } |
|
| 217 | + } |
|
| 218 | + |
|
| 219 | + private void updateFilterDimensions() { |
|
| 220 | + clearContent(); |
|
| 221 | + dataMiningService.getReducedDimensionsMappedByLevelFor(retrieverChain, LocaleInfo.getCurrentLocale().getLocaleName(), new AsyncCallback<ReducedDimensionsDTO>() { |
|
| 222 | + @Override |
|
| 223 | + public void onSuccess(ReducedDimensionsDTO result) { |
|
| 224 | + reducedDimensions = result; |
|
| 225 | + for (Entry<DataRetrieverLevelDTO, HashSet<FunctionDTO>> entry : reducedDimensions.getReducedDimensions().entrySet()) { |
|
| 226 | + DataRetrieverLevelDTO retrieverlevel = entry.getKey(); |
|
| 227 | + for (FunctionDTO dimension : entry.getValue()) { |
|
| 228 | + allFilterDimensions.add(new DimensionWithContext(dimension, retrieverlevel)); |
|
| 229 | + } |
|
| 230 | + } |
|
| 231 | + allFilterDimensions.sort(null); |
|
| 232 | + filterFilterDimensionsPanel.updateAll(allFilterDimensions); |
|
| 233 | + } |
|
| 234 | + @Override |
|
| 235 | + public void onFailure(Throwable caught) { |
|
| 236 | + errorReporter.reportError("Error fetching the dimensions of the retriever chain from the server: " + caught.getMessage()); |
|
| 237 | + } |
|
| 238 | + }); |
|
| 239 | + } |
|
| 240 | + |
|
| 241 | + private void clearContent() { |
|
| 242 | + reducedDimensions = null; |
|
| 243 | + allFilterDimensions.clear(); |
|
| 244 | + filterDimensionSelectionModel.clear(); |
|
| 245 | + filterFilterDimensionsPanel.removeAll(); |
|
| 246 | + } |
|
| 247 | + |
|
| 248 | + @Override |
|
| 249 | + public void applyQueryDefinition(StatisticQueryDefinitionDTO queryDefinition) { |
|
| 250 | + HashMap<DataRetrieverLevelDTO, HashMap<FunctionDTO, HashSet<? extends Serializable>>> filterSelection = queryDefinition.getFilterSelection(); |
|
| 251 | + for (DimensionWithContext dimensionWithContext : allFilterDimensions) { |
|
| 252 | + HashMap<FunctionDTO, HashSet<? extends Serializable>> retrieverLevelSelection = filterSelection.get(dimensionWithContext.getRetrieverLevel()); |
|
| 253 | + if (retrieverLevelSelection != null) { |
|
| 254 | + HashSet<? extends Serializable> items = retrieverLevelSelection.get(dimensionWithContext.getDimension()); |
|
| 255 | + if (items != null) { |
|
| 256 | + setSelection(dimensionWithContext, items); |
|
| 257 | + } |
|
| 258 | + } |
|
| 259 | + } |
|
| 260 | + } |
|
| 261 | + |
|
| 262 | + @Override |
|
| 263 | + public void setHighestRetrieverLevelWithFilterDimension(FunctionDTO dimension, Serializable groupKey) { |
|
| 264 | + FunctionDTO reducedDimension = reducedDimensions == null ? dimension : reducedDimensions.getReducedDimension(dimension); |
|
| 265 | + Collection<Serializable> items = Collections.singleton(groupKey); |
|
| 266 | + for (DimensionWithContext dimensionWithContext : allFilterDimensions) { |
|
| 267 | + if (dimensionWithContext.getDimension().equals(reducedDimension)) { |
|
| 268 | + setSelection(dimensionWithContext, items); |
|
| 269 | + break; |
|
| 270 | + } |
|
| 271 | + } |
|
| 272 | + } |
|
| 273 | + |
|
| 274 | + private void setSelection(DimensionWithContext dimension, Collection<? extends Serializable> items) { |
|
| 275 | + DimensionFilterSelectionProvider selectionProvider; |
|
| 276 | + if (filterDimensionSelectionModel.isSelected(dimension)) { |
|
| 277 | + selectionProvider = dimensionFilterSelectionProviders.get(dimension); |
|
| 278 | + } else { |
|
| 279 | + selectionProvider = addDimensionFilterSelectionProvider(dimension); |
|
| 280 | + filterDimensionSelectionModel.setSelected(dimension, true); |
|
| 281 | + } |
|
| 282 | + selectionProvider.setSelection(items); |
|
| 283 | + } |
|
| 284 | + |
|
| 285 | + private void selectedFilterDimensionsChanged(SelectionChangeEvent event) { |
|
| 286 | + Iterable<DimensionWithContext> displayedDimensions = new HashSet<>(dimensionFilterSelectionProviders.keySet()); |
|
| 287 | + for (DimensionWithContext displayedDimension : displayedDimensions) { |
|
| 288 | + if (!filterDimensionSelectionModel.isSelected(displayedDimension)) { |
|
| 289 | + removeDimensionFilterSelectionProvider(displayedDimension); |
|
| 290 | + } |
|
| 291 | + } |
|
| 292 | + |
|
| 293 | + for (DimensionWithContext selectedDimension : filterDimensionSelectionModel.getSelectedSet()) { |
|
| 294 | + if (!dimensionFilterSelectionProviders.containsKey(selectedDimension)) { |
|
| 295 | + addDimensionFilterSelectionProvider(selectedDimension); |
|
| 296 | + } |
|
| 297 | + } |
|
| 298 | + } |
|
| 299 | + |
|
| 300 | + private DimensionFilterSelectionProvider addDimensionFilterSelectionProvider(DimensionWithContext dimension) { |
|
| 301 | + DimensionFilterSelectionProvider selectionProvider = new DimensionFilterSelectionProvider(this, getComponentContext(), |
|
| 302 | + dataMiningService, errorReporter, session, retrieverChainProvider, this, dimension.getRetrieverLevel(), dimension.getDimension()); |
|
| 303 | + selectionProvider.addListener(() -> filterSelectionChanged(dimension)); |
|
| 304 | + dimensionFilterSelectionProviders.put(dimension, selectionProvider); |
|
| 305 | + |
|
| 306 | + DimensionWithContext nextDimension = null; |
|
| 307 | + for (DimensionWithContext displayedDimension : dimensionFilterSelectionProviders.keySet()) { |
|
| 308 | + if (displayedDimension.compareTo(dimension) > 0 && |
|
| 309 | + (nextDimension == null || displayedDimension.compareTo(nextDimension) < 0)) { |
|
| 310 | + nextDimension = displayedDimension; |
|
| 311 | + } |
|
| 312 | + } |
|
| 313 | + Widget beforeWidget = nextDimension != null ? dimensionFilterSelectionProviders.get(nextDimension).getEntryWidget() : null; |
|
| 314 | + dimensionFilterSelectionProvidersPanel.insertWest(selectionProvider.getEntryWidget(), FilterSelectionTableWidth, beforeWidget); |
|
| 315 | + |
|
| 316 | + return selectionProvider; |
|
| 317 | + } |
|
| 318 | + |
|
| 319 | + private void removeDimensionFilterSelectionProvider(DimensionWithContext dimension) { |
|
| 320 | + DimensionFilterSelectionProvider selectionProvider = dimensionFilterSelectionProviders.get(dimension); |
|
| 321 | + if (selectionProvider != null) { |
|
| 322 | + selectionProvider.clearSelection(); |
|
| 323 | + dimensionFilterSelectionProviders.remove(dimension); |
|
| 324 | + dimensionFilterSelectionProvidersPanel.remove(selectionProvider.getEntryWidget()); |
|
| 325 | + dimensionFilterSelectionProvidersPanel.animate(0); // Schedule Layout |
|
| 326 | + } |
|
| 327 | + } |
|
| 328 | + |
|
| 329 | + private void filterSelectionChanged(DimensionWithContext changedDimension) { |
|
| 330 | + if (!updateInProgress) { |
|
| 331 | + updateInProgress = true; |
|
| 332 | + int levelToStartWith = changedDimension.getRetrieverLevel().getLevel(); |
|
| 333 | + List<DimensionWithContext> dimensionsToUpdate = dimensionFilterSelectionProviders.keySet() |
|
| 334 | + .stream().filter(d -> d.getRetrieverLevel().getLevel() >= levelToStartWith) |
|
| 335 | + .collect(Collectors.toList()); |
|
| 336 | + updateDimensionFilterSelectionProviders(dimensionsToUpdate.iterator(), changedDimension); |
|
| 337 | + } |
|
| 338 | + } |
|
| 339 | + |
|
| 340 | + private void updateDimensionFilterSelectionProviders(Iterator<DimensionWithContext> dimensionIterator, DimensionWithContext exceptDimension) { |
|
| 341 | + if (dimensionIterator.hasNext()) { |
|
| 342 | + DimensionWithContext dimension = dimensionIterator.next(); |
|
| 343 | + if (dimension.equals(exceptDimension)) { |
|
| 344 | + updateDimensionFilterSelectionProviders(dimensionIterator, exceptDimension); |
|
| 345 | + } else { |
|
| 346 | + DimensionFilterSelectionProvider selectionProvider = dimensionFilterSelectionProviders.get(dimension); |
|
| 347 | + HashSet<? extends Serializable> selectionBefore = selectionProvider.getSelection(); |
|
| 348 | + selectionProvider.updateContent(() -> { |
|
| 349 | + boolean selectionChanged = !selectionBefore.equals(selectionProvider.getSelection()); |
|
| 350 | + if (selectionChanged) { |
|
| 351 | + updateInProgress = false; |
|
| 352 | + filterSelectionChanged(dimension); |
|
| 353 | + } else { |
|
| 354 | + updateDimensionFilterSelectionProviders(dimensionIterator, exceptDimension); |
|
| 355 | + } |
|
| 356 | + }); |
|
| 357 | + } |
|
| 358 | + } else { |
|
| 359 | + updateInProgress = false; |
|
| 360 | + notifyListeners(); |
|
| 361 | + } |
|
| 362 | + } |
|
| 363 | + |
|
| 364 | + @Override |
|
| 365 | + public HashMap<DataRetrieverLevelDTO, HashMap<FunctionDTO, HashSet<? extends Serializable>>> getSelection() { |
|
| 366 | + HashMap<DataRetrieverLevelDTO, HashMap<FunctionDTO, HashSet<? extends Serializable>>> filterSelection = new HashMap<>(); |
|
| 367 | + for (DimensionWithContext dimensionWithContext : allFilterDimensions) { |
|
| 368 | + DataRetrieverLevelDTO retrieverLevel = dimensionWithContext.getRetrieverLevel(); |
|
| 369 | + FunctionDTO dimension = dimensionWithContext.getDimension(); |
|
| 370 | + DimensionFilterSelectionProvider selectionProvider = dimensionFilterSelectionProviders.get(dimensionWithContext); |
|
| 371 | + if (selectionProvider != null) { |
|
| 372 | + HashSet<? extends Serializable> dimensionFilterSelection = selectionProvider.getSelection(); |
|
| 373 | + if (!dimensionFilterSelection.isEmpty()) { |
|
| 374 | + HashMap<FunctionDTO, HashSet<? extends Serializable>> retrieverFilterSelection = filterSelection.get(retrieverLevel); |
|
| 375 | + if (retrieverFilterSelection == null) { |
|
| 376 | + retrieverFilterSelection = new HashMap<>(); |
|
| 377 | + filterSelection.put(retrieverLevel, retrieverFilterSelection); |
|
| 378 | + } |
|
| 379 | + retrieverFilterSelection.put(dimension, dimensionFilterSelection); |
|
| 380 | + } |
|
| 381 | + } |
|
| 382 | + } |
|
| 383 | + return filterSelection; |
|
| 384 | + } |
|
| 385 | + |
|
| 386 | + @Override |
|
| 387 | + public void clearSelection() { |
|
| 388 | + for (DimensionFilterSelectionProvider selectionProvider : dimensionFilterSelectionProviders.values()) { |
|
| 389 | + selectionProvider.clearSelection(); |
|
| 390 | + } |
|
| 391 | + } |
|
| 392 | + |
|
| 393 | + @Override |
|
| 394 | + public void addSelectionChangedListener(FilterSelectionChangedListener listener) { |
|
| 395 | + listeners.add(listener); |
|
| 396 | + } |
|
| 397 | + |
|
| 398 | + private void notifyListeners() { |
|
| 399 | + mainPanel.setWidgetHidden(filterSelectionPresenterContainer, getSelection().isEmpty()); |
|
| 400 | + for (FilterSelectionChangedListener listener : listeners) { |
|
| 401 | + listener.selectionChanged(); |
|
| 402 | + } |
|
| 403 | + } |
|
| 404 | + |
|
| 405 | + @Override |
|
| 406 | + public String getLocalizedShortName() { |
|
| 407 | + return getClass().getSimpleName(); |
|
| 408 | + } |
|
| 409 | + |
|
| 410 | + @Override |
|
| 411 | + public Widget getEntryWidget() { |
|
| 412 | + return mainPanel; |
|
| 413 | + } |
|
| 414 | + |
|
| 415 | + @Override |
|
| 416 | + public boolean isVisible() { |
|
| 417 | + return mainPanel.isVisible(); |
|
| 418 | + } |
|
| 419 | + |
|
| 420 | + @Override |
|
| 421 | + public void setVisible(boolean visibility) { |
|
| 422 | + mainPanel.setVisible(visibility); |
|
| 423 | + } |
|
| 424 | + |
|
| 425 | + @Override |
|
| 426 | + public String getDependentCssClassName() { |
|
| 427 | + return "hierarchicalDimensionListFilterSelectionProvider"; |
|
| 428 | + } |
|
| 429 | + |
|
| 430 | + @Override |
|
| 431 | + public boolean hasSettings() { |
|
| 432 | + return false; |
|
| 433 | + } |
|
| 434 | + |
|
| 435 | + @Override |
|
| 436 | + public SettingsDialogComponent<SerializableSettings> getSettingsDialogComponent(SerializableSettings settings) { |
|
| 437 | + return null; |
|
| 438 | + } |
|
| 439 | + |
|
| 440 | + @Override |
|
| 441 | + public void updateSettings(SerializableSettings newSettings) { |
|
| 442 | + // no-op |
|
| 443 | + } |
|
| 444 | + |
|
| 445 | + @Override |
|
| 446 | + public SerializableSettings getSettings() { |
|
| 447 | + return null; |
|
| 448 | + } |
|
| 449 | + |
|
| 450 | + @Override |
|
| 451 | + public String getId() { |
|
| 452 | + return "HierarchicalDimensionListFilterSelectionProvider"; |
|
| 453 | + } |
|
| 454 | + |
|
| 455 | + private static class DimensionWithContext implements Comparable<DimensionWithContext> { |
|
| 456 | + |
|
| 457 | + private final FunctionDTO dimension; |
|
| 458 | + private final DataRetrieverLevelDTO retrieverLevel; |
|
| 459 | + private Collection<String> matchingStrings; |
|
| 460 | + |
|
| 461 | + public DimensionWithContext(FunctionDTO dimension, DataRetrieverLevelDTO retrieverLevel) { |
|
| 462 | + this.dimension = dimension; |
|
| 463 | + this.retrieverLevel = retrieverLevel; |
|
| 464 | + } |
|
| 465 | + |
|
| 466 | + public FunctionDTO getDimension() { |
|
| 467 | + return dimension; |
|
| 468 | + } |
|
| 469 | + |
|
| 470 | + public DataRetrieverLevelDTO getRetrieverLevel() { |
|
| 471 | + return retrieverLevel; |
|
| 472 | + } |
|
| 473 | + |
|
| 474 | + public Collection<String> getMatchingStrings() { |
|
| 475 | + if (matchingStrings == null) { |
|
| 476 | + matchingStrings = new ArrayList<>(2); |
|
| 477 | + matchingStrings.add(dimension.getDisplayName()); |
|
| 478 | + matchingStrings.add(retrieverLevel.getRetrievedDataType().getDisplayName()); |
|
| 479 | + } |
|
| 480 | + return matchingStrings; |
|
| 481 | + } |
|
| 482 | + |
|
| 483 | + @Override |
|
| 484 | + public int compareTo(DimensionWithContext o) { |
|
| 485 | + int retrieverLevelComparison = retrieverLevel.compareTo(o.retrieverLevel); |
|
| 486 | + if (retrieverLevelComparison != 0) return retrieverLevelComparison; |
|
| 487 | + |
|
| 488 | + return dimension.compareTo(o.dimension); |
|
| 489 | + } |
|
| 490 | + |
|
| 491 | + @Override |
|
| 492 | + public int hashCode() { |
|
| 493 | + final int prime = 31; |
|
| 494 | + int result = 1; |
|
| 495 | + result = prime * result + ((dimension == null) ? 0 : dimension.hashCode()); |
|
| 496 | + result = prime * result + ((retrieverLevel == null) ? 0 : retrieverLevel.hashCode()); |
|
| 497 | + return result; |
|
| 498 | + } |
|
| 499 | + |
|
| 500 | + @Override |
|
| 501 | + public boolean equals(Object obj) { |
|
| 502 | + if (this == obj) |
|
| 503 | + return true; |
|
| 504 | + if (obj == null) |
|
| 505 | + return false; |
|
| 506 | + if (getClass() != obj.getClass()) |
|
| 507 | + return false; |
|
| 508 | + DimensionWithContext other = (DimensionWithContext) obj; |
|
| 509 | + if (dimension == null) { |
|
| 510 | + if (other.dimension != null) |
|
| 511 | + return false; |
|
| 512 | + } else if (!dimension.equals(other.dimension)) |
|
| 513 | + return false; |
|
| 514 | + if (retrieverLevel == null) { |
|
| 515 | + if (other.retrieverLevel != null) |
|
| 516 | + return false; |
|
| 517 | + } else if (!retrieverLevel.equals(other.retrieverLevel)) |
|
| 518 | + return false; |
|
| 519 | + return true; |
|
| 520 | + } |
|
| 521 | + |
|
| 522 | + } |
|
| 523 | + |
|
| 524 | + private class FilterDimensionsListBuilder extends BaseCellTableBuilder<DimensionWithContext> { |
|
| 525 | + |
|
| 526 | + private final String headerStyle; |
|
| 527 | + private final String subHeaderStyle; |
|
| 528 | + private final String spacedSubHeaderStyle; |
|
| 529 | + private final String subHeaderLabelStyle; |
|
| 530 | + private final String firstColumnStyle; |
|
| 531 | + private final String hoveredRowStyle; |
|
| 532 | + private final String hoveredRowCellStyle; |
|
| 533 | + private final String clearFocus; |
|
| 534 | + |
|
| 535 | + public FilterDimensionsListBuilder(AbstractCellTable<DimensionWithContext> cellTable, DataMiningDataGridStyle style) { |
|
| 536 | + super(cellTable); |
|
| 537 | + headerStyle = style.dataGridHeader(); |
|
| 538 | + subHeaderStyle = style.dataGridSubHeader(); |
|
| 539 | + firstColumnStyle = style.dataGridFirstColumn(); |
|
| 540 | + spacedSubHeaderStyle = style.dataGridSpacedSubHeader(); |
|
| 541 | + hoveredRowStyle = style.dataGridHoveredRow(); |
|
| 542 | + hoveredRowCellStyle = style.dataGridHoveredRowCell(); |
|
| 543 | + subHeaderLabelStyle = style.dataGridSubHeaderLabel(); |
|
| 544 | + clearFocus = style.dataGridClearFocus(); |
|
| 545 | + |
|
| 546 | + cellTable.addRowHoverHandler(new RowHoverEvent.Handler() { |
|
| 547 | + @Override |
|
| 548 | + public void onRowHover(RowHoverEvent event) { |
|
| 549 | + TableRowElement tr = event.getHoveringRow(); |
|
| 550 | + if (tr.hasAttribute(DimensionListSubheaderAttribute)) { |
|
| 551 | + tr.removeClassName(hoveredRowStyle); |
|
| 552 | + NodeList<TableCellElement> cells = tr.getCells(); |
|
| 553 | + for (int i = 0; i < cells.getLength(); i++) { |
|
| 554 | + cells.getItem(i).removeClassName(hoveredRowCellStyle); |
|
| 555 | + } |
|
| 556 | + } |
|
| 557 | + } |
|
| 558 | + }); |
|
| 559 | + } |
|
| 560 | + |
|
| 561 | + @Override |
|
| 562 | + public void buildRowImpl(DimensionWithContext rowValue, int absRowIndex) { |
|
| 563 | + DataRetrieverLevelDTO valueLevel = rowValue.getRetrieverLevel(); |
|
| 564 | + DataRetrieverLevelDTO previousLevel = null; |
|
| 565 | + if (absRowIndex > 0) { |
|
| 566 | + previousLevel = filteredFilterDimensions.getList().get(absRowIndex - 1).getRetrieverLevel(); |
|
| 567 | + } |
|
| 568 | + |
|
| 569 | + if (!Objects.equals(previousLevel, valueLevel)) { |
|
| 570 | + StringBuilder styleBuilder = new StringBuilder(); |
|
| 571 | + styleBuilder.append(subHeaderStyle).append(" ").append(headerStyle) |
|
| 572 | + .append(" ").append(clearFocus); |
|
| 573 | + if (absRowIndex != 0) { |
|
| 574 | + styleBuilder.append(" ").append(spacedSubHeaderStyle); |
|
| 575 | + } |
|
| 576 | + String style = styleBuilder.toString(); |
|
| 577 | + |
|
| 578 | + String subHeaderText = valueLevel.getRetrievedDataType().getDisplayName(); |
|
| 579 | + TableRowBuilder subHeaderBuilder = startRow().className(clearFocus).attribute(DimensionListSubheaderAttribute, subHeaderText); |
|
| 580 | + // Additional cell to fix the checkbox column size |
|
| 581 | + subHeaderBuilder.startTD().className(style + " " + firstColumnStyle).endTD(); |
|
| 582 | + // Actual header cell |
|
| 583 | + TableCellBuilder headerCellBuilder = subHeaderBuilder.startTD(); |
|
| 584 | + headerCellBuilder.colSpan(this.cellTable.getColumnCount() - 1).className(style); |
|
| 585 | + headerCellBuilder.startDiv().className(subHeaderLabelStyle).text(subHeaderText).endDiv(); |
|
| 586 | + headerCellBuilder.endTD(); |
|
| 587 | + subHeaderBuilder.endTR(); |
|
| 588 | + } |
|
| 589 | + |
|
| 590 | + super.buildRowImpl(rowValue, absRowIndex); |
|
| 591 | + } |
|
| 592 | + } |
|
| 593 | + |
|
| 594 | + private class CustomCheckboxEventTranslator implements EventTranslator<DimensionWithContext> { |
|
| 595 | + |
|
| 596 | + @Override |
|
| 597 | + public boolean clearCurrentSelection(CellPreviewEvent<DimensionWithContext> event) { |
|
| 598 | + return false; |
|
| 599 | + } |
|
| 600 | + |
|
| 601 | + @Override |
|
| 602 | + public SelectAction translateSelectionEvent(CellPreviewEvent<DimensionWithContext> event) { |
|
| 603 | + SelectAction action = SelectAction.TOGGLE; |
|
| 604 | + |
|
| 605 | + NativeEvent nativeEvent = event.getNativeEvent(); |
|
| 606 | + Element targetRow = Element.as(nativeEvent.getEventTarget()); |
|
| 607 | + while (!TableRowElement.is(targetRow) && targetRow != null) { |
|
| 608 | + targetRow = targetRow.getParentElement(); |
|
| 609 | + } |
|
| 610 | + if (targetRow != null && targetRow.hasAttribute(DimensionListSubheaderAttribute)) { |
|
| 611 | + action = SelectAction.IGNORE; |
|
| 612 | + } |
|
| 613 | + return action; |
|
| 614 | + } |
|
| 615 | + |
|
| 616 | + } |
|
| 617 | + |
|
| 618 | +} |
java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/QueryDefinitionProviderWithControls.java
| ... | ... | @@ -43,7 +43,6 @@ import com.sap.sse.datamining.ui.client.StatisticProvider; |
| 43 | 43 | import com.sap.sse.datamining.ui.client.WithControls; |
| 44 | 44 | import com.sap.sse.datamining.ui.client.developer.PredefinedQueryRunner; |
| 45 | 45 | import com.sap.sse.datamining.ui.client.developer.QueryDefinitionViewer; |
| 46 | -import com.sap.sse.datamining.ui.client.selection.filter.HierarchicalDimensionListFilterSelectionProvider; |
|
| 47 | 46 | import com.sap.sse.datamining.ui.client.settings.AdvancedDataMiningSettings; |
| 48 | 47 | import com.sap.sse.datamining.ui.client.settings.AdvancedDataMiningSettingsDialogComponent; |
| 49 | 48 | import com.sap.sse.gwt.client.ErrorReporter; |
java/com.sap.sse.datamining.ui/src/main/java/com/sap/sse/datamining/ui/client/selection/SuggestBoxStatisticProvider.java
| ... | ... | @@ -219,24 +219,12 @@ public class SuggestBoxStatisticProvider extends AbstractDataMiningComponent<Com |
| 219 | 219 | awaitingRetrieverChainStatistics--; |
| 220 | 220 | if (awaitingRetrieverChainStatistics == 0) { |
| 221 | 221 | Collections.sort(availableExtractionFunctions); |
| 222 | - Map<String, ExtractionFunctionWithContext> displayDuplicates = new HashMap<>(); |
|
| 223 | - for (ExtractionFunctionWithContext statistic : availableExtractionFunctions) { |
|
| 224 | - ExtractionFunctionWithContext duplicate = displayDuplicates |
|
| 225 | - .get(statistic.getExtractionFunction().getDisplayName()); |
|
| 226 | - if (duplicate == null) { |
|
| 227 | - displayDuplicates.put(statistic.getExtractionFunction().getDisplayName(), statistic); |
|
| 228 | - } else { |
|
| 229 | - statistic.setVerbose(true); |
|
| 230 | - duplicate.setVerbose(true); |
|
| 231 | - } |
|
| 232 | - } |
|
| 233 | 222 | extractionFunctionSuggestBox.setSelectableValues(availableExtractionFunctions); |
| 234 | 223 | |
| 235 | 224 | // TODO Do not pre-select the first element. The other UI components have to be able to handle "empty content" |
| 236 | 225 | ExtractionFunctionWithContext currentValue = extractionFunctionSuggestBox.getExtractionFunction(); |
| 237 | 226 | ExtractionFunctionWithContext valueToBeSelected = availableExtractionFunctions.contains(currentValue) |
| 238 | 227 | ? currentValue : Util.first(availableExtractionFunctions); |
| 239 | - extractionFunctionSuggestBox.getValueBox().setValue(valueToBeSelected.getDisplayString(), false); |
|
| 240 | 228 | extractionFunctionSuggestBox.setExtractionFunction(valueToBeSelected); |
| 241 | 229 | } |
| 242 | 230 | } |
| ... | ... | @@ -377,18 +365,9 @@ public class SuggestBoxStatisticProvider extends AbstractDataMiningComponent<Com |
| 377 | 365 | if (index != -1) { |
| 378 | 366 | statistic = availableExtractionFunctions.get(index); |
| 379 | 367 | } else { |
| 380 | - String displayName = extractionFunction.getDisplayName(); |
|
| 381 | - for (ExtractionFunctionWithContext availableStatistic : availableExtractionFunctions) { |
|
| 382 | - if (availableStatistic.getExtractionFunction().getDisplayName().equals(displayName)) { |
|
| 383 | - statistic.setVerbose(true); |
|
| 384 | - availableStatistic.setVerbose(true); |
|
| 385 | - } |
|
| 386 | - } |
|
| 387 | 368 | availableExtractionFunctions.add(statistic); |
| 388 | - extractionFunctionSuggestBox.setSelectableValues(availableExtractionFunctions); |
|
| 389 | 369 | } |
| 390 | 370 | |
| 391 | - extractionFunctionSuggestBox.getValueBox().setValue(statistic.getDisplayString(), false); |
|
| 392 | 371 | extractionFunctionSuggestBox.setExtractionFunction(statistic); |
| 393 | 372 | aggregatorListBox.setValue(queryDefinition.getAggregatorDefinition()); |
| 394 | 373 | } |
| ... | ... | @@ -488,7 +467,6 @@ public class SuggestBoxStatisticProvider extends AbstractDataMiningComponent<Com |
| 488 | 467 | private final DataRetrieverChainDefinitionDTO retrieverChain; |
| 489 | 468 | private final FunctionDTO extractionFunction; |
| 490 | 469 | private final Collection<String> matchingStrings; |
| 491 | - private boolean verbose; |
|
| 492 | 470 | |
| 493 | 471 | public ExtractionFunctionWithContext(DataRetrieverChainDefinitionDTO retrieverChain, |
| 494 | 472 | FunctionDTO extractionFunction) { |
| ... | ... | @@ -511,30 +489,13 @@ public class SuggestBoxStatisticProvider extends AbstractDataMiningComponent<Com |
| 511 | 489 | return matchingStrings; |
| 512 | 490 | } |
| 513 | 491 | |
| 514 | - public boolean isVerbose() { |
|
| 515 | - return verbose; |
|
| 516 | - } |
|
| 517 | - |
|
| 518 | - public void setVerbose(boolean verbose) { |
|
| 519 | - this.verbose = verbose; |
|
| 520 | - } |
|
| 521 | - |
|
| 522 | - public String getDisplayString() { |
|
| 523 | - StringBuilder builder = new StringBuilder(extractionFunction.getDisplayName()); |
|
| 524 | - if (isVerbose()) { |
|
| 525 | - builder.append(" (").append(getDataMiningStringMessages().basedOn()).append(" ") |
|
| 526 | - .append(retrieverChain.getName()).append(")"); |
|
| 527 | - } |
|
| 528 | - return builder.toString(); |
|
| 529 | - } |
|
| 530 | - |
|
| 531 | 492 | @Override |
| 532 | 493 | public int compareTo(ExtractionFunctionWithContext o) { |
| 533 | - int comparedDisplayName = extractionFunction.getDisplayName() |
|
| 534 | - .compareTo(o.getExtractionFunction().getDisplayName()); |
|
| 535 | - if (comparedDisplayName != 0) |
|
| 494 | + String otherDisplayName = o.getExtractionFunction().getDisplayName(); |
|
| 495 | + int comparedDisplayName = extractionFunction.getDisplayName().compareToIgnoreCase(otherDisplayName); |
|
| 496 | + if (comparedDisplayName != 0) { |
|
| 536 | 497 | return comparedDisplayName; |
| 537 | - |
|
| 498 | + } |
|
| 538 | 499 | return retrieverChain.compareTo(o.getRetrieverChain()); |
| 539 | 500 | } |
| 540 | 501 | |
| ... | ... | @@ -597,12 +558,12 @@ public class SuggestBoxStatisticProvider extends AbstractDataMiningComponent<Com |
| 597 | 558 | |
| 598 | 559 | @Override |
| 599 | 560 | protected String createSuggestionKeyString(ExtractionFunctionWithContext value) { |
| 600 | - return value.getDisplayString(); |
|
| 561 | + return value.getExtractionFunction().getDisplayName(); |
|
| 601 | 562 | } |
| 602 | 563 | |
| 603 | 564 | @Override |
| 604 | 565 | protected String createSuggestionAdditionalDisplayString(ExtractionFunctionWithContext value) { |
| 605 | - return null; |
|
| 566 | + return value.getRetrieverChain().getName(); |
|
| 606 | 567 | } |
| 607 | 568 | }, new ScrollableSuggestionDisplay()); |
| 608 | 569 | suggestOracle = (AbstractListSuggestOracle<ExtractionFunctionWithContext>) getSuggestOracle(); |
| ... | ... | @@ -622,9 +583,10 @@ public class SuggestBoxStatisticProvider extends AbstractDataMiningComponent<Com |
| 622 | 583 | public void setExtractionFunction(ExtractionFunctionWithContext extractionFunction) { |
| 623 | 584 | if (!Objects.equals(this.extractionFunction, extractionFunction)) { |
| 624 | 585 | this.extractionFunction = extractionFunction; |
| 625 | - this.setFocus(false); |
|
| 586 | + setValue(extractionFunction.getExtractionFunction().getDisplayName(), false); |
|
| 626 | 587 | onValueChange(); |
| 627 | 588 | } |
| 589 | + setFocus(false); |
|
| 628 | 590 | } |
| 629 | 591 | |
| 630 | 592 | public ExtractionFunctionWithContext getExtractionFunction() { |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/components/ProcessorInstructionHandler.java
| ... | ... | @@ -2,9 +2,11 @@ package com.sap.sse.datamining.components; |
| 2 | 2 | |
| 3 | 3 | public interface ProcessorInstructionHandler<ResultType> { |
| 4 | 4 | |
| 5 | - public void instructionSucceeded(ResultType result); |
|
| 6 | - public void instructionFailed(Exception e); |
|
| 5 | + boolean isAborted(); |
|
| 7 | 6 | |
| 8 | - public void afterInstructionFinished(); |
|
| 7 | + void instructionSucceeded(ResultType result); |
|
| 8 | + void instructionFailed(Exception e); |
|
| 9 | + |
|
| 10 | + void afterInstructionFinished(ProcessorInstruction<ResultType> instruction); |
|
| 9 | 11 | |
| 10 | 12 | } |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/components/management/FunctionProvider.java
| ... | ... | @@ -24,7 +24,9 @@ public interface FunctionProvider { |
| 24 | 24 | DataRetrieverChainDefinition<?, ?> dataRetrieverChainDefinition); |
| 25 | 25 | |
| 26 | 26 | /** |
| 27 | - * @param classLoader TODO |
|
| 27 | + * @param functionDTO The {@link FunctionDTO} to resolve |
|
| 28 | + * @param classLoader The class loader used to get the actual {@link Class} objects described |
|
| 29 | + * by the <code>functionDTO</code> |
|
| 28 | 30 | * @return The first function, that matches the given DTO or <code>null</code> |
| 29 | 31 | */ |
| 30 | 32 | public Function<?> getFunctionForDTO(FunctionDTO functionDTO, ClassLoader classLoader); |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java
| ... | ... | @@ -69,6 +69,9 @@ public abstract class AbstractParallelMultiDimensionalNestingGroupingProcessor<D |
| 69 | 69 | } else { |
| 70 | 70 | List<GroupKey> keys = new ArrayList<>(); |
| 71 | 71 | for (ParameterizedFunction<?> parameterizedDimension : parameterizedDimensions) { |
| 72 | + if (isAborted()) { |
|
| 73 | + break; |
|
| 74 | + } |
|
| 72 | 75 | keys.add(createGroupKeyFor(input, parameterizedDimension.getFunction(), parameterizedDimension.getParameterProvider())); |
| 73 | 76 | } |
| 74 | 77 | return new CompoundGroupKey(keys); |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelProcessor.java
| ... | ... | @@ -59,18 +59,21 @@ public abstract class AbstractParallelProcessor<InputType, ResultType> extends A |
| 59 | 59 | private boolean isInstructionValid(ProcessorInstruction<ResultType> instruction) { |
| 60 | 60 | return instruction != null; |
| 61 | 61 | } |
| 62 | - |
|
| 62 | + |
|
| 63 | + @Override |
|
| 63 | 64 | public void instructionSucceeded(ResultType result) { |
| 64 | 65 | forwardResultToReceivers(result); |
| 65 | 66 | } |
| 66 | - |
|
| 67 | + |
|
| 68 | + @Override |
|
| 67 | 69 | public void instructionFailed(Exception e) { |
| 68 | 70 | if (!isAborted() || !(e instanceof InterruptedException)) { |
| 69 | 71 | onFailure(e); |
| 70 | 72 | } |
| 71 | 73 | } |
| 72 | - |
|
| 73 | - public void afterInstructionFinished() { |
|
| 74 | + |
|
| 75 | + @Override |
|
| 76 | + public void afterInstructionFinished(ProcessorInstruction<ResultType> instruction) { |
|
| 74 | 77 | unfinishedInstructionsCounter.getAndDecrement(); |
| 75 | 78 | } |
| 76 | 79 |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java
| ... | ... | @@ -52,17 +52,27 @@ public abstract class AbstractProcessorInstruction<ResultType> implements Proces |
| 52 | 52 | @Override |
| 53 | 53 | public void run() { |
| 54 | 54 | try { |
| 55 | - ResultType result = computeResult(); |
|
| 56 | - handler.instructionSucceeded(result); |
|
| 55 | + if (!isAborted()) { |
|
| 56 | + ResultType result = computeResult(); |
|
| 57 | + handler.instructionSucceeded(result); |
|
| 58 | + } |
|
| 57 | 59 | } catch (Exception e) { |
| 58 | 60 | handler.instructionFailed(e); |
| 59 | 61 | } finally { |
| 60 | - handler.afterInstructionFinished(); |
|
| 62 | + handler.afterInstructionFinished(this); |
|
| 61 | 63 | } |
| 62 | 64 | } |
| 65 | + |
|
| 66 | + protected boolean isAborted() { |
|
| 67 | + return handler.isAborted(); |
|
| 68 | + } |
|
| 63 | 69 | |
| 64 | 70 | protected abstract ResultType computeResult() throws Exception; |
| 65 | 71 | |
| 72 | + public ProcessorInstructionHandler<ResultType> getHandler() { |
|
| 73 | + return handler; |
|
| 74 | + } |
|
| 75 | + |
|
| 66 | 76 | @Override |
| 67 | 77 | public int getPriority() { |
| 68 | 78 | return priority; |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java
| ... | ... | @@ -38,6 +38,9 @@ public abstract class AbstractRetrievalProcessor<InputType, ResultType> extends |
| 38 | 38 | @Override |
| 39 | 39 | public ResultType computeResult() { |
| 40 | 40 | for (ResultType retrievedElement : retrieveData(element)) { |
| 41 | + if (isAborted()) { |
|
| 42 | + break; |
|
| 43 | + } |
|
| 41 | 44 | retrievedDataAmount.incrementAndGet(); |
| 42 | 45 | forwardResultToReceivers(retrievedElement); |
| 43 | 46 | } |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelAggregationProcessor.java
| ... | ... | @@ -5,6 +5,7 @@ import java.util.concurrent.ExecutorService; |
| 5 | 5 | |
| 6 | 6 | import com.sap.sse.datamining.components.AdditionalResultDataBuilder; |
| 7 | 7 | import com.sap.sse.datamining.components.Processor; |
| 8 | +import com.sap.sse.datamining.components.ProcessorInstruction; |
|
| 8 | 9 | import com.sap.sse.datamining.impl.components.AbstractParallelProcessor; |
| 9 | 10 | import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; |
| 10 | 11 | import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; |
| ... | ... | @@ -26,7 +27,7 @@ public abstract class AbstractParallelAggregationProcessor<InputType, Aggregated |
| 26 | 27 | } |
| 27 | 28 | |
| 28 | 29 | @Override |
| 29 | - protected AbstractProcessorInstruction<AggregatedType> createInstruction(final InputType element) { |
|
| 30 | + protected ProcessorInstruction<AggregatedType> createInstruction(final InputType element) { |
|
| 30 | 31 | if (needsSynchronization()) { |
| 31 | 32 | return new AbstractProcessorInstruction<AggregatedType>(this, ProcessorInstructionPriority.Aggregation) { |
| 32 | 33 | @Override |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberDataAverageAggregationProcessor.java
| ... | ... | @@ -82,6 +82,9 @@ public class ParallelGroupedNumberDataAverageAggregationProcessor |
| 82 | 82 | protected Map<GroupKey, AverageWithStats<Number>> aggregateResult() { |
| 83 | 83 | Map<GroupKey, AverageWithStats<Number>> result = new HashMap<>(); |
| 84 | 84 | for (Entry<GroupKey, DoubleHolder> sumAggregationEntry : sumPerKey.entrySet()) { |
| 85 | + if (isAborted()) { |
|
| 86 | + break; |
|
| 87 | + } |
|
| 85 | 88 | GroupKey key = sumAggregationEntry.getKey(); |
| 86 | 89 | result.put(key, new AverageWithStatsImpl<Number>(sumAggregationEntry.getValue().value / elementAmountPerKey.get(key).get(), |
| 87 | 90 | minPerKey.get(key), maxPerKey.get(key), |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberDataMedianAggregationProcessor.java
| ... | ... | @@ -47,6 +47,9 @@ public class ParallelGroupedNumberDataMedianAggregationProcessor |
| 47 | 47 | protected Map<GroupKey, Number> aggregateResult() { |
| 48 | 48 | Map<GroupKey, Number> result = new HashMap<>(); |
| 49 | 49 | for (Entry<GroupKey, List<Number>> groupedValuesEntry : groupedValues.entrySet()) { |
| 50 | + if (isAborted()) { |
|
| 51 | + break; |
|
| 52 | + } |
|
| 50 | 53 | result.put(groupedValuesEntry.getKey(), getMedianOf(groupedValuesEntry.getValue())); |
| 51 | 54 | } |
| 52 | 55 | return result; |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairAverageAggregationProcessor.java
| ... | ... | @@ -90,6 +90,9 @@ public class ParallelGroupedNumberPairAverageAggregationProcessor |
| 90 | 90 | protected Map<GroupKey, PairWithStats<Number>> aggregateResult() { |
| 91 | 91 | Map<GroupKey, PairWithStats<Number>> result = new HashMap<>(); |
| 92 | 92 | for (Entry<GroupKey, Pair<Number, Number>> sumAggregationEntry : sumPerKey.entrySet()) { |
| 93 | + if (isAborted()) { |
|
| 94 | + break; |
|
| 95 | + } |
|
| 93 | 96 | GroupKey key = sumAggregationEntry.getKey(); |
| 94 | 97 | result.put(key, new PairWithStatsImpl<Number>(new Pair<>(sumAggregationEntry.getValue().getA() != null ? sumAggregationEntry.getValue().getA().doubleValue() / elementAmountPerKey.get(key).get() : null, sumAggregationEntry.getValue().getB() != null ? sumAggregationEntry.getValue().getB().doubleValue() / elementAmountPerKey.get(key).get() : null) , |
| 95 | 98 | minPerKey.get(key), maxPerKey.get(key), |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/ParallelGroupedNumberPairCollectingProcessor.java
| ... | ... | @@ -81,6 +81,9 @@ public class ParallelGroupedNumberPairCollectingProcessor |
| 81 | 81 | protected Map<GroupKey, PairWithStats<Number>> aggregateResult() { |
| 82 | 82 | Map<GroupKey, PairWithStats<Number>> result = new HashMap<>(); |
| 83 | 83 | for (Entry<GroupKey, HashSet<Pair<Number, Number>>> sumAggregationEntry : individualPairs.entrySet()) { |
| 84 | + if (isAborted()) { |
|
| 85 | + break; |
|
| 86 | + } |
|
| 84 | 87 | GroupKey key = sumAggregationEntry.getKey(); |
| 85 | 88 | result.put(key, new PairWithStatsImpl<Number>(null, |
| 86 | 89 | /* min */ null, |
java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/functions/ConcatenatingCompoundFunction.java
| ... | ... | @@ -228,7 +228,7 @@ public class ConcatenatingCompoundFunction<ReturnType> extends AbstractFunction< |
| 228 | 228 | |
| 229 | 229 | @Override |
| 230 | 230 | public String toString() { |
| 231 | - return getSimpleName(); |
|
| 231 | + return getDeclaringType().getSimpleName() + "." + getSimpleName() + " : " + getReturnType().getSimpleName(); |
|
| 232 | 232 | } |
| 233 | 233 | |
| 234 | 234 | @Override |
java/com.sap.sse.gwt.test/.project
| ... | ... | @@ -21,16 +21,6 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | - <arguments> |
|
| 26 | - </arguments> |
|
| 27 | - </buildCommand> |
|
| 28 | - <buildCommand> |
|
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | - <arguments> |
|
| 31 | - </arguments> |
|
| 32 | - </buildCommand> |
|
| 33 | - <buildCommand> |
|
| 34 | 24 | <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
| 35 | 25 | <arguments> |
| 36 | 26 | </arguments> |
| ... | ... | @@ -44,7 +34,6 @@ |
| 44 | 34 | <natures> |
| 45 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 46 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 47 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 48 | 37 | <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
| 49 | 38 | </natures> |
| 50 | 39 | </projectDescription> |
java/com.sap.sse.gwt/.project
| ... | ... | @@ -11,16 +11,6 @@ |
| 11 | 11 | </arguments> |
| 12 | 12 | </buildCommand> |
| 13 | 13 | <buildCommand> |
| 14 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 15 | - <arguments> |
|
| 16 | - </arguments> |
|
| 17 | - </buildCommand> |
|
| 18 | - <buildCommand> |
|
| 19 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 20 | - <arguments> |
|
| 21 | - </arguments> |
|
| 22 | - </buildCommand> |
|
| 23 | - <buildCommand> |
|
| 24 | 14 | <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
| 25 | 15 | <arguments> |
| 26 | 16 | </arguments> |
| ... | ... | @@ -33,7 +23,7 @@ |
| 33 | 23 | </buildSpec> |
| 34 | 24 | <natures> |
| 35 | 25 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 36 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 26 | + <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
|
| 37 | 27 | <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
| 38 | 28 | </natures> |
| 39 | 29 | </projectDescription> |
java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/NotificationPanel.java
| ... | ... | @@ -1,9 +1,13 @@ |
| 1 | 1 | package com.sap.sse.gwt.client; |
| 2 | 2 | |
| 3 | 3 | import com.google.gwt.animation.client.Animation; |
| 4 | +import com.google.gwt.dom.client.Element; |
|
| 4 | 5 | import com.google.gwt.dom.client.Style.Cursor; |
| 5 | -import com.google.gwt.event.dom.client.ClickEvent; |
|
| 6 | -import com.google.gwt.event.dom.client.ClickHandler; |
|
| 6 | +import com.google.gwt.event.shared.HandlerRegistration; |
|
| 7 | +import com.google.gwt.storage.client.Storage; |
|
| 8 | +import com.google.gwt.user.client.Event; |
|
| 9 | +import com.google.gwt.user.client.Event.NativePreviewEvent; |
|
| 10 | +import com.google.gwt.user.client.Event.NativePreviewHandler; |
|
| 7 | 11 | import com.google.gwt.user.client.ui.FlowPanel; |
| 8 | 12 | import com.google.gwt.user.client.ui.Panel; |
| 9 | 13 | import com.sap.sse.gwt.client.Notification.NotificationType; |
| ... | ... | @@ -24,6 +28,7 @@ public class NotificationPanel { |
| 24 | 28 | private final Animation animation; |
| 25 | 29 | |
| 26 | 30 | private boolean alreadyShown = false; |
| 31 | + private HandlerRegistration registration; |
|
| 27 | 32 | |
| 28 | 33 | |
| 29 | 34 | public NotificationPanel(String message, NotificationType type, Panel parent) { |
| ... | ... | @@ -37,12 +42,17 @@ public class NotificationPanel { |
| 37 | 42 | panel.getElement().getStyle().setColor(type.getColor()); |
| 38 | 43 | panel.getElement().getStyle().setBackgroundColor(type.getBackgroundColor()); |
| 39 | 44 | panel.getElement().setInnerText(type.getDecorator() + " " + message); |
| 40 | - panel.addDomHandler(new ClickHandler() { |
|
| 45 | + |
|
| 46 | + // ensure notifications work if a dataentry dialog is open! |
|
| 47 | + registration = Event.addNativePreviewHandler(new NativePreviewHandler() { |
|
| 41 | 48 | @Override |
| 42 | - public void onClick(ClickEvent event) { |
|
| 43 | - animation.cancel(); |
|
| 49 | + public void onPreviewNativeEvent(NativePreviewEvent event) { |
|
| 50 | + Element target = Element.as(event.getNativeEvent().getEventTarget()); |
|
| 51 | + if (event.getTypeInt() == Event.ONCLICK && target == panel.getElement()) { |
|
| 52 | + animation.cancel(); |
|
| 53 | + } |
|
| 44 | 54 | } |
| 45 | - }, ClickEvent.getType()); |
|
| 55 | + }); |
|
| 46 | 56 | |
| 47 | 57 | animation = new Animation() { |
| 48 | 58 | @Override |
| ... | ... | @@ -61,7 +71,7 @@ public class NotificationPanel { |
| 61 | 71 | double relPr = (progress - FADE_OUT_PERCENT) / (1 - FADE_OUT_PERCENT); |
| 62 | 72 | panel.getElement().getStyle().setOpacity(1 - relPr); |
| 63 | 73 | } else { |
| 64 | - panel.getElement().getStyle().setOpacity(1); |
|
| 74 | + panel.getElement().getStyle().clearOpacity(); |
|
| 65 | 75 | } |
| 66 | 76 | } |
| 67 | 77 | |
| ... | ... | @@ -81,9 +91,21 @@ public class NotificationPanel { |
| 81 | 91 | * Displays notification at UI. |
| 82 | 92 | */ |
| 83 | 93 | public void show() { |
| 94 | + final Storage localStorageIfSupported = Storage.getLocalStorageIfSupported(); |
|
| 95 | + int timeout = NOTIFICATION_TIME; |
|
| 96 | + if (localStorageIfSupported != null) { |
|
| 97 | + final String customTimeOut = localStorageIfSupported.getItem("sse.notification.customTimeOutInSeconds"); |
|
| 98 | + if (customTimeOut != null && !customTimeOut.isEmpty()) { |
|
| 99 | + try { |
|
| 100 | + timeout = Integer.parseInt(customTimeOut) * 1000; |
|
| 101 | + } catch (Exception e) { |
|
| 102 | + // If the value can't be parsed, we just use the default |
|
| 103 | + } |
|
| 104 | + } |
|
| 105 | + } |
|
| 84 | 106 | if (!animation.isRunning()) { |
| 85 | 107 | parent.add(panel); |
| 86 | - animation.run(NOTIFICATION_TIME); |
|
| 108 | + animation.run(timeout); |
|
| 87 | 109 | } |
| 88 | 110 | } |
| 89 | 111 | |
| ... | ... | @@ -99,6 +121,7 @@ public class NotificationPanel { |
| 99 | 121 | * Removes panel from parent element at UI and force checking of queue for notifications. |
| 100 | 122 | */ |
| 101 | 123 | public void remove() { |
| 124 | + registration.removeHandler(); |
|
| 102 | 125 | parent.remove(panel); |
| 103 | 126 | Notification.checkQueue(this); |
| 104 | 127 | } |
java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/controls/datetime/DateInput.java
| ... | ... | @@ -14,7 +14,7 @@ public class DateInput extends AbstractInput { |
| 14 | 14 | * Created a new {@link DateInput} instance. |
| 15 | 15 | */ |
| 16 | 16 | public DateInput() { |
| 17 | - super(DateTimeInputType.TIME.isSupported() ? NativeDateTimeInput.date() : new CustomDateBox()); |
|
| 17 | + super(DateTimeInputType.DATE.isSupported() ? NativeDateTimeInput.date() : new CustomDateBox()); |
|
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | private static class CustomDateBox extends DateBox { |
java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/suggestion/AbstractListSuggestOracle.java
| ... | ... | @@ -18,8 +18,9 @@ public abstract class AbstractListSuggestOracle<C> extends AbstractSuggestOracle |
| 18 | 18 | |
| 19 | 19 | @Override |
| 20 | 20 | protected final void getSuggestions(Request request, Callback callback, Iterable<String> queryTokens) { |
| 21 | - Iterable<C> filteredList = suggestionMatchingFilter.applyFilter(getKeywordStrings(queryTokens), suggestionObjectList); |
|
| 22 | - this.setSuggestions(request, callback, filteredList, queryTokens); |
|
| 21 | + Iterable<String> keywords = getKeywordStrings(queryTokens); |
|
| 22 | + Iterable<C> filteredList = suggestionMatchingFilter.applyFilter(keywords, suggestionObjectList); |
|
| 23 | + this.setSuggestions(request, callback, filteredList, keywords); |
|
| 23 | 24 | } |
| 24 | 25 | |
| 25 | 26 | protected Iterable<String> getKeywordStrings(Iterable<String> queryTokens) { |
java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/suggestion/AbstractSuggestOracle.java
| ... | ... | @@ -90,10 +90,12 @@ public abstract class AbstractSuggestOracle<T> extends SuggestOracle { |
| 90 | 90 | int index = displayString.length(); |
| 91 | 91 | String matchToken = null; |
| 92 | 92 | for (String token : queryTokens) { |
| 93 | - int matchIndex = normalizedString.indexOf(token, cursor); |
|
| 94 | - if (matchIndex >= 0 && matchIndex < index) { |
|
| 95 | - index = matchIndex; |
|
| 96 | - matchToken = token; |
|
| 93 | + if (token != null && !token.isEmpty()) { |
|
| 94 | + int matchIndex = normalizedString.indexOf(token, cursor); |
|
| 95 | + if (matchIndex >= 0 && matchIndex < index) { |
|
| 96 | + index = matchIndex; |
|
| 97 | + matchToken = token; |
|
| 98 | + } |
|
| 97 | 99 | } |
| 98 | 100 | } |
| 99 | 101 | if (matchToken != null) { |
java/com.sap.sse.security.ui/.project
| ... | ... | @@ -21,16 +21,6 @@ |
| 21 | 21 | </arguments> |
| 22 | 22 | </buildCommand> |
| 23 | 23 | <buildCommand> |
| 24 | - <name>com.google.gdt.eclipse.core.webAppProjectValidator</name> |
|
| 25 | - <arguments> |
|
| 26 | - </arguments> |
|
| 27 | - </buildCommand> |
|
| 28 | - <buildCommand> |
|
| 29 | - <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> |
|
| 30 | - <arguments> |
|
| 31 | - </arguments> |
|
| 32 | - </buildCommand> |
|
| 33 | - <buildCommand> |
|
| 34 | 24 | <name>com.gwtplugins.gdt.eclipse.core.webAppProjectValidator</name> |
| 35 | 25 | <arguments> |
| 36 | 26 | </arguments> |
| ... | ... | @@ -44,7 +34,6 @@ |
| 44 | 34 | <natures> |
| 45 | 35 | <nature>org.eclipse.pde.PluginNature</nature> |
| 46 | 36 | <nature>org.eclipse.jdt.core.javanature</nature> |
| 47 | - <nature>com.google.gwt.eclipse.core.gwtNature</nature> |
|
| 48 | 37 | <nature>com.gwtplugins.gwt.eclipse.core.gwtNature</nature> |
| 49 | 38 | </natures> |
| 50 | 39 | </projectDescription> |
java/com.tractrac.clientmodule/META-INF/MANIFEST.MF
| ... | ... | @@ -2,7 +2,7 @@ Manifest-Version: 1.0 |
| 2 | 2 | Bundle-ManifestVersion: 2 |
| 3 | 3 | Bundle-Name: TracTrac Client module |
| 4 | 4 | Bundle-SymbolicName: com.tractrac.clientmodule |
| 5 | -Bundle-Version: 3.10.1 |
|
| 5 | +Bundle-Version: 3.11.0 |
|
| 6 | 6 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 |
| 7 | 7 | Bundle-ClassPath: ., |
| 8 | 8 | lib/TracAPI.jar |
| ... | ... | @@ -88,7 +88,6 @@ Export-Package: com.tractrac.asio.lib.api, |
| 88 | 88 | com.tractrac.subscription.lib.impl.io.controllers, |
| 89 | 89 | com.tractrac.subscription.lib.impl.io.receivers, |
| 90 | 90 | com.tractrac.subscription.lib.impl.race, |
| 91 | - com.tractrac.subscription.lib.impl.route, |
|
| 92 | 91 | com.tractrac.subscription.lib.impl.ws, |
| 93 | 92 | com.tractrac.util.lib.api, |
| 94 | 93 | com.tractrac.util.lib.api.autolog, |
java/com.tractrac.clientmodule/README.txt
| ... | ... | @@ -17,10 +17,38 @@ It contains also some files: |
| 17 | 17 | - Manifest.txt -> manifest used to create the test.jar file |
| 18 | 18 | |
| 19 | 19 | ******************************************** |
| 20 | +************* TracAPI 3.11.0 *************** |
|
| 21 | +******************************************** |
|
| 22 | +This is a final version. It changes the implementation of the IRaceSubscriber interface, |
|
| 23 | +breaking the backward compatibility: |
|
| 24 | + |
|
| 25 | + - The methods IRaceSubscriber.subscribeRoutes() and IRaceSubscriber.unsubscribeRoutes() |
|
| 26 | + have been removed. |
|
| 27 | + - The IRoutesListener has been removed. |
|
| 28 | + - The IControlRouteChangeListener has been extended adding a new method to get updates |
|
| 29 | + of a IPathRoute. If you are managing "sailing events" this method will never be invoked. |
|
| 30 | + - When any of the attributes of the route is updated, will be notified using the |
|
| 31 | + IRaceSubscriber.subscribeRouteChanges(IControlRouteChangeListener) method |
|
| 32 | + |
|
| 33 | +Release date: 30/07/2018 |
|
| 34 | +Build number: 416b827959b696583cce509ac39b7fd64aaefe9b |
|
| 35 | + |
|
| 36 | + 1) Features |
|
| 37 | + |
|
| 38 | + - Merging the subscriptions IRaceSubscriber.subscribeRouteChanges and IRaceSubscriber.subscribeRoutes |
|
| 39 | + in the same method (Requested by Axel Uhl, 23/07/2018) |
|
| 40 | + |
|
| 41 | + 2) Bugs |
|
| 42 | + |
|
| 43 | + - When the client is offline, if it tries to load a race it gets a RaceLoadingException. But then, |
|
| 44 | + when the client is online again, it can't reuse the same race because it is in an internal wrong |
|
| 45 | + status (Reported by Thomas Scott, 19/06/2018) |
|
| 46 | + |
|
| 47 | +******************************************** |
|
| 20 | 48 | ************* TracAPI 3.10.1 *************** |
| 21 | 49 | ******************************************** |
| 22 | - This is a final version.It fixes bugs in the implementation and it adds a some features. |
|
| 23 | - It keeps the backward compatibility. |
|
| 50 | +This is a final version.It fixes bugs in the implementation and it adds a some features. |
|
| 51 | +It keeps the backward compatibility: |
|
| 24 | 52 | |
| 25 | 53 | Release date: 28/06/2018 |
| 26 | 54 | Build number: 35a26e503339fff26fe984617e5190a18438e10b |
| ... | ... | @@ -35,7 +63,7 @@ It contains also some files: |
| 35 | 63 | when the client is online again, it can't reuse the same race because it is in an internal wrong |
| 36 | 64 | status (Reported by Thomas Scott, 19/06/2018) |
| 37 | 65 | - The live delay is not propagated (sometimes). This feature has been reimplemented and now the |
| 38 | - value is attached and send with the race object using the same approach used to transmit the race |
|
| 66 | + value is attached and sent with the race object using the same approach used to transmit the race |
|
| 39 | 67 | start time or the tracking start time (Reported by Axel Uhl, 19/06/2018) |
| 40 | 68 | |
| 41 | 69 | ******************************************** |
java/com.tractrac.clientmodule/javadoc/allclasses-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>All Classes</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/allclasses-noframe.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>All Classes</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/IIdentifiable.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IIdentifiable</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/INamed.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>INamed</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/ModelLocator.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ModelLocator</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/AbstractAttachable.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>AbstractAttachable</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/IAttachable.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IAttachable</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/IAttachmentKey.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IAttachmentKey</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/IAttachmentManager.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IAttachmentManager</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.attachment</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.attachment</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/attachment/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.attachment Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IControlPassing.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IControlPassing</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IControlPassings.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IControlPassings</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -128,7 +128,7 @@ var activeTableTab = "activeTableTab"; |
| 128 | 128 | <td class="colFirst"><code>java.util.List<<a href="../../../../../../com/tractrac/model/lib/api/data/IControlPassing.html" title="interface in com.tractrac.model.lib.api.data">IControlPassing</a>></code></td> |
| 129 | 129 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../com/tractrac/model/lib/api/data/IControlPassings.html#getPassings--">getPassings</a></span>()</code> |
| 130 | 130 | <div class="block"> |
| 131 | - Returns a list of control passings.</div> |
|
| 131 | + Returns a list of control passings sorted by time.</div> |
|
| 132 | 132 | </td> |
| 133 | 133 | </tr> |
| 134 | 134 | </table> |
| ... | ... | @@ -154,7 +154,7 @@ var activeTableTab = "activeTableTab"; |
| 154 | 154 | <h4>getPassings</h4> |
| 155 | 155 | <pre>java.util.List<<a href="../../../../../../com/tractrac/model/lib/api/data/IControlPassing.html" title="interface in com.tractrac.model.lib.api.data">IControlPassing</a>> getPassings()</pre> |
| 156 | 156 | <div class="block"><p> |
| 157 | - Returns a list of control passings. |
|
| 157 | + Returns a list of control passings sorted by time. |
|
| 158 | 158 | </p> |
| 159 | 159 | <p> |
| 160 | 160 | This method is thread-safety: it returns a copy of the list. |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IMessageData.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IMessageData</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IPosition.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPosition</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IPositionFactory.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPositionFactory</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IPositionOffset.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPositionOffset</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IPositionSnapped.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPositionSnapped</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/IStartStopData.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IStartStopData</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/ITimeData.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ITimeData</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.data</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.data</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/data/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.data Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/CreateModelException.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>CreateModelException</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/DataSource.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>DataSource</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/EventType.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>EventType</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/ICompetitor.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ICompetitor</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/ICompetitorClass.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ICompetitorClass</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/IEvent.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IEvent</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/IEventFactory.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IEventFactory</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/IRace.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IRace</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/IRaceCompetitor.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IRaceCompetitor</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/IRaceSerie.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IRaceSerie</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/ITeam.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ITeam</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/RaceCompetitorStatusType.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>RaceCompetitorStatusType</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/RaceLoadingException.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>RaceLoadingException</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/RaceStatusType.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>RaceStatusType</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/RaceVisibilityType.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>RaceVisibilityType</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/StartTimeType.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>StartTimeType</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.event</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.event</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/event/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.event Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -150,12 +150,12 @@ |
| 150 | 150 | <ul> |
| 151 | 151 | <li type="circle">java.lang.Enum<E> (implements java.lang.Comparable<T>, java.io.Serializable) |
| 152 | 152 | <ul> |
| 153 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/RaceVisibilityType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceVisibilityType</span></a></li> |
|
| 154 | 153 | <li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/EventType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">EventType</span></a></li> |
| 155 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/StartTimeType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">StartTimeType</span></a></li> |
|
| 156 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/RaceStatusType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceStatusType</span></a></li> |
|
| 157 | 154 | <li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/RaceCompetitorStatusType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceCompetitorStatusType</span></a></li> |
| 158 | 155 | <li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/DataSource.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">DataSource</span></a></li> |
| 156 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/RaceStatusType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceStatusType</span></a></li> |
|
| 157 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/RaceVisibilityType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceVisibilityType</span></a></li> |
|
| 158 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="../../../../../../com/tractrac/model/lib/api/event/StartTimeType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">StartTimeType</span></a></li> |
|
| 159 | 159 | </ul> |
| 160 | 160 | </li> |
| 161 | 161 | </ul> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/IMetadata.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IMetadata</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/IMetadataContainer.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IMetadataContainer</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/IMetadataFactory.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IMetadataFactory</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/IPropertiesContainer.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPropertiesContainer</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.metadata</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.metadata</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/metadata/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.metadata Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IControl.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IControl</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IControlPoint.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IControlPoint</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IControlRoute.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IControlRoute</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IPathRoute.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPathRoute</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IPathRouteFactory.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPathRouteFactory</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IPathSegment.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IPathSegment</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/IRoute.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IRoute</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/ISegment.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ISegment</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.route</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.route</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/route/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.route Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/sensor/ISensorData.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ISensorData</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/sensor/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.sensor</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/sensor/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.sensor</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/sensor/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.sensor Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/ICoordinate.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ICoordinate</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/ICoordinateSequence.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ICoordinateSequence</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/IExtent.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IExtent</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/IGeoCoordinate.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IGeoCoordinate</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.spatial</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.spatial</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/model/lib/api/spatial/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.model.lib.api.spatial Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/IEventSubscriber.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IEventSubscriber</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/IRaceSubscriber.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IRaceSubscriber</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | catch(err) { |
| 19 | 19 | } |
| 20 | 20 | //--> |
| 21 | -var methods = {"i0":6,"i1":6,"i2":6,"i3":6,"i4":6,"i5":6,"i6":6,"i7":6,"i8":6,"i9":6,"i10":6,"i11":6,"i12":6,"i13":6,"i14":6,"i15":6,"i16":6,"i17":6,"i18":6,"i19":6,"i20":6,"i21":6,"i22":6,"i23":6,"i24":6,"i25":6,"i26":6,"i27":6,"i28":6,"i29":6}; |
|
| 21 | +var methods = {"i0":6,"i1":6,"i2":6,"i3":6,"i4":6,"i5":6,"i6":6,"i7":6,"i8":6,"i9":6,"i10":6,"i11":6,"i12":6,"i13":6,"i14":6,"i15":6,"i16":6,"i17":6,"i18":6,"i19":6,"i20":6,"i21":6,"i22":6,"i23":6,"i24":6,"i25":6,"i26":6,"i27":6,"i28":6,"i29":6,"i30":6,"i31":6,"i32":6}; |
|
| 22 | 22 | var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],4:["t3","Abstract Methods"]}; |
| 23 | 23 | var altColor = "altColor"; |
| 24 | 24 | var rowColor = "rowColor"; |
| ... | ... | @@ -149,11 +149,18 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 149 | 149 | </tr> |
| 150 | 150 | <tr id="i3" class="rowColor"> |
| 151 | 151 | <td class="colFirst"><code>void</code></td> |
| 152 | +<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlPassings-com.tractrac.subscription.lib.api.control.IControlPassingsListener-java.util.UUID...-">subscribeControlPassings</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPassingsListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPassingsListener</a> listener, |
|
| 153 | + java.util.UUID... classIds)</code> |
|
| 154 | +<div class="block">Subscribes to control passing data for the specified race and a class(es)</div> |
|
| 155 | +</td> |
|
| 156 | +</tr> |
|
| 157 | +<tr id="i4" class="altColor"> |
|
| 158 | +<td class="colFirst"><code>void</code></td> |
|
| 152 | 159 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlPositions-com.tractrac.subscription.lib.api.control.IControlPointPositionListener-">subscribeControlPositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointPositionListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointPositionListener</a> listener)</code> |
| 153 | 160 | <div class="block">Subscribes to control positions for the race.</div> |
| 154 | 161 | </td> |
| 155 | 162 | </tr> |
| 156 | -<tr id="i4" class="altColor"> |
|
| 163 | +<tr id="i5" class="rowColor"> |
|
| 157 | 164 | <td class="colFirst"><code>void</code></td> |
| 158 | 165 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlPositions-com.tractrac.subscription.lib.api.control.IControlPointPositionListener-long-long-">subscribeControlPositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointPositionListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointPositionListener</a> listener, |
| 159 | 166 | long fromTime, |
| ... | ... | @@ -162,13 +169,13 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 162 | 169 | data.</div> |
| 163 | 170 | </td> |
| 164 | 171 | </tr> |
| 165 | -<tr id="i5" class="rowColor"> |
|
| 172 | +<tr id="i6" class="altColor"> |
|
| 166 | 173 | <td class="colFirst"><code>void</code></td> |
| 167 | 174 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlSensorData-com.tractrac.subscription.lib.api.control.IControlPointSensorDataListener-">subscribeControlSensorData</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointSensorDataListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointSensorDataListener</a> listener)</code> |
| 168 | 175 | <div class="block">Subscribes to control sensor data for the race.</div> |
| 169 | 176 | </td> |
| 170 | 177 | </tr> |
| 171 | -<tr id="i6" class="altColor"> |
|
| 178 | +<tr id="i7" class="rowColor"> |
|
| 172 | 179 | <td class="colFirst"><code>void</code></td> |
| 173 | 180 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlSensorData-com.tractrac.subscription.lib.api.control.IControlPointSensorDataListener-long-long-">subscribeControlSensorData</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointSensorDataListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointSensorDataListener</a> listener, |
| 174 | 181 | long fromTime, |
| ... | ... | @@ -177,13 +184,13 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 177 | 184 | data.</div> |
| 178 | 185 | </td> |
| 179 | 186 | </tr> |
| 180 | -<tr id="i7" class="rowColor"> |
|
| 187 | +<tr id="i8" class="altColor"> |
|
| 181 | 188 | <td class="colFirst"><code>void</code></td> |
| 182 | 189 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-">subscribePositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener)</code> |
| 183 | 190 | <div class="block">Subscribes to competitor positions for a given Race.</div> |
| 184 | 191 | </td> |
| 185 | 192 | </tr> |
| 186 | -<tr id="i8" class="altColor"> |
|
| 193 | +<tr id="i9" class="rowColor"> |
|
| 187 | 194 | <td class="colFirst"><code>void</code></td> |
| 188 | 195 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-long-long-">subscribePositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener, |
| 189 | 196 | long fromTime, |
| ... | ... | @@ -191,13 +198,29 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 191 | 198 | <div class="block">Subscribes to competitor positions for a given Race.</div> |
| 192 | 199 | </td> |
| 193 | 200 | </tr> |
| 194 | -<tr id="i9" class="rowColor"> |
|
| 201 | +<tr id="i10" class="altColor"> |
|
| 202 | +<td class="colFirst"><code>void</code></td> |
|
| 203 | +<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-long-long-java.util.UUID...-">subscribePositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener, |
|
| 204 | + long fromTime, |
|
| 205 | + long toTime, |
|
| 206 | + java.util.UUID... classIds)</code> |
|
| 207 | +<div class="block">Subscribes to competitor positions for a given Race and class(es).</div> |
|
| 208 | +</td> |
|
| 209 | +</tr> |
|
| 210 | +<tr id="i11" class="rowColor"> |
|
| 211 | +<td class="colFirst"><code>void</code></td> |
|
| 212 | +<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-java.util.UUID...-">subscribePositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener, |
|
| 213 | + java.util.UUID... classIds)</code> |
|
| 214 | +<div class="block">Subscribes to competitor positions for a given Race and class(es).</div> |
|
| 215 | +</td> |
|
| 216 | +</tr> |
|
| 217 | +<tr id="i12" class="altColor"> |
|
| 195 | 218 | <td class="colFirst"><code>void</code></td> |
| 196 | 219 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsOffset-com.tractrac.subscription.lib.api.competitor.IPositionOffsetListener-">subscribePositionsOffset</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionOffsetListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionOffsetListener</a> listener)</code> |
| 197 | 220 | <div class="block">Subscribes to offset competitor positions for a given Race.</div> |
| 198 | 221 | </td> |
| 199 | 222 | </tr> |
| 200 | -<tr id="i10" class="altColor"> |
|
| 223 | +<tr id="i13" class="rowColor"> |
|
| 201 | 224 | <td class="colFirst"><code>void</code></td> |
| 202 | 225 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsOffset-com.tractrac.subscription.lib.api.competitor.IPositionOffsetListener-long-long-">subscribePositionsOffset</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionOffsetListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionOffsetListener</a> listener, |
| 203 | 226 | long fromTime, |
| ... | ... | @@ -206,13 +229,13 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 206 | 229 | historic data.</div> |
| 207 | 230 | </td> |
| 208 | 231 | </tr> |
| 209 | -<tr id="i11" class="rowColor"> |
|
| 232 | +<tr id="i14" class="altColor"> |
|
| 210 | 233 | <td class="colFirst"><code>void</code></td> |
| 211 | 234 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-">subscribePositionsSnapped</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener)</code> |
| 212 | 235 | <div class="block">Subscribes to snapped competitor positions for a given Race.</div> |
| 213 | 236 | </td> |
| 214 | 237 | </tr> |
| 215 | -<tr id="i12" class="altColor"> |
|
| 238 | +<tr id="i15" class="rowColor"> |
|
| 216 | 239 | <td class="colFirst"><code>void</code></td> |
| 217 | 240 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-long-long-">subscribePositionsSnapped</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener, |
| 218 | 241 | long fromTime, |
| ... | ... | @@ -221,110 +244,113 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 221 | 244 | historic data.</div> |
| 222 | 245 | </td> |
| 223 | 246 | </tr> |
| 224 | -<tr id="i13" class="rowColor"> |
|
| 247 | +<tr id="i16" class="altColor"> |
|
| 248 | +<td class="colFirst"><code>void</code></td> |
|
| 249 | +<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-long-long-java.util.UUID...-">subscribePositionsSnapped</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener, |
|
| 250 | + long fromTime, |
|
| 251 | + long toTime, |
|
| 252 | + java.util.UUID... classIds)</code> |
|
| 253 | +<div class="block">Subscribes to snapped competitor positions for a given Race and class(es), including |
|
| 254 | + historic data.</div> |
|
| 255 | +</td> |
|
| 256 | +</tr> |
|
| 257 | +<tr id="i17" class="rowColor"> |
|
| 258 | +<td class="colFirst"><code>void</code></td> |
|
| 259 | +<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-java.util.UUID...-">subscribePositionsSnapped</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener, |
|
| 260 | + java.util.UUID... classIds)</code> |
|
| 261 | +<div class="block">Subscribes to snapped competitor positions for a given Race and class(es).</div> |
|
| 262 | +</td> |
|
| 263 | +</tr> |
|
| 264 | +<tr id="i18" class="altColor"> |
|
| 225 | 265 | <td class="colFirst"><code>void</code></td> |
| 226 | 266 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRaceCompetitor-com.tractrac.subscription.lib.api.race.IRaceCompetitorListener-">subscribeRaceCompetitor</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceCompetitorListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceCompetitorListener</a> listener)</code> |
| 227 | 267 | <div class="block">Subscribes to race competitor for a given Race.</div> |
| 228 | 268 | </td> |
| 229 | 269 | </tr> |
| 230 | -<tr id="i14" class="altColor"> |
|
| 270 | +<tr id="i19" class="rowColor"> |
|
| 231 | 271 | <td class="colFirst"><code>void</code></td> |
| 232 | 272 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRaceMessages-com.tractrac.subscription.lib.api.race.IRaceMessageListener-">subscribeRaceMessages</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceMessageListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceMessageListener</a> listener)</code> |
| 233 | 273 | <div class="block">Subscribe to messages for a race.</div> |
| 234 | 274 | </td> |
| 235 | 275 | </tr> |
| 236 | -<tr id="i15" class="rowColor"> |
|
| 276 | +<tr id="i20" class="altColor"> |
|
| 237 | 277 | <td class="colFirst"><code>void</code></td> |
| 238 | 278 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRaceTimesChanges-com.tractrac.subscription.lib.api.race.IRaceStartStopTimesChangeListener-">subscribeRaceTimesChanges</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceStartStopTimesChangeListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceStartStopTimesChangeListener</a> listener)</code> |
| 239 | 279 | <div class="block">Subscribes to changes in race start and stop times.</div> |
| 240 | 280 | </td> |
| 241 | 281 | </tr> |
| 242 | -<tr id="i16" class="altColor"> |
|
| 282 | +<tr id="i21" class="rowColor"> |
|
| 243 | 283 | <td class="colFirst"><code>void</code></td> |
| 244 | 284 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRouteChanges-com.tractrac.subscription.lib.api.control.IControlRouteChangeListener-">subscribeRouteChanges</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlRouteChangeListener</a> listener)</code> |
| 245 | 285 | <div class="block">Subscribes to route changes for a given Race.</div> |
| 246 | 286 | </td> |
| 247 | 287 | </tr> |
| 248 | -<tr id="i17" class="rowColor"> |
|
| 249 | -<td class="colFirst"><code>void</code></td> |
|
| 250 | -<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRoutes-com.tractrac.subscription.lib.api.route.IRoutesListener-">subscribeRoutes</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/route/IRoutesListener.html" title="interface in com.tractrac.subscription.lib.api.route">IRoutesListener</a> listener)</code> |
|
| 251 | -<div class="block"> |
|
| 252 | - Subscriber to route changes.</div> |
|
| 253 | -</td> |
|
| 254 | -</tr> |
|
| 255 | -<tr id="i18" class="altColor"> |
|
| 288 | +<tr id="i22" class="altColor"> |
|
| 256 | 289 | <td class="colFirst"><code>void</code></td> |
| 257 | 290 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeCompetitorSensorData-com.tractrac.subscription.lib.api.competitor.ICompetitorSensorDataListener-">unsubscribeCompetitorSensorData</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/ICompetitorSensorDataListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">ICompetitorSensorDataListener</a> listener)</code> |
| 258 | 291 | <div class="block">Unsubscribes to competitor sensor data for a given Race.</div> |
| 259 | 292 | </td> |
| 260 | 293 | </tr> |
| 261 | -<tr id="i19" class="rowColor"> |
|
| 294 | +<tr id="i23" class="rowColor"> |
|
| 262 | 295 | <td class="colFirst"><code>void</code></td> |
| 263 | 296 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeControlPassings-com.tractrac.subscription.lib.api.control.IControlPassingsListener-">unsubscribeControlPassings</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPassingsListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPassingsListener</a> listener)</code> |
| 264 | 297 | <div class="block">Unsubscribes to control passing data for the specified race.</div> |
| 265 | 298 | </td> |
| 266 | 299 | </tr> |
| 267 | -<tr id="i20" class="altColor"> |
|
| 300 | +<tr id="i24" class="altColor"> |
|
| 268 | 301 | <td class="colFirst"><code>void</code></td> |
| 269 | 302 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeControlPositions-com.tractrac.subscription.lib.api.control.IControlPointPositionListener-">unsubscribeControlPositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointPositionListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointPositionListener</a> listener)</code> |
| 270 | 303 | <div class="block">Unsubscribes to control positions.</div> |
| 271 | 304 | </td> |
| 272 | 305 | </tr> |
| 273 | -<tr id="i21" class="rowColor"> |
|
| 306 | +<tr id="i25" class="rowColor"> |
|
| 274 | 307 | <td class="colFirst"><code>void</code></td> |
| 275 | 308 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeControlSensorData-com.tractrac.subscription.lib.api.control.IControlPointSensorDataListener-">unsubscribeControlSensorData</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointSensorDataListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointSensorDataListener</a> listener)</code> |
| 276 | 309 | <div class="block">Unsubscribes to control sensor data for a given Race.</div> |
| 277 | 310 | </td> |
| 278 | 311 | </tr> |
| 279 | -<tr id="i22" class="altColor"> |
|
| 312 | +<tr id="i26" class="altColor"> |
|
| 280 | 313 | <td class="colFirst"><code>void</code></td> |
| 281 | 314 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-">unsubscribePositions</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener)</code> |
| 282 | 315 | <div class="block">Unsubscribes to competitor positions for a given Race.</div> |
| 283 | 316 | </td> |
| 284 | 317 | </tr> |
| 285 | -<tr id="i23" class="rowColor"> |
|
| 318 | +<tr id="i27" class="rowColor"> |
|
| 286 | 319 | <td class="colFirst"><code>void</code></td> |
| 287 | 320 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribePositionsOffset-com.tractrac.subscription.lib.api.competitor.IPositionOffsetListener-">unsubscribePositionsOffset</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionOffsetListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionOffsetListener</a> listener)</code> |
| 288 | 321 | <div class="block">Unsubscribes to competitor positions for a given Race.</div> |
| 289 | 322 | </td> |
| 290 | 323 | </tr> |
| 291 | -<tr id="i24" class="altColor"> |
|
| 324 | +<tr id="i28" class="altColor"> |
|
| 292 | 325 | <td class="colFirst"><code>void</code></td> |
| 293 | 326 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-">unsubscribePositionsSnapped</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener)</code> |
| 294 | 327 | <div class="block">Unsubscribes to competitor positions for a given Race.</div> |
| 295 | 328 | </td> |
| 296 | 329 | </tr> |
| 297 | -<tr id="i25" class="rowColor"> |
|
| 330 | +<tr id="i29" class="rowColor"> |
|
| 298 | 331 | <td class="colFirst"><code>void</code></td> |
| 299 | 332 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeRaceCompetitor-com.tractrac.subscription.lib.api.race.IRaceCompetitorListener-">unsubscribeRaceCompetitor</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceCompetitorListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceCompetitorListener</a> listener)</code> |
| 300 | 333 | <div class="block">Unsubscribes to race competitor</div> |
| 301 | 334 | </td> |
| 302 | 335 | </tr> |
| 303 | -<tr id="i26" class="altColor"> |
|
| 336 | +<tr id="i30" class="altColor"> |
|
| 304 | 337 | <td class="colFirst"><code>void</code></td> |
| 305 | 338 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeRaceMessages-com.tractrac.subscription.lib.api.race.IRaceMessageListener-">unsubscribeRaceMessages</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceMessageListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceMessageListener</a> listener)</code> |
| 306 | 339 | <div class="block">Unsubscribes to race messages</div> |
| 307 | 340 | </td> |
| 308 | 341 | </tr> |
| 309 | -<tr id="i27" class="rowColor"> |
|
| 342 | +<tr id="i31" class="rowColor"> |
|
| 310 | 343 | <td class="colFirst"><code>void</code></td> |
| 311 | 344 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeRaceTimesChanges-com.tractrac.subscription.lib.api.race.IRaceStartStopTimesChangeListener-">unsubscribeRaceTimesChanges</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceStartStopTimesChangeListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceStartStopTimesChangeListener</a> listener)</code> |
| 312 | 345 | <div class="block">Unsubscribes to changes in race start and stop times.</div> |
| 313 | 346 | </td> |
| 314 | 347 | </tr> |
| 315 | -<tr id="i28" class="altColor"> |
|
| 348 | +<tr id="i32" class="altColor"> |
|
| 316 | 349 | <td class="colFirst"><code>void</code></td> |
| 317 | 350 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeRouteChanges-com.tractrac.subscription.lib.api.control.IControlRouteChangeListener-">unsubscribeRouteChanges</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlRouteChangeListener</a> listener)</code> |
| 318 | 351 | <div class="block">Unsubscribes to route changes for a given Race.</div> |
| 319 | 352 | </td> |
| 320 | 353 | </tr> |
| 321 | -<tr id="i29" class="rowColor"> |
|
| 322 | -<td class="colFirst"><code>void</code></td> |
|
| 323 | -<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeRoutes-com.tractrac.subscription.lib.api.route.IRoutesListener-">unsubscribeRoutes</a></span>(<a href="../../../../../com/tractrac/subscription/lib/api/route/IRoutesListener.html" title="interface in com.tractrac.subscription.lib.api.route">IRoutesListener</a> listener)</code> |
|
| 324 | -<div class="block"> |
|
| 325 | - Unsubscribes to route changes for a given Race.</div> |
|
| 326 | -</td> |
|
| 327 | -</tr> |
|
| 328 | 354 | </table> |
| 329 | 355 | <ul class="blockList"> |
| 330 | 356 | <li class="blockList"><a name="methods.inherited.from.class.com.tractrac.subscription.lib.api.ISubscriber"> |
| ... | ... | @@ -356,7 +382,28 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 356 | 382 | <pre>void subscribePositions(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener)</pre> |
| 357 | 383 | <div class="block">Subscribes to competitor positions for a given Race. It uses the tracking |
| 358 | 384 | start time and the tracking end time as time interval to receive positions. |
| 359 | - |
|
| 385 | + |
|
| 386 | + <p> |
|
| 387 | + The method returns immediately and the positions are subsequently sent to |
|
| 388 | + the given listener, as they are received. |
|
| 389 | + </p></div> |
|
| 390 | +<dl> |
|
| 391 | +<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 392 | +<dd><code>listener</code> - the listener to receive the positions.</dd> |
|
| 393 | +</dl> |
|
| 394 | +</li> |
|
| 395 | +</ul> |
|
| 396 | +<a name="subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-java.util.UUID...-"> |
|
| 397 | +<!-- --> |
|
| 398 | +</a> |
|
| 399 | +<ul class="blockList"> |
|
| 400 | +<li class="blockList"> |
|
| 401 | +<h4>subscribePositions</h4> |
|
| 402 | +<pre>void subscribePositions(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener, |
|
| 403 | + java.util.UUID... classIds)</pre> |
|
| 404 | +<div class="block">Subscribes to competitor positions for a given Race and class(es). It uses the tracking |
|
| 405 | + start time and the tracking end time as time interval to receive positions. |
|
| 406 | + |
|
| 360 | 407 | <p> |
| 361 | 408 | The method returns immediately and the positions are subsequently sent to |
| 362 | 409 | the given listener, as they are received. |
| ... | ... | @@ -364,6 +411,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 364 | 411 | <dl> |
| 365 | 412 | <dt><span class="paramLabel">Parameters:</span></dt> |
| 366 | 413 | <dd><code>listener</code> - the listener to receive the positions.</dd> |
| 414 | +<dd><code>classIds</code> - the class ids</dd> |
|
| 367 | 415 | </dl> |
| 368 | 416 | </li> |
| 369 | 417 | </ul> |
| ... | ... | @@ -377,7 +425,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 377 | 425 | long fromTime, |
| 378 | 426 | long toTime)</pre> |
| 379 | 427 | <div class="block">Subscribes to competitor positions for a given Race. |
| 380 | - |
|
| 428 | + |
|
| 381 | 429 | <p> |
| 382 | 430 | The method returns immediately and the positions are subsequently sent to |
| 383 | 431 | the given listener, as they are received. |
| ... | ... | @@ -392,6 +440,33 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 392 | 440 | </dl> |
| 393 | 441 | </li> |
| 394 | 442 | </ul> |
| 443 | +<a name="subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-long-long-java.util.UUID...-"> |
|
| 444 | +<!-- --> |
|
| 445 | +</a> |
|
| 446 | +<ul class="blockList"> |
|
| 447 | +<li class="blockList"> |
|
| 448 | +<h4>subscribePositions</h4> |
|
| 449 | +<pre>void subscribePositions(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionListener</a> listener, |
|
| 450 | + long fromTime, |
|
| 451 | + long toTime, |
|
| 452 | + java.util.UUID... classIds)</pre> |
|
| 453 | +<div class="block">Subscribes to competitor positions for a given Race and class(es). |
|
| 454 | + |
|
| 455 | + <p> |
|
| 456 | + The method returns immediately and the positions are subsequently sent to |
|
| 457 | + the given listener, as they are received. |
|
| 458 | + </p></div> |
|
| 459 | +<dl> |
|
| 460 | +<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 461 | +<dd><code>listener</code> - the listener to receive the positions.</dd> |
|
| 462 | +<dd><code>fromTime</code> - stored positions (if supported) will be requested from this time |
|
| 463 | + and forward. The value <code>0</code> is allowed and means all |
|
| 464 | + historic data.</dd> |
|
| 465 | +<dd><code>toTime</code> - The value <code>Long.MAXVALUE</code> means all data in the future</dd> |
|
| 466 | +<dd><code>classIds</code> - the class ids</dd> |
|
| 467 | +</dl> |
|
| 468 | +</li> |
|
| 469 | +</ul> |
|
| 395 | 470 | <a name="unsubscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-"> |
| 396 | 471 | <!-- --> |
| 397 | 472 | </a> |
| ... | ... | @@ -416,7 +491,29 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 416 | 491 | <div class="block">Subscribes to snapped competitor positions for a given Race. It uses the |
| 417 | 492 | tracking start time and the tracking end time as time interval to receive |
| 418 | 493 | positions. |
| 419 | - |
|
| 494 | + |
|
| 495 | + <p> |
|
| 496 | + The method returns immediately and the positions are subsequently sent to |
|
| 497 | + the given listener, as they are received. |
|
| 498 | + </p></div> |
|
| 499 | +<dl> |
|
| 500 | +<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 501 | +<dd><code>listener</code> - the listener to receive the positions.</dd> |
|
| 502 | +</dl> |
|
| 503 | +</li> |
|
| 504 | +</ul> |
|
| 505 | +<a name="subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-java.util.UUID...-"> |
|
| 506 | +<!-- --> |
|
| 507 | +</a> |
|
| 508 | +<ul class="blockList"> |
|
| 509 | +<li class="blockList"> |
|
| 510 | +<h4>subscribePositionsSnapped</h4> |
|
| 511 | +<pre>void subscribePositionsSnapped(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener, |
|
| 512 | + java.util.UUID... classIds)</pre> |
|
| 513 | +<div class="block">Subscribes to snapped competitor positions for a given Race and class(es). It uses the |
|
| 514 | + tracking start time and the tracking end time as time interval to receive |
|
| 515 | + positions. |
|
| 516 | + |
|
| 420 | 517 | <p> |
| 421 | 518 | The method returns immediately and the positions are subsequently sent to |
| 422 | 519 | the given listener, as they are received. |
| ... | ... | @@ -424,6 +521,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 424 | 521 | <dl> |
| 425 | 522 | <dt><span class="paramLabel">Parameters:</span></dt> |
| 426 | 523 | <dd><code>listener</code> - the listener to receive the positions.</dd> |
| 524 | +<dd><code>classIds</code> - the class ids</dd> |
|
| 427 | 525 | </dl> |
| 428 | 526 | </li> |
| 429 | 527 | </ul> |
| ... | ... | @@ -438,7 +536,34 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 438 | 536 | long toTime)</pre> |
| 439 | 537 | <div class="block">Subscribes to snapped competitor positions for a given Race, including |
| 440 | 538 | historic data. |
| 441 | - |
|
| 539 | + |
|
| 540 | + <p> |
|
| 541 | + The method returns immediately and the positions are subsequently sent to |
|
| 542 | + the given listener, as they are received. |
|
| 543 | + </p></div> |
|
| 544 | +<dl> |
|
| 545 | +<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 546 | +<dd><code>listener</code> - the listener to receive the positions.</dd> |
|
| 547 | +<dd><code>fromTime</code> - stored positions (if supported) will be requested from this time |
|
| 548 | + and forward. The value <code>0</code> is allowed and means all |
|
| 549 | + historic data.</dd> |
|
| 550 | +<dd><code>toTime</code> - The value <code>Long.MAXVALUE</code> means all data in the future</dd> |
|
| 551 | +</dl> |
|
| 552 | +</li> |
|
| 553 | +</ul> |
|
| 554 | +<a name="subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-long-long-java.util.UUID...-"> |
|
| 555 | +<!-- --> |
|
| 556 | +</a> |
|
| 557 | +<ul class="blockList"> |
|
| 558 | +<li class="blockList"> |
|
| 559 | +<h4>subscribePositionsSnapped</h4> |
|
| 560 | +<pre>void subscribePositionsSnapped(<a href="../../../../../com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">IPositionSnappedListener</a> listener, |
|
| 561 | + long fromTime, |
|
| 562 | + long toTime, |
|
| 563 | + java.util.UUID... classIds)</pre> |
|
| 564 | +<div class="block">Subscribes to snapped competitor positions for a given Race and class(es), including |
|
| 565 | + historic data. |
|
| 566 | + |
|
| 442 | 567 | <p> |
| 443 | 568 | The method returns immediately and the positions are subsequently sent to |
| 444 | 569 | the given listener, as they are received. |
| ... | ... | @@ -450,6 +575,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 450 | 575 | and forward. The value <code>0</code> is allowed and means all |
| 451 | 576 | historic data.</dd> |
| 452 | 577 | <dd><code>toTime</code> - The value <code>Long.MAXVALUE</code> means all data in the future</dd> |
| 578 | +<dd><code>classIds</code> - the class ids</dd> |
|
| 453 | 579 | </dl> |
| 454 | 580 | </li> |
| 455 | 581 | </ul> |
| ... | ... | @@ -477,7 +603,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 477 | 603 | <div class="block">Subscribes to offset competitor positions for a given Race. It uses the |
| 478 | 604 | tracking start time and the tracking end time as time interval to receive |
| 479 | 605 | positions. |
| 480 | - |
|
| 606 | + |
|
| 481 | 607 | <p> |
| 482 | 608 | The method returns immediately and the positions are subsequently sent to |
| 483 | 609 | the given listener, as they are received. |
| ... | ... | @@ -499,7 +625,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 499 | 625 | long toTime)</pre> |
| 500 | 626 | <div class="block">Subscribes to offset competitor positions for a given Race, including |
| 501 | 627 | historic data. |
| 502 | - |
|
| 628 | + |
|
| 503 | 629 | <p> |
| 504 | 630 | The method returns immediately and the positions are subsequently sent to |
| 505 | 631 | the given listener, as they are received. |
| ... | ... | @@ -536,7 +662,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 536 | 662 | <h4>subscribeControlPositions</h4> |
| 537 | 663 | <pre>void subscribeControlPositions(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPointPositionListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPointPositionListener</a> listener)</pre> |
| 538 | 664 | <div class="block">Subscribes to control positions for the race. |
| 539 | - |
|
| 665 | + |
|
| 540 | 666 | <p> |
| 541 | 667 | The method returns immediately and the positions are subsequently sent to |
| 542 | 668 | the given listener, as they are received. |
| ... | ... | @@ -563,7 +689,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 563 | 689 | long toTime)</pre> |
| 564 | 690 | <div class="block">Subscribes to control positions for the race, also retrieving historic |
| 565 | 691 | data. |
| 566 | - |
|
| 692 | + |
|
| 567 | 693 | <p> |
| 568 | 694 | The method returns immediately and the positions are subsequently sent to |
| 569 | 695 | the given listener, as they are received. |
| ... | ... | @@ -605,7 +731,27 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 605 | 731 | <h4>subscribeControlPassings</h4> |
| 606 | 732 | <pre>void subscribeControlPassings(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPassingsListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPassingsListener</a> listener)</pre> |
| 607 | 733 | <div class="block">Subscribes to control passing data for the specified race. |
| 608 | - |
|
| 734 | + |
|
| 735 | + <p> |
|
| 736 | + The method returns immediately and the positions are subsequently sent to |
|
| 737 | + the given listener, as they are received. |
|
| 738 | + </p></div> |
|
| 739 | +<dl> |
|
| 740 | +<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 741 | +<dd><code>listener</code> - the listener to receive the control passings.</dd> |
|
| 742 | +</dl> |
|
| 743 | +</li> |
|
| 744 | +</ul> |
|
| 745 | +<a name="subscribeControlPassings-com.tractrac.subscription.lib.api.control.IControlPassingsListener-java.util.UUID...-"> |
|
| 746 | +<!-- --> |
|
| 747 | +</a> |
|
| 748 | +<ul class="blockList"> |
|
| 749 | +<li class="blockList"> |
|
| 750 | +<h4>subscribeControlPassings</h4> |
|
| 751 | +<pre>void subscribeControlPassings(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlPassingsListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlPassingsListener</a> listener, |
|
| 752 | + java.util.UUID... classIds)</pre> |
|
| 753 | +<div class="block">Subscribes to control passing data for the specified race and a class(es) |
|
| 754 | + |
|
| 609 | 755 | <p> |
| 610 | 756 | The method returns immediately and the positions are subsequently sent to |
| 611 | 757 | the given listener, as they are received. |
| ... | ... | @@ -613,6 +759,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 613 | 759 | <dl> |
| 614 | 760 | <dt><span class="paramLabel">Parameters:</span></dt> |
| 615 | 761 | <dd><code>listener</code> - the listener to receive the control passings.</dd> |
| 762 | +<dd><code>classIds</code> - the class ids</dd> |
|
| 616 | 763 | </dl> |
| 617 | 764 | </li> |
| 618 | 765 | </ul> |
| ... | ... | @@ -638,7 +785,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 638 | 785 | <h4>subscribeRaceTimesChanges</h4> |
| 639 | 786 | <pre>void subscribeRaceTimesChanges(<a href="../../../../../com/tractrac/subscription/lib/api/race/IRaceStartStopTimesChangeListener.html" title="interface in com.tractrac.subscription.lib.api.race">IRaceStartStopTimesChangeListener</a> listener)</pre> |
| 640 | 787 | <div class="block">Subscribes to changes in race start and stop times. |
| 641 | - |
|
| 788 | + |
|
| 642 | 789 | <p> |
| 643 | 790 | The method returns immediately and the changes are subsequently sent to the |
| 644 | 791 | given listener, as they are received. |
| ... | ... | @@ -663,24 +810,6 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 663 | 810 | </dl> |
| 664 | 811 | </li> |
| 665 | 812 | </ul> |
| 666 | -<a name="subscribeRoutes-com.tractrac.subscription.lib.api.route.IRoutesListener-"> |
|
| 667 | -<!-- --> |
|
| 668 | -</a> |
|
| 669 | -<ul class="blockList"> |
|
| 670 | -<li class="blockList"> |
|
| 671 | -<h4>subscribeRoutes</h4> |
|
| 672 | -<pre>void subscribeRoutes(<a href="../../../../../com/tractrac/subscription/lib/api/route/IRoutesListener.html" title="interface in com.tractrac.subscription.lib.api.route">IRoutesListener</a> listener)</pre> |
|
| 673 | -<div class="block"><p> |
|
| 674 | - Subscriber to route changes. A race change happens when an static property |
|
| 675 | - of the route changes. |
|
| 676 | - |
|
| 677 | - </p></div> |
|
| 678 | -<dl> |
|
| 679 | -<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 680 | -<dd><code>listener</code> - the listener used in the subscribe method</dd> |
|
| 681 | -</dl> |
|
| 682 | -</li> |
|
| 683 | -</ul> |
|
| 684 | 813 | <a name="subscribeRouteChanges-com.tractrac.subscription.lib.api.control.IControlRouteChangeListener-"> |
| 685 | 814 | <!-- --> |
| 686 | 815 | </a> |
| ... | ... | @@ -689,7 +818,7 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 689 | 818 | <h4>subscribeRouteChanges</h4> |
| 690 | 819 | <pre>void subscribeRouteChanges(<a href="../../../../../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlRouteChangeListener</a> listener)</pre> |
| 691 | 820 | <div class="block">Subscribes to route changes for a given Race. |
| 692 | - |
|
| 821 | + |
|
| 693 | 822 | <p> |
| 694 | 823 | The method returns immediately and the positions are subsequently sent to |
| 695 | 824 | the given listener, as they are received. |
| ... | ... | @@ -700,22 +829,6 @@ extends <a href="../../../../../com/tractrac/subscription/lib/api/ISubscriber.ht |
| 700 | 829 | </dl> |
| 701 | 830 | </li> |
| 702 | 831 | </ul> |
| 703 | -<a name="unsubscribeRoutes-com.tractrac.subscription.lib.api.route.IRoutesListener-"> |
|
| 704 | -<!-- --> |
|
| 705 | -</a> |
|
| 706 | -<ul class="blockList"> |
|
| 707 | -<li class="blockList"> |
|
| 708 | -<h4>unsubscribeRoutes</h4> |
|
| 709 | -<pre>void unsubscribeRoutes(<a href="../../../../../com/tractrac/subscription/lib/api/route/IRoutesListener.html" title="interface in com.tractrac.subscription.lib.api.route">IRoutesListener</a> listener)</pre> |
|
| 710 | -<div class="block"><p> |
|
| 711 | - Unsubscribes to route changes for a given Race. |
|
| 712 | - </p></div> |
|
| 713 | -<dl> |
|
| 714 | -<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 715 | -<dd><code>listener</code> - the listener used in the subscribe method</dd> |
|
| 716 | -</dl> |
|
| 717 | -</li> |
|
| 718 | -</ul> |
|
| 719 | 832 | <a name="unsubscribeRouteChanges-com.tractrac.subscription.lib.api.control.IControlRouteChangeListener-"> |
| 720 | 833 | <!-- --> |
| 721 | 834 | </a> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/ISubscriber.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ISubscriber</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/ISubscriberFactory.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ISubscriberFactory</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/ISubscriberListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ISubscriberListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/SubscriberInitializationException.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>SubscriberInitializationException</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -149,6 +149,9 @@ extends java.lang.Exception</pre> |
| 149 | 149 | <tr class="altColor"> |
| 150 | 150 | <td class="colOne"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/SubscriberInitializationException.html#SubscriberInitializationException-java.lang.Exception-">SubscriberInitializationException</a></span>(java.lang.Exception ex)</code> </td> |
| 151 | 151 | </tr> |
| 152 | +<tr class="rowColor"> |
|
| 153 | +<td class="colOne"><code><span class="memberNameLink"><a href="../../../../../com/tractrac/subscription/lib/api/SubscriberInitializationException.html#SubscriberInitializationException-java.lang.String-">SubscriberInitializationException</a></span>(java.lang.String message)</code> </td> |
|
| 154 | +</tr> |
|
| 152 | 155 | </table> |
| 153 | 156 | </li> |
| 154 | 157 | </ul> |
| ... | ... | @@ -197,6 +200,15 @@ extends java.lang.Exception</pre> |
| 197 | 200 | <!-- --> |
| 198 | 201 | </a> |
| 199 | 202 | <h3>Constructor Detail</h3> |
| 203 | +<a name="SubscriberInitializationException-java.lang.String-"> |
|
| 204 | +<!-- --> |
|
| 205 | +</a> |
|
| 206 | +<ul class="blockList"> |
|
| 207 | +<li class="blockList"> |
|
| 208 | +<h4>SubscriberInitializationException</h4> |
|
| 209 | +<pre>public SubscriberInitializationException(java.lang.String message)</pre> |
|
| 210 | +</li> |
|
| 211 | +</ul> |
|
| 200 | 212 | <a name="SubscriberInitializationException-java.lang.Exception-"> |
| 201 | 213 | <!-- --> |
| 202 | 214 | </a> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/SubscriptionLocator.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>SubscriptionLocator</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/ICompetitorSensorDataListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ICompetitorSensorDataListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/ICompetitorsListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>ICompetitorsListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/IPositionListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IPositionListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/IPositionOffsetListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IPositionOffsetListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/IPositionSnappedListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IPositionSnappedListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.competitor</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.competitor</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/competitor/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.competitor Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/IControlPassingsListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IControlPassingsListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/IControlPointPositionListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IControlPointPositionListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/IControlPointSensorDataListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IControlPointSensorDataListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IControlRouteChangeListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | catch(err) { |
| 19 | 19 | } |
| 20 | 20 | //--> |
| 21 | -var methods = {"i0":6}; |
|
| 21 | +var methods = {"i0":6,"i1":6}; |
|
| 22 | 22 | var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],4:["t3","Abstract Methods"]}; |
| 23 | 23 | var altColor = "altColor"; |
| 24 | 24 | var rowColor = "rowColor"; |
| ... | ... | @@ -133,7 +133,14 @@ extends <a href="../../../../../../com/tractrac/subscription/lib/api/ISubscriber |
| 133 | 133 | <td class="colFirst"><code>void</code></td> |
| 134 | 134 | <td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html#gotRouteChange-com.tractrac.model.lib.api.route.IControlRoute-long-">gotRouteChange</a></span>(<a href="../../../../../../com/tractrac/model/lib/api/route/IControlRoute.html" title="interface in com.tractrac.model.lib.api.route">IControlRoute</a> controlRoute, |
| 135 | 135 | long timeStamp)</code> |
| 136 | -<div class="block">Invoked when updates to a route arrives</div> |
|
| 136 | +<div class="block">Invoked when updates to a control route arrives</div> |
|
| 137 | +</td> |
|
| 138 | +</tr> |
|
| 139 | +<tr id="i1" class="rowColor"> |
|
| 140 | +<td class="colFirst"><code>void</code></td> |
|
| 141 | +<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html#gotRouteChange-com.tractrac.model.lib.api.route.IPathRoute-long-">gotRouteChange</a></span>(<a href="../../../../../../com/tractrac/model/lib/api/route/IPathRoute.html" title="interface in com.tractrac.model.lib.api.route">IPathRoute</a> pathRoute, |
|
| 142 | + long timeStamp)</code> |
|
| 143 | +<div class="block">Invoked when updates to a path route arrives</div> |
|
| 137 | 144 | </td> |
| 138 | 145 | </tr> |
| 139 | 146 | </table> |
| ... | ... | @@ -154,12 +161,12 @@ extends <a href="../../../../../../com/tractrac/subscription/lib/api/ISubscriber |
| 154 | 161 | <a name="gotRouteChange-com.tractrac.model.lib.api.route.IControlRoute-long-"> |
| 155 | 162 | <!-- --> |
| 156 | 163 | </a> |
| 157 | -<ul class="blockListLast"> |
|
| 164 | +<ul class="blockList"> |
|
| 158 | 165 | <li class="blockList"> |
| 159 | 166 | <h4>gotRouteChange</h4> |
| 160 | 167 | <pre>void gotRouteChange(<a href="../../../../../../com/tractrac/model/lib/api/route/IControlRoute.html" title="interface in com.tractrac.model.lib.api.route">IControlRoute</a> controlRoute, |
| 161 | 168 | long timeStamp)</pre> |
| 162 | -<div class="block">Invoked when updates to a route arrives</div> |
|
| 169 | +<div class="block">Invoked when updates to a control route arrives</div> |
|
| 163 | 170 | <dl> |
| 164 | 171 | <dt><span class="paramLabel">Parameters:</span></dt> |
| 165 | 172 | <dd><code>controlRoute</code> - the new configuration of the route.</dd> |
| ... | ... | @@ -167,6 +174,22 @@ extends <a href="../../../../../../com/tractrac/subscription/lib/api/ISubscriber |
| 167 | 174 | </dl> |
| 168 | 175 | </li> |
| 169 | 176 | </ul> |
| 177 | +<a name="gotRouteChange-com.tractrac.model.lib.api.route.IPathRoute-long-"> |
|
| 178 | +<!-- --> |
|
| 179 | +</a> |
|
| 180 | +<ul class="blockListLast"> |
|
| 181 | +<li class="blockList"> |
|
| 182 | +<h4>gotRouteChange</h4> |
|
| 183 | +<pre>void gotRouteChange(<a href="../../../../../../com/tractrac/model/lib/api/route/IPathRoute.html" title="interface in com.tractrac.model.lib.api.route">IPathRoute</a> pathRoute, |
|
| 184 | + long timeStamp)</pre> |
|
| 185 | +<div class="block">Invoked when updates to a path route arrives</div> |
|
| 186 | +<dl> |
|
| 187 | +<dt><span class="paramLabel">Parameters:</span></dt> |
|
| 188 | +<dd><code>pathRoute</code> - the new configuration of the route.</dd> |
|
| 189 | +<dd><code>timeStamp</code> - a time stamp when the new route is valid.</dd> |
|
| 190 | +</dl> |
|
| 191 | +</li> |
|
| 192 | +</ul> |
|
| 170 | 193 | </li> |
| 171 | 194 | </ul> |
| 172 | 195 | </li> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/IControlsListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IControlsListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.control</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.control</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/control/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.control Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/IConnectionStatusListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IConnectionStatusListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/IEventMessageListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IEventMessageListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/ILiveDataEvent.StatusType.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ILiveDataEvent.StatusType</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/ILiveDataEvent.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>ILiveDataEvent</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/IMessage.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IMessage</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/IServerTimeListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IServerTimeListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/IStoredDataEvent.Type.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IStoredDataEvent.Type</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/IStoredDataEvent.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IStoredDataEvent</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.event</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.event</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/event/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.event Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -95,8 +95,8 @@ |
| 95 | 95 | <ul> |
| 96 | 96 | <li type="circle">java.lang.Enum<E> (implements java.lang.Comparable<T>, java.io.Serializable) |
| 97 | 97 | <ul> |
| 98 | -<li type="circle">com.tractrac.subscription.lib.api.event.<a href="../../../../../../com/tractrac/subscription/lib/api/event/IStoredDataEvent.Type.html" title="enum in com.tractrac.subscription.lib.api.event"><span class="typeNameLink">IStoredDataEvent.Type</span></a></li> |
|
| 99 | 98 | <li type="circle">com.tractrac.subscription.lib.api.event.<a href="../../../../../../com/tractrac/subscription/lib/api/event/ILiveDataEvent.StatusType.html" title="enum in com.tractrac.subscription.lib.api.event"><span class="typeNameLink">ILiveDataEvent.StatusType</span></a></li> |
| 99 | +<li type="circle">com.tractrac.subscription.lib.api.event.<a href="../../../../../../com/tractrac/subscription/lib/api/event/IStoredDataEvent.Type.html" title="enum in com.tractrac.subscription.lib.api.event"><span class="typeNameLink">IStoredDataEvent.Type</span></a></li> |
|
| 100 | 100 | </ul> |
| 101 | 101 | </li> |
| 102 | 102 | </ul> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/IRaceCompetitorListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IRaceCompetitorListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/IRaceMessageListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IRaceMessageListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/IRaceStartStopTimesChangeListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IRaceStartStopTimesChangeListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/IRacesListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IRacesListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/IStartStopTimesChangeListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:08 UTC 2018 --> |
|
| 6 | 6 | <title>IStartStopTimesChangeListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.race</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.race</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/race/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.race Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/route/IRoutesListener.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>IRoutesListener</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/route/package-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.route</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/route/package-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.route</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/com/tractrac/subscription/lib/api/route/package-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>com.tractrac.subscription.lib.api.route Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../../../../../../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/constant-values.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Constant Field Values</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/deprecated-list.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Deprecated List</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/help-doc.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>API Help</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-1.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>A-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-10.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>L-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-11.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>M-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-12.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>N-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-13.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>O-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-14.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>R-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-15.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>S-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -161,6 +161,10 @@ |
| 161 | 161 | <dd> |
| 162 | 162 | <div class="block">Subscribes to control passing data for the specified race.</div> |
| 163 | 163 | </dd> |
| 164 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlPassings-com.tractrac.subscription.lib.api.control.IControlPassingsListener-java.util.UUID...-">subscribeControlPassings(IControlPassingsListener, UUID...)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 165 | +<dd> |
|
| 166 | +<div class="block">Subscribes to control passing data for the specified race and a class(es)</div> |
|
| 167 | +</dd> |
|
| 164 | 168 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeControlPositions-com.tractrac.subscription.lib.api.control.IControlPointPositionListener-">subscribeControlPositions(IControlPointPositionListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
| 165 | 169 | <dd> |
| 166 | 170 | <div class="block">Subscribes to control positions for the race.</div> |
| ... | ... | @@ -196,10 +200,18 @@ |
| 196 | 200 | <dd> |
| 197 | 201 | <div class="block">Subscribes to competitor positions for a given Race.</div> |
| 198 | 202 | </dd> |
| 203 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-java.util.UUID...-">subscribePositions(IPositionListener, UUID...)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 204 | +<dd> |
|
| 205 | +<div class="block">Subscribes to competitor positions for a given Race and class(es).</div> |
|
| 206 | +</dd> |
|
| 199 | 207 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-long-long-">subscribePositions(IPositionListener, long, long)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
| 200 | 208 | <dd> |
| 201 | 209 | <div class="block">Subscribes to competitor positions for a given Race.</div> |
| 202 | 210 | </dd> |
| 211 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositions-com.tractrac.subscription.lib.api.competitor.IPositionListener-long-long-java.util.UUID...-">subscribePositions(IPositionListener, long, long, UUID...)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 212 | +<dd> |
|
| 213 | +<div class="block">Subscribes to competitor positions for a given Race and class(es).</div> |
|
| 214 | +</dd> |
|
| 203 | 215 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsOffset-com.tractrac.subscription.lib.api.competitor.IPositionOffsetListener-">subscribePositionsOffset(IPositionOffsetListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
| 204 | 216 | <dd> |
| 205 | 217 | <div class="block">Subscribes to offset competitor positions for a given Race.</div> |
| ... | ... | @@ -213,11 +225,20 @@ |
| 213 | 225 | <dd> |
| 214 | 226 | <div class="block">Subscribes to snapped competitor positions for a given Race.</div> |
| 215 | 227 | </dd> |
| 228 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-java.util.UUID...-">subscribePositionsSnapped(IPositionSnappedListener, UUID...)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 229 | +<dd> |
|
| 230 | +<div class="block">Subscribes to snapped competitor positions for a given Race and class(es).</div> |
|
| 231 | +</dd> |
|
| 216 | 232 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-long-long-">subscribePositionsSnapped(IPositionSnappedListener, long, long)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
| 217 | 233 | <dd> |
| 218 | 234 | <div class="block">Subscribes to snapped competitor positions for a given Race, including |
| 219 | 235 | historic data.</div> |
| 220 | 236 | </dd> |
| 237 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribePositionsSnapped-com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener-long-long-java.util.UUID...-">subscribePositionsSnapped(IPositionSnappedListener, long, long, UUID...)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 238 | +<dd> |
|
| 239 | +<div class="block">Subscribes to snapped competitor positions for a given Race and class(es), including |
|
| 240 | + historic data.</div> |
|
| 241 | +</dd> |
|
| 221 | 242 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRaceCompetitor-com.tractrac.subscription.lib.api.race.IRaceCompetitorListener-">subscribeRaceCompetitor(IRaceCompetitorListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
| 222 | 243 | <dd> |
| 223 | 244 | <div class="block">Subscribes to race competitor for a given Race.</div> |
| ... | ... | @@ -239,17 +260,14 @@ |
| 239 | 260 | <dd> |
| 240 | 261 | <div class="block">This exception is thrown when it is not possible to create a susbcriber.</div> |
| 241 | 262 | </dd> |
| 263 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/SubscriberInitializationException.html#SubscriberInitializationException-java.lang.String-">SubscriberInitializationException(String)</a></span> - Constructor for exception com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/SubscriberInitializationException.html" title="class in com.tractrac.subscription.lib.api">SubscriberInitializationException</a></dt> |
|
| 264 | +<dd> </dd> |
|
| 242 | 265 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/SubscriberInitializationException.html#SubscriberInitializationException-java.lang.Exception-">SubscriberInitializationException(Exception)</a></span> - Constructor for exception com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/SubscriberInitializationException.html" title="class in com.tractrac.subscription.lib.api">SubscriberInitializationException</a></dt> |
| 243 | 266 | <dd> </dd> |
| 244 | 267 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRouteChanges-com.tractrac.subscription.lib.api.control.IControlRouteChangeListener-">subscribeRouteChanges(IControlRouteChangeListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
| 245 | 268 | <dd> |
| 246 | 269 | <div class="block">Subscribes to route changes for a given Race.</div> |
| 247 | 270 | </dd> |
| 248 | -<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#subscribeRoutes-com.tractrac.subscription.lib.api.route.IRoutesListener-">subscribeRoutes(IRoutesListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 249 | -<dd> |
|
| 250 | -<div class="block"> |
|
| 251 | - Subscriber to route changes.</div> |
|
| 252 | -</dd> |
|
| 253 | 271 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IEventSubscriber.html#subscribeServerTime-com.tractrac.subscription.lib.api.event.IServerTimeListener-">subscribeServerTime(IServerTimeListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IEventSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IEventSubscriber</a></dt> |
| 254 | 272 | <dd> |
| 255 | 273 | <div class="block">Subscribe to messages for the server time.</div> |
java/com.tractrac.clientmodule/javadoc/index-files/index-16.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>T-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-17.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>U-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -144,11 +144,6 @@ |
| 144 | 144 | <dd> |
| 145 | 145 | <div class="block">Unsubscribes to route changes for a given Race.</div> |
| 146 | 146 | </dd> |
| 147 | -<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html#unsubscribeRoutes-com.tractrac.subscription.lib.api.route.IRoutesListener-">unsubscribeRoutes(IRoutesListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IRaceSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IRaceSubscriber</a></dt> |
|
| 148 | -<dd> |
|
| 149 | -<div class="block"> |
|
| 150 | - Unsubscribes to route changes for a given Race.</div> |
|
| 151 | -</dd> |
|
| 152 | 147 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/IEventSubscriber.html#unsubscribeServerTime-com.tractrac.subscription.lib.api.event.IServerTimeListener-">unsubscribeServerTime(IServerTimeListener)</a></span> - Method in interface com.tractrac.subscription.lib.api.<a href="../com/tractrac/subscription/lib/api/IEventSubscriber.html" title="interface in com.tractrac.subscription.lib.api">IEventSubscriber</a></dt> |
| 153 | 148 | <dd> |
| 154 | 149 | <div class="block">Unsubscribes to messages for the server time.</div> |
java/com.tractrac.clientmodule/javadoc/index-files/index-18.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>V-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-2.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>B-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-3.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>C-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-4.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>D-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-5.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>E-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-6.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>F-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-7.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>G-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -406,7 +406,7 @@ |
| 406 | 406 | <dt><span class="memberNameLink"><a href="../com/tractrac/model/lib/api/data/IControlPassings.html#getPassings--">getPassings()</a></span> - Method in interface com.tractrac.model.lib.api.data.<a href="../com/tractrac/model/lib/api/data/IControlPassings.html" title="interface in com.tractrac.model.lib.api.data">IControlPassings</a></dt> |
| 407 | 407 | <dd> |
| 408 | 408 | <div class="block"> |
| 409 | - Returns a list of control passings.</div> |
|
| 409 | + Returns a list of control passings sorted by time.</div> |
|
| 410 | 410 | </dd> |
| 411 | 411 | <dt><span class="memberNameLink"><a href="../com/tractrac/model/lib/api/ModelLocator.html#getPathRouteFactory--">getPathRouteFactory()</a></span> - Static method in class com.tractrac.model.lib.api.<a href="../com/tractrac/model/lib/api/ModelLocator.html" title="class in com.tractrac.model.lib.api">ModelLocator</a></dt> |
| 412 | 412 | <dd> |
| ... | ... | @@ -753,7 +753,11 @@ |
| 753 | 753 | </dd> |
| 754 | 754 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html#gotRouteChange-com.tractrac.model.lib.api.route.IControlRoute-long-">gotRouteChange(IControlRoute, long)</a></span> - Method in interface com.tractrac.subscription.lib.api.control.<a href="../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlRouteChangeListener</a></dt> |
| 755 | 755 | <dd> |
| 756 | -<div class="block">Invoked when updates to a route arrives</div> |
|
| 756 | +<div class="block">Invoked when updates to a control route arrives</div> |
|
| 757 | +</dd> |
|
| 758 | +<dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html#gotRouteChange-com.tractrac.model.lib.api.route.IPathRoute-long-">gotRouteChange(IPathRoute, long)</a></span> - Method in interface com.tractrac.subscription.lib.api.control.<a href="../com/tractrac/subscription/lib/api/control/IControlRouteChangeListener.html" title="interface in com.tractrac.subscription.lib.api.control">IControlRouteChangeListener</a></dt> |
|
| 759 | +<dd> |
|
| 760 | +<div class="block">Invoked when updates to a path route arrives</div> |
|
| 757 | 761 | </dd> |
| 758 | 762 | <dt><span class="memberNameLink"><a href="../com/tractrac/subscription/lib/api/competitor/ICompetitorSensorDataListener.html#gotSensorData-com.tractrac.model.lib.api.event.IRaceCompetitor-com.tractrac.model.lib.api.sensor.ISensorData-">gotSensorData(IRaceCompetitor, ISensorData)</a></span> - Method in interface com.tractrac.subscription.lib.api.competitor.<a href="../com/tractrac/subscription/lib/api/competitor/ICompetitorSensorDataListener.html" title="interface in com.tractrac.subscription.lib.api.competitor">ICompetitorSensorDataListener</a></dt> |
| 759 | 763 | <dd> |
java/com.tractrac.clientmodule/javadoc/index-files/index-8.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>H-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index-files/index-9.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>I-Index</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="../script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/index.html
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Generated Documentation (Untitled)</title> |
| 7 | 7 | <script type="text/javascript"> |
| 8 | 8 | tmpTargetPage = "" + window.location.search; |
java/com.tractrac.clientmodule/javadoc/overview-frame.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Overview List</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/overview-summary.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Overview</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/javadoc/overview-tree.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Class Hierarchy</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
| ... | ... | @@ -337,12 +337,12 @@ |
| 337 | 337 | <ul> |
| 338 | 338 | <li type="circle">java.lang.Enum<E> (implements java.lang.Comparable<T>, java.io.Serializable) |
| 339 | 339 | <ul> |
| 340 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/RaceVisibilityType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceVisibilityType</span></a></li> |
|
| 341 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/RaceCompetitorStatusType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceCompetitorStatusType</span></a></li> |
|
| 342 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/DataSource.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">DataSource</span></a></li> |
|
| 343 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/StartTimeType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">StartTimeType</span></a></li> |
|
| 344 | -<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/EventType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">EventType</span></a></li> |
|
| 345 | 340 | <li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/RaceStatusType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceStatusType</span></a></li> |
| 341 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/EventType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">EventType</span></a></li> |
|
| 342 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/StartTimeType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">StartTimeType</span></a></li> |
|
| 343 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/DataSource.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">DataSource</span></a></li> |
|
| 344 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/RaceCompetitorStatusType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceCompetitorStatusType</span></a></li> |
|
| 345 | +<li type="circle">com.tractrac.model.lib.api.event.<a href="com/tractrac/model/lib/api/event/RaceVisibilityType.html" title="enum in com.tractrac.model.lib.api.event"><span class="typeNameLink">RaceVisibilityType</span></a></li> |
|
| 346 | 346 | <li type="circle">com.tractrac.subscription.lib.api.event.<a href="com/tractrac/subscription/lib/api/event/IStoredDataEvent.Type.html" title="enum in com.tractrac.subscription.lib.api.event"><span class="typeNameLink">IStoredDataEvent.Type</span></a></li> |
| 347 | 347 | <li type="circle">com.tractrac.subscription.lib.api.event.<a href="com/tractrac/subscription/lib/api/event/ILiveDataEvent.StatusType.html" title="enum in com.tractrac.subscription.lib.api.event"><span class="typeNameLink">ILiveDataEvent.StatusType</span></a></li> |
| 348 | 348 | </ul> |
java/com.tractrac.clientmodule/javadoc/serialized-form.html
| ... | ... | @@ -2,9 +2,9 @@ |
| 2 | 2 | <!-- NewPage --> |
| 3 | 3 | <html lang="en"> |
| 4 | 4 | <head> |
| 5 | -<!-- Generated by javadoc (1.8.0_161) on Fri Mar 02 11:40:31 UTC 2018 --> |
|
| 5 | +<!-- Generated by javadoc (1.8.0_161) on Mon Jul 30 09:28:09 UTC 2018 --> |
|
| 6 | 6 | <title>Serialized Form</title> |
| 7 | -<meta name="date" content="2018-03-02"> |
|
| 7 | +<meta name="date" content="2018-07-30"> |
|
| 8 | 8 | <link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style"> |
| 9 | 9 | <script type="text/javascript" src="script.js"></script> |
| 10 | 10 | </head> |
java/com.tractrac.clientmodule/lib/TracAPI-src.jar
java/com.tractrac.clientmodule/pom.xml
| ... | ... | @@ -8,6 +8,6 @@ |
| 8 | 8 | <version>1.0.0-SNAPSHOT</version> |
| 9 | 9 | </parent> |
| 10 | 10 | <artifactId>com.tractrac.clientmodule</artifactId> |
| 11 | - <version>3.10.1</version> |
|
| 11 | + <version>3.11.0</version> |
|
| 12 | 12 | <packaging>eclipse-plugin</packaging> |
| 13 | 13 | </project> |
java/com.tractrac.clientmodule/src/com/tractrac/subscription/app/tracapi/AbstractListener.java
| ... | ... | @@ -0,0 +1,190 @@ |
| 1 | +package com.tractrac.subscription.app.tracapi; |
|
| 2 | + |
|
| 3 | +import java.net.URI; |
|
| 4 | +import java.util.UUID; |
|
| 5 | + |
|
| 6 | +import com.tractrac.model.lib.api.data.IControlPassings; |
|
| 7 | +import com.tractrac.model.lib.api.data.IMessageData; |
|
| 8 | +import com.tractrac.model.lib.api.data.IPosition; |
|
| 9 | +import com.tractrac.model.lib.api.data.IPositionOffset; |
|
| 10 | +import com.tractrac.model.lib.api.data.IPositionSnapped; |
|
| 11 | +import com.tractrac.model.lib.api.data.IStartStopData; |
|
| 12 | +import com.tractrac.model.lib.api.event.DataSource; |
|
| 13 | +import com.tractrac.model.lib.api.event.ICompetitor; |
|
| 14 | +import com.tractrac.model.lib.api.event.IEvent; |
|
| 15 | +import com.tractrac.model.lib.api.event.IRace; |
|
| 16 | +import com.tractrac.model.lib.api.event.IRaceCompetitor; |
|
| 17 | +import com.tractrac.model.lib.api.route.IControl; |
|
| 18 | +import com.tractrac.model.lib.api.route.IControlRoute; |
|
| 19 | +import com.tractrac.model.lib.api.route.IPathRoute; |
|
| 20 | +import com.tractrac.model.lib.api.sensor.ISensorData; |
|
| 21 | +import com.tractrac.subscription.lib.api.competitor.ICompetitorSensorDataListener; |
|
| 22 | +import com.tractrac.subscription.lib.api.competitor.ICompetitorsListener; |
|
| 23 | +import com.tractrac.subscription.lib.api.competitor.IPositionListener; |
|
| 24 | +import com.tractrac.subscription.lib.api.competitor.IPositionOffsetListener; |
|
| 25 | +import com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener; |
|
| 26 | +import com.tractrac.subscription.lib.api.control.IControlPassingsListener; |
|
| 27 | +import com.tractrac.subscription.lib.api.control.IControlPointPositionListener; |
|
| 28 | +import com.tractrac.subscription.lib.api.control.IControlRouteChangeListener; |
|
| 29 | +import com.tractrac.subscription.lib.api.control.IControlsListener; |
|
| 30 | +import com.tractrac.subscription.lib.api.event.IConnectionStatusListener; |
|
| 31 | +import com.tractrac.subscription.lib.api.event.IEventMessageListener; |
|
| 32 | +import com.tractrac.subscription.lib.api.event.ILiveDataEvent; |
|
| 33 | +import com.tractrac.subscription.lib.api.event.IStoredDataEvent; |
|
| 34 | +import com.tractrac.subscription.lib.api.race.IRaceMessageListener; |
|
| 35 | +import com.tractrac.subscription.lib.api.race.IRaceStartStopTimesChangeListener; |
|
| 36 | +import com.tractrac.subscription.lib.api.race.IRacesListener; |
|
| 37 | + |
|
| 38 | +/** |
|
| 39 | + * @author <a href="mailto:jorge@tractrac.dk">Jorge Piera Llodrá</a> |
|
| 40 | + */ |
|
| 41 | +public abstract class AbstractListener implements IEventMessageListener, |
|
| 42 | + IRaceMessageListener, IPositionListener, IPositionOffsetListener, |
|
| 43 | + IPositionSnappedListener, IConnectionStatusListener, IControlPointPositionListener, |
|
| 44 | + IControlPassingsListener, IRaceStartStopTimesChangeListener, |
|
| 45 | + IControlRouteChangeListener, ICompetitorSensorDataListener, |
|
| 46 | + IRacesListener, ICompetitorsListener, IControlsListener { |
|
| 47 | + |
|
| 48 | + @Override |
|
| 49 | + public void gotStoredDataEvent(IStoredDataEvent storedDataEvent) { |
|
| 50 | + |
|
| 51 | + } |
|
| 52 | + |
|
| 53 | + @Override |
|
| 54 | + public void gotLiveDataEvent(ILiveDataEvent liveDataEvent) { |
|
| 55 | + |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + @Override |
|
| 59 | + public void gotRouteChange(IControlRoute controlRoute, long timeStamp) { |
|
| 60 | + |
|
| 61 | + } |
|
| 62 | + |
|
| 63 | + @Override |
|
| 64 | + public void gotRouteChange(IPathRoute controlRoute, long timeStamp) { |
|
| 65 | + |
|
| 66 | + } |
|
| 67 | + |
|
| 68 | + @Override |
|
| 69 | + public void gotControlPassings(IRaceCompetitor raceCompetitor, |
|
| 70 | + IControlPassings markPassings) { |
|
| 71 | + |
|
| 72 | + } |
|
| 73 | + |
|
| 74 | + @Override |
|
| 75 | + public void gotControlPointPosition(IControl control, IPosition position, int markNumber) { |
|
| 76 | + |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + @Override |
|
| 80 | + public void gotPositionSnapped(IRaceCompetitor raceCompetitor, |
|
| 81 | + IPositionSnapped positionSnapped) { |
|
| 82 | + |
|
| 83 | + } |
|
| 84 | + |
|
| 85 | + @Override |
|
| 86 | + public void gotPositionOffset(IRaceCompetitor raceCompetitor, |
|
| 87 | + IPositionOffset position) { |
|
| 88 | + |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + @Override |
|
| 92 | + public void gotPosition(IRaceCompetitor raceCompetitor, IPosition position) { |
|
| 93 | + |
|
| 94 | + } |
|
| 95 | + |
|
| 96 | + @Override |
|
| 97 | + public void gotRaceStartStopTime(IRace race, IStartStopData startStopData) { |
|
| 98 | + |
|
| 99 | + } |
|
| 100 | + |
|
| 101 | + @Override |
|
| 102 | + public void gotTrackingStartStopTime(IRace race, IStartStopData startStopData) { |
|
| 103 | + |
|
| 104 | + } |
|
| 105 | + |
|
| 106 | + @Override |
|
| 107 | + public void gotRaceMessage(IRace race, IMessageData messageData) { |
|
| 108 | + |
|
| 109 | + } |
|
| 110 | + |
|
| 111 | + @Override |
|
| 112 | + public void stopped(Object object) { |
|
| 113 | + |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + @Override |
|
| 117 | + public void gotEventMessage(IEvent event, IMessageData messageData) { |
|
| 118 | + |
|
| 119 | + } |
|
| 120 | + |
|
| 121 | + @Override |
|
| 122 | + public void gotSensorData(IRaceCompetitor raceCompetitor, ISensorData sensorData) { |
|
| 123 | + |
|
| 124 | + } |
|
| 125 | + |
|
| 126 | + @Override |
|
| 127 | + public void updateCompetitor(ICompetitor competitor) { |
|
| 128 | + |
|
| 129 | + } |
|
| 130 | + |
|
| 131 | + @Override |
|
| 132 | + public void addCompetitor(ICompetitor competitor) { |
|
| 133 | + |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + @Override |
|
| 137 | + public void deleteCompetitor(UUID competitorId) { |
|
| 138 | + |
|
| 139 | + } |
|
| 140 | + |
|
| 141 | + @Override |
|
| 142 | + public void updateControl(IControl control) { |
|
| 143 | + |
|
| 144 | + } |
|
| 145 | + |
|
| 146 | + @Override |
|
| 147 | + public void addControl(IControl control) { |
|
| 148 | + |
|
| 149 | + } |
|
| 150 | + |
|
| 151 | + @Override |
|
| 152 | + public void deleteControl(UUID controlId) { |
|
| 153 | + |
|
| 154 | + } |
|
| 155 | + |
|
| 156 | + @Override |
|
| 157 | + public void updateRace(IRace race) { |
|
| 158 | + |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + @Override |
|
| 162 | + public void addRace(IRace race) { |
|
| 163 | + |
|
| 164 | + } |
|
| 165 | + |
|
| 166 | + @Override |
|
| 167 | + public void deleteRace(UUID raceId) { |
|
| 168 | + |
|
| 169 | + } |
|
| 170 | + |
|
| 171 | + @Override |
|
| 172 | + public void reloadRace(UUID raceId) { |
|
| 173 | + |
|
| 174 | + } |
|
| 175 | + |
|
| 176 | + @Override |
|
| 177 | + public void abandonRace(UUID raceId) { |
|
| 178 | + |
|
| 179 | + } |
|
| 180 | + |
|
| 181 | + @Override |
|
| 182 | + public void startTracking(UUID raceId) { |
|
| 183 | + |
|
| 184 | + } |
|
| 185 | + |
|
| 186 | + @Override |
|
| 187 | + public void dataSourceChanged(IRace race, DataSource oldDataSource, URI oldLiveURI, URI oldStoredURI) { |
|
| 188 | + |
|
| 189 | + } |
|
| 190 | +} |
java/com.tractrac.clientmodule/src/com/tractrac/subscription/app/tracapi/DelayListener.java
| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | +package com.tractrac.subscription.app.tracapi; |
|
| 2 | + |
|
| 3 | +import com.tractrac.model.lib.api.data.*; |
|
| 4 | +import com.tractrac.model.lib.api.event.*; |
|
| 5 | +import com.tractrac.model.lib.api.route.IControl; |
|
| 6 | +import com.tractrac.util.lib.api.TimeUtils; |
|
| 7 | + |
|
| 8 | +import java.util.Date; |
|
| 9 | + |
|
| 10 | +/** |
|
| 11 | + * @author <a href="mailto:jorge@tractrac.dk">Jorge Piera Llodrá</a> |
|
| 12 | + */ |
|
| 13 | +public class DelayListener extends AbstractListener { |
|
| 14 | + |
|
| 15 | + @Override |
|
| 16 | + public void gotControlPointPosition(IControl control, IPosition position, int markNumber) { |
|
| 17 | + //printDelay(position.getTimestamp(), control.getName()); |
|
| 18 | + } |
|
| 19 | + |
|
| 20 | + @Override |
|
| 21 | + public void gotPosition(IRaceCompetitor raceCompetitor, IPosition position) { |
|
| 22 | + if (!raceCompetitor.getCompetitor().isNonCompeting()) { |
|
| 23 | + printDelay(position.getTimestamp(), raceCompetitor.getCompetitor().getName()); |
|
| 24 | + } |
|
| 25 | + } |
|
| 26 | + |
|
| 27 | + private void printDelay(long sampleTime, String name) { |
|
| 28 | + long now = new Date().getTime(); |
|
| 29 | + long diff = now - sampleTime; |
|
| 30 | + int steps = Math.round(diff/100); |
|
| 31 | + StringBuilder delay = new StringBuilder(); |
|
| 32 | + for (int i = 0 ; i<steps ; i++) { |
|
| 33 | + delay.append("*"); |
|
| 34 | + } |
|
| 35 | + |
|
| 36 | + System.out.println( |
|
| 37 | + String.valueOf(TimeUtils.formatDateInMillis(now)) + ": " + |
|
| 38 | + String.valueOf(TimeUtils.formatDateInMillis(sampleTime)) + ": " + |
|
| 39 | + fillString(name, 25) + "-> " + |
|
| 40 | + delay.toString() |
|
| 41 | + ); |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + public String fillString(String string, int count){ |
|
| 45 | + if (string.length() > count) { |
|
| 46 | + return string.substring(0, count); |
|
| 47 | + } |
|
| 48 | + String out = string; |
|
| 49 | + for (int i=string.length() ;i<count ; i++) { |
|
| 50 | + out = out + "-"; |
|
| 51 | + } |
|
| 52 | + return out; |
|
| 53 | + } |
|
| 54 | +} |
|
| 55 | + |
java/com.tractrac.clientmodule/src/com/tractrac/subscription/app/tracapi/EventListener.java
| ... | ... | @@ -7,42 +7,36 @@ |
| 7 | 7 | */ |
| 8 | 8 | package com.tractrac.subscription.app.tracapi; |
| 9 | 9 | |
| 10 | +import java.net.URI; |
|
| 11 | +import java.util.Date; |
|
| 12 | +import java.util.UUID; |
|
| 13 | + |
|
| 10 | 14 | import com.tractrac.model.lib.api.data.IControlPassings; |
| 11 | 15 | import com.tractrac.model.lib.api.data.IMessageData; |
| 12 | 16 | import com.tractrac.model.lib.api.data.IPosition; |
| 13 | 17 | import com.tractrac.model.lib.api.data.IPositionOffset; |
| 14 | 18 | import com.tractrac.model.lib.api.data.IPositionSnapped; |
| 15 | 19 | import com.tractrac.model.lib.api.data.IStartStopData; |
| 20 | +import com.tractrac.model.lib.api.event.DataSource; |
|
| 21 | +import com.tractrac.model.lib.api.event.ICompetitor; |
|
| 16 | 22 | import com.tractrac.model.lib.api.event.IEvent; |
| 17 | 23 | import com.tractrac.model.lib.api.event.IRace; |
| 18 | 24 | import com.tractrac.model.lib.api.event.IRaceCompetitor; |
| 19 | 25 | import com.tractrac.model.lib.api.route.IControl; |
| 20 | 26 | import com.tractrac.model.lib.api.route.IControlRoute; |
| 21 | -import com.tractrac.subscription.lib.api.competitor.IPositionListener; |
|
| 22 | -import com.tractrac.subscription.lib.api.competitor.IPositionOffsetListener; |
|
| 23 | -import com.tractrac.subscription.lib.api.competitor.IPositionSnappedListener; |
|
| 24 | -import com.tractrac.subscription.lib.api.control.IControlPassingsListener; |
|
| 25 | -import com.tractrac.subscription.lib.api.control.IControlPointPositionListener; |
|
| 26 | -import com.tractrac.subscription.lib.api.control.IControlRouteChangeListener; |
|
| 27 | -import com.tractrac.subscription.lib.api.event.IConnectionStatusListener; |
|
| 28 | -import com.tractrac.subscription.lib.api.event.IEventMessageListener; |
|
| 27 | +import com.tractrac.model.lib.api.sensor.ISensorData; |
|
| 29 | 28 | import com.tractrac.subscription.lib.api.event.ILiveDataEvent; |
| 30 | 29 | import com.tractrac.subscription.lib.api.event.IStoredDataEvent; |
| 31 | -import com.tractrac.subscription.lib.api.race.IRaceMessageListener; |
|
| 32 | -import com.tractrac.subscription.lib.api.race.IRaceStartStopTimesChangeListener; |
|
| 30 | +import com.tractrac.util.lib.api.TimeUtils; |
|
| 33 | 31 | |
| 34 | 32 | /** |
| 35 | 33 | * |
| 36 | - * @author <a href="mailto:jorge@tractrac.dk">Jorge Piera Llodrá</a> |
|
| 34 | + * @author <a href="mailto:jorge@tractrac.dk">Jorge Piera Llodrá</a> |
|
| 37 | 35 | */ |
| 38 | -public class EventListener implements IEventMessageListener, |
|
| 39 | - IRaceMessageListener, IPositionListener, IPositionOffsetListener, |
|
| 40 | - IPositionSnappedListener, IConnectionStatusListener, IControlPointPositionListener, |
|
| 41 | - IControlPassingsListener, IRaceStartStopTimesChangeListener, |
|
| 42 | - IControlRouteChangeListener { |
|
| 36 | +public class EventListener extends AbstractListener { |
|
| 43 | 37 | |
| 44 | 38 | private static void show(Object obj) { |
| 45 | - System.out.println(Thread.currentThread().getName() + ": " + obj); |
|
| 39 | + System.out.println(String.valueOf(TimeUtils.formatDateInMillis(new Date().getTime())) + ": " + obj); |
|
| 46 | 40 | } |
| 47 | 41 | |
| 48 | 42 | @Override |
| ... | ... | @@ -57,7 +51,13 @@ public class EventListener implements IEventMessageListener, |
| 57 | 51 | |
| 58 | 52 | @Override |
| 59 | 53 | public void gotRouteChange(IControlRoute controlRoute, long timeStamp) { |
| 60 | - show("New route at " + timeStamp + ": " + controlRoute.toString()); |
|
| 54 | + StringBuilder message = new StringBuilder(); |
|
| 55 | + message.append("New route at " + timeStamp + ": " + controlRoute.toString()); |
|
| 56 | + for (int i=0 ; i<controlRoute.getControls().size() ; i++) { |
|
| 57 | + message.append("\n\t" + i + ": " + controlRoute.getControls().get(i).getName()); |
|
| 58 | + } |
|
| 59 | + message.append("\n\t" + controlRoute.getMetadata().getText()); |
|
| 60 | + show(message); |
|
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | @Override |
| ... | ... | @@ -68,7 +68,11 @@ public class EventListener implements IEventMessageListener, |
| 68 | 68 | |
| 69 | 69 | @Override |
| 70 | 70 | public void gotControlPointPosition(IControl control, IPosition position, int markNumber) { |
| 71 | - show("New position " + position + " for the mark " + control + ", " + markNumber); |
|
| 71 | + StringBuilder message = new StringBuilder(); |
|
| 72 | + message.append("COTRLPOS " + markNumber); |
|
| 73 | + message.append("\t").append(control.getShortName()).append("\t"); |
|
| 74 | + message.append(position.toString()); |
|
| 75 | + show(message.toString()); |
|
| 72 | 76 | } |
| 73 | 77 | |
| 74 | 78 | @Override |
| ... | ... | @@ -85,7 +89,13 @@ public class EventListener implements IEventMessageListener, |
| 85 | 89 | |
| 86 | 90 | @Override |
| 87 | 91 | public void gotPosition(IRaceCompetitor raceCompetitor, IPosition position) { |
| 88 | - show("New position " + position + " for the competitor " + raceCompetitor.getCompetitor().toString()); |
|
| 92 | + StringBuilder message = new StringBuilder(); |
|
| 93 | + message.append("POSITION"); |
|
| 94 | + if (raceCompetitor != null) { |
|
| 95 | + message.append("\t").append(raceCompetitor.getCompetitor().getShortName()).append("\t"); |
|
| 96 | + } |
|
| 97 | + message.append(position.toString()); |
|
| 98 | + show(message.toString()); |
|
| 89 | 99 | } |
| 90 | 100 | |
| 91 | 101 | @Override |
| ... | ... | @@ -112,4 +122,85 @@ public class EventListener implements IEventMessageListener, |
| 112 | 122 | public void gotEventMessage(IEvent event, IMessageData messageData) { |
| 113 | 123 | show("New event message " + messageData.toString()); |
| 114 | 124 | } |
| 125 | + |
|
| 126 | + @Override |
|
| 127 | + public void gotSensorData(IRaceCompetitor raceCompetitor, ISensorData sensorData) { |
|
| 128 | + StringBuilder message = new StringBuilder(); |
|
| 129 | + message.append("SENSOR"); |
|
| 130 | + if (raceCompetitor != null) { |
|
| 131 | + message.append("\t").append(raceCompetitor.getCompetitor().getShortName()).append("\t"); |
|
| 132 | + } |
|
| 133 | + message.append(sensorData.toString()); |
|
| 134 | + show(message.toString()); |
|
| 135 | + } |
|
| 136 | + |
|
| 137 | + @Override |
|
| 138 | + public void updateCompetitor(ICompetitor competitor) { |
|
| 139 | + show("UPDATE COMPETITOR " + competitor.toString()); |
|
| 140 | + } |
|
| 141 | + |
|
| 142 | + @Override |
|
| 143 | + public void addCompetitor(ICompetitor competitor) { |
|
| 144 | + show("ADD COMPETITOR " + competitor.toString()); |
|
| 145 | + } |
|
| 146 | + |
|
| 147 | + @Override |
|
| 148 | + public void deleteCompetitor(UUID competitorId) { |
|
| 149 | + show("DELETE COMPETITOR"); |
|
| 150 | + } |
|
| 151 | + |
|
| 152 | + @Override |
|
| 153 | + public void updateControl(IControl control) { |
|
| 154 | + show("UPDATE CONTROL " + control.toString()); |
|
| 155 | + } |
|
| 156 | + |
|
| 157 | + @Override |
|
| 158 | + public void addControl(IControl control) { |
|
| 159 | + show("ADD CONTROL " + control.toString()); |
|
| 160 | + } |
|
| 161 | + |
|
| 162 | + @Override |
|
| 163 | + public void deleteControl(UUID controlId) { |
|
| 164 | + show("DELETE CONTROL " + controlId); |
|
| 165 | + } |
|
| 166 | + |
|
| 167 | + @Override |
|
| 168 | + public void updateRace(IRace race) { |
|
| 169 | + show("UPDATE RACE " + race.toString() + |
|
| 170 | + "[" + TimeUtils.formatDate(race.getTrackingStartTime()) + |
|
| 171 | + "," + TimeUtils.formatDate(race.getTrackingEndTime()) + "] - " + |
|
| 172 | + TimeUtils.formatDate(race.getRaceStartTime()) + |
|
| 173 | + " liveDelay = " + race.getLiveDelay() |
|
| 174 | + ); |
|
| 175 | + } |
|
| 176 | + |
|
| 177 | + @Override |
|
| 178 | + public void addRace(IRace race) { |
|
| 179 | + show("ADD RACE " + race.toString()); |
|
| 180 | + } |
|
| 181 | + |
|
| 182 | + @Override |
|
| 183 | + public void deleteRace(UUID raceId) { |
|
| 184 | + show("DELETE RACE " + raceId); |
|
| 185 | + } |
|
| 186 | + |
|
| 187 | + @Override |
|
| 188 | + public void reloadRace(UUID raceId) { |
|
| 189 | + show("RELOAD RACE " + raceId); |
|
| 190 | + } |
|
| 191 | + |
|
| 192 | + @Override |
|
| 193 | + public void abandonRace(UUID raceId) { |
|
| 194 | + show("ABANDON RACE " + raceId); |
|
| 195 | + } |
|
| 196 | + |
|
| 197 | + @Override |
|
| 198 | + public void startTracking(UUID raceId) { |
|
| 199 | + show("START TRACKING " + raceId); |
|
| 200 | + } |
|
| 201 | + |
|
| 202 | + @Override |
|
| 203 | + public void dataSourceChanged(IRace race, DataSource oldDataSource, URI oldLiveURI, URI oldStoredURI) { |
|
| 204 | + show("DATA SOURCE CHANGE " + race); |
|
| 205 | + } |
|
| 115 | 206 | } |
java/com.tractrac.clientmodule/src/com/tractrac/subscription/app/tracapi/Main.java
| ... | ... | @@ -22,21 +22,23 @@ import java.net.URI; |
| 22 | 22 | import java.net.URISyntaxException; |
| 23 | 23 | |
| 24 | 24 | /** |
| 25 | - * |
|
| 26 | - * @author <a href="mailto:jorge@tractrac.dk">Jorge Piera Llodrá</a> |
|
| 25 | + * |
|
| 26 | + * @author <a href="mailto:jorge@tractrac.dk">Jorge Piera Llodrá</a> |
|
| 27 | 27 | */ |
| 28 | 28 | public class Main { |
| 29 | 29 | |
| 30 | 30 | /** |
| 31 | 31 | * @param args |
| 32 | 32 | * the command line arguments |
| 33 | - * @throws CreateModelException |
|
| 33 | + * @throws CreateModelException |
|
| 34 | 34 | */ |
| 35 | 35 | public static void main(String[] args) throws URISyntaxException, |
| 36 | 36 | MalformedURLException, FileNotFoundException, IOException, |
| 37 | 37 | SubscriberInitializationException, CreateModelException, TimeOutException { |
| 38 | 38 | |
| 39 | - URI paramURI = parseArguments(args); |
|
| 39 | + Object[] myArgs = parseArguments(args); |
|
| 40 | + URI paramURI = (URI)myArgs[0]; |
|
| 41 | + boolean measureDelay = (boolean)myArgs[1];; |
|
| 40 | 42 | |
| 41 | 43 | // Create the event object |
| 42 | 44 | IEventFactory eventFactory = ModelLocator.getEventFactory(); |
| ... | ... | @@ -46,44 +48,55 @@ public class Main { |
| 46 | 48 | ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory(); |
| 47 | 49 | IEventSubscriber eventSubscriber = subscriberFactory.createEventSubscriber(race.getEvent()); |
| 48 | 50 | |
| 49 | - EventListener eventListener = new EventListener(); |
|
| 50 | - eventSubscriber.subscribeConnectionStatus(eventListener); |
|
| 51 | - eventSubscriber.subscribeEventMessages(eventListener); |
|
| 52 | - |
|
| 51 | + AbstractListener listener; |
|
| 52 | + if (measureDelay) { |
|
| 53 | + listener = new DelayListener(); |
|
| 54 | + } else { |
|
| 55 | + listener = new EventListener(); |
|
| 56 | + } |
|
| 57 | + |
|
| 58 | + eventSubscriber.subscribeConnectionStatus(listener); |
|
| 59 | + eventSubscriber.subscribeEventMessages(listener); |
|
| 60 | + eventSubscriber.subscribeRaces(listener); |
|
| 61 | + eventSubscriber.subscribeControls(listener); |
|
| 62 | + eventSubscriber.subscribeCompetitors(listener); |
|
| 63 | + |
|
| 53 | 64 | IRaceSubscriber raceSubscriber = subscriberFactory.createRaceSubscriber(race); |
| 54 | - raceSubscriber.subscribeConnectionStatus(eventListener); |
|
| 55 | - raceSubscriber.subscribeControlPositions(eventListener); |
|
| 56 | - raceSubscriber.subscribePositions(eventListener); |
|
| 57 | - raceSubscriber.subscribePositionsSnapped(eventListener); |
|
| 58 | - raceSubscriber.subscribeControlPassings(eventListener); |
|
| 59 | - raceSubscriber.subscribeRaceMessages(eventListener); |
|
| 60 | - raceSubscriber.subscribeRaceMessages(eventListener); |
|
| 61 | - raceSubscriber.subscribeRaceTimesChanges(eventListener); |
|
| 62 | - raceSubscriber.subscribeRouteChanges(eventListener); |
|
| 63 | - raceSubscriber.start(); |
|
| 64 | - eventSubscriber.start(); |
|
| 65 | - |
|
| 65 | + raceSubscriber.subscribeConnectionStatus(listener); |
|
| 66 | + raceSubscriber.subscribeControlPositions(listener); |
|
| 67 | + raceSubscriber.subscribePositions(listener); |
|
| 68 | +// raceSubscriber.subscribePositionsSnapped(listener); |
|
| 69 | + raceSubscriber.subscribeControlPassings(listener); |
|
| 70 | + raceSubscriber.subscribeCompetitorSensorData(listener); |
|
| 71 | + raceSubscriber.subscribeRaceMessages(listener); |
|
| 72 | + raceSubscriber.subscribeRaceTimesChanges(listener); |
|
| 73 | + raceSubscriber.subscribeRouteChanges(listener); |
|
| 74 | + raceSubscriber.start(); |
|
| 75 | + eventSubscriber.start(); |
|
| 76 | + |
|
| 66 | 77 | // Go ahead with GUI or other stuff in main thread |
| 67 | 78 | System.out.println("Press key to cancel live data stream"); |
| 68 | 79 | System.in.read(); |
| 69 | 80 | System.out.println("Cancelling data stream"); |
| 70 | - |
|
| 81 | + |
|
| 71 | 82 | // Stop data streams |
| 72 | - eventSubscriber.stop(); |
|
| 73 | - raceSubscriber.stop(); |
|
| 83 | + eventSubscriber.stop(); |
|
| 84 | + raceSubscriber.stop(); |
|
| 74 | 85 | } |
| 75 | 86 | |
| 76 | - private static URI parseArguments(String[] args) { |
|
| 77 | - if (args.length != 1) { |
|
| 78 | - System.out.println("Usage: java -jar TracAPI.jar parametersfile"); |
|
| 87 | + private static Object[] parseArguments(String[] args) { |
|
| 88 | + if (args.length < 1) { |
|
| 89 | + System.out.println("Usage: java -jar TracAPI.jar parametersfile measureDelay"); |
|
| 79 | 90 | System.exit(0); |
| 80 | 91 | } |
| 92 | + Object[] myArgs = new Object[2]; |
|
| 81 | 93 | try { |
| 82 | - return new URI(args[0]); |
|
| 94 | + myArgs[0] = new URI(args[0]); |
|
| 95 | + myArgs[1] = args.length >= 2 && args[1].equals("1"); |
|
| 83 | 96 | } catch (URISyntaxException ex) { |
| 84 | 97 | System.out.println("Malformed URL " + ex.getMessage()); |
| 85 | 98 | System.exit(0); |
| 86 | 99 | } |
| 87 | - return null; |
|
| 100 | + return myArgs; |
|
| 88 | 101 | } |
| 89 | 102 | } |
java/org.openqa.selenium.osgi/.classpath
| ... | ... | @@ -1,9 +1,18 @@ |
| 1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
| 2 | 2 | <classpath> |
| 3 | - <classpathentry exported="true" kind="lib" path="lib/guava-15.0.jar"/> |
|
| 4 | - <classpathentry exported="true" kind="lib" path="selenium-java-2.40.0.jar" sourcepath="C:/data/java/selenium-selenium-2.40.0/java/client/src"/> |
|
| 3 | + <classpathentry exported="true" kind="lib" path="lib/byte-buddy-1.8.3.jar"/> |
|
| 4 | + <classpathentry exported="true" kind="lib" path="lib/commons-codec-1.10.jar"/> |
|
| 5 | + <classpathentry exported="true" kind="lib" path="lib/commons-exec-1.3.jar"/> |
|
| 6 | + <classpathentry exported="true" kind="lib" path="lib/commons-logging-1.2.jar"/> |
|
| 7 | + <classpathentry exported="true" kind="lib" path="lib/gson-2.8.4.jar"/> |
|
| 8 | + <classpathentry exported="true" kind="lib" path="lib/guava-25.0-jre.jar"/> |
|
| 9 | + <classpathentry exported="true" kind="lib" path="lib/httpclient-4.5.5.jar"/> |
|
| 10 | + <classpathentry exported="true" kind="lib" path="lib/httpcore-4.4.9.jar"/> |
|
| 11 | + <classpathentry exported="true" kind="lib" path="lib/okhttp-3.10.0.jar"/> |
|
| 12 | + <classpathentry exported="true" kind="lib" path="lib/okio-1.14.1.jar"/> |
|
| 13 | + <classpathentry exported="true" kind="lib" path="client-combined-3.13.0.jar" sourcepath="client-combined-3.13.0-sources.jar"/> |
|
| 14 | + <classpathentry exported="true" kind="lib" path="lib/json-20080701.jar"/> |
|
| 5 | 15 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> |
| 6 | 16 | <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> |
| 7 | - <classpathentry exported="true" kind="lib" path="lib/json-20080701.jar"/> |
|
| 8 | 17 | <classpathentry kind="output" path="bin"/> |
| 9 | 18 | </classpath> |
java/org.openqa.selenium.osgi/META-INF/MANIFEST.MF
| ... | ... | @@ -2,92 +2,49 @@ Manifest-Version: 1.0 |
| 2 | 2 | Bundle-ManifestVersion: 2 |
| 3 | 3 | Bundle-Name: Selenium |
| 4 | 4 | Bundle-SymbolicName: org.openqa.selenium.osgi |
| 5 | -Bundle-Version: 2.40.0 |
|
| 6 | -Bundle-ClassPath: lib/apache-mime4j-0.6.jar, |
|
| 7 | - lib/bsh-1.3.0.jar, |
|
| 8 | - lib/cglib-nodep-2.1_3.jar, |
|
| 9 | - lib/commons-codec-1.8.jar, |
|
| 10 | - lib/commons-collections-3.2.1.jar, |
|
| 11 | - lib/commons-exec-1.1.jar, |
|
| 12 | - lib/commons-io-2.2.jar, |
|
| 13 | - lib/commons-jxpath-1.3.jar, |
|
| 14 | - lib/commons-lang3-3.1.jar, |
|
| 15 | - lib/commons-logging-1.1.1.jar, |
|
| 16 | - lib/cssparser-0.9.11.jar, |
|
| 17 | - lib/hamcrest-core-1.3.jar, |
|
| 18 | - lib/hamcrest-library-1.3.jar, |
|
| 19 | - lib/htmlunit-2.13.jar, |
|
| 20 | - lib/htmlunit-core-js-2.13.jar, |
|
| 21 | - lib/httpclient-4.3.1.jar, |
|
| 22 | - lib/httpcore-4.3.jar, |
|
| 23 | - lib/httpmime-4.3.1.jar, |
|
| 24 | - lib/ini4j-0.5.2.jar, |
|
| 25 | - lib/jcommander-1.29.jar, |
|
| 26 | - lib/jetty-websocket-8.1.8.jar, |
|
| 27 | - lib/jna-3.4.0.jar, |
|
| 28 | - lib/jna-platform-3.4.0.jar, |
|
| 29 | - lib/json-20080701.jar, |
|
| 30 | - lib/junit-dep-4.11.jar, |
|
| 31 | - lib/nekohtml-1.9.19.jar, |
|
| 32 | - lib/netty-3.5.7.Final.jar, |
|
| 33 | - lib/operadriver-1.5.jar, |
|
| 34 | - lib/phantomjsdriver-1.1.0.jar, |
|
| 35 | - lib/protobuf-java-2.4.1.jar, |
|
| 36 | - lib/sac-1.3.jar, |
|
| 37 | - lib/serializer-2.7.1.jar, |
|
| 38 | - lib/testng-6.8.5.jar, |
|
| 39 | - lib/xalan-2.7.1.jar, |
|
| 40 | - lib/xercesImpl-2.10.0.jar, |
|
| 41 | - selenium-java-2.40.0.jar, |
|
| 42 | - lib/guava-15.0.jar |
|
| 5 | +Bundle-Version: 3.13.0 |
|
| 6 | +Bundle-ClassPath: lib/json-20080701.jar, |
|
| 7 | + client-combined-3.13.0.jar, |
|
| 8 | + lib/commons-codec-1.10.jar, |
|
| 9 | + lib/byte-buddy-1.8.3.jar, |
|
| 10 | + lib/commons-exec-1.3.jar, |
|
| 11 | + lib/commons-logging-1.2.jar, |
|
| 12 | + lib/gson-2.8.4.jar, |
|
| 13 | + lib/guava-25.0-jre.jar, |
|
| 14 | + lib/httpclient-4.5.5.jar, |
|
| 15 | + lib/httpcore-4.4.9.jar, |
|
| 16 | + lib/okhttp-3.10.0.jar, |
|
| 17 | + lib/okio-1.14.1.jar |
|
| 43 | 18 | Bundle-Vendor: openqa |
| 44 | 19 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 |
| 45 | -Export-Package: com.google.common.annotations, |
|
| 46 | - com.google.common.base, |
|
| 47 | - com.google.common.base.internal, |
|
| 48 | - com.google.common.cache, |
|
| 20 | +Export-Package: com.google.common.base, |
|
| 49 | 21 | com.google.common.collect, |
| 50 | - com.google.common.escape, |
|
| 51 | - com.google.common.eventbus, |
|
| 52 | - com.google.common.hash, |
|
| 53 | - com.google.common.html, |
|
| 54 | - com.google.common.io, |
|
| 55 | - com.google.common.math, |
|
| 56 | - com.google.common.net, |
|
| 57 | - com.google.common.primitives, |
|
| 58 | - com.google.common.reflect, |
|
| 59 | - com.google.common.util.concurrent, |
|
| 60 | - com.google.common.xml, |
|
| 61 | - com.thoughtworks.selenium, |
|
| 62 | - com.thoughtworks.selenium.condition, |
|
| 63 | 22 | org.json, |
| 64 | 23 | org.openqa.selenium, |
| 65 | - org.openqa.selenium.browserlaunchers, |
|
| 66 | - org.openqa.selenium.browserlaunchers.locators, |
|
| 67 | 24 | org.openqa.selenium.chrome, |
| 25 | + org.openqa.selenium.edge, |
|
| 68 | 26 | org.openqa.selenium.firefox, |
| 69 | 27 | org.openqa.selenium.firefox.internal, |
| 70 | 28 | org.openqa.selenium.html5, |
| 71 | - org.openqa.selenium.htmlunit, |
|
| 72 | 29 | org.openqa.selenium.ie, |
| 73 | 30 | org.openqa.selenium.interactions, |
| 74 | 31 | org.openqa.selenium.interactions.internal, |
| 75 | 32 | org.openqa.selenium.interactions.touch, |
| 76 | 33 | org.openqa.selenium.internal, |
| 77 | 34 | org.openqa.selenium.io, |
| 78 | - org.openqa.selenium.lift, |
|
| 79 | - org.openqa.selenium.lift.find, |
|
| 80 | - org.openqa.selenium.lift.match, |
|
| 81 | 35 | org.openqa.selenium.logging, |
| 82 | 36 | org.openqa.selenium.logging.profiler, |
| 37 | + org.openqa.selenium.mobile, |
|
| 83 | 38 | org.openqa.selenium.net, |
| 39 | + org.openqa.selenium.opera, |
|
| 84 | 40 | org.openqa.selenium.os, |
| 85 | 41 | org.openqa.selenium.remote, |
| 86 | 42 | org.openqa.selenium.remote.html5, |
| 43 | + org.openqa.selenium.remote.http, |
|
| 87 | 44 | org.openqa.selenium.remote.internal, |
| 45 | + org.openqa.selenium.remote.mobile, |
|
| 88 | 46 | org.openqa.selenium.remote.service, |
| 89 | 47 | org.openqa.selenium.safari, |
| 90 | - org.openqa.selenium.security, |
|
| 91 | 48 | org.openqa.selenium.support, |
| 92 | 49 | org.openqa.selenium.support.events, |
| 93 | 50 | org.openqa.selenium.support.events.internal, |
java/org.openqa.selenium.osgi/build.properties
| ... | ... | @@ -1,38 +1,13 @@ |
| 1 | 1 | bin.includes = META-INF/,\ |
| 2 | - lib/apache-mime4j-0.6.jar,\ |
|
| 3 | - lib/bsh-1.3.0.jar,\ |
|
| 4 | - lib/cglib-nodep-2.1_3.jar,\ |
|
| 5 | - lib/commons-codec-1.8.jar,\ |
|
| 6 | - lib/commons-collections-3.2.1.jar,\ |
|
| 7 | - lib/commons-exec-1.1.jar,\ |
|
| 8 | - lib/commons-io-2.2.jar,\ |
|
| 9 | - lib/commons-jxpath-1.3.jar,\ |
|
| 10 | - lib/commons-lang3-3.1.jar,\ |
|
| 11 | - lib/commons-logging-1.1.1.jar,\ |
|
| 12 | - lib/cssparser-0.9.11.jar,\ |
|
| 13 | - lib/hamcrest-core-1.3.jar,\ |
|
| 14 | - lib/hamcrest-library-1.3.jar,\ |
|
| 15 | - lib/htmlunit-2.13.jar,\ |
|
| 16 | - lib/htmlunit-core-js-2.13.jar,\ |
|
| 17 | - lib/httpclient-4.3.1.jar,\ |
|
| 18 | - lib/httpcore-4.3.jar,\ |
|
| 19 | - lib/httpmime-4.3.1.jar,\ |
|
| 20 | - lib/ini4j-0.5.2.jar,\ |
|
| 21 | - lib/jcommander-1.29.jar,\ |
|
| 22 | - lib/jetty-websocket-8.1.8.jar,\ |
|
| 23 | - lib/jna-3.4.0.jar,\ |
|
| 24 | - lib/jna-platform-3.4.0.jar,\ |
|
| 25 | 2 | lib/json-20080701.jar,\ |
| 26 | - lib/junit-dep-4.11.jar,\ |
|
| 27 | - lib/nekohtml-1.9.19.jar,\ |
|
| 28 | - lib/netty-3.5.7.Final.jar,\ |
|
| 29 | - lib/operadriver-1.5.jar,\ |
|
| 30 | - lib/protobuf-java-2.4.1.jar,\ |
|
| 31 | - lib/sac-1.3.jar,\ |
|
| 32 | - lib/serializer-2.7.1.jar,\ |
|
| 33 | - lib/testng-6.8.5.jar,\ |
|
| 34 | - lib/xalan-2.7.1.jar,\ |
|
| 35 | - lib/xercesImpl-2.10.0.jar,\ |
|
| 36 | - lib/phantomjsdriver-1.1.0.jar,\ |
|
| 37 | - selenium-java-2.40.0.jar,\ |
|
| 38 | - lib/guava-15.0.jar |
|
| 3 | + client-combined-3.13.0.jar,\ |
|
| 4 | + lib/byte-buddy-1.8.3.jar,\ |
|
| 5 | + lib/commons-codec-1.10.jar,\ |
|
| 6 | + lib/commons-exec-1.3.jar,\ |
|
| 7 | + lib/commons-logging-1.2.jar,\ |
|
| 8 | + lib/gson-2.8.4.jar,\ |
|
| 9 | + lib/guava-25.0-jre.jar,\ |
|
| 10 | + lib/httpclient-4.5.5.jar,\ |
|
| 11 | + lib/httpcore-4.4.9.jar,\ |
|
| 12 | + lib/okhttp-3.10.0.jar,\ |
|
| 13 | + lib/okio-1.14.1.jar |
java/org.openqa.selenium.osgi/client-combined-3.13.0-sources.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/client-combined-3.13.0-sources.jar differ |
java/org.openqa.selenium.osgi/client-combined-3.13.0.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/client-combined-3.13.0.jar differ |
java/org.openqa.selenium.osgi/lib/byte-buddy-1.8.3.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/byte-buddy-1.8.3.jar differ |
java/org.openqa.selenium.osgi/lib/commons-codec-1.10.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/commons-codec-1.10.jar differ |
java/org.openqa.selenium.osgi/lib/commons-exec-1.3.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/commons-exec-1.3.jar differ |
java/org.openqa.selenium.osgi/lib/commons-logging-1.2.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/commons-logging-1.2.jar differ |
java/org.openqa.selenium.osgi/lib/gson-2.8.4.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/gson-2.8.4.jar differ |
java/org.openqa.selenium.osgi/lib/guava-25.0-jre.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/guava-25.0-jre.jar differ |
java/org.openqa.selenium.osgi/lib/httpclient-4.5.5.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/httpclient-4.5.5.jar differ |
java/org.openqa.selenium.osgi/lib/httpcore-4.4.9.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/httpcore-4.4.9.jar differ |
java/org.openqa.selenium.osgi/lib/okhttp-3.10.0.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/okhttp-3.10.0.jar differ |
java/org.openqa.selenium.osgi/lib/okio-1.14.1.jar
| ... | ... | Binary files /dev/null and b/java/org.openqa.selenium.osgi/lib/okio-1.14.1.jar differ |
java/org.openqa.selenium.osgi/pom.xml
| ... | ... | @@ -8,6 +8,6 @@ |
| 8 | 8 | <version>1.0.0-SNAPSHOT</version> |
| 9 | 9 | </parent> |
| 10 | 10 | <artifactId>org.openqa.selenium.osgi</artifactId> |
| 11 | - <version>2.40.0</version> |
|
| 11 | + <version>3.13.0</version> |
|
| 12 | 12 | <packaging>eclipse-plugin</packaging> |
| 13 | 13 | </project> |
orchestration/Makefile
| ... | ... | @@ -72,7 +72,7 @@ build: |
| 72 | 72 | $(foreach GOARCH, $(ARCHITECTURES), cd ${PREFIX}/src/sapsailing.com/orchestrator; GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) ${LDFLAGS} -v -o $${PREFIX}/bin/orchestrator-$(GOOS)-$(GOARCH))) |
| 73 | 73 | $(foreach GOOS, $(PLATFORMS),\ |
| 74 | 74 | $(foreach GOARCH, $(ARCHITECTURES), cd ${PREFIX}/src/sapsailing.com/agent; GOOS=$(GOOS) GOARCH=$(GOARCH) $(GOBUILD) ${LDFLAGS} -v -o $${PREFIX}/bin/agent-$(GOOS)-$(GOARCH))) |
| 75 | - @/usr/bin/chmod +x $${PREFIX}/bin/* |
|
| 75 | + @chmod +x $${PREFIX}/bin/* |
|
| 76 | 76 | @echo "done." |
| 77 | 77 | |
| 78 | 78 | clean: |
wiki/howto/development/orchestration.md
| ... | ... | @@ -0,0 +1,127 @@ |
| 1 | +## Architecture |
|
| 2 | + |
|
| 3 | +### Overview |
|
| 4 | +The orchestration project consists out of two components. The orchestrator on the one hand and the agent on the other. |
|
| 5 | +The orchestrator takes care on all actions in regards of AWS and to execute the agent. The agent will be copied via ssh to a target system and then called with a subset of stages to execute. The actual implementation of e.g. handling apache2, is done inside the agent. Once the agent execution of a stage is finished the return will be transferred back to the orchestrator, who continues with the workflow. |
|
| 6 | + |
|
| 7 | + |
|
| 8 | + |
|
| 9 | +### Build and Test |
|
| 10 | +Currently we provide a Makefile, which implements all required steps to build and test the software. Optionally you can of course also use `go test` directly. Just make sure that the `PREFIX` enviroment is set and points to the project directory (contains `configs` and `bin` subdirectories). You can also use `source env.sh` to do this, which on top sets the `GOPATH` correctly. By default, all go dependencies should be downloaded to `$HOME/.go`. They should not be stored in the git project location. |
|
| 11 | + |
|
| 12 | +To build the software, just call `make build`. Make sure that all dependencies are downloaded before via `make dep`. |
|
| 13 | +To test the software, just call `make test` and to check the tests, call `make checktest`. There are also make steps for `fmt` and others. Just check out the Makefile in the project root. |
|
| 14 | +The verbose output of the test logs is written to a folder called `testlogs` (which initially needs to be created). |
|
| 15 | + |
|
| 16 | +### Develop |
|
| 17 | +As the only Plugin for Eclipse is not really maintained anymore, we do not recommend to use it (goclipse). There is actually also no reason for it, as we are using Go and not Java or any OSGI features. |
|
| 18 | +As go is pretty simple and straight forward, you can use any Go supported IDE as stated on https://golang.org/doc/editors.html. |
|
| 19 | + |
|
| 20 | +Anyways, we recommend either using Goland (from IntelliJ), VS Code or Atom with respective go-plus Plugin. |
|
| 21 | +All you need to do after [installing go](https://golang.org/doc/install) and the IDE, is to make sure to set the above mentioned environment variable `PREFIX` to the code directory inside your IDE, so that tests can be successfully executed. Furthermore make sure to set the `GOPATH` correctly, create a directory (outside of the git workspace) and point the `GOPATH` to it. Then, add the code directory from git also to the `GOPATH`. This will result in the fact, that go will download all external dependencies with e.g. `make dep` or `go get` to the first folder and not put everything into the code directories. You will find all dependencies needed for the project inside the top lines for the `makefile`. |
|
| 22 | + |
|
| 23 | +An example for a correct `GOPATH` could be: `GOPATH=/home/steffen/.godep:/home/steffen/sailing-automation/` |
|
| 24 | + |
|
| 25 | +Happy Coding! |
|
| 26 | + |
|
| 27 | +## Get and prepare the software |
|
| 28 | +You can get the current release of the orchestration software currently from [here](http://static.sapsailing.com/orchestration-0.0.1_7f7e4e40d30f21ffeb8495a370a540c23c496745.tgz) until a release model is decided. The releases of each build can be downloaded directly on hudson via archived artifacts. The currently set up hudson job is called `orchestration-master` and can be started manually (runs on the archive failover, where go is installed). |
|
| 29 | + |
|
| 30 | + |
|
| 31 | + |
|
| 32 | +Once downloaded, you just need to extract the archive locally to your machine. You will find the orchestrator and agent binaries in `bin` and all configurations in `configs` (like the instance templates or secrets). |
|
| 33 | +To get going, place your private key inside the secrets folder and name it `id_rsa`. This key must be pre-deployed in the used AWS AMI image. Furthermore, create a file called `conf_aws.json` (copy `conf_aws.json.sample` and fill in the values). A good example is |
|
| 34 | + |
|
| 35 | +``` |
|
| 36 | +{ |
|
| 37 | + "AWS_ACCESS_KEY_ID": "<your access key id>, |
|
| 38 | + "AWS_SECRET_ACCESS_KEY": "<your secret access key>", |
|
| 39 | + "AWS_DEFAULT_REGION": "eu-west-1", |
|
| 40 | + "AWS_ELB_NAME": "Sailing-eu-west-1", |
|
| 41 | + "AWS_SNS_TOPIC_ARN": "arn:aws:sns:eu-west-1:017363970217:SAPSailing-General-Alerting" |
|
| 42 | +} |
|
| 43 | +``` |
|
| 44 | + |
|
| 45 | +Inside the `config` folder you will find a folder called `instance_templates`. You can pre-define variables for launching EC2 instances. A valid example is |
|
| 46 | + |
|
| 47 | +``` |
|
| 48 | +{ |
|
| 49 | + "image": "ami-839f8769", |
|
| 50 | + "instance-type": "t2.medium", |
|
| 51 | + "vpc": "vpc-14b3477f", |
|
| 52 | + "subnet": "subnet-eab34781", |
|
| 53 | + "count": 1, |
|
| 54 | + "security-groups": [ |
|
| 55 | + "sg-eaf31e85" |
|
| 56 | + ], |
|
| 57 | + "tags": { |
|
| 58 | + } |
|
| 59 | +} |
|
| 60 | + |
|
| 61 | +``` |
|
| 62 | + |
|
| 63 | +You are ready to use the orchestration tool! Please note, that currently only linux-amd64 versions are built. Windows versions can be easily added, as go can also run under Windows and the project currently does not have any dependencies to linux. |
|
| 64 | + |
|
| 65 | +## Run the software |
|
| 66 | +You can run the orchestrator using |
|
| 67 | + |
|
| 68 | +``` |
|
| 69 | +./bin/orchestrator-linux-amd64 <commands> |
|
| 70 | +``` |
|
| 71 | + |
|
| 72 | +As we use log levels, you can increase logging verbosity to a different level by specifying a ENV variable in front of the orchestrator command, like: |
|
| 73 | + |
|
| 74 | +``` |
|
| 75 | +LOG=DEBUG ./bin/orchestrator-linux-amd64 <commands> |
|
| 76 | +``` |
|
| 77 | +We offer the following log levels: `DEBUG`, `INFO` (default), `WARNING`, `PANIC`, `FATAL`. If execution fails, you may re-execute the orchestrator using a higher log level to get more insights, what has happened. |
|
| 78 | + |
|
| 79 | +### General |
|
| 80 | +In general, the orchestrator accepts a set of arguments. The first level of parameters describe the type of action to be executed (basically a use-case). The following arguments are used to specify the use-case specific parameters. |
|
| 81 | + |
|
| 82 | +To show all available commands just call the orchestrator without any parameters. |
|
| 83 | + |
|
| 84 | +Non use-case specific commands are example commands like the `version` of the orchestrator. To do so, just use |
|
| 85 | + |
|
| 86 | +``` |
|
| 87 | +./bin/orchestrator-linux-amd64 version |
|
| 88 | +``` |
|
| 89 | + |
|
| 90 | +It will show the `version`, `build revision` (git commit) and the `branch`, from where the software was built. The agent should have the same version as the orchestrator and will be transferred to a target at each execution to make sure the target has the correct version. |
|
| 91 | + |
|
| 92 | +If you want to skip some steps done by the orchestrator on AWS level, you can use a command called `agent-only` as parameter. This will require a empty EC2 instance, where only agent actions (like bootstrapping,...) are executed. This step helps do debug actions of the agent, as you do not need to fire up a new EC2 instance all the time, but can use a already existing one. A sample call of this command looks like |
|
| 93 | + |
|
| 94 | +``` |
|
| 95 | +./bin/orchestrator-linux-amd64 agent-only event="test-steffen123-1:1. Steffen Liga" servername=test-steffen123-1 internalhostname=ec2-34-242-13-180.eu-west-1.compute.amazonaws.com externalip=34.242.13.180 internalip=172.31.22.105 scenario=master analyticsenvironment=live-master-server analyticsrelease=build-201807231413 |
|
| 96 | +``` |
|
| 97 | + |
|
| 98 | +### Use case: Create Master Server |
|
| 99 | +This is the first ready to use and implemented use-case. It will spawn a new EC2 instance (you need to use an AMI in your instance template from the "NEXTGEN" base using Ubuntu 16 with systemd) and spawn/configure a new java instance on it. Furthermore it makes sure, that apache2 is configured correctly and if so the workflow continues to create target groups (default and master), attach the just created EC2 instance, create according rules in the load balancer and finally create an Cloudwatch alarm for all target groups to get notified, if a failure occurs inside a target group. |
|
| 100 | + |
|
| 101 | +If a step during execution fails, the orchestrator decides if it can continue or not. If not the execution is stopped and actions done via the agent are rolled back. Rollback of AWS features is not yet implemented. |
|
| 102 | + |
|
| 103 | +The workflow can create multiple events on a java instance and configure apache2, EC2 load balancing and the java application itself (event creation, user creation, password changes, ...). |
|
| 104 | + |
|
| 105 | +To use the use-case you simply use the orchestrator command `master`. An example could look like: |
|
| 106 | + |
|
| 107 | +``` |
|
| 108 | +./bin/orchestrator-linux-amd64 master event="steffen2018:1. Steffen Liga" admin-password=supersicher123 user-name=steffen user-password=supersicher123 env=live-master-server release=build-201807231413 |
|
| 109 | +``` |
|
| 110 | + |
|
| 111 | +The following parameters are required for this use-case: |
|
| 112 | + |
|
| 113 | +``` |
|
| 114 | +- event=<hostname>:<eventname> (the command can be repeated to create multiple events on the java server) |
|
| 115 | +- admin-password=<password of default admin account> |
|
| 116 | +- user-name=<name of the new user> |
|
| 117 | +- user-password=<password of the new user> |
|
| 118 | +- env=<environment for env.sh from releases.sapsailing.com> |
|
| 119 | +``` |
|
| 120 | + |
|
| 121 | +Optionally you can specify the following parameters: |
|
| 122 | + |
|
| 123 | +``` |
|
| 124 | +- template-file=<path to template file> |
|
| 125 | +- release=<release to use from releases.sapsailing.com, default: get latest> |
|
| 126 | +- notify=<email for notify parameter in env.sh> |
|
| 127 | +``` |
wiki/howto/development/selenium-ui-tests.md
| ... | ... | @@ -4,19 +4,19 @@ |
| 4 | 4 | |
| 5 | 5 | ## Quick Start: How to run tests locally in Eclipse |
| 6 | 6 | |
| 7 | -There are two ways to run the Selenium tests locally on your computer. Either, you compile the GWT UI using our build script and run the tests based on the compiled UI, or you run the tests using the GWT hosted mode. |
|
| 7 | +There are two ways to run the Selenium tests locally on your computer. Either, you compile the GWT UI using our build script and run the tests based on the compiled UI, or you run the tests using the GWT super dev mode. |
|
| 8 | 8 | |
| 9 | 9 | ### Firefox Prerequisites |
| 10 | 10 | |
| 11 | -!Since old Firefox version do not work with WindowScaling, ensure that in windows the Font Scaling is set to 100%, else Firefox will not be able to click buttons. You can find this setting at "Settings>Display Settings>Change the size of text, apps and other items". Also make sure that Firefox is running maximized (at least at Windows) as per default it is not running maximized! |
|
| 11 | +Running Selenium tests with FireFox requires to use GeckoDriver. You need to download a current version of GeckoDriver from [the download page](https://github.com/mozilla/geckodriver/releases) and unzip it on your system. At the time this was written, the current version was 0.21.0 and it worked best with FireFox versions 57-61 but other versions of both, GeckoDriver and FireFox should also work. In the file "/com.sap.sailing.selenium.test/local-test-environment.xml" you need to adjust the property "webdriver.gecko.driver" to point to the unzipped GeckoDriver executable. If you have a version of FixeFox globally installed on your system, GeckoDriver will use this one. If you do not have an installed version of FireFox or need to use a different version, you can set the property "webdriver.firefox.bin" in "/com.sap.sailing.selenium.test/local-test-environment.xml" to point to the specific firefox executable. When using a portable version, it is not the "FirefoxPortable.exe" but "App/Firefox/firefox.exe". |
|
| 12 | 12 | |
| 13 | -You have to ensure that your Firefox browser has a profile called "Selenium" and that in this profile the latest version of the GWT plugin is installed. To ensure this, launch the server by choosing the "Sailing Server (Proxy)" or "Sailing Server (No Proxy)" launch config. Then, run the "SailingGWT" launch to start the GWT UI in hosted / development mode. Afterwards you can launch Firefox from the command line with the -p option. On Windows machines, you can do this by pressing the Windows key, then typing "firefox.exe -p". In the profile manager create a profile called Selenium and start Firefow with that profile. Hit the entry page of the AdminConsole by entering `http://127.0.0.1:8888/gwt/AdminConsole.html?gwt.codesvr=127.0.0.1:9997` into the address bar. This will ask you to install the GWT plugin into your Selenium profile. When done, exit the browser. You may use the profile manager again to set your default profile to your original profile. |
|
| 13 | +In older versions of Selenium, you needed to configure a special user profile in FireFox. With GeckoDriver, this isn't needed anymore. |
|
| 14 | 14 | |
| 15 | -### Running the tests with GWT hosted mode |
|
| 15 | +### Running the tests with GWT super dev mode |
|
| 16 | 16 | |
| 17 | -Launch the server by choosing the "Sailing Server (Proxy, winddbTest)" or "Sailing Server (No Proxy, winddbTest)" launch config. Then, run the "SailingGWT" launch to start the GWT UI in hosted / development mode. |
|
| 17 | +Launch the server by choosing the "Sailing Server (Proxy, winddbTest)" or "Sailing Server (No Proxy, winddbTest)" launch config. Then, run the "GWT Sailing SDM" launch to start the GWT UI in super dev mode (SDM). |
|
| 18 | 18 | |
| 19 | -When the GWT development mode has finished its initialization as indicated by the "Development Mode" view showing the entry point URLs, launch the "com.sap.sailing.senelium.test (Proxy)" or "com.sap.sailing.senelium.test (No Proxy)" launch. This will then pop up Firefox windows using the "Selenium" profile and run the tests. |
|
| 19 | +When the GWT SDM has finished its initialization as indicated by the "Development Mode" view showing the entry point URLs, launch the "com.sap.sailing.senelium.test (Proxy)" or "com.sap.sailing.senelium.test (No Proxy)" launch. This will then pop up Firefox and run the tests. |
|
| 20 | 20 | |
| 21 | 21 | ### Running the tests after a successful local GWT compile |
| 22 | 22 | |
| ... | ... | @@ -111,9 +111,11 @@ For a more practical example of how to write page objects and test you should ta |
| 111 | 111 | |
| 112 | 112 | While our build environment is stable regarding to the used browser version, this may not be the case in your development environment, where you have the newest browser version installed probably. The short release cycles of the browsers often bring changes in the implementation, which are incompatible with Selenium. Therefore you have to update the used Selenium version by performing the following steps to be able to run the tests local. |
| 113 | 113 | |
| 114 | -* Download the latest _Client & WebDriver Bindings_ for Java from the official [Selenium](http://docs.seleniumhq.org/download/) website |
|
| 115 | -* Delete the _selenium-java-<version>.jar_ in the root directory of the project _org.openqa.selenium.osgi_ as well as all libraries in the _lib_ directory and copy the new versions from the downloaded file in the appropriate folders |
|
| 114 | +* Download the latest _Client_ for Java from the official [Selenium](http://docs.seleniumhq.org/download/) website |
|
| 115 | +* Delete the _client-combined-<version>.jar_ (plus the _client-combined-<version>-sources.jar_) in the root directory of the project _org.openqa.selenium.osgi_ as well as all libraries in the _lib_ directory and copy the new versions from the downloaded file in the appropriate folders |
|
| 116 | 116 | * Open the _MANIFEST.MF_ with the Plug-in Manifest Editor and switch to the _Runtime_ tab |
| 117 | 117 | * Remove all the old libraries from the _Classpath_ section and add all new versions |
| 118 | 118 | * Add all new packages that start with _org.openqa.selenium_ to the _Exported Packages_ section in the case there were packages added |
| 119 | -* Updated the version number in the _MANIFEST.MF_ and in the _pom.xml_ |
|
| ... | ... | \ No newline at end of file |
| 0 | +* Updated the version number in the _MANIFEST.MF_ and in the _pom.xml_ |
|
| 1 | +* update build.properties to reflect the changed *.jar files |
|
| 2 | +* Update the version number in _MANIFEST.MF_ files referencing the _org.openqa.selenium_ bundle (e.g in _com.sap.sailing.selenium.test_) |
wiki/images/orchestration/architecture.png
| ... | ... | Binary files /dev/null and b/wiki/images/orchestration/architecture.png differ |
wiki/images/orchestration/hudson-artifacts.png
| ... | ... | Binary files /dev/null and b/wiki/images/orchestration/hudson-artifacts.png differ |
wiki/info/landscape/amazon-ec2.md
| ... | ... | @@ -514,6 +514,7 @@ Follow these steps to upgrade the AMI: |
| 514 | 514 | * Check the sizes of the mounted partitions by doing `df; swapon -s`. These will come in handy after creating the new AMI in order to tag the new volume snapshots accordingly |
| 515 | 515 | * Update any keys in `/root/.ssh/authorized_keys` and `/home/sailing/.ssh/authorized_keys` |
| 516 | 516 | * Remove created http rewrite entries in `/etc/httpd/conf.d/001-events.conf` |
| 517 | +* Edit /etc/update-motd.d/30-banner to set the current version |
|
| 517 | 518 | * In the EC2 administration console go to the "Instances" tab, select your running instance and from the "Actions" drop-down select "Create Image". Give the image the name "SAP Sailing Analytics App x.y" where "x.y" is the updated version number of the image. Just make sure it's greater than the previous one. If you feel like it, you may provide a short description telling the most important features of the image. |
| 518 | 519 | * Once the image creation has completed, go to the Snapshots list in the "Elastic Block Store" category and name the new snapshots appropriately. Now the information about the device sizes obtained earlier from the `df` and `swapon` commands will help you to identify which snapshot is which. Usually, the three snapshots would be something like AMI Analytics Home x.y, AMI Analytics System x.y and AMI Analytics Swap x.y with "x.y" being the version number matching that of your image. |
| 519 | 520 | * Now you can remove any earlier Sailing Server AMI version and the corresponding snapshots. |