mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-16 01:01:02 +00:00
Merge branch 'master' into bug2775
Conflicts: java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties java/com.sap.sailing.server/src/com/sap/sailing/server/impl/Activator.java
This commit is contained in:
commit
793c2c0341
215 files changed
+11209
-6198
No files matched your search
@@ -1,47 +1,47 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
|
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
|
||||||
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
|
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
|
||||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||||
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
|
<booleanAttribute key="com.google.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
|
||||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
|
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||||
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
|
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||||
<listEntry value="4"/>
|
<listEntry value="4"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||||
<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.6" path="1" type="4"/> "/>
|
<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.6" path="1" type="4"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/>
|
||||||
<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"/> "/>
|
<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"/> "/>
|
||||||
<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"/> "/>
|
<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"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/resources" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/resources" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||||
<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> "/>
|
<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> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-servlet.jar" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-servlet.jar" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-superDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9998 com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort 9998 com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
@@ -1,47 +1,47 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
|
||||||
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
<booleanAttribute key="com.google.gdt.eclipse.core.RUN_SERVER" value="false"/>
|
||||||
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.GWTShell"/>
|
||||||
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
|
<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="false"/>
|
||||||
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
|
<stringAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT" value="9998"/>
|
||||||
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
|
<booleanAttribute key="com.google.gwt.eclipse.core.CODE_SERVER_PORT_AUTO" value="true"/>
|
||||||
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
<listAttribute key="com.google.gwt.eclipse.core.ENTRY_POINT_MODULES">
|
||||||
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
<listEntry value="com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
|
<stringAttribute key="com.google.gwt.eclipse.core.URL" value="/dashboards/RibDashboard.html"/>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||||
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
|
<listEntry value="/com.sap.sailing.dashboards.gwt"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||||
<listEntry value="4"/>
|
<listEntry value="4"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||||
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||||
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
|
||||||
<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.6" path="1" type="4"/> "/>
|
<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.6" path="1" type="4"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.gwt.ui/src" path="3" type="2"/> "/>
|
||||||
<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"/> "/>
|
<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"/> "/>
|
||||||
<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"/> "/>
|
<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"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/resources" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.dashboards.gwt/src/main/resources" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.server/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.common/src" path="3" type="2"/> "/>
|
||||||
<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> "/>
|
<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> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-servlet.jar" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-servlet.jar" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.google.gwt.osgi/lib/gwt-user.jar" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sailing.domain.common/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/org.moxieapps.gwt.highcharts/src" path="3" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/com.sap.sse.gwt.adminconsole/src" path="3" type="2"/> "/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-nosuperDevMode -incremental -war "${project_loc:com.sap.sailing.dashboards.gwt}" -startupUrl /dashboards/RibDashboard.html -noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -logLevel INFO -codeServerPort auto com.sap.sailing.dashboards.gwt.RibDashboard"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.dashboards.gwt"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx2048m"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
@@ -21,6 +21,7 @@ Export-Package: com.sap.sailing.domain.common,
|
|||||||
com.sap.sailing.domain.common.racelog.utils,
|
com.sap.sailing.domain.common.racelog.utils,
|
||||||
com.sap.sailing.domain.common.scalablevalue.impl,
|
com.sap.sailing.domain.common.scalablevalue.impl,
|
||||||
com.sap.sailing.domain.common.security,
|
com.sap.sailing.domain.common.security,
|
||||||
|
com.sap.sailing.domain.common.sensordata,
|
||||||
com.sap.sailing.domain.common.trackfiles,
|
com.sap.sailing.domain.common.trackfiles,
|
||||||
com.sap.sailing.domain.common.tracking,
|
com.sap.sailing.domain.common.tracking,
|
||||||
com.sap.sailing.domain.common.tracking.impl
|
com.sap.sailing.domain.common.tracking.impl
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ import java.io.Serializable;
|
|||||||
public enum DetailType implements Serializable {
|
public enum DetailType implements Serializable {
|
||||||
DISTANCE_TRAVELED(0, ASCENDING), DISTANCE_TRAVELED_INCLUDING_GATE_START(0, ASCENDING),
|
DISTANCE_TRAVELED(0, ASCENDING), DISTANCE_TRAVELED_INCLUDING_GATE_START(0, ASCENDING),
|
||||||
AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), REGATTA_RANK(0, ASCENDING), OVERALL_RANK(0, ASCENDING),
|
AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), REGATTA_RANK(0, ASCENDING), OVERALL_RANK(0, ASCENDING),
|
||||||
RANK_GAIN(0, ASCENDING), NUMBER_OF_MANEUVERS(0, ASCENDING), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING),
|
RANK_GAIN(0, ASCENDING), NUMBER_OF_MANEUVERS(0, ASCENDING), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), CURRENT_RIDE_HEIGHT_IN_METERS(2, DESCENDING),
|
||||||
ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1, ASCENDING), VELOCITY_MADE_GOOD_IN_KNOTS(2, DESCENDING),
|
ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1, ASCENDING), VELOCITY_MADE_GOOD_IN_KNOTS(2, DESCENDING),
|
||||||
GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), GAP_CHANGE_SINCE_LEG_START_IN_SECONDS(0, ASCENDING),
|
GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), GAP_CHANGE_SINCE_LEG_START_IN_SECONDS(0, ASCENDING),
|
||||||
SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED(0, ASCENDING), WINDWARD_DISTANCE_TO_GO_IN_METERS(0, ASCENDING),
|
SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED(0, ASCENDING), WINDWARD_DISTANCE_TO_GO_IN_METERS(0, ASCENDING),
|
||||||
@@ -39,7 +39,7 @@ public enum DetailType implements Serializable {
|
|||||||
MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS(1, DESCENDING),
|
MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS(1, DESCENDING),
|
||||||
TIME_ON_TIME_FACTOR(4, DESCENDING), TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE(0, ASCENDING),
|
TIME_ON_TIME_FACTOR(4, DESCENDING), TIME_ON_DISTANCE_ALLOWANCE_IN_SECONDS_PER_NAUTICAL_MILE(0, ASCENDING),
|
||||||
TOTAL_DISTANCE_TRAVELED(0, ASCENDING), TOTAL_AVERAGE_SPEED_OVER_GROUND(2, DESCENDING),
|
TOTAL_DISTANCE_TRAVELED(0, ASCENDING), TOTAL_AVERAGE_SPEED_OVER_GROUND(2, DESCENDING),
|
||||||
TOTAL_TIME_SAILED_IN_SECONDS(1, ASCENDING), RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING),
|
TOTAL_TIME_SAILED_IN_SECONDS(1, ASCENDING), RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_CURRENT_RIDE_HEIGHT_IN_METERS(2, DESCENDING),
|
||||||
RACE_NET_POINTS(2, ASCENDING), REGATTA_NET_POINTS(2, ASCENDING), REGATTA_NET_POINTS_SUM(2, ASCENDING),
|
RACE_NET_POINTS(2, ASCENDING), REGATTA_NET_POINTS(2, ASCENDING), REGATTA_NET_POINTS_SUM(2, ASCENDING),
|
||||||
RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL(1, ASCENDING), RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START(1, ASCENDING),
|
RACE_RATIO_BETWEEN_TIME_SINCE_LAST_POSITION_FIX_AND_AVERAGE_SAMPLING_INTERVAL(1, ASCENDING), RACE_DISTANCE_TO_START_FIVE_SECONDS_BEFORE_RACE_START(1, ASCENDING),
|
||||||
RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START(2, DESCENDING),
|
RACE_SPEED_OVER_GROUND_FIVE_SECONDS_BEFORE_START(2, DESCENDING),
|
||||||
|
|||||||
+13
@@ -35,6 +35,13 @@ public class LegEntryDTO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public Double currentSpeedOverGroundInKnots;
|
public Double currentSpeedOverGroundInKnots;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the competitor has already finished the leg at the time point for which this entry was created, contains the
|
||||||
|
* <em>average</em> ride height (foiling), otherwise the current ride height. If the competitor hasn't started the
|
||||||
|
* leg yet, it's <code>null</code>.
|
||||||
|
*/
|
||||||
|
public Double currentRideHeightInMeters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the competitor has already finished the leg at the time point for which this entry was created, contains the
|
* If the competitor has already finished the leg at the time point for which this entry was created, contains the
|
||||||
* <em>average</em> VMG, otherwise the current VMG. If the competitor hasn't started the leg yet, it's
|
* <em>average</em> VMG, otherwise the current VMG. If the competitor hasn't started the leg yet, it's
|
||||||
@@ -68,6 +75,7 @@ public class LegEntryDTO implements Serializable {
|
|||||||
result = prime * result + ((averageManeuverLossInMeters == null) ? 0 : averageManeuverLossInMeters.hashCode());
|
result = prime * result + ((averageManeuverLossInMeters == null) ? 0 : averageManeuverLossInMeters.hashCode());
|
||||||
result = prime * result
|
result = prime * result
|
||||||
+ ((averageSpeedOverGroundInKnots == null) ? 0 : averageSpeedOverGroundInKnots.hashCode());
|
+ ((averageSpeedOverGroundInKnots == null) ? 0 : averageSpeedOverGroundInKnots.hashCode());
|
||||||
|
result = prime * result + ((currentRideHeightInMeters == null) ? 0 : currentRideHeightInMeters.hashCode());
|
||||||
result = prime * result
|
result = prime * result
|
||||||
+ ((currentSpeedOverGroundInKnots == null) ? 0 : currentSpeedOverGroundInKnots.hashCode());
|
+ ((currentSpeedOverGroundInKnots == null) ? 0 : currentSpeedOverGroundInKnots.hashCode());
|
||||||
result = prime * result + ((distanceTraveledInMeters == null) ? 0 : distanceTraveledInMeters.hashCode());
|
result = prime * result + ((distanceTraveledInMeters == null) ? 0 : distanceTraveledInMeters.hashCode());
|
||||||
@@ -122,6 +130,11 @@ public class LegEntryDTO implements Serializable {
|
|||||||
return false;
|
return false;
|
||||||
} else if (!averageSpeedOverGroundInKnots.equals(other.averageSpeedOverGroundInKnots))
|
} else if (!averageSpeedOverGroundInKnots.equals(other.averageSpeedOverGroundInKnots))
|
||||||
return false;
|
return false;
|
||||||
|
if (currentRideHeightInMeters == null) {
|
||||||
|
if (other.currentRideHeightInMeters != null)
|
||||||
|
return false;
|
||||||
|
} else if (!currentRideHeightInMeters.equals(other.currentRideHeightInMeters))
|
||||||
|
return false;
|
||||||
if (currentSpeedOverGroundInKnots == null) {
|
if (currentSpeedOverGroundInKnots == null) {
|
||||||
if (other.currentSpeedOverGroundInKnots != null)
|
if (other.currentSpeedOverGroundInKnots != null)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
+43
@@ -0,0 +1,43 @@
|
|||||||
|
package com.sap.sailing.domain.common.sensordata;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata that defines the column structure of {@link com.sap.sailing.domain.common.tracking.DoubleVectorFix}es when imported.
|
||||||
|
*/
|
||||||
|
public enum BravoSensorDataMetadata {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
private final String RIDE_HEIGHT = "RideHeight";
|
||||||
|
private final int HEADER_COLUMN_OFFSET = 3;
|
||||||
|
|
||||||
|
private final List<String> columns = Collections.unmodifiableList(Arrays.asList(RIDE_HEIGHT, "RideHeightPortHull",
|
||||||
|
"RideHeightStbdHull", "Heel", "Trim", "ImuSensor_GyroX", "ImuSensor_GyroY", "ImuSensor_GyroZ",
|
||||||
|
"ImuSensor_Pitch", "ImuSensor_Roll", "ImuSensor_Yaw", "ImuSensor_LinearAccX", "ImuSensor_LinearAccY",
|
||||||
|
"ImuSensor_LinearAccZ", "Hb_Z", "Dn_Z", "Db_Z", "LKF_ride_hgh", "LKF_ride_hgh_Position",
|
||||||
|
"LKF_ride_hgh_Velocity", "LKF_ride_hgh_Acceleration", "LKF_ride_hgh_PositionError",
|
||||||
|
"LKF_ride_hgh_VelocityError", "LKF_ride_hgh_AccelerationError", "Gps_Gga_PosFixTime", "Gps_Gga_Lat",
|
||||||
|
"Gps_Gga_Lon", "Gps_Gga_QI", "Gps_Gga_HDOP", "Gps_Gga_AntHeight", "Gps_Vtg_TMG", "Gps_Vtg_SOGKnots",
|
||||||
|
"Gps_Rmc_MagVar", "Gps_EastVelocity", "Gps_NorthVelocity", "Gps_UpVelocity", "BravoNet_Node0x0A0_Ch0",
|
||||||
|
"BravoNet_Node0x0A0_Voltage", "BravoNet_Node0x0A0_Temperature", "BravoNet_Node0x0A0_Current"));
|
||||||
|
|
||||||
|
public final int rideHeightColumn = getColumnIndex(RIDE_HEIGHT);
|
||||||
|
|
||||||
|
public List<String> getColumns() {
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasColumn(String columnName) {
|
||||||
|
return columns.contains(columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumnIndex(String columnName) {
|
||||||
|
return columns.indexOf(columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeaderColumnOffset() {
|
||||||
|
return HEADER_COLUMN_OFFSET;
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package com.sap.sailing.domain.common.tracking;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specific {@link SensorFix} for bravo devices (http://www.bravosystems.es/).
|
||||||
|
*/
|
||||||
|
public interface BravoFix extends SensorFix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ride height (foiling) for this fix.
|
||||||
|
*
|
||||||
|
* @return the ride height
|
||||||
|
*/
|
||||||
|
double getRideHeight();
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package com.sap.sailing.domain.common.tracking;
|
||||||
|
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fix that simply holds an array of double values. The interpretation of the data depends on the concrete mapping in
|
||||||
|
* the RegattaLog.
|
||||||
|
*/
|
||||||
|
public interface DoubleVectorFix extends Timed {
|
||||||
|
double[] get();
|
||||||
|
double get(int index);
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
package com.sap.sailing.domain.common.tracking;
|
||||||
|
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fix having sensor data provided by a device. This kind of fix is intended to be used in a way so that all data can
|
||||||
|
* be accessed in a generic way by using names for the specific values. The available value names are provided by the
|
||||||
|
* associated SensorFixTrack.
|
||||||
|
*
|
||||||
|
* {@link SensorFix} implementation typically don't directly have their data but wrap a
|
||||||
|
* {@link com.sap.sailing.domain.common.tracking.DoubleVectorFix}.
|
||||||
|
*/
|
||||||
|
public interface SensorFix extends Timed {
|
||||||
|
/**
|
||||||
|
* Gets a value by its name.
|
||||||
|
* The available value names are provided by the associated SensorFixTrack.
|
||||||
|
*
|
||||||
|
* @param valueName the name of the value to get from this fix
|
||||||
|
* @return the value
|
||||||
|
* @throws IllegalArgumentException if the valueName isn't known by this fix
|
||||||
|
*/
|
||||||
|
double get(String valueName) throws IllegalArgumentException;
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package com.sap.sailing.domain.common.tracking.impl;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||||
|
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link BravoFix} that wraps a {@link DoubleVectorFix} which holds the actual sensor data.
|
||||||
|
*/
|
||||||
|
public class BravoFixImpl implements BravoFix {
|
||||||
|
private static final long serialVersionUID = 2033254212013221160L;
|
||||||
|
|
||||||
|
private final DoubleVectorFix fix;
|
||||||
|
|
||||||
|
public BravoFixImpl(DoubleVectorFix fix) {
|
||||||
|
this.fix = fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double get(String valueName) {
|
||||||
|
int index = BravoSensorDataMetadata.INSTANCE.getColumnIndex(valueName);
|
||||||
|
if (index < 0) {
|
||||||
|
throw new IllegalArgumentException("Unknown value \"" + valueName + "\" for " + getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
return fix.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePoint getTimePoint() {
|
||||||
|
return fix.getTimePoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getRideHeight() {
|
||||||
|
return fix.get(BravoSensorDataMetadata.INSTANCE.rideHeightColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package com.sap.sailing.domain.common.tracking.impl;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link DoubleVectorFix}.
|
||||||
|
*/
|
||||||
|
public class DoubleVectorFixImpl implements DoubleVectorFix {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -425848879310273855L;
|
||||||
|
|
||||||
|
private final double[] fixData;
|
||||||
|
private final TimePoint timePoint;
|
||||||
|
|
||||||
|
public DoubleVectorFixImpl(TimePoint timePoint, double[] fixData) {
|
||||||
|
this.timePoint = timePoint;
|
||||||
|
this.fixData = fixData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimePoint getTimePoint() {
|
||||||
|
return timePoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double get(int index) {
|
||||||
|
return fixData[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double[] get() {
|
||||||
|
// TODO defensive copy?
|
||||||
|
return fixData;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+41
@@ -103,6 +103,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitor
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnTimeFactorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnTimeFactorEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpenEndedDeviceMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogCloseOpenEndedDeviceMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
|
||||||
@@ -1656,6 +1657,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
|||||||
String eventClass = (String) dbObject.get(FieldNames.REGATTA_LOG_EVENT_CLASS.name());
|
String eventClass = (String) dbObject.get(FieldNames.REGATTA_LOG_EVENT_CLASS.name());
|
||||||
if (eventClass.equals(RegattaLogDeviceCompetitorMappingEvent.class.getSimpleName())) {
|
if (eventClass.equals(RegattaLogDeviceCompetitorMappingEvent.class.getSimpleName())) {
|
||||||
return loadRegattaLogDeviceCompetitorMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, regattaLogIdentifier, o);
|
return loadRegattaLogDeviceCompetitorMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, regattaLogIdentifier, o);
|
||||||
|
} else if (eventClass.equals(RegattaLogDeviceCompetitorBravoMappingEventImpl.class.getSimpleName())) {
|
||||||
|
return loadRegattaLogDeviceCompetitorBravoMappingEvent(createdAt, author, logicalTimePoint, id, dbObject,
|
||||||
|
regattaLogIdentifier, o);
|
||||||
} else if (eventClass.equals(RegattaLogDeviceMarkMappingEvent.class.getSimpleName())) {
|
} else if (eventClass.equals(RegattaLogDeviceMarkMappingEvent.class.getSimpleName())) {
|
||||||
return loadRegattaLogDeviceMarkMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, regattaLogIdentifier, o);
|
return loadRegattaLogDeviceMarkMappingEvent(createdAt, author, logicalTimePoint, id, dbObject, regattaLogIdentifier, o);
|
||||||
} else if (eventClass.equals(RegattaLogCloseOpenEndedDeviceMappingEvent.class.getSimpleName())) {
|
} else if (eventClass.equals(RegattaLogCloseOpenEndedDeviceMappingEvent.class.getSimpleName())) {
|
||||||
@@ -1840,6 +1844,43 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RegattaLogDeviceCompetitorBravoMappingEventImpl loadRegattaLogDeviceCompetitorBravoMappingEvent(
|
||||||
|
TimePoint createdAt, AbstractLogEventAuthor author, TimePoint logicalTimePoint, Serializable id,
|
||||||
|
final DBObject dbObject, RegattaLikeIdentifier regattaLogIdentifier, DBObject outerDBObject) {
|
||||||
|
DeviceIdentifier device = null;
|
||||||
|
try {
|
||||||
|
device = loadDeviceId(deviceIdentifierServiceFinder, (DBObject) dbObject.get(FieldNames.DEVICE_ID.name()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.log(Level.WARNING, "Could not load deviceId for RaceLogEvent", e);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Competitor mappedTo = baseDomainFactory.getExistingCompetitorById((Serializable) dbObject
|
||||||
|
.get(FieldNames.COMPETITOR_ID.name()));
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
// used only for auto-migration; may be removed in future releases
|
||||||
|
final FieldNames deprecatedFromFieldName = FieldNames.RACE_LOG_FROM;
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
// used only for auto-migration; may be removed in future releases
|
||||||
|
final FieldNames deprecatedToFieldName = FieldNames.RACE_LOG_TO;
|
||||||
|
Triple<TimePoint, TimePoint, Boolean> times = loadFromToTimePoint(dbObject, FieldNames.REGATTA_LOG_FROM,
|
||||||
|
deprecatedFromFieldName, FieldNames.REGATTA_LOG_TO, deprecatedToFieldName);
|
||||||
|
final TimePoint from = times.getA();
|
||||||
|
final TimePoint to = times.getB();
|
||||||
|
final boolean needsMigration = times.getC();
|
||||||
|
final RegattaLogDeviceCompetitorBravoMappingEventImpl result = new RegattaLogDeviceCompetitorBravoMappingEventImpl(
|
||||||
|
createdAt, logicalTimePoint, author, id, mappedTo, device, from, to);
|
||||||
|
if (needsMigration) {
|
||||||
|
// remove old version of mapping event
|
||||||
|
WriteResult removeResult = database.getCollection(CollectionNames.REGATTA_LOGS.name())
|
||||||
|
.remove(outerDBObject);
|
||||||
|
assert removeResult.getN() == 1;
|
||||||
|
// and then insert using the fixed storage implementation
|
||||||
|
new MongoObjectFactoryImpl(database, serviceFinderFactory).storeRegattaLogEvent(regattaLogIdentifier,
|
||||||
|
result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The old field name WAYPOINT_PASSINGSIDE has been replaced by WAYPOINT_PASSINGINSTRUCTIONS. If a race with the old
|
* The old field name WAYPOINT_PASSINGSIDE has been replaced by WAYPOINT_PASSINGINSTRUCTIONS. If a race with the old
|
||||||
* field is loaded, the value of PASSINGSIDE is used and then migrated to PASSINGINSTRUCTION. If the first or last
|
* field is loaded, the value of PASSINGSIDE is used and then migrated to PASSINGINSTRUCTION. If the first or last
|
||||||
|
|||||||
+4
-1
@@ -153,5 +153,8 @@ public enum FieldNames {
|
|||||||
VIDEO_TAGS, VIDEO_THUMBNAIL_URL, VIDEO_LENGTH_IN_SECONDS,
|
VIDEO_TAGS, VIDEO_THUMBNAIL_URL, VIDEO_LENGTH_IN_SECONDS,
|
||||||
|
|
||||||
// sailors info fileds
|
// sailors info fileds
|
||||||
SAILORS_INFO_URL, SAILORS_INFO_LOCALE;
|
SAILORS_INFO_URL, SAILORS_INFO_LOCALE,
|
||||||
|
|
||||||
|
// double vector fixes
|
||||||
|
FIX;
|
||||||
}
|
}
|
||||||
+14
-3
@@ -52,12 +52,14 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnTimeFactorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnTimeFactorEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.ControlPoint;
|
import com.sap.sailing.domain.base.ControlPoint;
|
||||||
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
||||||
@@ -168,9 +170,9 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
storeTimePoint(timePoint, result, field.name());
|
storeTimePoint(timePoint, result, field.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void storeTimeRange(TimeRange timeRange, DBObject result, FieldNames field) {
|
public static void storeTimeRange(TimeRange timeRange, BasicDBObject result, FieldNames field) {
|
||||||
if (timeRange != null) {
|
if (timeRange != null) {
|
||||||
DBObject timeRangeObj = new BasicDBObject();
|
BasicDBObject timeRangeObj = new BasicDBObject();
|
||||||
storeTimePoint(timeRange.from(), timeRangeObj, FieldNames.FROM_MILLIS);
|
storeTimePoint(timeRange.from(), timeRangeObj, FieldNames.FROM_MILLIS);
|
||||||
storeTimePoint(timeRange.to(), timeRangeObj, FieldNames.TO_MILLIS);
|
storeTimePoint(timeRange.to(), timeRangeObj, FieldNames.TO_MILLIS);
|
||||||
result.put(field.name(), timeRangeObj);
|
result.put(field.name(), timeRangeObj);
|
||||||
@@ -1379,6 +1381,15 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
storeRegattaLogEvent(regattaLikeId, result);
|
storeRegattaLogEvent(regattaLikeId, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId,
|
||||||
|
RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||||
|
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogDeviceCompetitorBravoMappingEventImpl.class.getSimpleName());
|
||||||
|
storeDeviceMappingEvent(event, result, FieldNames.REGATTA_LOG_FROM, FieldNames.REGATTA_LOG_TO);
|
||||||
|
result.put(FieldNames.COMPETITOR_ID.name(), event.getMappedTo().getId());
|
||||||
|
storeRegattaLogEvent(regattaLikeId, result);
|
||||||
|
}
|
||||||
|
|
||||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogDeviceMarkMappingEvent event) {
|
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogDeviceMarkMappingEvent event) {
|
||||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||||
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogDeviceMarkMappingEvent.class.getSimpleName());
|
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogDeviceMarkMappingEvent.class.getSimpleName());
|
||||||
@@ -1484,4 +1495,4 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
|||||||
result.put(FieldNames.SAILORS_INFO_LOCALE.name(), locale != null ? locale.toLanguageTag() : null);
|
result.put(FieldNames.SAILORS_INFO_LOCALE.name(), locale != null ? locale.toLanguageTag() : null);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -6,6 +6,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||||
@@ -42,6 +43,10 @@ public class MongoRegattaLogStoreVisitor implements RegattaLogEventVisitor {
|
|||||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||||
|
|||||||
+3
-4
@@ -2,15 +2,14 @@ package com.sap.sailing.domain.persistence.racelog.tracking;
|
|||||||
|
|
||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationHandler;
|
import com.sap.sailing.domain.common.racelog.tracking.TransformationHandler;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sse.common.Timed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For GPS Fixes, the fully qualified class name is the type used to identify
|
* For fixes, the fully qualified class name is the type used to identify
|
||||||
* the handlers, as the fixes are domain objects and are not intended to carry
|
* the handlers, as the fixes are domain objects and are not intended to carry
|
||||||
* some separate type attribute.
|
* some separate type attribute.
|
||||||
*
|
*
|
||||||
* @author Fredrik Teschke
|
* @author Fredrik Teschke
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface GPSFixMongoHandler extends TransformationHandler<GPSFix, DBObject> {
|
public interface FixMongoHandler<T extends Timed> extends TransformationHandler<T, DBObject> {
|
||||||
}
|
}
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
package com.sap.sailing.domain.persistence.racelog.tracking;
|
|
||||||
|
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
|
|
||||||
public interface MongoGPSFixStore extends GPSFixStore {
|
|
||||||
|
|
||||||
}
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.sap.sailing.domain.persistence.racelog.tracking;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
|
|
||||||
|
public interface MongoSensorFixStore extends SensorFixStore {
|
||||||
|
|
||||||
|
}
|
||||||
+4
-4
@@ -5,17 +5,17 @@ import java.net.UnknownHostException;
|
|||||||
import com.mongodb.MongoException;
|
import com.mongodb.MongoException;
|
||||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoGPSFixStoreFactoryImpl;
|
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreFactoryImpl;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||||
|
|
||||||
public interface MongoGPSFixStoreFactory {
|
public interface MongoSensorFixStoreFactory {
|
||||||
MongoGPSFixStoreFactory INSTANCE = new MongoGPSFixStoreFactoryImpl();
|
MongoSensorFixStoreFactory INSTANCE = new MongoSensorFixStoreFactoryImpl();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default Mongo store based on the properties mongo.hostname[=localhost], mongo.port[=27017]
|
* Gets the default Mongo store based on the properties mongo.hostname[=localhost], mongo.port[=27017]
|
||||||
* and mongo.dbName[=<contents of constant {@link #DEFAULT_DB_NAME}>] specified in the bundle context
|
* and mongo.dbName[=<contents of constant {@link #DEFAULT_DB_NAME}>] specified in the bundle context
|
||||||
*/
|
*/
|
||||||
MongoGPSFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
|
MongoSensorFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
|
||||||
TypeBasedServiceFinderFactory serviceFinderFactory)
|
TypeBasedServiceFinderFactory serviceFinderFactory)
|
||||||
throws UnknownHostException, MongoException;
|
throws UnknownHostException, MongoException;
|
||||||
|
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBList;
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.impl.DoubleVectorFixImpl;
|
||||||
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.FieldNames;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
public class DoubleVectorFixMongoHandlerImpl implements FixMongoHandler<DoubleVectorFix> {
|
||||||
|
private final MongoObjectFactoryImpl mof;
|
||||||
|
private final DomainObjectFactoryImpl dof;
|
||||||
|
|
||||||
|
public DoubleVectorFixMongoHandlerImpl(MongoObjectFactory mof, DomainObjectFactory dof) {
|
||||||
|
this.mof = (MongoObjectFactoryImpl) mof;
|
||||||
|
this.dof = (DomainObjectFactoryImpl) dof;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DBObject transformForth(DoubleVectorFix fix) throws IllegalArgumentException {
|
||||||
|
DBObject result = new BasicDBObject();
|
||||||
|
mof.storeTimed(fix, result);
|
||||||
|
result.put(FieldNames.FIX.name(), toDBObject(fix.get()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DoubleVectorFix transformBack(DBObject dbObject) {
|
||||||
|
TimePoint timePoint = dof.loadTimePoint(dbObject);
|
||||||
|
return new DoubleVectorFixImpl(timePoint, fromDBObject((DBObject) dbObject.get(FieldNames.FIX.name())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private DBObject toDBObject(double[] data) {
|
||||||
|
BasicDBList result = new BasicDBList();
|
||||||
|
for (double value : data) {
|
||||||
|
result.add(value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double[] fromDBObject(DBObject dbObject) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Double> dbValues = (List<Double>) dbObject;
|
||||||
|
double[] result = new double[dbValues.size()];
|
||||||
|
for(int i = 0 ; i < dbValues.size() ; i++) {
|
||||||
|
result[i] = dbValues.get(i);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -9,10 +9,10 @@ import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
|||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
public class GPSFixMongoHandlerImpl implements GPSFixMongoHandler {
|
public class GPSFixMongoHandlerImpl implements FixMongoHandler<GPSFix> {
|
||||||
private final MongoObjectFactoryImpl mof;
|
private final MongoObjectFactoryImpl mof;
|
||||||
private final DomainObjectFactoryImpl dof;
|
private final DomainObjectFactoryImpl dof;
|
||||||
|
|
||||||
|
|||||||
+5
-6
@@ -4,17 +4,16 @@ import com.mongodb.BasicDBObject;
|
|||||||
import com.mongodb.DBObject;
|
import com.mongodb.DBObject;
|
||||||
import com.sap.sailing.domain.common.Position;
|
import com.sap.sailing.domain.common.Position;
|
||||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
public class GPSFixMovingMongoHandlerImpl implements GPSFixMongoHandler {
|
public class GPSFixMovingMongoHandlerImpl implements FixMongoHandler<GPSFixMoving> {
|
||||||
private final MongoObjectFactoryImpl mof;
|
private final MongoObjectFactoryImpl mof;
|
||||||
private final DomainObjectFactoryImpl dof;
|
private final DomainObjectFactoryImpl dof;
|
||||||
|
|
||||||
@@ -24,16 +23,16 @@ public class GPSFixMovingMongoHandlerImpl implements GPSFixMongoHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DBObject transformForth(GPSFix fix) throws IllegalArgumentException {
|
public DBObject transformForth(GPSFixMoving fix) throws IllegalArgumentException {
|
||||||
DBObject result = new BasicDBObject();
|
DBObject result = new BasicDBObject();
|
||||||
mof.storeTimed(fix, result);
|
mof.storeTimed(fix, result);
|
||||||
mof.storePositioned(fix, result);
|
mof.storePositioned(fix, result);
|
||||||
mof.storeSpeedWithBearing(((GPSFixMoving) fix).getSpeed(), result);
|
mof.storeSpeedWithBearing(fix.getSpeed(), result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GPSFix transformBack(DBObject dbObject) {
|
public GPSFixMoving transformBack(DBObject dbObject) {
|
||||||
TimePoint timePoint = dof.loadTimePoint(dbObject);
|
TimePoint timePoint = dof.loadTimePoint(dbObject);
|
||||||
Position position = dof.loadPosition(dbObject);
|
Position position = dof.loadPosition(dbObject);
|
||||||
SpeedWithBearing speed = dof.loadSpeedWithBearing(dbObject);
|
SpeedWithBearing speed = dof.loadSpeedWithBearing(dbObject);
|
||||||
|
|||||||
-264
@@ -1,264 +0,0 @@
|
|||||||
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import com.mongodb.BasicDBObject;
|
|
||||||
import com.mongodb.BasicDBObjectBuilder;
|
|
||||||
import com.mongodb.DBCollection;
|
|
||||||
import com.mongodb.DBCursor;
|
|
||||||
import com.mongodb.DBObject;
|
|
||||||
import com.mongodb.QueryBuilder;
|
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceCompetitorMappingFinder;
|
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMarkMappingFinder;
|
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
|
||||||
import com.sap.sailing.domain.base.Mark;
|
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
|
||||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
|
||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
|
||||||
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
|
||||||
import com.sap.sailing.domain.persistence.impl.FieldNames;
|
|
||||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixReceivedListener;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
|
||||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
|
||||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
|
||||||
import com.sap.sse.common.TimePoint;
|
|
||||||
import com.sap.sse.common.TimeRange;
|
|
||||||
import com.sap.sse.common.TypeBasedServiceFinder;
|
|
||||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
|
||||||
import com.sap.sse.common.Util;
|
|
||||||
import com.sap.sse.common.WithID;
|
|
||||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* At the moment, the timerange covered by the fixes for a device, and the number of
|
|
||||||
* fixes for a device are stored in a metadata collection. Should be changed, see bug 1982.
|
|
||||||
* @author Fredrik Teschke
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MongoGPSFixStoreImpl implements MongoGPSFixStore {
|
|
||||||
private static final Logger logger = Logger.getLogger(MongoGPSFixStore.class.getName());
|
|
||||||
private final TypeBasedServiceFinder<GPSFixMongoHandler> fixServiceFinder;
|
|
||||||
private final TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceServiceFinder;
|
|
||||||
private final DBCollection fixesCollection;
|
|
||||||
private final DBCollection metadataCollection;
|
|
||||||
private final MongoObjectFactoryImpl mongoOF;
|
|
||||||
private final Map<DeviceIdentifier, Set<GPSFixReceivedListener>> listeners = new HashMap<>();
|
|
||||||
|
|
||||||
public MongoGPSFixStoreImpl(MongoObjectFactory mongoObjectFactory,
|
|
||||||
DomainObjectFactory domainObjectFactory, TypeBasedServiceFinderFactory serviceFinderFactory) {
|
|
||||||
mongoOF = (MongoObjectFactoryImpl) mongoObjectFactory;
|
|
||||||
if (serviceFinderFactory != null) {
|
|
||||||
fixServiceFinder = serviceFinderFactory.createServiceFinder(GPSFixMongoHandler.class);
|
|
||||||
deviceServiceFinder = serviceFinderFactory.createServiceFinder(DeviceIdentifierMongoHandler.class);
|
|
||||||
} else {
|
|
||||||
fixServiceFinder = null;
|
|
||||||
deviceServiceFinder = null;
|
|
||||||
}
|
|
||||||
fixesCollection = mongoOF.getGPSFixCollection();
|
|
||||||
metadataCollection = mongoOF.getGPSFixMetadataCollection();
|
|
||||||
}
|
|
||||||
|
|
||||||
private GPSFix loadGPSFix(DBObject object) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
String type = (String) object.get(FieldNames.GPSFIX_TYPE.name());
|
|
||||||
DBObject fixObject = (DBObject) object.get(FieldNames.GPSFIX.name());
|
|
||||||
return fixServiceFinder.findService(type).transformBack(fixObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
|
|
||||||
TimePoint from, TimePoint to, boolean inclusive) throws NoCorrespondingServiceRegisteredException,
|
|
||||||
TransformationException {
|
|
||||||
Object dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device);
|
|
||||||
final QueryBuilder queryBuilder = QueryBuilder.start(FieldNames.DEVICE_ID.name()).is(dbDeviceId)
|
|
||||||
.and(FieldNames.TIME_AS_MILLIS.name());
|
|
||||||
if (inclusive) {
|
|
||||||
queryBuilder.greaterThanEquals(from.asMillis()).and(FieldNames.TIME_AS_MILLIS.name()).lessThanEquals(to.asMillis());
|
|
||||||
} else {
|
|
||||||
queryBuilder.greaterThan(from.asMillis()).and(FieldNames.TIME_AS_MILLIS.name()).lessThan(to.asMillis());
|
|
||||||
}
|
|
||||||
DBObject query = queryBuilder.get();
|
|
||||||
|
|
||||||
DBCursor result = fixesCollection.find(query);
|
|
||||||
for (DBObject fixObject : result) {
|
|
||||||
try {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
FixT fix = (FixT) loadGPSFix(fixObject);
|
|
||||||
track.add(fix);
|
|
||||||
} catch (TransformationException e) {
|
|
||||||
logger.log(Level.WARNING, "Could not read fix from MongoDB: " + fixObject);
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
String type = (String) fixObject.get(FieldNames.GPSFIX_TYPE.name());
|
|
||||||
logger.log(Level.WARNING, "Unexpected fix type (" + type + ") encountered when trying to load track for " + track.getTrackedItem());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log, Competitor competitor)
|
|
||||||
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
|
||||||
List<DeviceMapping<Competitor>> mappings = new RegattaLogDeviceCompetitorMappingFinder(log).analyze().get(competitor);
|
|
||||||
if (mappings != null) {
|
|
||||||
for (DeviceMapping<Competitor> mapping : mappings) {
|
|
||||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark)
|
|
||||||
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
|
||||||
List<DeviceMapping<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze().get(mark);
|
|
||||||
if (mappings != null) {
|
|
||||||
for (DeviceMapping<Mark> mapping : mappings) {
|
|
||||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void storeFix(DeviceIdentifier device, GPSFix fix) {
|
|
||||||
try {
|
|
||||||
Object dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device);
|
|
||||||
String type = fix.getClass().getName();
|
|
||||||
Object fixObject = fixServiceFinder.findService(type).transformForth(fix);
|
|
||||||
DBObject entry = new BasicDBObjectBuilder().add(FieldNames.DEVICE_ID.name(), dbDeviceId)
|
|
||||||
.add(FieldNames.GPSFIX_TYPE.name(), type).add(FieldNames.GPSFIX.name(), fixObject).get();
|
|
||||||
mongoOF.storeTimed(fix, entry);
|
|
||||||
|
|
||||||
fixesCollection.insert(entry);
|
|
||||||
|
|
||||||
TimeRange oldTimeRange = getTimeRangeCoveredByFixes(device);
|
|
||||||
long oldNumFixes = getNumberOfFixes(device);
|
|
||||||
|
|
||||||
DBObject newMetadata = new BasicDBObject();
|
|
||||||
newMetadata.put(FieldNames.DEVICE_ID.name(), MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device));
|
|
||||||
newMetadata.put(FieldNames.NUM_FIXES.name(), oldNumFixes + 1);
|
|
||||||
|
|
||||||
TimePoint newFrom = fix.getTimePoint();
|
|
||||||
TimePoint newTo = fix.getTimePoint();
|
|
||||||
if (oldTimeRange != null) {
|
|
||||||
if (oldTimeRange.from().before(newFrom)) {
|
|
||||||
newFrom = oldTimeRange.from();
|
|
||||||
}
|
|
||||||
if (oldTimeRange.to().after(newTo)) {
|
|
||||||
newTo = oldTimeRange.to();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MongoObjectFactoryImpl.storeTimeRange(new TimeRangeImpl(newFrom, newTo), newMetadata, FieldNames.TIMERANGE);
|
|
||||||
metadataCollection.update(getDeviceQuery(device), newMetadata, /*create if not existent*/ true,
|
|
||||||
/*update multiple*/ false);
|
|
||||||
} catch (TransformationException e) {
|
|
||||||
logger.log(Level.WARNING, "Could not store fix in MongoDB");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
notifyListeners(device, fix);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyListeners(DeviceIdentifier device, GPSFix fix) {
|
|
||||||
for (GPSFixReceivedListener listener : Util.get(listeners, device, Collections.<GPSFixReceivedListener>emptySet())) {
|
|
||||||
listener.fixReceived(device, fix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void addListener(GPSFixReceivedListener listener, DeviceIdentifier device) {
|
|
||||||
Util.addToValueSet(listeners, device, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void removeListener(GPSFixReceivedListener listener) {
|
|
||||||
for (Set<GPSFixReceivedListener> set : listeners.values()) {
|
|
||||||
set.remove(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, DeviceMapping<Competitor> mapping)
|
|
||||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log,
|
|
||||||
Competitor competitor, TimePoint start, TimePoint end) throws TransformationException {
|
|
||||||
List<DeviceMapping<Competitor>> mappings = new RegattaLogDeviceCompetitorMappingFinder(log).analyze().get(competitor);
|
|
||||||
if (mappings != null) {
|
|
||||||
for (DeviceMapping<Competitor> mapping : mappings) {
|
|
||||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
|
||||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
|
||||||
loadTrack(track, mapping.getDevice(), from, to, true /*inclusive*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping)
|
|
||||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark,
|
|
||||||
TimePoint start, TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
List<DeviceMapping<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze().get(mark);
|
|
||||||
if (mappings != null) {
|
|
||||||
for (DeviceMapping<Mark> mapping : mappings) {
|
|
||||||
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
|
||||||
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
|
||||||
loadTrack(track, mapping.getDevice(), from, to, true /*inclusive*/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadTrack(DynamicGPSFixTrack<WithID, ?> track, DeviceMapping<WithID> mapping)
|
|
||||||
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
|
||||||
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DBObject getDeviceQuery(DeviceIdentifier device)
|
|
||||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
Object dbDeviceId = MongoObjectFactoryImpl.storeDeviceId(deviceServiceFinder, device);
|
|
||||||
DBObject query = QueryBuilder.start(FieldNames.DEVICE_ID.name()).is(dbDeviceId).get();
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DBObject findMetadataObject(DeviceIdentifier device)
|
|
||||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
DBObject query = getDeviceQuery(device);
|
|
||||||
DBObject result = metadataCollection.findOne(query);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TimeRange getTimeRangeCoveredByFixes(DeviceIdentifier device)
|
|
||||||
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
DBObject result = findMetadataObject(device);
|
|
||||||
if (result == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return DomainObjectFactoryImpl.loadTimeRange(result, FieldNames.TIMERANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getNumberOfFixes(DeviceIdentifier device) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
|
||||||
DBObject result = findMetadataObject(device);
|
|
||||||
if (result == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ((Number) result.get(FieldNames.NUM_FIXES.name())).longValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-5
@@ -5,15 +5,15 @@ import java.net.UnknownHostException;
|
|||||||
import com.mongodb.MongoException;
|
import com.mongodb.MongoException;
|
||||||
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStore;
|
import com.sap.sailing.domain.persistence.racelog.tracking.MongoSensorFixStore;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.MongoGPSFixStoreFactory;
|
import com.sap.sailing.domain.persistence.racelog.tracking.MongoSensorFixStoreFactory;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||||
|
|
||||||
public class MongoGPSFixStoreFactoryImpl implements MongoGPSFixStoreFactory {
|
public class MongoSensorFixStoreFactoryImpl implements MongoSensorFixStoreFactory {
|
||||||
@Override
|
@Override
|
||||||
public MongoGPSFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory,
|
public MongoSensorFixStore getMongoGPSFixStore(MongoObjectFactory mongoObjectFactory,
|
||||||
DomainObjectFactory domainObjectFactory, TypeBasedServiceFinderFactory serviceFinderFactory)
|
DomainObjectFactory domainObjectFactory, TypeBasedServiceFinderFactory serviceFinderFactory)
|
||||||
throws UnknownHostException, MongoException {
|
throws UnknownHostException, MongoException {
|
||||||
return new MongoGPSFixStoreImpl(mongoObjectFactory, domainObjectFactory, serviceFinderFactory);
|
return new MongoSensorFixStoreImpl(mongoObjectFactory, domainObjectFactory, serviceFinderFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+239
@@ -0,0 +1,239 @@
|
|||||||
|
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
|
||||||
|
|
||||||
|
import static com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl.storeDeviceId;
|
||||||
|
import static com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl.storeTimeRange;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.mongodb.BasicDBObject;
|
||||||
|
import com.mongodb.BasicDBObjectBuilder;
|
||||||
|
import com.mongodb.DBCollection;
|
||||||
|
import com.mongodb.DBCursor;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import com.mongodb.QueryBuilder;
|
||||||
|
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||||
|
import com.sap.sailing.domain.persistence.DomainObjectFactory;
|
||||||
|
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.FieldNames;
|
||||||
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
|
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
||||||
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
|
import com.sap.sailing.domain.persistence.racelog.tracking.MongoSensorFixStore;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.FixReceivedListener;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
import com.sap.sse.common.TypeBasedServiceFinder;
|
||||||
|
import com.sap.sse.common.TypeBasedServiceFinderFactory;
|
||||||
|
import com.sap.sse.common.Util;
|
||||||
|
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At the moment, the timerange covered by the fixes for a device, and the number of fixes for a device are stored in a
|
||||||
|
* metadata collection. Should be changed, see bug 1982.
|
||||||
|
*
|
||||||
|
* @author Fredrik Teschke
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MongoSensorFixStoreImpl implements MongoSensorFixStore {
|
||||||
|
private static final Logger logger = Logger.getLogger(MongoSensorFixStoreImpl.class.getName());
|
||||||
|
private final TypeBasedServiceFinder<FixMongoHandler<?>> fixServiceFinder;
|
||||||
|
private final TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceServiceFinder;
|
||||||
|
private final DBCollection fixesCollection;
|
||||||
|
private final DBCollection metadataCollection;
|
||||||
|
private final MongoObjectFactoryImpl mongoOF;
|
||||||
|
private final Map<DeviceIdentifier, Set<FixReceivedListener<? extends Timed>>> listeners = new HashMap<>();
|
||||||
|
|
||||||
|
public MongoSensorFixStoreImpl(MongoObjectFactory mongoObjectFactory, DomainObjectFactory domainObjectFactory,
|
||||||
|
TypeBasedServiceFinderFactory serviceFinderFactory) {
|
||||||
|
mongoOF = (MongoObjectFactoryImpl) mongoObjectFactory;
|
||||||
|
if (serviceFinderFactory != null) {
|
||||||
|
fixServiceFinder = createFixServiceFinder(serviceFinderFactory);
|
||||||
|
deviceServiceFinder = serviceFinderFactory.createServiceFinder(DeviceIdentifierMongoHandler.class);
|
||||||
|
} else {
|
||||||
|
fixServiceFinder = null;
|
||||||
|
deviceServiceFinder = null;
|
||||||
|
}
|
||||||
|
fixesCollection = mongoOF.getGPSFixCollection();
|
||||||
|
metadataCollection = mongoOF.getGPSFixMetadataCollection();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
|
private TypeBasedServiceFinder<FixMongoHandler<?>> createFixServiceFinder(
|
||||||
|
TypeBasedServiceFinderFactory serviceFinderFactory) {
|
||||||
|
return (TypeBasedServiceFinder) serviceFinderFactory.createServiceFinder(FixMongoHandler.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Timed> T loadFix(DBObject object)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
String type = (String) object.get(FieldNames.GPSFIX_TYPE.name());
|
||||||
|
DBObject fixObject = (DBObject) object.get(FieldNames.GPSFIX.name());
|
||||||
|
return this.<T> findService(type).transformBack(fixObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends Timed> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier device, TimePoint from,
|
||||||
|
TimePoint to, boolean inclusive) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||||
|
final TimePoint loadFixesFrom = from == null ? TimePoint.BeginningOfTime : from;
|
||||||
|
final TimePoint loadFixesTo = to == null ? TimePoint.EndOfTime : to;
|
||||||
|
|
||||||
|
Object dbDeviceId = storeDeviceId(deviceServiceFinder, device);
|
||||||
|
final QueryBuilder queryBuilder = QueryBuilder.start(FieldNames.DEVICE_ID.name()).is(dbDeviceId)
|
||||||
|
.and(FieldNames.TIME_AS_MILLIS.name());
|
||||||
|
if (inclusive) {
|
||||||
|
queryBuilder.greaterThanEquals(loadFixesFrom.asMillis()).and(FieldNames.TIME_AS_MILLIS.name())
|
||||||
|
.lessThanEquals(loadFixesTo.asMillis());
|
||||||
|
} else {
|
||||||
|
queryBuilder.greaterThan(loadFixesFrom.asMillis()).and(FieldNames.TIME_AS_MILLIS.name()).lessThan(loadFixesTo.asMillis());
|
||||||
|
}
|
||||||
|
DBObject query = queryBuilder.get();
|
||||||
|
DBCursor result = fixesCollection.find(query);
|
||||||
|
for (DBObject fixObject : result) {
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
FixT fix = (FixT) loadFix(fixObject);
|
||||||
|
consumer.accept(fix);
|
||||||
|
} catch (TransformationException e) {
|
||||||
|
logger.log(Level.WARNING, "Could not read fix from MongoDB: " + fixObject);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
String type = (String) fixObject.get(FieldNames.GPSFIX_TYPE.name());
|
||||||
|
logger.log(Level.WARNING,
|
||||||
|
"Unexpected fix type (" + type + ") encountered when trying to load track for " + device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store fixes in batches, reducing metadata storage update.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <FixT extends Timed> void storeFixes(DeviceIdentifier device, Iterable<FixT> fixes) {
|
||||||
|
if (Util.isEmpty(fixes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
final Object dbDeviceId = storeDeviceId(deviceServiceFinder, device);
|
||||||
|
final int nrOfTotalFixes = Util.size(fixes);
|
||||||
|
final ArrayList<DBObject> dbFixes = new ArrayList<>(nrOfTotalFixes);
|
||||||
|
|
||||||
|
TimePoint newFrom = null;
|
||||||
|
TimePoint newTo = null;
|
||||||
|
for (FixT fix : fixes) {
|
||||||
|
String type = fix.getClass().getName();
|
||||||
|
FixMongoHandler<FixT> mongoHandler = findService(type);
|
||||||
|
Object fixObject = mongoHandler.transformForth(fix);
|
||||||
|
DBObject entry = new BasicDBObjectBuilder().add(FieldNames.DEVICE_ID.name(), dbDeviceId)
|
||||||
|
.add(FieldNames.GPSFIX_TYPE.name(), type).add(FieldNames.GPSFIX.name(), fixObject).get();
|
||||||
|
mongoOF.storeTimed(fix, entry);
|
||||||
|
dbFixes.add(entry);
|
||||||
|
TimePoint fixTP = fix.getTimePoint();
|
||||||
|
if (newFrom == null || newFrom.after(fixTP)) {
|
||||||
|
newFrom = fixTP;
|
||||||
|
}
|
||||||
|
if (newTo == null || newTo.before(fixTP)) {
|
||||||
|
newTo = fixTP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixesCollection.insert(dbFixes);
|
||||||
|
final BasicDBObject updateOperation = new BasicDBObject();
|
||||||
|
final BasicDBObject newMetadata = new BasicDBObject();
|
||||||
|
newMetadata.put(FieldNames.DEVICE_ID.name(), dbDeviceId);
|
||||||
|
|
||||||
|
TimeRange oldTimeRange = getTimeRangeCoveredByFixes(device);
|
||||||
|
if (oldTimeRange != null) {
|
||||||
|
newFrom = oldTimeRange.from().before(newFrom) ? oldTimeRange.from() : newFrom;
|
||||||
|
newTo = oldTimeRange.to().after(newTo) ? oldTimeRange.to() : newTo;
|
||||||
|
}
|
||||||
|
final TimeRange newTimeRange = new TimeRangeImpl(newFrom, newTo);
|
||||||
|
|
||||||
|
storeTimeRange(newTimeRange, newMetadata, FieldNames.TIMERANGE);
|
||||||
|
updateOperation.append("$set", newMetadata);
|
||||||
|
updateOperation.append("$inc", new BasicDBObject(FieldNames.NUM_FIXES.name(), nrOfTotalFixes));
|
||||||
|
metadataCollection.update(getDeviceQuery(device), updateOperation, /* create if not existent */ true,
|
||||||
|
/* update multiple */ false);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (TransformationException e) {
|
||||||
|
logger.log(Level.WARNING, "Could not store fix in MongoDB");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
for (FixT fix : fixes) {
|
||||||
|
notifyListeners(device, fix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends Timed> void storeFix(DeviceIdentifier device, FixT fix) {
|
||||||
|
storeFixes(device, Collections.singletonList(fix));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
private <FixT extends Timed> void notifyListeners(DeviceIdentifier device, FixT fix) {
|
||||||
|
for (FixReceivedListener<FixT> listener : Util.<DeviceIdentifier, Set<FixReceivedListener<FixT>>> get(
|
||||||
|
(Map) listeners, device, Collections.emptySet())) {
|
||||||
|
listener.fixReceived(device, fix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void addListener(FixReceivedListener<? extends Timed> listener, DeviceIdentifier device) {
|
||||||
|
Util.addToValueSet(listeners, device, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void removeListener(FixReceivedListener<? extends Timed> listener) {
|
||||||
|
for (Set<FixReceivedListener<? extends Timed>> set : listeners.values()) {
|
||||||
|
set.remove(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DBObject getDeviceQuery(DeviceIdentifier device)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
Object dbDeviceId = storeDeviceId(deviceServiceFinder, device);
|
||||||
|
DBObject query = QueryBuilder.start(FieldNames.DEVICE_ID.name()).is(dbDeviceId).get();
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DBObject findMetadataObject(DeviceIdentifier device)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
DBObject query = getDeviceQuery(device);
|
||||||
|
DBObject result = metadataCollection.findOne(query);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeRange getTimeRangeCoveredByFixes(DeviceIdentifier device)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
DBObject result = findMetadataObject(device);
|
||||||
|
if (result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return DomainObjectFactoryImpl.loadTimeRange(result, FieldNames.TIMERANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getNumberOfFixes(DeviceIdentifier device)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
DBObject result = findMetadataObject(device);
|
||||||
|
if (result == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ((Number) result.get(FieldNames.NUM_FIXES.name())).longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <FixT extends Timed> FixMongoHandler<FixT> findService(String type) {
|
||||||
|
return (FixMongoHandler<FixT>) fixServiceFinder.findService(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
+94
-93
@@ -1,94 +1,95 @@
|
|||||||
package com.sap.sailing.domain.racelogtracking.test;
|
package com.sap.sailing.domain.racelogtracking.test;
|
||||||
|
|
||||||
import static com.sap.sse.common.Util.size;
|
import static com.sap.sse.common.Util.size;
|
||||||
import static junit.framework.Assert.assertEquals;
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.DomainFactory;
|
import com.sap.sailing.domain.base.DomainFactory;
|
||||||
import com.sap.sailing.domain.base.Mark;
|
import com.sap.sailing.domain.base.Mark;
|
||||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoGPSFixStoreImpl;
|
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreImpl;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.MockDeviceAndSessionIdentifierWithGPSFixesDeserializer;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.MockDeviceAndSessionIdentifierWithGPSFixesDeserializer;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.tracking.Track;
|
import com.sap.sailing.domain.tracking.Track;
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
import com.sap.sailing.server.gateway.deserialization.impl.DeviceAndSessionIdentifierWithGPSFixesDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.impl.DeviceAndSessionIdentifierWithGPSFixesDeserializer;
|
||||||
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
public class AbstractGPSFixStoreTest {
|
public class AbstractGPSFixStoreTest {
|
||||||
protected RacingEventService service;
|
protected RacingEventService service;
|
||||||
protected final MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
|
protected final MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
|
||||||
DeviceAndSessionIdentifierWithGPSFixesDeserializer deserializer =
|
DeviceAndSessionIdentifierWithGPSFixesDeserializer deserializer =
|
||||||
new MockDeviceAndSessionIdentifierWithGPSFixesDeserializer();
|
new MockDeviceAndSessionIdentifierWithGPSFixesDeserializer();
|
||||||
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
|
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
|
||||||
protected RaceLog raceLog;
|
protected RaceLog raceLog;
|
||||||
protected RegattaLog regattaLog;
|
protected RegattaLog regattaLog;
|
||||||
protected GPSFixStore store;
|
protected SensorFixStore store;
|
||||||
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||||
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
|
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
|
||||||
|
|
||||||
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
||||||
|
|
||||||
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
||||||
return new GPSFixMovingImpl(new DegreePosition(lat, lng),
|
return new GPSFixMovingImpl(new DegreePosition(lat, lng),
|
||||||
new MillisecondsTimePoint(millis), new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
|
new MillisecondsTimePoint(millis), new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setServiceAndRaceLog() {
|
public void setServiceAndRaceLog() {
|
||||||
service = new RacingEventServiceImpl(null, null, serviceFinderFactory);
|
service = new RacingEventServiceImpl(null, null, serviceFinderFactory);
|
||||||
raceLog = new RaceLogImpl("racelog");
|
raceLog = new RaceLogImpl("racelog");
|
||||||
regattaLog = new RegattaLogImpl("regattalog");
|
regattaLog = new RegattaLogImpl("regattalog");
|
||||||
store = new MongoGPSFixStoreImpl(service.getMongoObjectFactory(), service.getDomainObjectFactory(),
|
|
||||||
serviceFinderFactory);
|
store = new MongoSensorFixStoreImpl(service.getMongoObjectFactory(), service.getDomainObjectFactory(),
|
||||||
}
|
serviceFinderFactory);
|
||||||
|
}
|
||||||
@After
|
|
||||||
public void after() {
|
@After
|
||||||
MongoObjectFactoryImpl mongoOF = (MongoObjectFactoryImpl) service.getMongoObjectFactory();
|
public void after() {
|
||||||
mongoOF.getGPSFixCollection().drop();
|
MongoObjectFactoryImpl mongoOF = (MongoObjectFactoryImpl) service.getMongoObjectFactory();
|
||||||
mongoOF.getGPSFixMetadataCollection().drop();
|
mongoOF.getGPSFixCollection().drop();
|
||||||
}
|
mongoOF.getGPSFixMetadataCollection().drop();
|
||||||
|
}
|
||||||
protected void map(RegattaLog regattaLog, Competitor comp, DeviceIdentifier device, long from, long to) {
|
|
||||||
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(),
|
protected void map(RegattaLog regattaLog, Competitor comp, DeviceIdentifier device, long from, long to) {
|
||||||
comp, device, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
|
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(),
|
||||||
}
|
comp, device, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
|
||||||
|
}
|
||||||
protected void map(Competitor comp, DeviceIdentifier device, long from, long to) {
|
|
||||||
map(regattaLog, comp, device, from, to);
|
protected void map(Competitor comp, DeviceIdentifier device, long from, long to) {
|
||||||
}
|
map(regattaLog, comp, device, from, to);
|
||||||
|
}
|
||||||
protected void map(Mark mark, DeviceIdentifier device, long from, long to) {
|
|
||||||
regattaLog.add(new RegattaLogDeviceMarkMappingEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(),
|
protected void map(Mark mark, DeviceIdentifier device, long from, long to) {
|
||||||
mark, device, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
|
regattaLog.add(new RegattaLogDeviceMarkMappingEventImpl(MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), author, UUID.randomUUID(),
|
||||||
}
|
mark, device, new MillisecondsTimePoint(from), new MillisecondsTimePoint(to)));
|
||||||
|
}
|
||||||
protected void testNumberOfRawFixes(Track<?> track, long expected) {
|
|
||||||
track.lockForRead();
|
protected void testNumberOfRawFixes(Track<?> track, long expected) {
|
||||||
assertEquals(expected, size(track.getRawFixes()));
|
track.lockForRead();
|
||||||
track.unlockAfterRead();
|
assertEquals(expected, size(track.getRawFixes()));
|
||||||
}
|
track.unlockAfterRead();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
+26
-11
@@ -16,6 +16,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
import org.junit.rules.Timeout;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
@@ -42,13 +43,15 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
|||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
|
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.MockSmartphoneImeiServiceFinderFactory;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter;
|
||||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.impl.fixtracker.RaceLogFixTrackerManager;
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.Track;
|
import com.sap.sailing.domain.tracking.Track;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.server.RacingEventService;
|
import com.sap.sailing.server.RacingEventService;
|
||||||
@@ -66,14 +69,17 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
private RaceLogTrackingAdapter adapter;
|
private RaceLogTrackingAdapter adapter;
|
||||||
private Regatta regatta;
|
private Regatta regatta;
|
||||||
private AbstractLogEventAuthor author;
|
private AbstractLogEventAuthor author;
|
||||||
private GPSFixStore gpsFixStore;
|
private SensorFixStore sensorFixStore;
|
||||||
|
|
||||||
private long time = 0;
|
private long time = 0;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public Timeout CreateAndTrackWithRaceLogTestTimeout = new Timeout(3 * 60 * 1000);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
service = new RacingEventServiceImpl(true, new MockSmartphoneImeiServiceFinderFactory());
|
service = new RacingEventServiceImpl(true, new MockSmartphoneImeiServiceFinderFactory());
|
||||||
gpsFixStore = service.getGPSFixStore();
|
sensorFixStore = service.getSensorFixStore();
|
||||||
service.getMongoObjectFactory().getDatabase().dropDatabase();
|
service.getMongoObjectFactory().getDatabase().dropDatabase();
|
||||||
author = service.getServerAuthor();
|
author = service.getServerAuthor();
|
||||||
Series series = new SeriesImpl("series", /* isMedal */ false, /* isFleetsCanRunInParallel */ true, Collections.singletonList(fleet), Collections.emptySet(),
|
Series series = new SeriesImpl("series", /* isMedal */ false, /* isFleetsCanRunInParallel */ true, Collections.singletonList(fleet), Collections.emptySet(),
|
||||||
@@ -118,9 +124,9 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
|
|
||||||
private void addFixes0(DeviceIdentifier dev1) throws TransformationException,
|
private void addFixes0(DeviceIdentifier dev1) throws TransformationException,
|
||||||
NoCorrespondingServiceRegisteredException {
|
NoCorrespondingServiceRegisteredException {
|
||||||
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(5), new KnotSpeedWithBearingImpl(
|
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(5), new KnotSpeedWithBearingImpl(
|
||||||
10, new DegreeBearingImpl(5))));
|
10, new DegreeBearingImpl(5))));
|
||||||
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(15), new KnotSpeedWithBearingImpl(
|
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(15), new KnotSpeedWithBearingImpl(
|
||||||
10, new DegreeBearingImpl(5))));
|
10, new DegreeBearingImpl(5))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +136,9 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
testSize(race.getTrack(comp1), 1);
|
testSize(race.getTrack(comp1), 1);
|
||||||
|
|
||||||
// further fix arrives in race
|
// further fix arrives in race
|
||||||
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(7), new KnotSpeedWithBearingImpl(
|
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(7), new KnotSpeedWithBearingImpl(
|
||||||
10, new DegreeBearingImpl(5))));
|
10, new DegreeBearingImpl(5))));
|
||||||
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(14), new KnotSpeedWithBearingImpl(
|
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(14), new KnotSpeedWithBearingImpl(
|
||||||
10, new DegreeBearingImpl(5)))); // outside mapping range
|
10, new DegreeBearingImpl(5)))); // outside mapping range
|
||||||
testSize(race.getTrack(comp1), 2);
|
testSize(race.getTrack(comp1), 2);
|
||||||
}
|
}
|
||||||
@@ -143,7 +149,7 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
testSize(race.getTrack(comp1), 4);
|
testSize(race.getTrack(comp1), 4);
|
||||||
|
|
||||||
// add another fix in new mapping range
|
// add another fix in new mapping range
|
||||||
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(18), new KnotSpeedWithBearingImpl(
|
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(18), new KnotSpeedWithBearingImpl(
|
||||||
10, new DegreeBearingImpl(5))));
|
10, new DegreeBearingImpl(5))));
|
||||||
testSize(race.getTrack(comp1), 5);
|
testSize(race.getTrack(comp1), 5);
|
||||||
}
|
}
|
||||||
@@ -151,7 +157,7 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
private void addFixes3(TrackedRace race, Competitor comp1, DeviceIdentifier dev1) throws TransformationException,
|
private void addFixes3(TrackedRace race, Competitor comp1, DeviceIdentifier dev1) throws TransformationException,
|
||||||
NoCorrespondingServiceRegisteredException {
|
NoCorrespondingServiceRegisteredException {
|
||||||
// stop tracking, then no more fixes arrive at race
|
// stop tracking, then no more fixes arrive at race
|
||||||
gpsFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(8), new KnotSpeedWithBearingImpl(
|
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(8), new KnotSpeedWithBearingImpl(
|
||||||
10, new DegreeBearingImpl(5))));
|
10, new DegreeBearingImpl(5))));
|
||||||
testSize(race.getTrack(comp1), 5);
|
testSize(race.getTrack(comp1), 5);
|
||||||
}
|
}
|
||||||
@@ -179,20 +185,25 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
raceLog.add(new RaceLogStartOfTrackingEventImpl(t(0), author, /* passId */ 0));
|
raceLog.add(new RaceLogStartOfTrackingEventImpl(t(0), author, /* passId */ 0));
|
||||||
// start tracking
|
// start tracking
|
||||||
adapter.startTracking(service, leaderboard, column, fleet);
|
adapter.startTracking(service, leaderboard, column, fleet);
|
||||||
|
|
||||||
|
|
||||||
// now there is a tracked race
|
// now there is a tracked race
|
||||||
TrackedRace race = column.getTrackedRace(fleet);
|
TrackedRace race = column.getTrackedRace(fleet);
|
||||||
assertNotNull(race);
|
assertNotNull(race);
|
||||||
|
|
||||||
|
RaceLogFixTrackerManager raceLogFixTrackerManager = new RaceLogFixTrackerManager((DynamicTrackedRace) race, sensorFixStore, null);
|
||||||
|
|
||||||
race.waitForLoadingFromGPSFixStoreToFinishRunning(regattaLog);
|
race.waitForLoadingToFinish();
|
||||||
addFixes1(race, comp1, dev1);
|
addFixes1(race, comp1, dev1);
|
||||||
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, 0, comp1, dev1, t(11), t(20)));
|
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, 0, comp1, dev1, t(11), t(20)));
|
||||||
|
|
||||||
|
race.waitForLoadingToFinish();
|
||||||
// add another mapping on the fly, other old fixes should be loaded
|
// add another mapping on the fly, other old fixes should be loaded
|
||||||
addFixes2(race, comp1, dev1);
|
addFixes2(race, comp1, dev1);
|
||||||
|
|
||||||
// stop tracking, then no more fixes arrive at race
|
// stop tracking, then no more fixes arrive at race
|
||||||
service.getRaceTrackerById(raceLog.getId()).stop(false);
|
service.getRaceTrackerById(raceLog.getId()).stop(false);
|
||||||
|
raceLogFixTrackerManager.stop(false);
|
||||||
addFixes3(race, comp1, dev1);
|
addFixes3(race, comp1, dev1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,17 +231,21 @@ public class CreateAndTrackWithRaceLogTest {
|
|||||||
// now there is a trackedrace
|
// now there is a trackedrace
|
||||||
TrackedRace race = column.getTrackedRace(fleet);
|
TrackedRace race = column.getTrackedRace(fleet);
|
||||||
assertNotNull(race);
|
assertNotNull(race);
|
||||||
|
|
||||||
|
RaceLogFixTrackerManager raceLogFixTrackerManager = new RaceLogFixTrackerManager((DynamicTrackedRace) race, sensorFixStore, null);
|
||||||
|
|
||||||
race.waitForLoadingFromGPSFixStoreToFinishRunning(regattaLog);
|
race.waitForLoadingToFinish();
|
||||||
addFixes1(race, comp1, dev1);
|
addFixes1(race, comp1, dev1);
|
||||||
|
|
||||||
// add another mapping on the fly, other old fixes should be loaded
|
// add another mapping on the fly, other old fixes should be loaded
|
||||||
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, UUID.randomUUID(), comp1, dev1,
|
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, UUID.randomUUID(), comp1, dev1,
|
||||||
t(11), t(20)));
|
t(11), t(20)));
|
||||||
|
race.waitForLoadingToFinish();
|
||||||
addFixes2(race, comp1, dev1);
|
addFixes2(race, comp1, dev1);
|
||||||
|
|
||||||
// stop tracking, then no more fixes arrive at race
|
// stop tracking, then no more fixes arrive at race
|
||||||
service.getRaceTrackerById(raceLog.getId()).stop(/* preemptive */ false);
|
service.getRaceTrackerById(raceLog.getId()).stop(/* preemptive */ false);
|
||||||
|
raceLogFixTrackerManager.stop(false);
|
||||||
addFixes3(race, comp1, dev1);
|
addFixes3(race, comp1, dev1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+23
-13
@@ -6,7 +6,9 @@ import static org.mockito.Mockito.mock;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.Timeout;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
|
||||||
@@ -26,10 +28,12 @@ import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
|||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.impl.fixtracker.FixLoaderAndTracker;
|
||||||
import com.sap.sailing.domain.racelogtracking.test.AbstractGPSFixStoreTest;
|
import com.sap.sailing.domain.racelogtracking.test.AbstractGPSFixStoreTest;
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
@@ -40,6 +44,9 @@ import com.sap.sse.common.impl.TimeRangeImpl;
|
|||||||
public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
||||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public Timeout TrackedRaceLoadsFixesTestTimeout = new Timeout(3 * 60 * 1000);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doesRaceLoadOnlyBetweenStartAndEndOfTracking() throws TransformationException,
|
public void doesRaceLoadOnlyBetweenStartAndEndOfTracking() throws TransformationException,
|
||||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||||
@@ -62,18 +69,20 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
|||||||
store.storeFix(markDevice, createFix(1100, 10, 20, 30, 40));
|
store.storeFix(markDevice, createFix(1100, 10, 20, 30, 40));
|
||||||
store.storeFix(markDevice, createFix(2100, 10, 20, 30, 40));
|
store.storeFix(markDevice, createFix(2100, 10, 20, 30, 40));
|
||||||
|
|
||||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||||
null, /* endDate */null, null, null, "a", null));
|
null, /* endDate */null, null, null, "a", null));
|
||||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
|
/* useMarkPassingCalculator */ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
trackedRace.setStartOfTrackingReceived(new MillisecondsTimePoint(1000));
|
trackedRace.setStartOfTrackingReceived(new MillisecondsTimePoint(1000));
|
||||||
trackedRace.setEndOfTrackingReceived(new MillisecondsTimePoint(2000));
|
trackedRace.setEndOfTrackingReceived(new MillisecondsTimePoint(2000));
|
||||||
|
new FixLoaderAndTracker(trackedRace, store, null);
|
||||||
|
|
||||||
trackedRace.attachRaceLog(raceLog);
|
trackedRace.attachRaceLog(raceLog);
|
||||||
trackedRace.attachRegattaLog(regattaLog);
|
trackedRace.attachRegattaLog(regattaLog);
|
||||||
trackedRace.waitForLoadingFromGPSFixStoreToFinishRunning(regattaLog);
|
trackedRace.waitForLoadingToFinish();
|
||||||
|
|
||||||
testNumberOfRawFixes(trackedRace.getTrack(comp), 1);
|
testNumberOfRawFixes(trackedRace.getTrack(comp), 1);
|
||||||
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
|
testNumberOfRawFixes(trackedRace.getOrCreateTrack(mark), 1);
|
||||||
@@ -98,8 +107,7 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
|||||||
DeviceIdentifier device3 = new SmartphoneImeiIdentifier("imei3");
|
DeviceIdentifier device3 = new SmartphoneImeiIdentifier("imei3");
|
||||||
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
||||||
new WaypointImpl(mark2) }));
|
new WaypointImpl(mark2) }));
|
||||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp,
|
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp, comp2));
|
||||||
comp2 }));
|
|
||||||
|
|
||||||
map(comp, device, 0, 20000);
|
map(comp, device, 0, 20000);
|
||||||
map(comp2, device2, 0, 600);
|
map(comp2, device2, 0, 600);
|
||||||
@@ -117,16 +125,18 @@ public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
|||||||
store.storeFix(device, createFix(i + 1000, 10, 20, 30, 40));
|
store.storeFix(device, createFix(i + 1000, 10, 20, 30, 40));
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||||
null, /* endDate */null, null, null, "a", null));
|
/* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
/*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
|
|
||||||
|
new FixLoaderAndTracker(trackedRace, store, null);
|
||||||
|
|
||||||
trackedRace.attachRaceLog(raceLog);
|
trackedRace.attachRaceLog(raceLog);
|
||||||
trackedRace.attachRegattaLog(regattaLog);
|
trackedRace.attachRegattaLog(regattaLog);
|
||||||
trackedRace.waitForLoadingFromGPSFixStoreToFinishRunning(regattaLog);
|
trackedRace.waitForLoadingToFinish();
|
||||||
|
|
||||||
testNumberOfRawFixes(trackedRace.getTrack(comp), 10002);
|
testNumberOfRawFixes(trackedRace.getTrack(comp), 10002);
|
||||||
testNumberOfRawFixes(trackedRace.getTrack(comp2), 1);
|
testNumberOfRawFixes(trackedRace.getTrack(comp2), 1);
|
||||||
|
|||||||
+14
-10
@@ -72,7 +72,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
|||||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||||
null, /* endDate */null, null, null, "a", null));
|
null, /* endDate */null, null, null, "a", null));
|
||||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
|
/* useMarkPassingCalculator */ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
|
|
||||||
setStartAndEndOfRaceInRaceLog(10000, 20000);
|
setStartAndEndOfRaceInRaceLog(10000, 20000);
|
||||||
@@ -80,7 +81,6 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
|||||||
trackedRace.attachRegattaLog(regattaLog);
|
trackedRace.attachRegattaLog(regattaLog);
|
||||||
|
|
||||||
// test inference via race start/end time in racelog
|
// test inference via race start/end time in racelog
|
||||||
trackedRace.waitForLoadingFromGPSFixStoreToFinishRunning(regattaLog);
|
|
||||||
MillisecondsTimePoint startOfRaceInRaceLog = new MillisecondsTimePoint(10000);
|
MillisecondsTimePoint startOfRaceInRaceLog = new MillisecondsTimePoint(10000);
|
||||||
TimePoint expectedStartOfTracking = startOfRaceInRaceLog.minus(Duration.ONE_MINUTE.times(TrackedRaceImpl.TRACKING_BUFFER_IN_MINUTES));
|
TimePoint expectedStartOfTracking = startOfRaceInRaceLog.minus(Duration.ONE_MINUTE.times(TrackedRaceImpl.TRACKING_BUFFER_IN_MINUTES));
|
||||||
MillisecondsTimePoint endOfRaceInRaceLog = new MillisecondsTimePoint(20000);
|
MillisecondsTimePoint endOfRaceInRaceLog = new MillisecondsTimePoint(20000);
|
||||||
@@ -134,7 +134,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
|||||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||||
null, /* endDate */null, null, null, "a", null));
|
null, /* endDate */null, null, null, "a", null));
|
||||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
|
/* useMarkPassingCalculator */ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
trackedRace.attachRaceLog(raceLog);
|
trackedRace.attachRaceLog(raceLog);
|
||||||
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
|
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
|
||||||
@@ -171,7 +172,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
|||||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||||
null, /* endDate */null, null, null, "a", null));
|
null, /* endDate */null, null, null, "a", null));
|
||||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
|
/* useMarkPassingCalculator */ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
|
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
|
||||||
trackedRace.addListener(new AbstractRaceChangeListener() {
|
trackedRace.addListener(new AbstractRaceChangeListener() {
|
||||||
@@ -212,19 +214,20 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
|||||||
null, /* endDate */null, null, null, "a", null));
|
null, /* endDate */null, null, null, "a", null));
|
||||||
assertTrue(regatta.getRegatta().useStartTimeInference());
|
assertTrue(regatta.getRegatta().useStartTimeInference());
|
||||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
|
/* useMarkPassingCalculator */ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
trackedRace.attachRaceLog(raceLog);
|
trackedRace.attachRaceLog(raceLog);
|
||||||
trackedRace.attachRegattaLog(regattaLog);
|
trackedRace.attachRegattaLog(regattaLog);
|
||||||
final TimePoint[] newStartAndEndOfTrackingNotifiedByRace = new TimePoint[2];
|
final TimePoint[] newStartAndEndOfTrackingNotifiedByRace = new TimePoint[2];
|
||||||
trackedRace.addListener(new AbstractRaceChangeListener() {
|
trackedRace.addListener(new AbstractRaceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void startOfTrackingChanged(TimePoint startOfTracking) {
|
public void startOfTrackingChanged(TimePoint oldStartOfRace, TimePoint newStartOfRace) {
|
||||||
newStartAndEndOfTrackingNotifiedByRace[0] = startOfTracking;
|
newStartAndEndOfTrackingNotifiedByRace[0] = newStartOfRace;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void endOfTrackingChanged(TimePoint endOfTracking) {
|
public void endOfTrackingChanged(TimePoint oldEndOfTracking, TimePoint newEndOfTracking) {
|
||||||
newStartAndEndOfTrackingNotifiedByRace[1] = endOfTracking;
|
newStartAndEndOfTrackingNotifiedByRace[1] = newEndOfTracking;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assertNull(trackedRace.getStartOfTracking());
|
assertNull(trackedRace.getStartOfTracking());
|
||||||
@@ -314,7 +317,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
|||||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||||
null, /* endDate */null, null, null, "a", null));
|
null, /* endDate */null, null, null, "a", null));
|
||||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, store, 0, 0, 0, /*useMarkPassingCalculator*/ false,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||||
|
/* useMarkPassingCalculator */ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
trackedRace.attachRaceLog(raceLog);
|
trackedRace.attachRaceLog(raceLog);
|
||||||
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
|
final TimePoint[] oldAndNewStartTimeNotifiedByRace = new TimePoint[2];
|
||||||
|
|||||||
+8
-8
@@ -10,19 +10,19 @@ import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
|||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMongoHandlerImpl;
|
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMongoHandlerImpl;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMovingMongoHandlerImpl;
|
import com.sap.sailing.domain.persistence.racelog.tracking.impl.GPSFixMovingMongoHandlerImpl;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinder;
|
import com.sap.sse.common.TypeBasedServiceFinder;
|
||||||
|
|
||||||
public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder<GPSFixMongoHandler> {
|
public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder<FixMongoHandler<?>> {
|
||||||
private final MongoObjectFactoryImpl mof = new MongoObjectFactoryImpl(null);
|
private final MongoObjectFactoryImpl mof = new MongoObjectFactoryImpl(null);
|
||||||
private final DomainObjectFactoryImpl dof = new DomainObjectFactoryImpl(null, null);
|
private final DomainObjectFactoryImpl dof = new DomainObjectFactoryImpl(null, null);
|
||||||
private final GPSFixMongoHandler movingHandler = new GPSFixMovingMongoHandlerImpl(mof, dof);
|
private final FixMongoHandler<?> movingHandler = new GPSFixMovingMongoHandlerImpl(mof, dof);
|
||||||
private final GPSFixMongoHandler handler = new GPSFixMongoHandlerImpl(mof, dof);
|
private final FixMongoHandler<?> handler = new GPSFixMongoHandlerImpl(mof, dof);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GPSFixMongoHandler findService(String fixType) {
|
public FixMongoHandler<?> findService(String fixType) {
|
||||||
if (fixType.equals(GPSFixMovingImpl.class.getName()) ||
|
if (fixType.equals(GPSFixMovingImpl.class.getName()) ||
|
||||||
fixType.equals(CompactGPSFixMovingImpl.class.getName())) return movingHandler;
|
fixType.equals(CompactGPSFixMovingImpl.class.getName())) return movingHandler;
|
||||||
if (fixType.equals(GPSFixImpl.class.getName()) ||
|
if (fixType.equals(GPSFixImpl.class.getName()) ||
|
||||||
@@ -31,11 +31,11 @@ public class MockGPSFixMongoServiceFinder implements TypeBasedServiceFinder<GPSF
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setFallbackService(GPSFixMongoHandler fallback) {
|
public void setFallbackService(FixMongoHandler<?> fallback) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<GPSFixMongoHandler> findAllServices() {
|
public Set<FixMongoHandler<?>> findAllServices() {
|
||||||
return new HashSet<GPSFixMongoHandler>(Arrays.asList(movingHandler, handler));
|
return new HashSet<FixMongoHandler<?>>(Arrays.asList(movingHandler, handler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -4,7 +4,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
|
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
|
||||||
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
|
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinder;
|
import com.sap.sse.common.TypeBasedServiceFinder;
|
||||||
@@ -24,7 +24,7 @@ public class MockSmartphoneImeiServiceFinderFactory implements TypeBasedServiceF
|
|||||||
public MockSmartphoneImeiServiceFinderFactory() {
|
public MockSmartphoneImeiServiceFinderFactory() {
|
||||||
serviceFinders.put(DeviceIdentifierMongoHandler.class, new MockServiceFinder<>(new SmartphoneImeiMongoHandler()));
|
serviceFinders.put(DeviceIdentifierMongoHandler.class, new MockServiceFinder<>(new SmartphoneImeiMongoHandler()));
|
||||||
serviceFinders.put(DeviceIdentifierJsonHandler.class, new MockServiceFinder<>(new SmartphoneImeiJsonHandler()));
|
serviceFinders.put(DeviceIdentifierJsonHandler.class, new MockServiceFinder<>(new SmartphoneImeiJsonHandler()));
|
||||||
serviceFinders.put(GPSFixMongoHandler.class, new MockGPSFixMongoServiceFinder());
|
serviceFinders.put(FixMongoHandler.class, new MockGPSFixMongoServiceFinder());
|
||||||
serviceFinders.put(GPSFixJsonHandler.class, new MockServiceFinder<>(new MockGPSFixJsonHandler()));
|
serviceFinders.put(GPSFixJsonHandler.class, new MockServiceFinder<>(new MockGPSFixJsonHandler()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.GPSFixMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||||
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDMongoHandler;
|
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDMongoHandler;
|
||||||
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
|
import com.sap.sailing.server.gateway.serialization.racelog.tracking.DeviceIdentifierJsonHandler;
|
||||||
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
|
import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonHandler;
|
||||||
@@ -26,7 +26,7 @@ public class MockSmartphoneUuidServiceFinderFactory implements TypeBasedServiceF
|
|||||||
public MockSmartphoneUuidServiceFinderFactory() {
|
public MockSmartphoneUuidServiceFinderFactory() {
|
||||||
serviceFinders.put(DeviceIdentifierMongoHandler.class, new MockServiceFinder<>(new SmartphoneUUIDMongoHandler()));
|
serviceFinders.put(DeviceIdentifierMongoHandler.class, new MockServiceFinder<>(new SmartphoneUUIDMongoHandler()));
|
||||||
serviceFinders.put(DeviceIdentifierJsonHandler.class, new MockServiceFinder<>(new SmartphoneUUIDJsonHandler()));
|
serviceFinders.put(DeviceIdentifierJsonHandler.class, new MockServiceFinder<>(new SmartphoneUUIDJsonHandler()));
|
||||||
serviceFinders.put(GPSFixMongoHandler.class, new MockGPSFixMongoServiceFinder());
|
serviceFinders.put(FixMongoHandler.class, new MockGPSFixMongoServiceFinder());
|
||||||
serviceFinders.put(GPSFixJsonHandler.class, new MockServiceFinder<>(new MockGPSFixJsonHandler()));
|
serviceFinders.put(GPSFixJsonHandler.class, new MockServiceFinder<>(new MockGPSFixJsonHandler()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ Require-Bundle: com.sap.sailing.domain,
|
|||||||
com.sap.sse.mail
|
com.sap.sse.mail
|
||||||
Import-Package: com.google.zxing;version="3.1.0",
|
Import-Package: com.google.zxing;version="3.1.0",
|
||||||
com.mongodb,
|
com.mongodb,
|
||||||
|
com.sap.sse.concurrent,
|
||||||
com.sap.sse.shared.media,
|
com.sap.sse.shared.media,
|
||||||
javax.mail;version="1.4.0",
|
javax.mail;version="1.4.0",
|
||||||
javax.mail.internet;version="1.4.0",
|
javax.mail.internet;version="1.4.0",
|
||||||
@@ -28,7 +29,8 @@ Import-Package: com.google.zxing;version="3.1.0",
|
|||||||
javax.servlet;version="2.6.0",
|
javax.servlet;version="2.6.0",
|
||||||
org.json.simple,
|
org.json.simple,
|
||||||
org.json.simple.parser,
|
org.json.simple.parser,
|
||||||
org.osgi.framework;version="1.6.0"
|
org.osgi.framework;version="1.6.0",
|
||||||
|
org.osgi.util.tracker;version="1.5.1"
|
||||||
Export-Package: com.sap.sailing.domain.racelogtracking,
|
Export-Package: com.sap.sailing.domain.racelogtracking,
|
||||||
com.sap.sailing.domain.racelogtracking.impl;x-friends:="com.sap.sailing.domain.racelogtrackingadapter.testsupport,com.sap.sailing.gwt.ui.test"
|
com.sap.sailing.domain.racelogtracking.impl;x-friends:="com.sap.sailing.domain.racelogtrackingadapter.testsupport,com.sap.sailing.gwt.ui.test"
|
||||||
Bundle-Activator: com.sap.sailing.domain.racelogtracking.impl.Activator
|
Bundle-Activator: com.sap.sailing.domain.racelogtracking.impl.Activator
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package com.sap.sailing.domain.racelogsensortracking;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixMapper;
|
||||||
|
import com.sap.sailing.domain.tracking.Track;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
|
||||||
|
public interface SensorFixMapperFactory {
|
||||||
|
|
||||||
|
<FixT extends Timed, TrackT extends Track<?>> SensorFixMapper<FixT, TrackT, Competitor>
|
||||||
|
createCompetitorMapper(Class<? extends RegattaLogDeviceMappingEvent<?>> eventType);
|
||||||
|
|
||||||
|
// <FixT extends Timed, TrackT extends Track<?>> SensorFixMapper<FixT, TrackT, Mark>
|
||||||
|
// createMarkMapper(RegattaLogDeviceMarkMappingEvent event);
|
||||||
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package com.sap.sailing.domain.racelogsensortracking.impl;
|
||||||
|
|
||||||
|
import org.osgi.framework.ServiceReference;
|
||||||
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixMapper;
|
||||||
|
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||||
|
import com.sap.sailing.domain.tracking.Track;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
|
||||||
|
public class SensorFixMapperFactoryImpl implements SensorFixMapperFactory {
|
||||||
|
|
||||||
|
private final ServiceTracker<SensorFixMapper<?, ?, ?>, SensorFixMapper<?, ?, ?>> tracker;
|
||||||
|
|
||||||
|
public SensorFixMapperFactoryImpl(ServiceTracker<SensorFixMapper<?, ?, ?>, SensorFixMapper<?, ?, ?>> tracker) {
|
||||||
|
this.tracker = tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <FixT extends Timed, TrackT extends Track<?>> SensorFixMapper<FixT, TrackT, Competitor>
|
||||||
|
createCompetitorMapper(Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
|
||||||
|
for (ServiceReference<SensorFixMapper<?, ?, ?>> serviceReference : tracker.getServiceReferences()) {
|
||||||
|
SensorFixMapper<?, ?, ?> service = tracker.getService(serviceReference);
|
||||||
|
if (service != null && service.isResponsibleFor(eventType)) {
|
||||||
|
return (SensorFixMapper<FixT, TrackT, Competitor>) service;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException("No SensorFixMapper found for event type: " + eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
-1
@@ -21,7 +21,6 @@ import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
|||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.impl.RaceLogRaceTracker;
|
import com.sap.sailing.domain.racelogtracking.impl.RaceLogRaceTracker;
|
||||||
import com.sap.sailing.domain.tracking.RaceHandle;
|
import com.sap.sailing.domain.tracking.RaceHandle;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
|
|||||||
+29
-2
@@ -10,15 +10,21 @@ import java.util.logging.Logger;
|
|||||||
import org.osgi.framework.BundleActivator;
|
import org.osgi.framework.BundleActivator;
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
import org.osgi.framework.ServiceRegistration;
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
import com.sap.sailing.domain.persistence.racelog.tracking.DeviceIdentifierMongoHandler;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixMapper;
|
||||||
|
import com.sap.sailing.domain.racelogsensortracking.impl.SensorFixMapperFactoryImpl;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifierStringSerializationHandler;
|
||||||
import com.sap.sailing.domain.racelogtracking.PingDeviceIdentifierImpl;
|
import com.sap.sailing.domain.racelogtracking.PingDeviceIdentifierImpl;
|
||||||
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapterFactory;
|
||||||
import com.sap.sailing.domain.racelogtracking.SmartphoneUUIDIdentifier;
|
import com.sap.sailing.domain.racelogtracking.SmartphoneUUIDIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.impl.fixtracker.RegattaLogFixTrackerRegattaListener;
|
||||||
import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier;
|
import com.sap.sailing.domain.trackfiles.TrackFileImportDeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRegattaListener;
|
||||||
import com.sap.sailing.server.MasterDataImportClassLoaderService;
|
import com.sap.sailing.server.MasterDataImportClassLoaderService;
|
||||||
|
import com.sap.sailing.server.RacingEventService;
|
||||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixJsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixJsonDeserializer;
|
||||||
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixMovingJsonDeserializer;
|
import com.sap.sailing.server.gateway.deserialization.impl.GPSFixMovingJsonDeserializer;
|
||||||
@@ -30,12 +36,16 @@ import com.sap.sailing.server.gateway.serialization.racelog.tracking.GPSFixJsonH
|
|||||||
import com.sap.sailing.server.gateway.serialization.racelog.tracking.impl.GPSFixJsonHandlerImpl;
|
import com.sap.sailing.server.gateway.serialization.racelog.tracking.impl.GPSFixJsonHandlerImpl;
|
||||||
import com.sap.sailing.server.gateway.serialization.racelog.tracking.impl.SmartphoneUUIDJsonHandler;
|
import com.sap.sailing.server.gateway.serialization.racelog.tracking.impl.SmartphoneUUIDJsonHandler;
|
||||||
import com.sap.sse.common.TypeBasedServiceFinder;
|
import com.sap.sse.common.TypeBasedServiceFinder;
|
||||||
|
import com.sap.sse.replication.Replicable;
|
||||||
|
import com.sap.sse.util.ServiceTrackerFactory;
|
||||||
|
|
||||||
public class Activator implements BundleActivator {
|
public class Activator implements BundleActivator {
|
||||||
private static final Logger logger = Logger.getLogger(Activator.class.getName());
|
private static final Logger logger = Logger.getLogger(Activator.class.getName());
|
||||||
|
|
||||||
private static BundleContext context;
|
private static BundleContext context;
|
||||||
|
private ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
|
||||||
|
private ServiceTracker<SensorFixMapper<?, ?, ?>, SensorFixMapper<?, ?, ?>> sensorFixMapperTracker;
|
||||||
|
|
||||||
public static BundleContext getContext() {
|
public static BundleContext getContext() {
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
@@ -76,14 +86,31 @@ public class Activator implements BundleActivator {
|
|||||||
|
|
||||||
registrations.add(context.registerService(MasterDataImportClassLoaderService.class,
|
registrations.add(context.registerService(MasterDataImportClassLoaderService.class,
|
||||||
new MasterDataImportClassLoaderServiceImpl(), null));
|
new MasterDataImportClassLoaderServiceImpl(), null));
|
||||||
|
registrations.add(context.registerService(SensorFixMapper.class, new BravoDataFixMapper(), null));
|
||||||
|
|
||||||
|
sensorFixMapperTracker = createSensorFixMapperServiceTracker(context);
|
||||||
|
racingEventServiceTracker = ServiceTrackerFactory.createAndOpen(context, RacingEventService.class);
|
||||||
|
|
||||||
|
RegattaLogFixTrackerRegattaListener regattaLogSensorDataTrackerTrackedRegattaListener = new RegattaLogFixTrackerRegattaListener(
|
||||||
|
racingEventServiceTracker, new SensorFixMapperFactoryImpl(sensorFixMapperTracker));
|
||||||
|
registrations.add(context.registerService(TrackedRegattaListener.class,
|
||||||
|
regattaLogSensorDataTrackerTrackedRegattaListener, null));
|
||||||
|
registrations.add(context.registerService(Replicable.class,
|
||||||
|
regattaLogSensorDataTrackerTrackedRegattaListener, null));
|
||||||
|
|
||||||
logger.log(Level.INFO, "Started "+context.getBundle().getSymbolicName());
|
logger.log(Level.INFO, "Started "+context.getBundle().getSymbolicName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
private ServiceTracker<SensorFixMapper<?, ?, ?>, SensorFixMapper<?, ?, ?>> createSensorFixMapperServiceTracker(BundleContext context) {
|
||||||
|
return (ServiceTracker) ServiceTrackerFactory.createAndOpen(context, SensorFixMapper.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(BundleContext context) throws Exception {
|
public void stop(BundleContext context) throws Exception {
|
||||||
Activator.context = null;
|
Activator.context = null;
|
||||||
|
racingEventServiceTracker.close();
|
||||||
|
sensorFixMapperTracker.close();
|
||||||
for (ServiceRegistration<?> reg : registrations) {
|
for (ServiceRegistration<?> reg : registrations) {
|
||||||
reg.unregister();
|
reg.unregister();
|
||||||
}
|
}
|
||||||
|
|||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.impl.BravoFixImpl;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixMapper;
|
||||||
|
import com.sap.sailing.domain.tracking.BravoFixTrack;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicSensorFixTrack;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.impl.BravoFixTrackImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SensorFixMapper} to handle {@link BravoFix}es.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BravoDataFixMapper implements SensorFixMapper<DoubleVectorFix, DynamicSensorFixTrack<Competitor, BravoFix>, Competitor> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DynamicSensorFixTrack<Competitor, BravoFix> getTrack(DynamicTrackedRace race, Competitor key) {
|
||||||
|
return race.getOrCreateSensorTrack(key, BravoFixTrack.TRACK_NAME,
|
||||||
|
() -> new BravoFixTrackImpl<Competitor>(key, BravoFixTrack.TRACK_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFix(DynamicSensorFixTrack<Competitor, BravoFix> track, DoubleVectorFix fix) {
|
||||||
|
track.add(new BravoFixImpl(fix));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isResponsibleFor(Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
|
||||||
|
return RegattaLogDeviceCompetitorBravoMappingEventImpl.class.isAssignableFrom(eventType);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-5
@@ -19,7 +19,6 @@ import com.sap.sailing.domain.base.impl.RegattaImpl;
|
|||||||
import com.sap.sailing.domain.common.racelog.tracking.DoesNotHaveRegattaLogException;
|
import com.sap.sailing.domain.common.racelog.tracking.DoesNotHaveRegattaLogException;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
|
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||||
@@ -54,13 +53,13 @@ public class RaceLogConnectivityParams implements RaceTrackingConnectivityParame
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
||||||
GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) {
|
RaceLogResolver raceLogResolver) {
|
||||||
return createRaceTracker(regatta, trackedRegattaRegistry, windStore, gpsFixStore, raceLogResolver);
|
return createRaceTracker(regatta, trackedRegattaRegistry, windStore, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) {
|
WindStore windStore, RaceLogResolver raceLogResolver) {
|
||||||
if (regatta == null) {
|
if (regatta == null) {
|
||||||
BoatClass boatClass = new RaceInformationFinder(getRaceLog()).analyze().getBoatClass();
|
BoatClass boatClass = new RaceInformationFinder(getRaceLog()).analyze().getBoatClass();
|
||||||
regatta = service.getOrCreateDefaultRegatta(
|
regatta = service.getOrCreateDefaultRegatta(
|
||||||
@@ -71,7 +70,7 @@ public class RaceLogConnectivityParams implements RaceTrackingConnectivityParame
|
|||||||
throw new RaceNotCreatedException("No regatta for race-log tracked race");
|
throw new RaceNotCreatedException("No regatta for race-log tracked race");
|
||||||
}
|
}
|
||||||
DynamicTrackedRegatta trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(regatta);
|
DynamicTrackedRegatta trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(regatta);
|
||||||
return new RaceLogRaceTracker(trackedRegatta, this, windStore, gpsFixStore, raceLogResolver);
|
return new RaceLogRaceTracker(trackedRegatta, this, windStore, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+14
-280
@@ -8,8 +8,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -36,18 +34,13 @@ import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTr
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.impl.BaseRegattaLogEventVisitor;
|
import com.sap.sailing.domain.abstractlog.regatta.impl.BaseRegattaLogEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceCompetitorMappingFinder;
|
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMarkMappingFinder;
|
|
||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.ControlPoint;
|
import com.sap.sailing.domain.base.ControlPoint;
|
||||||
import com.sap.sailing.domain.base.Course;
|
import com.sap.sailing.domain.base.Course;
|
||||||
import com.sap.sailing.domain.base.CourseBase;
|
import com.sap.sailing.domain.base.CourseBase;
|
||||||
import com.sap.sailing.domain.base.Fleet;
|
import com.sap.sailing.domain.base.Fleet;
|
||||||
import com.sap.sailing.domain.base.Mark;
|
|
||||||
import com.sap.sailing.domain.base.RaceColumn;
|
import com.sap.sailing.domain.base.RaceColumn;
|
||||||
import com.sap.sailing.domain.base.RaceDefinition;
|
import com.sap.sailing.domain.base.RaceDefinition;
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
@@ -58,35 +51,21 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
|
|||||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||||
import com.sap.sailing.domain.common.PassingInstruction;
|
import com.sap.sailing.domain.common.PassingInstruction;
|
||||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
|
||||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||||
import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLog;
|
import com.sap.sailing.domain.common.abstractlog.TimePointSpecificationFoundInLog;
|
||||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.DoesNotHaveRegattaLogException;
|
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
|
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixReceivedListener;
|
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
|
||||||
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
import com.sap.sailing.domain.regattalike.IsRegattaLike;
|
||||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
import com.sap.sailing.domain.tracking.AbstractRaceTrackerBaseImpl;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.RaceHandle;
|
import com.sap.sailing.domain.tracking.RaceHandle;
|
||||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.WindStore;
|
import com.sap.sailing.domain.tracking.WindStore;
|
||||||
import com.sap.sailing.domain.tracking.WindTrack;
|
import com.sap.sailing.domain.tracking.WindTrack;
|
||||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
|
||||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
|
||||||
import com.sap.sse.common.TimePoint;
|
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
import com.sap.sse.common.Util.Pair;
|
import com.sap.sse.common.Util.Pair;
|
||||||
import com.sap.sse.common.WithID;
|
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
import difflib.PatchFailedException;
|
import difflib.PatchFailedException;
|
||||||
@@ -100,33 +79,26 @@ import difflib.PatchFailedException;
|
|||||||
* Otherwise, the tracker waits until a {@link RaceLogStartTrackingEvent} is received to perform these tasks.
|
* Otherwise, the tracker waits until a {@link RaceLogStartTrackingEvent} is received to perform these tasks.
|
||||||
*
|
*
|
||||||
* @author Fredrik Teschke
|
* @author Fredrik Teschke
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
|
||||||
|
|
||||||
|
private static final String LOGGER_AND_LOGAUTHOR_NAME = RaceLogRaceTracker.class.getName();
|
||||||
|
private static final Logger logger = Logger.getLogger(LOGGER_AND_LOGAUTHOR_NAME);
|
||||||
|
|
||||||
|
private final AbstractLogEventAuthor raceLogEventAuthor = new LogEventAuthorImpl(LOGGER_AND_LOGAUTHOR_NAME, 0);
|
||||||
|
private final Map<AbstractLog<?, ?>, Object> visitors = new HashMap<AbstractLog<?, ?>, Object>();
|
||||||
|
|
||||||
private final RaceLogConnectivityParams params;
|
private final RaceLogConnectivityParams params;
|
||||||
private final WindStore windStore;
|
private final WindStore windStore;
|
||||||
private final GPSFixStore gpsFixStore;
|
|
||||||
private final DynamicTrackedRegatta regatta;
|
private final DynamicTrackedRegatta regatta;
|
||||||
private final RaceLogResolver raceLogResolver;
|
private final RaceLogResolver raceLogResolver;
|
||||||
private final Map<AbstractLog<?, ?>, Object> visitors = new HashMap<AbstractLog<?, ?>, Object>();
|
|
||||||
|
|
||||||
private final ConcurrentMap<Competitor, List<DeviceMapping<Competitor>>> competitorMappings = new ConcurrentHashMap<>();
|
|
||||||
private final ConcurrentMap<Mark, List<DeviceMapping<Mark>>> markMappings = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private final Map<DeviceIdentifier, List<DeviceMapping<Mark>>> markMappingsByDevices = new HashMap<>();
|
|
||||||
private final Map<DeviceIdentifier, List<DeviceMapping<Competitor>>> competitorMappingsByDevices = new HashMap<>();
|
|
||||||
|
|
||||||
private DynamicTrackedRace trackedRace;
|
private DynamicTrackedRace trackedRace;
|
||||||
private final AbstractLogEventAuthor raceLogEventAuthor = new LogEventAuthorImpl(
|
|
||||||
RaceLogRaceTracker.class.getName(), 0);
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(RaceLogRaceTracker.class.getName());
|
|
||||||
|
|
||||||
public RaceLogRaceTracker(DynamicTrackedRegatta regatta, RaceLogConnectivityParams params, WindStore windStore,
|
public RaceLogRaceTracker(DynamicTrackedRegatta regatta, RaceLogConnectivityParams params, WindStore windStore,
|
||||||
GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) {
|
RaceLogResolver raceLogResolver) {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
this.windStore = windStore;
|
this.windStore = windStore;
|
||||||
this.gpsFixStore = gpsFixStore;
|
|
||||||
this.regatta = regatta;
|
this.regatta = regatta;
|
||||||
this.raceLogResolver = raceLogResolver;
|
this.raceLogResolver = raceLogResolver;
|
||||||
|
|
||||||
@@ -168,20 +140,11 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
((RaceLog) log).addListener(visitor);
|
((RaceLog) log).addListener(visitor);
|
||||||
} else if (log instanceof RegattaLog) {
|
} else if (log instanceof RegattaLog) {
|
||||||
RegattaLogEventVisitor visitor = new BaseRegattaLogEventVisitor() {
|
RegattaLogEventVisitor visitor = new BaseRegattaLogEventVisitor() {
|
||||||
@Override
|
|
||||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
|
||||||
RaceLogRaceTracker.this.onDeviceCompetitorMappingEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
|
||||||
RaceLogRaceTracker.this.onDeviceMarkMappingEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RegattaLogDefineMarkEvent event) {
|
public void visit(RegattaLogDefineMarkEvent event) {
|
||||||
RaceLogRaceTracker.this.onDefineMarkEvent(event);
|
RaceLogRaceTracker.this.onDefineMarkEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
visitors.put(log, visitor);
|
visitors.put(log, visitor);
|
||||||
((RegattaLog) log).addListener(visitor);
|
((RegattaLog) log).addListener(visitor);
|
||||||
@@ -198,7 +161,7 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(boolean preemptive) {
|
protected void onStop(boolean preemptive) {
|
||||||
RaceLog raceLog = params.getRaceLog();
|
RaceLog raceLog = params.getRaceLog();
|
||||||
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = new TrackingTimesFinder(raceLog).analyze();
|
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = new TrackingTimesFinder(raceLog).analyze();
|
||||||
if (trackingTimes == null || trackingTimes.getB() == null || trackingTimes.getB().getTimePoint() == null) {
|
if (trackingTimes == null || trackingTimes.getB() == null || trackingTimes.getB().getTimePoint() == null) {
|
||||||
@@ -207,18 +170,11 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
raceLog.add(new RaceLogEndOfTrackingEventImpl(MillisecondsTimePoint.now(), raceLogEventAuthor, /* passId */ 0));
|
raceLog.add(new RaceLogEndOfTrackingEventImpl(MillisecondsTimePoint.now(), raceLogEventAuthor, /* passId */ 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark passing calculator is automatically stopped, when the race status is set to {@link
|
|
||||||
// TrackedRaceStatusEnum#FINISHED}
|
|
||||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, 100));
|
|
||||||
|
|
||||||
// remove listeners on logs
|
// remove listeners on logs
|
||||||
for (Entry<AbstractLog<?, ?>, Object> visitor : visitors.entrySet()) {
|
for (Entry<AbstractLog<?, ?>, Object> visitor : visitors.entrySet()) {
|
||||||
visitor.getKey().removeListener(visitor.getValue());
|
visitor.getKey().removeListener(visitor.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove listener for fixes
|
|
||||||
gpsFixStore.removeListener(this);
|
|
||||||
|
|
||||||
logger.info(String.format("Stopped tracking race-log race %s %s %s", params.getLeaderboard(),
|
logger.info(String.format("Stopped tracking race-log race %s %s %s", params.getLeaderboard(),
|
||||||
params.getRaceColumn(), params.getFleet()));
|
params.getRaceColumn(), params.getFleet()));
|
||||||
}
|
}
|
||||||
@@ -253,107 +209,10 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
return windStore;
|
return windStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public GPSFixStore getGPSFixStore() {
|
|
||||||
return gpsFixStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getID() {
|
public Object getID() {
|
||||||
return params.getRaceLog().getId();
|
return params.getRaceLog().getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Competitor, List<DeviceMapping<Competitor>>> getNewCompetitorMappings() throws DoesNotHaveRegattaLogException {
|
|
||||||
return new RegattaLogDeviceCompetitorMappingFinder(params.getRegattaLog()).analyze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<Mark, List<DeviceMapping<Mark>>> getNewMarkMappings() throws DoesNotHaveRegattaLogException {
|
|
||||||
return new RegattaLogDeviceMarkMappingFinder(params.getRegattaLog()).analyze();
|
|
||||||
}
|
|
||||||
|
|
||||||
private <ItemT extends WithID, FixT extends GPSFix> boolean hasMappingAlreadyBeenLoaded(
|
|
||||||
DeviceMapping<ItemT> newMapping, List<DeviceMapping<ItemT>> oldMappings) {
|
|
||||||
if (oldMappings == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (DeviceMapping<ItemT> oldMapping : oldMappings) {
|
|
||||||
if (newMapping.getDevice() == oldMapping.getDevice()
|
|
||||||
&& newMapping.getTimeRange().liesWithin(oldMapping.getTimeRange())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private <ItemT extends WithID, FixT extends GPSFix> Map<DeviceIdentifier, List<DeviceMapping<ItemT>>> transformToMappingsByDevice(
|
|
||||||
Map<ItemT, List<DeviceMapping<ItemT>>> mappings) {
|
|
||||||
|
|
||||||
Map<DeviceIdentifier, List<DeviceMapping<ItemT>>> result = new HashMap<>();
|
|
||||||
for (ItemT item : mappings.keySet()) {
|
|
||||||
for (DeviceMapping<ItemT> mapping : mappings.get(item)) {
|
|
||||||
List<DeviceMapping<ItemT>> list = result.get(mapping.getDevice());
|
|
||||||
if (list == null) {
|
|
||||||
list = new ArrayList<>();
|
|
||||||
result.put(mapping.getDevice(), list);
|
|
||||||
}
|
|
||||||
list.add(mapping);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjusts the contents of {@link #markMappings} according to the device mappings for marks found in the regatta
|
|
||||||
* log. Afterwards, the start end end of tracking is {@link #updateStartAndEndOfTracking(boolean) updated}.
|
|
||||||
*
|
|
||||||
* @param loadIfNotCovered
|
|
||||||
* If <code>true</code>, for additional time ranges added compared to the previous contents of
|
|
||||||
* {@link #markMappings}, their fixes are loaded from the {@link #gpsFixStore}.
|
|
||||||
* @throws DoesNotHaveRegattaLogException
|
|
||||||
*/
|
|
||||||
private void updateMarkMappings(boolean loadIfNotCovered) throws DoesNotHaveRegattaLogException {
|
|
||||||
assert trackedRace != null;
|
|
||||||
// TODO remove fixes, if mappings have been removed
|
|
||||||
// check if there are new time ranges not covered so far
|
|
||||||
Map<Mark, List<DeviceMapping<Mark>>> newMappings = getNewMarkMappings();
|
|
||||||
|
|
||||||
if (loadIfNotCovered) {
|
|
||||||
for (Mark mark : newMappings.keySet()) {
|
|
||||||
DynamicGPSFixTrack<Mark, GPSFix> track = trackedRace.getOrCreateTrack(mark);
|
|
||||||
List<DeviceMapping<Mark>> oldMappings = markMappings.get(mark);
|
|
||||||
|
|
||||||
if (oldMappings != null) {
|
|
||||||
for (DeviceMapping<Mark> newMapping : newMappings.get(mark)) {
|
|
||||||
if (!hasMappingAlreadyBeenLoaded(newMapping, oldMappings)) {
|
|
||||||
try {
|
|
||||||
gpsFixStore.loadMarkTrack(track, newMapping);
|
|
||||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
|
||||||
logger.log(Level.WARNING, "Could not load mark track " + newMapping.getMappedTo());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
markMappings.clear();
|
|
||||||
markMappings.putAll(newMappings);
|
|
||||||
|
|
||||||
markMappingsByDevices.clear();
|
|
||||||
markMappingsByDevices.putAll(transformToMappingsByDevice(markMappings));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onDeviceMarkMappingEvent(RegattaLogDeviceMarkMappingEvent event) {
|
|
||||||
if (trackedRace != null) {
|
|
||||||
try {
|
|
||||||
updateMarkMappings(true);
|
|
||||||
} catch (DoesNotHaveRegattaLogException e) {
|
|
||||||
logger.warning("Could not load update mark mappings as RegattaLog couldn't be found");
|
|
||||||
}
|
|
||||||
gpsFixStore.addListener(this, event.getDevice());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a log is attached to it, the tracked race creates mark tracks for all marks either defined or with a device
|
* When a log is attached to it, the tracked race creates mark tracks for all marks either defined or with a device
|
||||||
@@ -367,56 +226,6 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDeviceCompetitorMappingEvent(RegattaLogDeviceCompetitorMappingEvent event) {
|
|
||||||
if (trackedRace != null) {
|
|
||||||
try {
|
|
||||||
updateCompetitorMappings(true);
|
|
||||||
} catch (DoesNotHaveRegattaLogException e) {
|
|
||||||
logger.warning("Could not load update competitor mappings as RegattaLog couldn't be found");
|
|
||||||
}
|
|
||||||
gpsFixStore.addListener(this, event.getDevice());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjusts the {@link #competitorMappings} map according to the competitor registrations for the race managed by
|
|
||||||
* this tracked, either from the regatta log or the race log. Then, the {@link TrackedRace}'s start and end of
|
|
||||||
* tracking time frame is {@link #updateStartAndEndOfTracking(boolean) updated} from the mapping intervals.
|
|
||||||
*
|
|
||||||
* @param loadIfNotCovered
|
|
||||||
* if <code>true</code>, the GPS fixes for the mappings will be loaded based on a comparison of the
|
|
||||||
* previous mappings from {@link #competitorMappings} and the new mappings.
|
|
||||||
*
|
|
||||||
* @throws DoesNotHaveRegattaLogException
|
|
||||||
*/
|
|
||||||
private void updateCompetitorMappings(boolean loadIfNotCovered) throws DoesNotHaveRegattaLogException {
|
|
||||||
// TODO remove fixes, if mappings have been removed
|
|
||||||
|
|
||||||
// check if there are new time ranges not covered so far
|
|
||||||
Map<Competitor, List<DeviceMapping<Competitor>>> newMappings = getNewCompetitorMappings();
|
|
||||||
|
|
||||||
if (loadIfNotCovered) {
|
|
||||||
for (Competitor competitor : newMappings.keySet()) {
|
|
||||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = trackedRace.getTrack(competitor);
|
|
||||||
List<DeviceMapping<Competitor>> oldMappings = competitorMappings.get(competitor);
|
|
||||||
|
|
||||||
for (DeviceMapping<Competitor> newMapping : newMappings.get(competitor)) {
|
|
||||||
if (!hasMappingAlreadyBeenLoaded(newMapping, oldMappings)) {
|
|
||||||
try {
|
|
||||||
gpsFixStore.loadCompetitorTrack(track, newMapping);
|
|
||||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
|
||||||
logger.log(Level.WARNING, "Could not load competitor track " + newMapping.getMappedTo());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
competitorMappings.clear();
|
|
||||||
competitorMappings.putAll(newMappings);
|
|
||||||
competitorMappingsByDevices.clear();
|
|
||||||
competitorMappingsByDevices.putAll(transformToMappingsByDevice(competitorMappings));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onStartTrackingEvent(RaceLogStartTrackingEvent event) {
|
private void onStartTrackingEvent(RaceLogStartTrackingEvent event) {
|
||||||
if (trackedRace == null) {
|
if (trackedRace == null) {
|
||||||
startTracking(event);
|
startTracking(event);
|
||||||
@@ -457,8 +266,7 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
RaceLogDenoteForTrackingEvent denoteEvent = new RaceInformationFinder(raceLog).analyze();
|
RaceLogDenoteForTrackingEvent denoteEvent = new RaceInformationFinder(raceLog).analyze();
|
||||||
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = new TrackingTimesFinder(raceLog).analyze();
|
final Pair<TimePointSpecificationFoundInLog, TimePointSpecificationFoundInLog> trackingTimes = new TrackingTimesFinder(raceLog).analyze();
|
||||||
if (trackingTimes == null || trackingTimes.getA() == null || trackingTimes.getA().getTimePoint() == null) {
|
if (trackingTimes == null || trackingTimes.getA() == null || trackingTimes.getA().getTimePoint() == null) {
|
||||||
// the start of tracking interval is unset or set to null; enter "now" as start of tracking
|
// the start of tracking interval is unset or set to null; enter "now" as start of tracking into the race log
|
||||||
// into the race log
|
|
||||||
raceLog.add(new RaceLogStartOfTrackingEventImpl(MillisecondsTimePoint.now(), raceLogEventAuthor, /* passId */ 0));
|
raceLog.add(new RaceLogStartOfTrackingEventImpl(MillisecondsTimePoint.now(), raceLogEventAuthor, /* passId */ 0));
|
||||||
}
|
}
|
||||||
BoatClass boatClass = denoteEvent.getBoatClass();
|
BoatClass boatClass = denoteEvent.getBoatClass();
|
||||||
@@ -487,87 +295,13 @@ public class RaceLogRaceTracker implements RaceTracker, GPSFixReceivedListener {
|
|||||||
// set race definition, so race is linked to leaderboard automatically
|
// set race definition, so race is linked to leaderboard automatically
|
||||||
regatta.getRegatta().addRace(raceDef);
|
regatta.getRegatta().addRace(raceDef);
|
||||||
raceColumn.setRaceIdentifier(fleet, regatta.getRegatta().getRaceIdentifier(raceDef));
|
raceColumn.setRaceIdentifier(fleet, regatta.getRegatta().getRaceIdentifier(raceDef));
|
||||||
trackedRace = regatta.createTrackedRace(raceDef, sidelines, windStore, gpsFixStore,
|
trackedRace = regatta.createTrackedRace(raceDef, sidelines, windStore,
|
||||||
params.getDelayToLiveInMillis(), WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
|
params.getDelayToLiveInMillis(), WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
|
||||||
boatClass.getApproximateManeuverDurationInMilliseconds(), null, /*useMarkPassingCalculator*/ true, raceLogResolver);
|
boatClass.getApproximateManeuverDurationInMilliseconds(), null, /*useMarkPassingCalculator*/ true, raceLogResolver);
|
||||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, 0));
|
|
||||||
//attach regatta logs
|
|
||||||
for (AbstractLog<?, ?> log : params.getLogHierarchy()) {
|
|
||||||
if (log instanceof RegattaLog) {
|
|
||||||
trackedRace.attachRegattaLog((RegattaLog) log);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// update the device mappings (without loading the fixes, as the TrackedRace does this itself on startup)
|
|
||||||
try {
|
|
||||||
updateCompetitorMappings(false);
|
|
||||||
updateMarkMappings(false);
|
|
||||||
} catch (DoesNotHaveRegattaLogException e) {
|
|
||||||
logger.warning("Could not load update mark and competitor mappings as RegattaLog couldn't be found");
|
|
||||||
}
|
|
||||||
// add listeners for devices in mappings already present
|
|
||||||
addListeners(competitorMappings);
|
|
||||||
addListeners(markMappings);
|
|
||||||
logger.info(String.format("Started tracking race-log race (%s)", raceLog));
|
logger.info(String.format("Started tracking race-log race (%s)", raceLog));
|
||||||
// this wakes up all waiting race handles
|
// this wakes up all waiting race handles
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
this.notifyAll();
|
this.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends WithID> void addListeners(Map<T, List<DeviceMapping<T>>> mappings) {
|
|
||||||
for (List<DeviceMapping<T>> list : mappings.values()) {
|
|
||||||
for (DeviceMapping<T> mapping : list) {
|
|
||||||
gpsFixStore.addListener(this, mapping.getDevice());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RaceLogConnectivityParams getParams() {
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fixReceived(DeviceIdentifier device, GPSFix fix) {
|
|
||||||
TimePoint timePoint = fix.getTimePoint();
|
|
||||||
if (markMappingsByDevices.get(device) != null) {
|
|
||||||
for (DeviceMapping<Mark> mapping : markMappingsByDevices.get(device)) {
|
|
||||||
Mark mark = mapping.getMappedTo();
|
|
||||||
if (mapping.getTimeRange().includes(timePoint)) {
|
|
||||||
final DynamicGPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
|
|
||||||
final GPSFix firstFixAtOrAfter;
|
|
||||||
boolean forceFix;
|
|
||||||
markTrack.lockForRead();
|
|
||||||
try {
|
|
||||||
forceFix = Util.isEmpty(markTrack.getRawFixes()) ||
|
|
||||||
(firstFixAtOrAfter=markTrack.getFirstFixAtOrAfter(timePoint)) != null &&
|
|
||||||
firstFixAtOrAfter.getTimePoint().equals(timePoint);
|
|
||||||
} finally {
|
|
||||||
markTrack.unlockAfterRead();
|
|
||||||
}
|
|
||||||
if (forceFix) {
|
|
||||||
trackedRace.recordFix(mark, fix, /* only when in tracking interval */ false); // force fix into track
|
|
||||||
} else {
|
|
||||||
trackedRace.recordFix(mark, fix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (competitorMappingsByDevices.get(device) != null) {
|
|
||||||
for (DeviceMapping<Competitor> mapping : competitorMappingsByDevices.get(device)) {
|
|
||||||
Competitor comp = mapping.getMappedTo();
|
|
||||||
if (mapping.getTimeRange().includes(timePoint)) {
|
|
||||||
if (fix instanceof GPSFixMoving) {
|
|
||||||
trackedRace.recordFix(comp, (GPSFixMoving) fix);
|
|
||||||
} else {
|
|
||||||
logger.log(
|
|
||||||
Level.WARNING,
|
|
||||||
String.format(
|
|
||||||
"Could not add fix for competitor (%s) in race (%s), as it is no GPSFixMoving, meaning it is missing COG/SOG values",
|
|
||||||
comp, params.getRaceLog()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+2
-3
@@ -56,7 +56,6 @@ import com.sap.sailing.domain.common.racelog.tracking.NotDenotableForRaceLogTrac
|
|||||||
import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException;
|
import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.RaceLogRaceTrackerExistsException;
|
import com.sap.sailing.domain.common.racelog.tracking.RaceLogRaceTrackerExistsException;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||||
@@ -250,8 +249,8 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
|||||||
now, service.getServerAuthor(), UUID.randomUUID(), mark, device, timePoint, timePoint);
|
now, service.getServerAuthor(), UUID.randomUUID(), mark, device, timePoint, timePoint);
|
||||||
log.add(mapping);
|
log.add(mapping);
|
||||||
try {
|
try {
|
||||||
service.getGPSFixStore().storeFix(device, gpsFix);
|
service.getSensorFixStore().storeFix(device, gpsFix);
|
||||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
} catch (NoCorrespondingServiceRegisteredException e) {
|
||||||
logger.log(Level.WARNING, "Could not ping mark " + mark);
|
logger.log(Level.WARNING, "Could not ping mark " + mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+362
@@ -0,0 +1,362 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.base.Mark;
|
||||||
|
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||||
|
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||||
|
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||||
|
import com.sap.sailing.domain.racelog.impl.GPSFixStoreImpl;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.FixReceivedListener;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixMapper;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
|
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicSensorFixTrack;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||||
|
import com.sap.sailing.domain.tracking.Track;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
|
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||||
|
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
||||||
|
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
import com.sap.sse.common.Util;
|
||||||
|
import com.sap.sse.common.WithID;
|
||||||
|
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||||
|
import com.sap.sse.concurrent.LockUtil;
|
||||||
|
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class listens to RaceLog Events, changes to the race and fix loading events and properly handles mappings and
|
||||||
|
* fix loading.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link RaceChangeListener},</li>
|
||||||
|
* <li>{@link RegattaLogEventVisitor}</li>
|
||||||
|
* <li>{@link FixReceivedListener}</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||||
|
private static final Logger logger = Logger.getLogger(FixLoaderAndTracker.class.getName());
|
||||||
|
protected final DynamicTrackedRace trackedRace;
|
||||||
|
private final NamedReentrantReadWriteLock loadingFromFixStoreLock;
|
||||||
|
private final SensorFixStore sensorFixStore;
|
||||||
|
private final GPSFixStore gpsFixStore;
|
||||||
|
private RegattaLogDeviceMappings<WithID> deviceMappings;
|
||||||
|
private final AtomicInteger activeLoaders = new AtomicInteger();
|
||||||
|
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||||
|
private AtomicBoolean preemptiveStopRequested = new AtomicBoolean(false);
|
||||||
|
private AtomicBoolean stopRequested = new AtomicBoolean(false);
|
||||||
|
private final AbstractRaceChangeListener raceChangeListener = new AbstractRaceChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void startOfTrackingChanged(TimePoint oldStartOfTracking, TimePoint newStartOfTracking) {
|
||||||
|
if ((newStartOfTracking == null
|
||||||
|
|| (oldStartOfTracking != null && newStartOfTracking.before(oldStartOfTracking)))) {
|
||||||
|
loadFixesForExtendedTimeRange(newStartOfTracking, oldStartOfTracking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endOfTrackingChanged(TimePoint oldEndOfTracking, TimePoint newEndOfTracking) {
|
||||||
|
if (newEndOfTracking == null || (oldEndOfTracking != null && newEndOfTracking.after(oldEndOfTracking))) {
|
||||||
|
loadFixesForExtendedTimeRange(oldEndOfTracking, newEndOfTracking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void regattaLogAttached(RegattaLog regattaLog) {
|
||||||
|
deviceMappings.addRegattaLog(regattaLog);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private final FixReceivedListener<Timed> listener = new FixReceivedListener<Timed>() {
|
||||||
|
@Override
|
||||||
|
public void fixReceived(DeviceIdentifier device, Timed fix) {
|
||||||
|
if (preemptiveStopRequested.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final TimePoint timePoint = fix.getTimePoint();
|
||||||
|
deviceMappings.forEachMappingOfDeviceIncludingTimePoint(device, fix.getTimePoint(), (mapping) -> {
|
||||||
|
mapping.getRegattaLogEvent().accept(new MappingEventVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
if (preemptiveStopRequested.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SensorFixMapper<DoubleVectorFix, DynamicSensorFixTrack<Competitor, SensorFix>, Competitor> mapper = sensorFixMapperFactory
|
||||||
|
.createCompetitorMapper(event.getClass());
|
||||||
|
DynamicSensorFixTrack<Competitor, SensorFix> track = mapper.getTrack(trackedRace,
|
||||||
|
event.getMappedTo());
|
||||||
|
if (track != null && trackedRace.isWithinStartAndEndOfTracking(fix.getTimePoint())) {
|
||||||
|
mapper.addFix(track, (DoubleVectorFix) fix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||||
|
if (preemptiveStopRequested.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Competitor comp = event.getMappedTo();
|
||||||
|
if (fix instanceof GPSFixMoving) {
|
||||||
|
trackedRace.recordFix(comp, (GPSFixMoving) fix);
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING,
|
||||||
|
String.format(
|
||||||
|
"Could not add fix for competitor (%s) in race (%s), as it"
|
||||||
|
+ " is no GPSFixMoving, meaning it is missing COG/SOG values",
|
||||||
|
comp, trackedRace.getRace().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
||||||
|
if (preemptiveStopRequested.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Mark mark = event.getMappedTo();
|
||||||
|
final DynamicGPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
|
||||||
|
final GPSFix firstFixAtOrAfter;
|
||||||
|
final boolean forceFix;
|
||||||
|
markTrack.lockForRead();
|
||||||
|
try {
|
||||||
|
forceFix = Util.isEmpty(markTrack.getRawFixes())
|
||||||
|
|| (firstFixAtOrAfter = markTrack.getFirstFixAtOrAfter(timePoint)) != null
|
||||||
|
&& firstFixAtOrAfter.getTimePoint().equals(timePoint);
|
||||||
|
} finally {
|
||||||
|
markTrack.unlockAfterRead();
|
||||||
|
}
|
||||||
|
trackedRace.recordFix(mark, (GPSFix) fix, /* only when in tracking interval */ !forceFix);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public FixLoaderAndTracker(DynamicTrackedRace trackedRace, SensorFixStore sensorFixStore,
|
||||||
|
SensorFixMapperFactory sensorFixMapperFactory) {
|
||||||
|
this.sensorFixStore = sensorFixStore;
|
||||||
|
this.gpsFixStore = new GPSFixStoreImpl(sensorFixStore);
|
||||||
|
this.sensorFixMapperFactory = sensorFixMapperFactory;
|
||||||
|
this.trackedRace = trackedRace;
|
||||||
|
loadingFromFixStoreLock = new NamedReentrantReadWriteLock(
|
||||||
|
"Loading from SensorFix store lock for tracked race " + trackedRace.getRace().getName(), false);
|
||||||
|
|
||||||
|
startTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadFixes(TimeRange timeRangeToLoad, DeviceMappingWithRegattaLogEvent<? extends WithID> mapping) {
|
||||||
|
if (preemptiveStopRequested.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mapping.getRegattaLogEvent().accept(new MappingEventVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
SensorFixMapper<Timed, Track<?>, Competitor> mapper = sensorFixMapperFactory
|
||||||
|
.createCompetitorMapper(event.getClass());
|
||||||
|
Track<?> track = mapper.getTrack(trackedRace, event.getMappedTo());
|
||||||
|
try {
|
||||||
|
sensorFixStore.loadFixes((DoubleVectorFix fix) -> mapper.addFix(track, fix), mapping.getDevice(),
|
||||||
|
timeRangeToLoad.from(), timeRangeToLoad.to(), true);
|
||||||
|
} catch (NoCorrespondingServiceRegisteredException | TransformationException e) {
|
||||||
|
logger.log(Level.WARNING, "Could not load track for competitor: " + mapping.getMappedTo()
|
||||||
|
+ "; device: " + mapping.getDevice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||||
|
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = trackedRace.getTrack(event.getMappedTo());
|
||||||
|
try {
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
DeviceMapping<Competitor> competitorMapping = (DeviceMapping<Competitor>) mapping;
|
||||||
|
gpsFixStore.loadCompetitorTrack(track, competitorMapping, getStartOfTracking(),
|
||||||
|
getEndOfTracking());
|
||||||
|
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||||
|
logger.log(Level.WARNING, "Could not load competitor track " + mapping.getMappedTo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
||||||
|
DynamicGPSFixTrack<Mark, GPSFix> track = trackedRace.getOrCreateTrack(event.getMappedTo());
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
DeviceMapping<Mark> markMapping = (DeviceMapping<Mark>) mapping;
|
||||||
|
TimePoint from = getStartOfTracking();
|
||||||
|
TimePoint to = getEndOfTracking();
|
||||||
|
gpsFixStore.loadMarkTrack(track, markMapping, from, to);
|
||||||
|
if (track.getFirstRawFix() == null) {
|
||||||
|
logger.fine("Loading mark positions from outside of start/end of tracking interval (" + from
|
||||||
|
+ ".." + to + ") because no fixes were found in that interval");
|
||||||
|
// got an empty track for the mark; try again without constraining the mapping interval
|
||||||
|
// by start/end of tracking to at least attempt to get fixes at all in case there were any
|
||||||
|
// within the device mapping interval specified
|
||||||
|
gpsFixStore.loadMarkTrack(track, markMapping, /* startOfTimeWindowToLoad */ null,
|
||||||
|
/* endOfTimeWindowToLoad */ null);
|
||||||
|
}
|
||||||
|
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||||
|
logger.log(Level.WARNING, "Could not load mark track " + mapping.getMappedTo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeRange getTrackingTimeRange() {
|
||||||
|
return new TimeRangeImpl(getStartOfTracking() == null ? TimePoint.BeginningOfTime : getStartOfTracking(),
|
||||||
|
getEndOfTracking() == null ? TimePoint.EndOfTime : getEndOfTracking());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(boolean preemptive) {
|
||||||
|
preemptiveStopRequested.set(preemptive);
|
||||||
|
stopRequested.set(true);
|
||||||
|
trackedRace.removeListener(raceChangeListener);
|
||||||
|
deviceMappings.stop();
|
||||||
|
synchronized (this) {
|
||||||
|
if (activeLoaders.get() == 0) {
|
||||||
|
setStatusAndProgress(TrackedRaceStatusEnum.FINISHED, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sensorFixStore.removeListener(listener);
|
||||||
|
if (preemptiveStopRequested.get()) {
|
||||||
|
waitForLoadingToFinishRunning();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void startTracking() {
|
||||||
|
trackedRace.addListener(raceChangeListener);
|
||||||
|
this.deviceMappings = new FixLoaderDeviceMappings(trackedRace.getAttachedRegattaLogs());
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void waitForLoadingToFinishRunning() {
|
||||||
|
try {
|
||||||
|
while (activeLoaders.get() > 0) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.log(Level.WARNING, "Interrupted while waiting for Fixes to be loaded", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEMP: kommt von RaceLogSensorFixTracker
|
||||||
|
protected TimePoint getStartOfTracking() {
|
||||||
|
return trackedRace.getStartOfTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TEMP: kommt von RaceLogSensorFixTracker
|
||||||
|
protected TimePoint getEndOfTracking() {
|
||||||
|
return trackedRace.getEndOfTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadFixesForExtendedTimeRange(TimePoint loadFixesFrom, TimePoint loadFixesTo) {
|
||||||
|
final TimeRangeImpl extendedTimeRange = new TimeRangeImpl(loadFixesFrom, loadFixesTo);
|
||||||
|
deviceMappings.forEachMapping((mapping) -> {
|
||||||
|
TimeRange timeRangeToLoad = extendedTimeRange.intersection(mapping.getTimeRange());
|
||||||
|
if (timeRangeToLoad != null && !preemptiveStopRequested.get()) {
|
||||||
|
loadFixes(timeRangeToLoad, mapping);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConcurrent(final Runnable updateCallback) {
|
||||||
|
synchronized (FixLoaderAndTracker.this) {
|
||||||
|
activeLoaders.incrementAndGet();
|
||||||
|
setStatusAndProgress(TrackedRaceStatusEnum.LOADING, 0.5);
|
||||||
|
}
|
||||||
|
Thread t = new Thread(
|
||||||
|
this.getClass().getSimpleName() + " loader for tracked race " + trackedRace.getRace().getName()) {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if (!preemptiveStopRequested.get()) {
|
||||||
|
trackedRace.lockForSerializationRead();
|
||||||
|
setStatusAndProgress(TrackedRaceStatusEnum.LOADING, 0.5);
|
||||||
|
LockUtil.lockForWrite(loadingFromFixStoreLock);
|
||||||
|
synchronized (FixLoaderAndTracker.this) {
|
||||||
|
FixLoaderAndTracker.this.notifyAll();
|
||||||
|
}
|
||||||
|
updateCallback.run();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
LockUtil.unlockAfterWrite(loadingFromFixStoreLock);
|
||||||
|
synchronized (FixLoaderAndTracker.this) {
|
||||||
|
int currentActiveLoaders;
|
||||||
|
currentActiveLoaders = activeLoaders.decrementAndGet();
|
||||||
|
FixLoaderAndTracker.this.notifyAll();
|
||||||
|
if (currentActiveLoaders == 0) {
|
||||||
|
setStatusAndProgress(stopRequested.get() ? TrackedRaceStatusEnum.FINISHED
|
||||||
|
: TrackedRaceStatusEnum.TRACKING, 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trackedRace.unlockAfterSerializationRead();
|
||||||
|
logger.info("Thread " + getName() + " done.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if currently the race is loading GPS fixes from the {@link GPSFixStore}. Clients may {@link Object#wait()}
|
||||||
|
* on <code>this</code> object and will be notified whenever a change of this flag's value occurs.
|
||||||
|
*/
|
||||||
|
public boolean isLoadingFromGPSFixStore() {
|
||||||
|
return activeLoaders.get() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStatusAndProgress(TrackedRaceStatusEnum status, double progress) {
|
||||||
|
trackedRace.onStatusChanged(this, new TrackedRaceStatusImpl(status, progress));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FixLoaderDeviceMappings extends RegattaLogDeviceMappings<WithID> {
|
||||||
|
public FixLoaderDeviceMappings(Iterable<RegattaLog> initialRegattaLogs) {
|
||||||
|
super(initialRegattaLogs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateMappings() {
|
||||||
|
updateConcurrent(() -> {
|
||||||
|
FixLoaderDeviceMappings.super.updateMappings();
|
||||||
|
// add listeners for devices in mappings already present
|
||||||
|
forEachDevice((device) -> sensorFixStore.addListener(listener, device));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mappingRemoved(DeviceMappingWithRegattaLogEvent<WithID> mapping) {
|
||||||
|
// TODO if tracks are always associated to only one device mapping, we could remove tracks here
|
||||||
|
// TODO remove listener from store if there is no mapping left for the DeviceIdentifier
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mappingAdded(DeviceMappingWithRegattaLogEvent<WithID> mapping) {
|
||||||
|
loadFixes(getTrackingTimeRange().intersection(mapping.getTimeRange()), mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void mappingChanged(DeviceMappingWithRegattaLogEvent<WithID> oldMapping,
|
||||||
|
DeviceMappingWithRegattaLogEvent<WithID> newMapping) {
|
||||||
|
// TODO can the new time range be bigger than the old one? In this case we would need to load the
|
||||||
|
// additional time range.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+153
@@ -0,0 +1,153 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
|
||||||
|
|
||||||
|
import java.security.acl.Owner;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.RaceLogRevokeEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.impl.BaseRaceLogEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogTrackingStateAnalyzer;
|
||||||
|
import com.sap.sailing.domain.common.racelog.tracking.RaceLogTrackingState;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
|
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
|
import com.sap.sailing.domain.tracking.impl.AbstractRaceChangeListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class manages the lifecycle of the {@link FixLoaderAndTracker} by listening to
|
||||||
|
* {@link RaceLogDenoteForTrackingEvent}, race log attached and stop tracking race changes.
|
||||||
|
*
|
||||||
|
* Once the race is stopped, it notifies its own {@link Owner} so that all reference to this instance can be cleanly
|
||||||
|
* removed to prevent memory leaks.
|
||||||
|
*/
|
||||||
|
public class RaceLogFixTrackerManager implements TrackingDataLoader {
|
||||||
|
private static final Logger logger = Logger.getLogger(RaceLogFixTrackerManager.class.getName());
|
||||||
|
|
||||||
|
private final DynamicTrackedRace trackedRace;
|
||||||
|
|
||||||
|
private final SensorFixStore sensorFixStore;
|
||||||
|
|
||||||
|
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We maintain our own collection that holds the RaceLogs. The known RaceLogs should by in sync with the ones that
|
||||||
|
* can be obtained from the TrackedRace. When stopping, there could be a concurrency issue that leads to a listener
|
||||||
|
* not being removed. This is prevented by remembering all RaceLogs to which we attached a listener. So we can be
|
||||||
|
* sure to not produce a memory leak.
|
||||||
|
*/
|
||||||
|
private final Set<RaceLog> knownRaceLogs = new HashSet<>();
|
||||||
|
|
||||||
|
private FixLoaderAndTracker tracker;
|
||||||
|
|
||||||
|
private final RaceChangeListener raceChangeListener = new AbstractRaceChangeListener() {
|
||||||
|
public void raceLogAttached(RaceLog raceLog) {
|
||||||
|
addRaceLog(raceLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void raceLogDetached(RaceLog raceLog) {
|
||||||
|
removeRaceLog(raceLog);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final RaceLogEventVisitor raceLogEventVisitor = new BaseRaceLogEventVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visit(RaceLogDenoteForTrackingEvent event) {
|
||||||
|
updateDenotationState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RaceLogRevokeEvent event) {
|
||||||
|
updateDenotationState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public RaceLogFixTrackerManager(DynamicTrackedRace trackedRace, SensorFixStore sensorFixStore,
|
||||||
|
SensorFixMapperFactory sensorFixMapperFactory) {
|
||||||
|
this.trackedRace = trackedRace;
|
||||||
|
this.sensorFixStore = sensorFixStore;
|
||||||
|
this.sensorFixMapperFactory = sensorFixMapperFactory;
|
||||||
|
|
||||||
|
trackedRace.addListener(raceChangeListener);
|
||||||
|
|
||||||
|
synchronized (knownRaceLogs) {
|
||||||
|
for (RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||||
|
addRaceLogUnlocked(raceLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDenotationState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void updateDenotationState() {
|
||||||
|
if (isForTracking()) {
|
||||||
|
startTrackerIfNotAlreadyStarted();
|
||||||
|
} else {
|
||||||
|
stopTrackerIfStillRunning(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRaceLog(RaceLog raceLog) {
|
||||||
|
synchronized (knownRaceLogs) {
|
||||||
|
addRaceLogUnlocked(raceLog);
|
||||||
|
}
|
||||||
|
updateDenotationState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRaceLog(RaceLog raceLog) {
|
||||||
|
synchronized (knownRaceLogs) {
|
||||||
|
removeRaceLogUnlocked(raceLog);
|
||||||
|
}
|
||||||
|
updateDenotationState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRaceLogUnlocked(RaceLog raceLog) {
|
||||||
|
knownRaceLogs.add(raceLog);
|
||||||
|
raceLog.addListener(raceLogEventVisitor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRaceLogUnlocked(RaceLog raceLog) {
|
||||||
|
raceLog.removeListener(raceLogEventVisitor);
|
||||||
|
knownRaceLogs.remove(raceLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(boolean preemptive) {
|
||||||
|
stopTrackerIfStillRunning(preemptive);
|
||||||
|
trackedRace.removeListener(raceChangeListener);
|
||||||
|
synchronized (knownRaceLogs) {
|
||||||
|
for (RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||||
|
removeRaceLogUnlocked(raceLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void startTrackerIfNotAlreadyStarted() {
|
||||||
|
if (tracker == null) {
|
||||||
|
logger.fine("Starting fix tracker for TrackedRace: " + trackedRace.getRaceIdentifier());
|
||||||
|
tracker = new FixLoaderAndTracker(trackedRace, sensorFixStore, sensorFixMapperFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void stopTrackerIfStillRunning(boolean preemptive) {
|
||||||
|
if (tracker != null) {
|
||||||
|
logger.fine("Stopping fix tracker for TrackedRace: " + trackedRace.getRaceIdentifier());
|
||||||
|
tracker.stop(preemptive);
|
||||||
|
tracker = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isForTracking() {
|
||||||
|
for (RaceLog raceLog : trackedRace.getAttachedRaceLogs()) {
|
||||||
|
RaceLogTrackingState raceLogTrackingState = new RaceLogTrackingStateAnalyzer(raceLog).analyze();
|
||||||
|
if (raceLogTrackingState.isForTracking()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
+331
@@ -0,0 +1,331 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.impl.BaseRegattaLogEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMappingFinder;
|
||||||
|
import com.sap.sailing.domain.common.racelog.tracking.DoesNotHaveRegattaLogException;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrack;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
import com.sap.sse.common.WithID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds DeviceMappings to make it possible to track changes. This makes it possible to only process mappings that
|
||||||
|
* weren't processed before.
|
||||||
|
*
|
||||||
|
* @param <ItemT> The type of items the DeviceMappings are mapped to
|
||||||
|
*/
|
||||||
|
public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
|
||||||
|
private static final Logger logger = Logger.getLogger(RegattaLogDeviceMappings.class.getName());
|
||||||
|
/**
|
||||||
|
* We maintain our own collection that holds the RegattaLogs. The known RegattaLogs should by in sync with the ones that
|
||||||
|
* can be obtained from the TrackedRace. When stopping, there could be a concurrency issue that leads to a listener
|
||||||
|
* not being removed. This is prevented by remembering all RegattaLogs to which we attached a listener. So we can be
|
||||||
|
* sure to not produce a memory leak.
|
||||||
|
*/
|
||||||
|
private final Set<RegattaLog> knownRegattaLogs = new HashSet<>();
|
||||||
|
|
||||||
|
private final Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> mappings = new HashMap<>();
|
||||||
|
private final Map<DeviceIdentifier, List<DeviceMappingWithRegattaLogEvent<ItemT>>> mappingsByDevice = new HashMap<>();
|
||||||
|
|
||||||
|
private final RegattaLogEventVisitor regattaLogEventVisitor = new BaseRegattaLogEventVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
logger.log(Level.FINE, "New mapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||||
|
updateMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
||||||
|
logger.log(Level.FINE,
|
||||||
|
"New DeviceMarkMapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||||
|
updateMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||||
|
logger.log(Level.FINE,
|
||||||
|
"New DeviceCompetitorMapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||||
|
updateMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||||
|
logger.log(Level.FINE, "CloseOpenEndedDeviceMapping closed: " + event.getDeviceMappingEventId());
|
||||||
|
updateMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogRevokeEvent event) {
|
||||||
|
logger.log(Level.FINE, "Mapping revoked for: " + event.getRevokedEventId());
|
||||||
|
updateMappings();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
public RegattaLogDeviceMappings(Iterable<RegattaLog> initialRegattaLogs) {
|
||||||
|
final boolean hasRegattaLogs;
|
||||||
|
synchronized (knownRegattaLogs) {
|
||||||
|
initialRegattaLogs.forEach(this::addRegattaLogUnlocked);
|
||||||
|
hasRegattaLogs = !knownRegattaLogs.isEmpty();
|
||||||
|
}
|
||||||
|
if (hasRegattaLogs) {
|
||||||
|
updateMappings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRegattaLog(RegattaLog regattaLog) {
|
||||||
|
synchronized (knownRegattaLogs) {
|
||||||
|
addRegattaLogUnlocked(regattaLog);
|
||||||
|
}
|
||||||
|
updateMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRegattaLogUnlocked(RegattaLog log) {
|
||||||
|
log.addListener(regattaLogEventVisitor);
|
||||||
|
knownRegattaLogs.add(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
synchronized (knownRegattaLogs) {
|
||||||
|
knownRegattaLogs.forEach((log) -> log.removeListener(regattaLogEventVisitor));
|
||||||
|
knownRegattaLogs.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateMappings() {
|
||||||
|
try {
|
||||||
|
updateMappings(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.warning("Could not update device mappings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to access {@link #mappings} with a defensive copy to not run into concurrency issues if this is
|
||||||
|
* called while an update is done.
|
||||||
|
*
|
||||||
|
* @return the mappings
|
||||||
|
*/
|
||||||
|
private synchronized Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> getDeviceMappings() {
|
||||||
|
return new HashMap<>(mappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to access {@link #mappingsByDevice} with a defensive copy to not run into concurrency issues if
|
||||||
|
* this is called while an update is done.
|
||||||
|
*
|
||||||
|
* @return the mappings
|
||||||
|
*/
|
||||||
|
private synchronized Map<DeviceIdentifier, List<DeviceMappingWithRegattaLogEvent<ItemT>>> getMappingsByDevice() {
|
||||||
|
return new HashMap<>(mappingsByDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the given callback for every known mapping that's currently known.
|
||||||
|
*
|
||||||
|
* @param callback the callback to call for every known mapping
|
||||||
|
*/
|
||||||
|
public void forEachMapping(Consumer<DeviceMappingWithRegattaLogEvent<ItemT>> callback) {
|
||||||
|
forEachMapping((item, mapping) -> callback.accept(mapping));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the given callback for every device mapped by at least one of the known mappings.
|
||||||
|
*
|
||||||
|
* @param callback the callback to call for every mapped device
|
||||||
|
*/
|
||||||
|
public void forEachDevice(Consumer<DeviceIdentifier> callback) {
|
||||||
|
getMappingsByDevice().keySet().forEach(callback::accept);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the given callback for every known mapping that's currently known.
|
||||||
|
*
|
||||||
|
* @param callback the callback to call for every known mapping
|
||||||
|
*/
|
||||||
|
public void forEachMapping(BiConsumer<ItemT, DeviceMappingWithRegattaLogEvent<ItemT>> callback) {
|
||||||
|
for (Map.Entry<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> entry : getDeviceMappings().entrySet()) {
|
||||||
|
ItemT item = entry.getKey();
|
||||||
|
for (DeviceMappingWithRegattaLogEvent<ItemT> mapping : entry.getValue()) {
|
||||||
|
callback.accept(item, mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the given callback for every DeviceMapping that is known for the given {@link DeviceIdentifier} that
|
||||||
|
* includes the given {@link TimePoint}.
|
||||||
|
*
|
||||||
|
* @param device
|
||||||
|
* the device to get the mappings for
|
||||||
|
* @param timePoint
|
||||||
|
* the TimePoint to check DeviceMappings for
|
||||||
|
* @param callback
|
||||||
|
* the callback to call for every known mapping of the given {@link DeviceIdentifier} that includes the
|
||||||
|
* given {@link TimePoint}.
|
||||||
|
*/
|
||||||
|
public void forEachMappingOfDeviceIncludingTimePoint(DeviceIdentifier device, TimePoint timePoint,
|
||||||
|
Consumer<DeviceMappingWithRegattaLogEvent<ItemT>> callback) {
|
||||||
|
List<DeviceMappingWithRegattaLogEvent<ItemT>> mappingsForDevice;
|
||||||
|
synchronized (this) {
|
||||||
|
mappingsForDevice = mappingsByDevice.get(device);
|
||||||
|
}
|
||||||
|
if (mappingsForDevice != null) {
|
||||||
|
for (DeviceMappingWithRegattaLogEvent<ItemT> mapping : mappingsForDevice) {
|
||||||
|
if (mapping.getTimeRange().includes(timePoint)) {
|
||||||
|
callback.accept(mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To be implemented by subclasses to calculate the current {@link DeviceMapping}s.
|
||||||
|
*
|
||||||
|
* @return All currently known DeviceMappings
|
||||||
|
*/
|
||||||
|
protected Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> calculateMappings() {
|
||||||
|
Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> result = new HashMap<>();
|
||||||
|
forEachRegattaLog(
|
||||||
|
(log) -> result.putAll(new RegattaLogDeviceMappingFinder<ItemT>(log).analyze()));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void forEachRegattaLog(Consumer<RegattaLog> regattaLogConsumer) {
|
||||||
|
synchronized (knownRegattaLogs) {
|
||||||
|
knownRegattaLogs.forEach(regattaLogConsumer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts the {@link #mappings} map according to the device mappings provided from the {@link #calculateMappings()}
|
||||||
|
* method. Afterwards, the start end end of tracking is {@link #updateStartAndEndOfTracking() updated} from the
|
||||||
|
* mapping intervals.
|
||||||
|
*
|
||||||
|
* @param loadIfNotCovered
|
||||||
|
* if <code>true</code>, the fixes for the mappings will be loaded based on a comparison of the previous
|
||||||
|
* mappings and the new mappings.
|
||||||
|
*
|
||||||
|
* @throws DoesNotHaveRegattaLogException
|
||||||
|
*/
|
||||||
|
private final <FixT extends Timed, TrackT extends DynamicTrack<FixT>> void updateMappings(boolean loadIfNotCovered) {
|
||||||
|
// TODO remove fixes, if mappings have been removed
|
||||||
|
// check if there are new time ranges not covered so far
|
||||||
|
Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> newMappings = calculateMappings();
|
||||||
|
updateMappings(newMappings, loadIfNotCovered);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally to update the internal set of mappings to the state of the new mappings.
|
||||||
|
* This ensures that the internal state is updated and all new and changed mappings are correctly processed.
|
||||||
|
*
|
||||||
|
* @param newMappings the new mappings
|
||||||
|
* @param loadIfNotCovered true to inform about new/changed/removed mappings
|
||||||
|
*/
|
||||||
|
private synchronized void updateMappings(Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> newMappings,
|
||||||
|
boolean loadIfNotCovered) {
|
||||||
|
if (loadIfNotCovered) {
|
||||||
|
Set<ItemT> itemsToProcess = new HashSet<ItemT>(mappings.keySet());
|
||||||
|
itemsToProcess.addAll(newMappings.keySet());
|
||||||
|
for(ItemT item : itemsToProcess) {
|
||||||
|
if(!newMappings.containsKey(item)) {
|
||||||
|
mappings.get(item).forEach(this::mappingRemoved);
|
||||||
|
} else {
|
||||||
|
final List<DeviceMappingWithRegattaLogEvent<ItemT>> oldMappings = mappings.containsKey(item)
|
||||||
|
? mappings.get(item) : Collections.emptyList();
|
||||||
|
|
||||||
|
for (DeviceMappingWithRegattaLogEvent<ItemT> newMapping : newMappings.get(item)) {
|
||||||
|
DeviceMappingWithRegattaLogEvent<ItemT> oldMapping = findAndRemoveMapping(newMapping,
|
||||||
|
oldMappings);
|
||||||
|
if (oldMapping == null) {
|
||||||
|
mappingAdded(newMapping);
|
||||||
|
} else if (newMapping.getTimeRange().equals(oldMapping.getTimeRange())) {
|
||||||
|
mappingChanged(oldMapping, newMapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oldMappings.forEach(this::mappingRemoved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mappings.clear();
|
||||||
|
mappings.putAll(newMappings);
|
||||||
|
mappingsByDevice.clear();
|
||||||
|
for (ItemT item : newMappings.keySet()) {
|
||||||
|
for (DeviceMappingWithRegattaLogEvent<ItemT> mapping : newMappings.get(item)) {
|
||||||
|
List<DeviceMappingWithRegattaLogEvent<ItemT>> list = mappingsByDevice.get(mapping.getDevice());
|
||||||
|
if (list == null) {
|
||||||
|
list = new ArrayList<>();
|
||||||
|
mappingsByDevice.put(mapping.getDevice(), list);
|
||||||
|
}
|
||||||
|
list.add(mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a {@link DeviceMapping} was removed.
|
||||||
|
*
|
||||||
|
* @param mapping the removed mapping
|
||||||
|
*/
|
||||||
|
protected abstract void mappingRemoved(DeviceMappingWithRegattaLogEvent<ItemT> mapping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a {@link DeviceMapping} was added.
|
||||||
|
*
|
||||||
|
* @param mapping the new mapping
|
||||||
|
*/
|
||||||
|
protected abstract void mappingAdded(DeviceMappingWithRegattaLogEvent<ItemT> mapping);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a {@link DeviceMapping} was changed regarding its mapped time range.
|
||||||
|
* This can occur if an open ended mapping is being closed or a close event gets revoked.
|
||||||
|
*
|
||||||
|
* @param oldMapping the old mapping
|
||||||
|
* @param newMapping the new mapping
|
||||||
|
*/
|
||||||
|
protected abstract void mappingChanged(DeviceMappingWithRegattaLogEvent<ItemT> oldMapping,
|
||||||
|
DeviceMappingWithRegattaLogEvent<ItemT> newMapping);
|
||||||
|
|
||||||
|
private DeviceMappingWithRegattaLogEvent<ItemT> findAndRemoveMapping(
|
||||||
|
DeviceMappingWithRegattaLogEvent<ItemT> mappingToFind,
|
||||||
|
List<DeviceMappingWithRegattaLogEvent<ItemT>> newItemsToProcess) {
|
||||||
|
for (Iterator<DeviceMappingWithRegattaLogEvent<ItemT>> iterator = newItemsToProcess.iterator(); iterator
|
||||||
|
.hasNext();) {
|
||||||
|
DeviceMappingWithRegattaLogEvent<ItemT> deviceMapping = iterator.next();
|
||||||
|
if(isSame(mappingToFind, deviceMapping)) {
|
||||||
|
iterator.remove();
|
||||||
|
return deviceMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSame(DeviceMappingWithRegattaLogEvent<ItemT> mapping1,
|
||||||
|
DeviceMappingWithRegattaLogEvent<ItemT> mapping2) {
|
||||||
|
return mapping1.getDevice().equals(mapping2.getDevice()) && mapping1.getMappedTo().equals(mapping2.getMappedTo())
|
||||||
|
&& mapping1.getEventType().equals(mapping2.getEventType());
|
||||||
|
}
|
||||||
|
}
|
||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
|
import com.sap.sailing.domain.tracking.RaceListener;
|
||||||
|
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||||
|
import com.sap.sailing.server.RacingEventService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of this class is created for every {@link TrackedRegatta} by {@link RegattaLogFixTrackerRegattaListener}.
|
||||||
|
* This observes the given {@link TrackedRegatta} to get to know about every {@link TrackedRace} of the
|
||||||
|
* {@link TrackedRegatta}.
|
||||||
|
*
|
||||||
|
* An instance of {@link RaceLogFixTrackerManager} is created for every {@link TrackedRace}. It is ensured that
|
||||||
|
* {@link RaceLogFixTrackerManager} are stopped when a {@link TrackedRace} is removed from the {@link TrackedRegatta}.
|
||||||
|
*/
|
||||||
|
public class RegattaLogFixTrackerRaceListener {
|
||||||
|
private final Map<RegattaAndRaceIdentifier, DynamicTrackedRace> knownTrackedRaces = new ConcurrentHashMap<>();
|
||||||
|
private final Map<RegattaAndRaceIdentifier, RaceLogFixTrackerManager> dataTrackers = new ConcurrentHashMap<>();
|
||||||
|
private final DynamicTrackedRegatta trackedRegatta;
|
||||||
|
private final RaceListener raceListener;
|
||||||
|
private final RacingEventService racingEventService;
|
||||||
|
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||||
|
|
||||||
|
public RegattaLogFixTrackerRaceListener(final DynamicTrackedRegatta trackedRegatta, ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker,
|
||||||
|
final SensorFixMapperFactory sensorFixMapperFactory) {
|
||||||
|
this.trackedRegatta = trackedRegatta;
|
||||||
|
this.racingEventService = racingEventServiceTracker.getService();
|
||||||
|
this.sensorFixMapperFactory = sensorFixMapperFactory;
|
||||||
|
this.raceListener = new RaceListener() {
|
||||||
|
@Override
|
||||||
|
public void raceRemoved(TrackedRace trackedRace) {
|
||||||
|
RegattaLogFixTrackerRaceListener.this.raceRemoved(trackedRace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void raceAdded(TrackedRace trackedRace) {
|
||||||
|
RegattaLogFixTrackerRaceListener.this.raceAdded(trackedRace);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
trackedRegatta.addRaceListener(raceListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void raceRemoved(TrackedRace trackedRace) {
|
||||||
|
removeRaceLogSensorDataTracker(trackedRace.getRaceIdentifier());
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void raceAdded(TrackedRace trackedRace) {
|
||||||
|
if (trackedRace instanceof DynamicTrackedRace) {
|
||||||
|
DynamicTrackedRace dynamicTrackedRace = (DynamicTrackedRace) trackedRace;
|
||||||
|
RegattaAndRaceIdentifier raceIdentifier = dynamicTrackedRace.getRaceIdentifier();
|
||||||
|
DynamicTrackedRace existingRace = knownTrackedRaces.get(raceIdentifier);
|
||||||
|
if (existingRace != null) {
|
||||||
|
removeRaceLogSensorDataTracker(raceIdentifier);
|
||||||
|
}
|
||||||
|
racingEventService.getRaceTrackerByRegattaAndRaceIdentifier(raceIdentifier, (raceTracker) -> {
|
||||||
|
if (raceTracker != null) {
|
||||||
|
boolean added = raceTracker.add(new RaceTracker.Listener() {
|
||||||
|
@Override
|
||||||
|
public void onTrackerWillStop(boolean preemptive) {
|
||||||
|
raceTracker.remove(this);
|
||||||
|
removeRaceLogSensorDataTracker(raceIdentifier, preemptive);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// if !added, the RaceTracker is already stopped, so we are not allowed to start fix tracking
|
||||||
|
if (added) {
|
||||||
|
RaceLogFixTrackerManager trackerManager = new RaceLogFixTrackerManager(
|
||||||
|
(DynamicTrackedRace) trackedRace, racingEventService.getSensorFixStore(),
|
||||||
|
sensorFixMapperFactory);
|
||||||
|
RaceLogFixTrackerManager oldInstance = dataTrackers.put(raceIdentifier, trackerManager);
|
||||||
|
if (oldInstance != null) {
|
||||||
|
oldInstance.stop(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void trackerStopped(RegattaAndRaceIdentifier raceIdentifier, RaceLogFixTrackerManager trackerManager) {
|
||||||
|
dataTrackers.remove(raceIdentifier, trackerManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by {@link RegattaLogFixTrackerRegattaListener} when the {@link TrackedRegatta} was removed or the
|
||||||
|
* {@link TrackedRegatta} shouldn't be tracked anymore (this is e.g. the case in replication state.
|
||||||
|
*/
|
||||||
|
public synchronized void stop() {
|
||||||
|
trackedRegatta.removeRaceListener(raceListener);
|
||||||
|
knownTrackedRaces.keySet().forEach(this::removeRaceLogSensorDataTracker);
|
||||||
|
knownTrackedRaces.clear();
|
||||||
|
dataTrackers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRaceLogSensorDataTracker(RegattaAndRaceIdentifier raceIdentifier) {
|
||||||
|
removeRaceLogSensorDataTracker(raceIdentifier, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeRaceLogSensorDataTracker(RegattaAndRaceIdentifier raceIdentifier, boolean preemptive) {
|
||||||
|
RaceLogFixTrackerManager currentActiveDataTracker = dataTrackers.get(raceIdentifier);
|
||||||
|
if (currentActiveDataTracker != null) {
|
||||||
|
currentActiveDataTracker.stop(preemptive);
|
||||||
|
trackerStopped(raceIdentifier, currentActiveDataTracker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "RegattaLogSensorDataTracker [regattaId=" + trackedRegatta.getRegatta().getId() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+180
@@ -0,0 +1,180 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl.fixtracker;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.osgi.util.tracker.ServiceTracker;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
|
import com.sap.sailing.domain.racelogsensortracking.SensorFixMapperFactory;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackedRegattaListener;
|
||||||
|
import com.sap.sailing.server.RacingEventService;
|
||||||
|
import com.sap.sse.replication.OperationExecutionListener;
|
||||||
|
import com.sap.sse.replication.OperationWithResult;
|
||||||
|
import com.sap.sse.replication.ReplicationMasterDescriptor;
|
||||||
|
import com.sap.sse.replication.impl.OperationWithResultWithIdWrapper;
|
||||||
|
import com.sap.sse.replication.impl.ReplicableWithObjectInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the main entry point of the {@link SensorFixStore} based fix tracking.
|
||||||
|
*
|
||||||
|
* This listener is informed about every {@link TrackedRegatta} by {@link RacingEventService} via the implemented
|
||||||
|
* {@link TrackedRegattaListener}. For every known {@link TrackedRegatta}, a {@link RegattaLogFixTrackerRaceListener} is
|
||||||
|
* started.
|
||||||
|
*
|
||||||
|
* In addition this is a {@link ReplicableWithObjectInputStream} because we need to know if the current node is a
|
||||||
|
* replica. Replicas must not do any fix tracking because fixes are being loaded on the master and transferred to the
|
||||||
|
* replicas through the replication mechanism. That's why in replication state, no
|
||||||
|
* {@link RegattaLogFixTrackerRaceListener} instances are created at all.
|
||||||
|
*/
|
||||||
|
public class RegattaLogFixTrackerRegattaListener implements TrackedRegattaListener,
|
||||||
|
ReplicableWithObjectInputStream<RegattaLogFixTrackerRegattaListener, OperationWithResult<RegattaLogFixTrackerRegattaListener, ?>> {
|
||||||
|
|
||||||
|
private static final Logger log = Logger.getLogger(RegattaLogFixTrackerRegattaListener.class.getName());
|
||||||
|
|
||||||
|
private final Map<Serializable, RegattaLogFixTrackerRaceListener> registeredTrackers = new HashMap<>();
|
||||||
|
private final ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker;
|
||||||
|
private final SensorFixMapperFactory sensorFixMapperFactory;
|
||||||
|
|
||||||
|
public RegattaLogFixTrackerRegattaListener(
|
||||||
|
ServiceTracker<RacingEventService, RacingEventService> racingEventServiceTracker,
|
||||||
|
SensorFixMapperFactory sensorFixMapperFactory) {
|
||||||
|
this.racingEventServiceTracker = racingEventServiceTracker;
|
||||||
|
this.sensorFixMapperFactory = sensorFixMapperFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void regattaAdded(TrackedRegatta trackedRegatta) {
|
||||||
|
final Serializable regattaId = trackedRegatta.getRegatta().getId();
|
||||||
|
if (!isReplica()) {
|
||||||
|
RegattaLogFixTrackerRaceListener tracker = new RegattaLogFixTrackerRaceListener((DynamicTrackedRegatta)
|
||||||
|
trackedRegatta, racingEventServiceTracker, sensorFixMapperFactory);
|
||||||
|
this.stopIfNotNull(registeredTrackers.put(regattaId, tracker));
|
||||||
|
log.fine("Added sensor data tracker to tracked regatta: " + trackedRegatta.getRegatta().getName());
|
||||||
|
} else {
|
||||||
|
log.warning("Regatta already known, not adding sensor twice");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void regattaRemoved(TrackedRegatta trackedRegatta) {
|
||||||
|
final Serializable regattaId = trackedRegatta.getRegatta().getId();
|
||||||
|
try {
|
||||||
|
this.stopIfNotNull(registeredTrackers.get(regattaId));
|
||||||
|
} finally {
|
||||||
|
registeredTrackers.remove(regattaId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopIfNotNull(RegattaLogFixTrackerRaceListener tracker) {
|
||||||
|
if (tracker != null) {
|
||||||
|
try {
|
||||||
|
tracker.stop();
|
||||||
|
} catch (Exception exc) {
|
||||||
|
log.log(Level.SEVERE, "Stopping of tracker failed: " + tracker, exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replication related methods and fields
|
||||||
|
private final ConcurrentHashMap<OperationExecutionListener<RegattaLogFixTrackerRegattaListener>, OperationExecutionListener<RegattaLogFixTrackerRegattaListener>> operationExecutionListeners = new ConcurrentHashMap<>();
|
||||||
|
private final ThreadLocal<Boolean> currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster = ThreadLocal.withInitial(() -> false);
|
||||||
|
private final Set<OperationWithResultWithIdWrapper<RegattaLogFixTrackerRegattaListener, ?>> operationsSentToMasterForReplication = new HashSet<>();
|
||||||
|
private ReplicationMasterDescriptor master;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable getId() {
|
||||||
|
return getClass().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReplicationMasterDescriptor getMasterDescriptor() {
|
||||||
|
return master;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startedReplicatingFrom(ReplicationMasterDescriptor master) {
|
||||||
|
this.master = master;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stoppedReplicatingFrom(ReplicationMasterDescriptor master) {
|
||||||
|
this.master = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<OperationExecutionListener<RegattaLogFixTrackerRegattaListener>> getOperationExecutionListeners() {
|
||||||
|
return operationExecutionListeners.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addOperationExecutionListener(
|
||||||
|
OperationExecutionListener<RegattaLogFixTrackerRegattaListener> listener) {
|
||||||
|
this.operationExecutionListeners.put(listener, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeOperationExecutionListener(
|
||||||
|
OperationExecutionListener<RegattaLogFixTrackerRegattaListener> listener) {
|
||||||
|
this.operationExecutionListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCurrentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster() {
|
||||||
|
return currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster(boolean b) {
|
||||||
|
this.currentlyFillingFromInitialLoadOrApplyingOperationReceivedFromMaster.set(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addOperationSentToMasterForReplication(
|
||||||
|
OperationWithResultWithIdWrapper<RegattaLogFixTrackerRegattaListener, ?> operationWithResultWithIdWrapper) {
|
||||||
|
this.operationsSentToMasterForReplication.add(operationWithResultWithIdWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSentOperationToMaster(
|
||||||
|
OperationWithResult<RegattaLogFixTrackerRegattaListener, ?> operation) {
|
||||||
|
return operationsSentToMasterForReplication.remove(operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectInputStream createObjectInputStreamResolvingAgainstCache(InputStream is) throws IOException {
|
||||||
|
return new ObjectInputStream(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void initiallyFillFromInternal(ObjectInputStream is)
|
||||||
|
throws IOException, ClassNotFoundException, InterruptedException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serializeForInitialReplicationInternal(ObjectOutputStream objectOutputStream) throws IOException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void clearReplicaState() throws MalformedURLException, IOException, InterruptedException {
|
||||||
|
this.registeredTrackers.values().forEach(this::stopIfNotNull);
|
||||||
|
this.registeredTrackers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isReplica() {
|
||||||
|
return master != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
+46
-46
@@ -8,8 +8,6 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
@@ -22,10 +20,12 @@ import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
|||||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||||
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
||||||
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||||
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||||
@@ -33,7 +33,7 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
|
|
||||||
private int time = 0;
|
private int time = 0;
|
||||||
|
|
||||||
private List<DeviceMapping<Competitor>> getMappings() {
|
private List<DeviceMappingWithRegattaLogEvent<Competitor>> getMappings() {
|
||||||
return new RegattaLogDeviceCompetitorMappingFinder(log).analyze().get(competitor);
|
return new RegattaLogDeviceCompetitorMappingFinder(log).analyze().get(competitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,24 +66,24 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
||||||
addMapping(author, device, 100l, 200l, competitor);
|
addMapping(author, device, 100l, 200l, competitor);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(150));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(150));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(2, deviceMappings.size());
|
assertEquals(2, deviceMappings.size());
|
||||||
boolean found100 = false;
|
boolean found100 = false;
|
||||||
for (final DeviceMapping<Competitor> mapping : deviceMappings) {
|
for (final DeviceMappingWithRegattaLogEvent<Competitor> mapping : deviceMappings) {
|
||||||
if (mapping.getTimeRange().from().asMillis() == 100) {
|
if (mapping.getTimeRange().from().asMillis() == 100) {
|
||||||
found100 = true;
|
found100 = true;
|
||||||
assertEquals(149, mapping.getTimeRange().to().asMillis());
|
assertEquals(149, mapping.getTimeRange().to().asMillis());
|
||||||
@@ -102,23 +102,23 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
||||||
closeMapping(author, device, mappingId, 200);
|
closeMapping(author, device, mappingId, 200);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(150));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(150));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(2, deviceMappings.size());
|
assertEquals(2, deviceMappings.size());
|
||||||
for (final DeviceMapping<Competitor> mapping : deviceMappings) {
|
for (final DeviceMappingWithRegattaLogEvent<Competitor> mapping : deviceMappings) {
|
||||||
if (mapping.getTimeRange().from().asMillis() == 100) {
|
if (mapping.getTimeRange().from().asMillis() == 100) {
|
||||||
assertEquals(149, mapping.getTimeRange().to().asMillis());
|
assertEquals(149, mapping.getTimeRange().to().asMillis());
|
||||||
} else {
|
} else {
|
||||||
@@ -134,21 +134,21 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
||||||
addMapping(author, device, 100l, 200l, competitor);
|
addMapping(author, device, 100l, 200l, competitor);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
assertEquals(101, deviceMappings.get(0).getTimeRange().from().asMillis());
|
assertEquals(101, deviceMappings.get(0).getTimeRange().from().asMillis());
|
||||||
assertEquals(200, deviceMappings.get(0).getTimeRange().to().asMillis());
|
assertEquals(200, deviceMappings.get(0).getTimeRange().to().asMillis());
|
||||||
@@ -161,21 +161,21 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
||||||
closeMapping(author, device, mappingId, 200);
|
closeMapping(author, device, mappingId, 200);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
assertEquals(101, deviceMappings.get(0).getTimeRange().from().asMillis());
|
assertEquals(101, deviceMappings.get(0).getTimeRange().from().asMillis());
|
||||||
assertEquals(200, deviceMappings.get(0).getTimeRange().to().asMillis());
|
assertEquals(200, deviceMappings.get(0).getTimeRange().to().asMillis());
|
||||||
@@ -187,21 +187,21 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
||||||
addMapping(author, device, 100l, 200l, competitor);
|
addMapping(author, device, 100l, 200l, competitor);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(200));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(200));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
assertEquals(100, deviceMappings.get(0).getTimeRange().from().asMillis());
|
assertEquals(100, deviceMappings.get(0).getTimeRange().from().asMillis());
|
||||||
assertEquals(199, deviceMappings.get(0).getTimeRange().to().asMillis());
|
assertEquals(199, deviceMappings.get(0).getTimeRange().to().asMillis());
|
||||||
@@ -214,21 +214,21 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
||||||
closeMapping(author, device, mappingId, 200);
|
closeMapping(author, device, mappingId, 200);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(200), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(200));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(200));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
assertEquals(100, deviceMappings.get(0).getTimeRange().from().asMillis());
|
assertEquals(100, deviceMappings.get(0).getTimeRange().from().asMillis());
|
||||||
assertEquals(199, deviceMappings.get(0).getTimeRange().to().asMillis());
|
assertEquals(199, deviceMappings.get(0).getTimeRange().to().asMillis());
|
||||||
@@ -240,18 +240,18 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
final RegattaLogDeviceCompetitorMappingFinder finder = new RegattaLogDeviceCompetitorMappingFinder(log);
|
||||||
addMapping(author, device, 100l, 100l, competitor);
|
addMapping(author, device, 100l, 100l, competitor);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertTrue(mappings.isEmpty());
|
assertTrue(mappings.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,18 +262,18 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
final Serializable mappingId = addMapping(author, device, 100l, null, competitor);
|
||||||
closeMapping(author, device, mappingId, 100);
|
closeMapping(author, device, mappingId, 100);
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
assertTrue(mappings.containsKey(competitor));
|
assertTrue(mappings.containsKey(competitor));
|
||||||
final List<DeviceMapping<Competitor>> deviceMappings = mappings.get(competitor);
|
final List<DeviceMappingWithRegattaLogEvent<Competitor>> deviceMappings = mappings.get(competitor);
|
||||||
assertEquals(1, deviceMappings.size());
|
assertEquals(1, deviceMappings.size());
|
||||||
final DeviceMapping<Competitor> mapping = deviceMappings.iterator().next();
|
final DeviceMappingWithRegattaLogEvent<Competitor> mapping = deviceMappings.iterator().next();
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().from());
|
||||||
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().to());
|
assertEquals(new MillisecondsTimePoint(100), mapping.getTimeRange().to());
|
||||||
}
|
}
|
||||||
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
finder.removeTimePointFromMapping(competitor, new MillisecondsTimePoint(100));
|
||||||
{
|
{
|
||||||
final Map<Competitor, List<DeviceMapping<Competitor>>> mappings = finder.analyze();
|
final Map<Competitor, List<DeviceMappingWithRegattaLogEvent<Competitor>>> mappings = finder.analyze();
|
||||||
assertTrue(mappings.isEmpty());
|
assertTrue(mappings.isEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,9 +297,9 @@ public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
|||||||
//close one range
|
//close one range
|
||||||
Serializable id = addMapping(author, device, 10L, null, competitor);
|
Serializable id = addMapping(author, device, 10L, null, competitor);
|
||||||
closeMapping(author, device, id, 20);
|
closeMapping(author, device, id, 20);
|
||||||
List<DeviceMapping<Competitor>> mappings = getMappings();
|
List<DeviceMappingWithRegattaLogEvent<Competitor>> mappings = getMappings();
|
||||||
assertEquals(1, mappings.size());
|
assertEquals(1, mappings.size());
|
||||||
DeviceMapping<Competitor> mapping = mappings.get(0);
|
DeviceMappingWithRegattaLogEvent<Competitor> mapping = mappings.get(0);
|
||||||
assertEquals(10, mapping.getTimeRange().from().asMillis());
|
assertEquals(10, mapping.getTimeRange().from().asMillis());
|
||||||
assertEquals(20, mapping.getTimeRange().to().asMillis());
|
assertEquals(20, mapping.getTimeRange().to().asMillis());
|
||||||
|
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.regatta;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to dynamically dispatch calls for {@link RegattaLogDeviceMappingEvent}s depending on the concrete type.
|
||||||
|
*/
|
||||||
|
public interface MappingEventVisitor {
|
||||||
|
|
||||||
|
void visit(RegattaLogDeviceMarkMappingEvent event);
|
||||||
|
|
||||||
|
void visit(RegattaLogDeviceCompetitorMappingEvent event);
|
||||||
|
|
||||||
|
void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event);
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.abstractlog.regatta;
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||||
@@ -16,6 +17,8 @@ public interface RegattaLogEventVisitor {
|
|||||||
|
|
||||||
void visit(RegattaLogDeviceCompetitorMappingEvent event);
|
void visit(RegattaLogDeviceCompetitorMappingEvent event);
|
||||||
|
|
||||||
|
void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event);
|
||||||
|
|
||||||
void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event);
|
void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event);
|
||||||
|
|
||||||
void visit(RegattaLogRegisterCompetitorEvent event);
|
void visit(RegattaLogRegisterCompetitorEvent event);
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.regatta.events;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
|
||||||
|
public interface RegattaLogDeviceCompetitorSensorDataMappingEvent extends RegattaLogDeviceMappingEvent<Competitor> {
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -1,6 +1,7 @@
|
|||||||
package com.sap.sailing.domain.abstractlog.regatta.events;
|
package com.sap.sailing.domain.abstractlog.regatta.events;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.Revokable;
|
import com.sap.sailing.domain.abstractlog.Revokable;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDefinedMarkAnalyzer;
|
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDefinedMarkAnalyzer;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
@@ -37,4 +38,11 @@ public interface RegattaLogDeviceMappingEvent<ItemType extends WithID> extends R
|
|||||||
* In that case the device should be mapped to the item for any timepoint after that specified by {@link #getFrom()}.
|
* In that case the device should be mapped to the item for any timepoint after that specified by {@link #getFrom()}.
|
||||||
*/
|
*/
|
||||||
TimePoint getTo();
|
TimePoint getTo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visitor patter implementation for event mapping handling differentiation.
|
||||||
|
*
|
||||||
|
* @param visitor
|
||||||
|
*/
|
||||||
|
void accept(MappingEventVisitor visitor);
|
||||||
}
|
}
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping event for devices mapped for Bravo type fixes.
|
||||||
|
*/
|
||||||
|
public class RegattaLogDeviceCompetitorBravoMappingEventImpl extends RegattaLogDeviceMappingEventImpl<Competitor>
|
||||||
|
implements RegattaLogDeviceCompetitorSensorDataMappingEvent {
|
||||||
|
private static final long serialVersionUID = -1494030544804758753L;
|
||||||
|
|
||||||
|
|
||||||
|
public RegattaLogDeviceCompetitorBravoMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||||
|
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
||||||
|
TimePoint from, TimePoint to) {
|
||||||
|
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegattaLogDeviceCompetitorBravoMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||||
|
Competitor mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
|
||||||
|
super(logicalTimePoint, author, mappedTo, device, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(RegattaLogEventVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(MappingEventVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
||||||
@@ -29,4 +30,9 @@ public class RegattaLogDeviceCompetitorMappingEventImpl extends RegattaLogDevice
|
|||||||
public void accept(RegattaLogEventVisitor visitor) {
|
public void accept(RegattaLogEventVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(MappingEventVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
@@ -29,4 +30,9 @@ public class RegattaLogDeviceMarkMappingEventImpl extends RegattaLogDeviceMappin
|
|||||||
public void accept(RegattaLogEventVisitor visitor) {
|
public void accept(RegattaLogEventVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(MappingEventVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+5
@@ -4,6 +4,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||||
@@ -24,6 +25,10 @@ public class BaseRegattaLogEventVisitor implements RegattaLogEventVisitor {
|
|||||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||||
@@ -48,9 +49,14 @@ public abstract class RegattaLogEventListener implements RegattaLogEventVisitor
|
|||||||
public void visit(RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent event) {
|
public void visit(RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent event) {
|
||||||
eventAdded(event);
|
eventAdded(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RegattaLogDefineMarkEvent event) {
|
public void visit(RegattaLogDefineMarkEvent event) {
|
||||||
eventAdded(event);
|
eventAdded(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||||
|
eventAdded(event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||||
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
|
import com.sap.sse.common.WithID;
|
||||||
|
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the {@link DeviceMapping}s with the appropriate {@link TimeRange}s from the {@link RaceLog}.
|
||||||
|
* Based on the {@link RegattaLogDeviceMappingEvent}s found in the {@code RaceLog} for the tracked {@code items}
|
||||||
|
* ({@code Competitor}s and {@code Marks}), the actual mappings are created.
|
||||||
|
* <p>
|
||||||
|
* Mappings can be defined with an open-ended time range (e.g. track this from now on), which should then be
|
||||||
|
* closed by a corresponding {@link RegattaLogCloseOpenEndedDeviceMappingEvent}.
|
||||||
|
* <p>
|
||||||
|
* The process of removing conflicts between mappings to ensure that only one mapping was active for
|
||||||
|
* one tracked item has been removed. Instead, every {@code DeviceMappingEvent} now results directly in one
|
||||||
|
* {@code DeviceMapping}, the only changes being introduced by closing open time ranges in cases where an
|
||||||
|
* according {@code CloseOpenEndedDeviceMappingEvent} exists.
|
||||||
|
*/
|
||||||
|
public abstract class BaseRegattaLogDeviceMappingFinder<ItemT extends WithID>
|
||||||
|
extends RegattaLogDeviceMappingFinder<ItemT> {
|
||||||
|
|
||||||
|
public BaseRegattaLogDeviceMappingFinder(RegattaLog log) {
|
||||||
|
super(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By revoking existing mappings for {@code item} and replacing them by mappings that exclude {@code fixTimePoint},
|
||||||
|
* any fix at {@code fixTimePoint} will no longer be linked to {@code item}. If a mapping is limited to the exact
|
||||||
|
* fix time point, the mapping is only revoked and not replaced. If one boundary is exactly the fix time point, the
|
||||||
|
* interval is revoked and replaced by a single interval with that border adjusted so it excludes the fix.
|
||||||
|
*/
|
||||||
|
public void removeTimePointFromMapping(ItemT item, TimePoint fixTimePoint) throws NotRevokableException {
|
||||||
|
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
|
||||||
|
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
|
||||||
|
findUnrevokedMappingAndClosingEvents(events, closingEvents);
|
||||||
|
for (final RegattaLogDeviceMappingEvent<ItemT> event : events.get(item)) {
|
||||||
|
final TimePoint from = event.getFrom();
|
||||||
|
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
|
||||||
|
final TimePoint to = closingEvent != null ? closingEvent.getClosingTimePoint() : event.getTo();
|
||||||
|
final TimeRange mappingTimeRange = new TimeRangeImpl(from, to);
|
||||||
|
if (mappingTimeRange.includes(fixTimePoint)) {
|
||||||
|
if (closingEvent != null) {
|
||||||
|
log.revokeEvent(closingEvent.getAuthor(), closingEvent,
|
||||||
|
"removing single time point " + fixTimePoint + " from mapping for " + item);
|
||||||
|
}
|
||||||
|
log.revokeEvent(event.getAuthor(), event,
|
||||||
|
"removing single time point " + fixTimePoint + " from mapping for " + item);
|
||||||
|
final TimePoint endOfFirstHalf = fixTimePoint.minus(1);
|
||||||
|
final TimePoint startOfSecondHalf = fixTimePoint.plus(1);
|
||||||
|
if (!endOfFirstHalf.before(from)) {
|
||||||
|
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
|
||||||
|
}
|
||||||
|
if (!to.before(startOfSecondHalf)) {
|
||||||
|
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, to,
|
||||||
|
event.getDevice()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item,
|
||||||
|
AbstractLogEventAuthor author, TimePoint plus, TimePoint to, DeviceIdentifier deviceId);
|
||||||
|
|
||||||
|
}
|
||||||
+1
-1
@@ -12,7 +12,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
|||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
public class RegattaLogDeviceCompetitorMappingFinder extends RegattaLogDeviceMappingFinder<Competitor> {
|
public class RegattaLogDeviceCompetitorMappingFinder extends BaseRegattaLogDeviceMappingFinder<Competitor> {
|
||||||
|
|
||||||
public RegattaLogDeviceCompetitorMappingFinder(RegattaLog log) {
|
public RegattaLogDeviceCompetitorMappingFinder(RegattaLog log) {
|
||||||
super(log);
|
super(log);
|
||||||
|
|||||||
+17
-49
@@ -8,16 +8,15 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
|
||||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
|
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingWithRegattaLogEventImpl;
|
||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.TimeRange;
|
import com.sap.sse.common.TimeRange;
|
||||||
import com.sap.sse.common.WithID;
|
import com.sap.sse.common.WithID;
|
||||||
@@ -36,7 +35,8 @@ import com.sap.sse.common.impl.TimeRangeImpl;
|
|||||||
* {@code DeviceMapping}, the only changes being introduced by closing open time ranges in cases where an
|
* {@code DeviceMapping}, the only changes being introduced by closing open time ranges in cases where an
|
||||||
* according {@code CloseOpenEndedDeviceMappingEvent} exists.
|
* according {@code CloseOpenEndedDeviceMappingEvent} exists.
|
||||||
*/
|
*/
|
||||||
public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extends RegattaLogAnalyzer<Map<ItemT, List<DeviceMapping<ItemT>>>> {
|
public class RegattaLogDeviceMappingFinder<ItemT extends WithID>
|
||||||
|
extends RegattaLogAnalyzer<Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>>> {
|
||||||
private static Logger logger = Logger.getLogger(RegattaLogDeviceMappingFinder.class.getName());
|
private static Logger logger = Logger.getLogger(RegattaLogDeviceMappingFinder.class.getName());
|
||||||
|
|
||||||
public RegattaLogDeviceMappingFinder(RegattaLog log) {
|
public RegattaLogDeviceMappingFinder(RegattaLog log) {
|
||||||
@@ -47,10 +47,10 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
|
|||||||
return mapping instanceof RegattaLogDeviceMappingEvent;
|
return mapping instanceof RegattaLogDeviceMappingEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DeviceMapping<ItemT> createMapping(DeviceIdentifier device, ItemT item,
|
protected DeviceMappingWithRegattaLogEvent<ItemT> createMapping(DeviceIdentifier device, ItemT item,
|
||||||
TimePoint from, TimePoint to, Serializable originalEventId) {
|
TimePoint from, TimePoint to, Serializable originalEventId, RegattaLogDeviceMappingEvent<ItemT> event) {
|
||||||
return new DeviceMappingImpl<ItemT>(item, device, new TimeRangeImpl(from, to),
|
return new DeviceMappingWithRegattaLogEventImpl<ItemT>(item, device, new TimeRangeImpl(from, to),
|
||||||
Collections.singletonList(originalEventId));
|
Collections.singletonList(originalEventId), event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RegattaLogDeviceMappingEvent<ItemT>> getMappingEventsForItem(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> map, ItemT item) {
|
private List<RegattaLogDeviceMappingEvent<ItemT>> getMappingEventsForItem(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> map, ItemT item) {
|
||||||
@@ -63,18 +63,18 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<ItemT, List<DeviceMapping<ItemT>>> performAnalysis() {
|
protected Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> performAnalysis() {
|
||||||
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
|
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<>();
|
||||||
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
|
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<>();
|
||||||
findUnrevokedMappingAndClosingEvents(events, closingEvents);
|
findUnrevokedMappingAndClosingEvents(events, closingEvents);
|
||||||
Map<ItemT, List<DeviceMapping<ItemT>>> mappings = new HashMap<ItemT, List<DeviceMapping<ItemT>>>();
|
Map<ItemT, List<DeviceMappingWithRegattaLogEvent<ItemT>>> mappings = new HashMap<>();
|
||||||
for (ItemT item : events.keySet()) {
|
for (ItemT item : events.keySet()) {
|
||||||
mappings.put(item, closeOpenRanges(events.get(item), item, closingEvents));
|
mappings.put(item, closeOpenRanges(events.get(item), item, closingEvents));
|
||||||
}
|
}
|
||||||
return mappings;
|
return mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findUnrevokedMappingAndClosingEvents(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events,
|
protected void findUnrevokedMappingAndClosingEvents(Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events,
|
||||||
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents) {
|
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents) {
|
||||||
for (RegattaLogEvent e : getLog().getUnrevokedEvents()) {
|
for (RegattaLogEvent e : getLog().getUnrevokedEvents()) {
|
||||||
if (e instanceof RegattaLogDeviceMappingEvent && isValidMapping(((RegattaLogDeviceMappingEvent<?>) e))) {
|
if (e instanceof RegattaLogDeviceMappingEvent && isValidMapping(((RegattaLogDeviceMappingEvent<?>) e))) {
|
||||||
@@ -89,9 +89,10 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<DeviceMapping<ItemT>> closeOpenRanges(List<RegattaLogDeviceMappingEvent<ItemT>> events, ItemT item,
|
private List<DeviceMappingWithRegattaLogEvent<ItemT>> closeOpenRanges(
|
||||||
|
List<RegattaLogDeviceMappingEvent<ItemT>> events, ItemT item,
|
||||||
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents) {
|
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents) {
|
||||||
List<DeviceMapping<ItemT>> result = new ArrayList<DeviceMapping<ItemT>>();
|
List<DeviceMappingWithRegattaLogEvent<ItemT>> result = new ArrayList<>();
|
||||||
for (final RegattaLogDeviceMappingEvent<ItemT> event : events) {
|
for (final RegattaLogDeviceMappingEvent<ItemT> event : events) {
|
||||||
TimePoint from = event.getFrom();
|
TimePoint from = event.getFrom();
|
||||||
TimePoint to = event.getTo();
|
TimePoint to = event.getTo();
|
||||||
@@ -103,42 +104,9 @@ public abstract class RegattaLogDeviceMappingFinder<ItemT extends WithID> extend
|
|||||||
if (to == null) {
|
if (to == null) {
|
||||||
to = closingTimePoint;
|
to = closingTimePoint;
|
||||||
}
|
}
|
||||||
result.add(createMapping(event.getDevice(), item, from, to, event.getId()));
|
result.add(createMapping(event.getDevice(), item, from, to, event.getId(), event));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* By revoking existing mappings for {@code item} and replacing them by mappings that exclude {@code fixTimePoint}, any
|
|
||||||
* fix at {@code fixTimePoint} will no longer be linked to {@code item}. If a mapping is limited to the exact fix time point,
|
|
||||||
* the mapping is only revoked and not replaced. If one boundary is exactly the fix time point, the interval is revoked and
|
|
||||||
* replaced by a single interval with that border adjusted so it excludes the fix.
|
|
||||||
*/
|
|
||||||
public void removeTimePointFromMapping(ItemT item, TimePoint fixTimePoint) throws NotRevokableException {
|
|
||||||
Map<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>> events = new HashMap<ItemT, List<RegattaLogDeviceMappingEvent<ItemT>>>();
|
|
||||||
Map<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent> closingEvents = new HashMap<Serializable, RegattaLogCloseOpenEndedDeviceMappingEvent>();
|
|
||||||
findUnrevokedMappingAndClosingEvents(events, closingEvents);
|
|
||||||
for (final RegattaLogDeviceMappingEvent<ItemT> event : events.get(item)) {
|
|
||||||
final TimePoint from = event.getFrom();
|
|
||||||
final RegattaLogCloseOpenEndedDeviceMappingEvent closingEvent = closingEvents.get(event.getId());
|
|
||||||
final TimePoint to = closingEvent!= null ? closingEvent.getClosingTimePoint() : event.getTo();
|
|
||||||
final TimeRange mappingTimeRange = new TimeRangeImpl(from, to);
|
|
||||||
if (mappingTimeRange.includes(fixTimePoint)) {
|
|
||||||
if (closingEvent != null) {
|
|
||||||
log.revokeEvent(closingEvent.getAuthor(), closingEvent, "removing single time point "+fixTimePoint+" from mapping for "+item);
|
|
||||||
}
|
|
||||||
log.revokeEvent(event.getAuthor(), event, "removing single time point "+fixTimePoint+" from mapping for "+item);
|
|
||||||
final TimePoint endOfFirstHalf = fixTimePoint.minus(1);
|
|
||||||
final TimePoint startOfSecondHalf = fixTimePoint.plus(1);
|
|
||||||
if (!endOfFirstHalf.before(from)) {
|
|
||||||
log.add(createDeviceMappingEvent(item, event.getAuthor(), from, endOfFirstHalf, event.getDevice()));
|
|
||||||
}
|
|
||||||
if (!to.before(startOfSecondHalf)) {
|
|
||||||
log.add(createDeviceMappingEvent(item, event.getAuthor(), startOfSecondHalf, to, event.getDevice()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract RegattaLogDeviceMappingEvent<ItemT> createDeviceMappingEvent(ItemT item, AbstractLogEventAuthor author, TimePoint plus, TimePoint to, DeviceIdentifier deviceId);
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -12,7 +12,7 @@ import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
|||||||
import com.sap.sse.common.TimePoint;
|
import com.sap.sse.common.TimePoint;
|
||||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||||
|
|
||||||
public class RegattaLogDeviceMarkMappingFinder extends RegattaLogDeviceMappingFinder<Mark> {
|
public class RegattaLogDeviceMarkMappingFinder extends BaseRegattaLogDeviceMappingFinder<Mark> {
|
||||||
|
|
||||||
public RegattaLogDeviceMarkMappingFinder(RegattaLog log) {
|
public RegattaLogDeviceMarkMappingFinder(RegattaLog log) {
|
||||||
super(log);
|
super(log);
|
||||||
|
|||||||
+3
@@ -25,4 +25,7 @@ public interface DeviceMapping<ItemType extends WithID> extends Timed {
|
|||||||
DeviceIdentifier getDevice();
|
DeviceIdentifier getDevice();
|
||||||
|
|
||||||
TimeRange getTimeRange();
|
TimeRange getTimeRange();
|
||||||
|
|
||||||
|
Class<?> getEventType();
|
||||||
|
|
||||||
}
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMappingFinder;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
|
import com.sap.sse.common.WithID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see RegattaLogDeviceMappingFinder {@code DeviceMappings} are derived from {@code DeviceMappingEvents}. The
|
||||||
|
* {@link Timed} interface is to be implemented as providing the {@link TimeRange#from()} time point as the answer
|
||||||
|
* to {@link Timed#getTimePoint()}.
|
||||||
|
*
|
||||||
|
* This instance provides access to the originating event.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface DeviceMappingWithRegattaLogEvent<ItemType extends WithID> extends DeviceMapping<ItemType> {
|
||||||
|
|
||||||
|
RegattaLogDeviceMappingEvent<ItemType> getRegattaLogEvent();
|
||||||
|
}
|
||||||
+16
-7
@@ -19,20 +19,24 @@ public class DeviceMappingImpl<ItemType extends WithID> implements DeviceMapping
|
|||||||
private final DeviceIdentifier device;
|
private final DeviceIdentifier device;
|
||||||
private final TimeRange timeRange;
|
private final TimeRange timeRange;
|
||||||
private final List<Serializable> originalRaceLogEventIds = new ArrayList<Serializable>();
|
private final List<Serializable> originalRaceLogEventIds = new ArrayList<Serializable>();
|
||||||
|
private final Class<?> eventType;
|
||||||
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange) {
|
|
||||||
|
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange, Class<?> eventType) {
|
||||||
this.mappedTo = mappedTo;
|
this.mappedTo = mappedTo;
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.timeRange = timeRange;
|
this.timeRange = timeRange;
|
||||||
|
this.eventType = eventType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange, Serializable originalRaceLogEventId) {
|
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange,
|
||||||
this(mappedTo, device, timeRange);
|
Serializable originalRaceLogEventId, Class<?> eventType) {
|
||||||
|
this(mappedTo, device, timeRange, eventType);
|
||||||
if (originalRaceLogEventId != null) originalRaceLogEventIds.add(originalRaceLogEventId);
|
if (originalRaceLogEventId != null) originalRaceLogEventIds.add(originalRaceLogEventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange, List<? extends Serializable> originalRaceLogEventIds) {
|
public DeviceMappingImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange,
|
||||||
this(mappedTo, device, timeRange);
|
List<? extends Serializable> originalRaceLogEventIds, Class<?> eventType) {
|
||||||
|
this(mappedTo, device, timeRange, eventType);
|
||||||
if (originalRaceLogEventIds != null) this.originalRaceLogEventIds.addAll(originalRaceLogEventIds);
|
if (originalRaceLogEventIds != null) this.originalRaceLogEventIds.addAll(originalRaceLogEventIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,9 +60,14 @@ public class DeviceMappingImpl<ItemType extends WithID> implements DeviceMapping
|
|||||||
return timeRange.from();
|
return timeRange.from();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T extends WithID> DeviceMapping<T> convertToDeviceMapping(RegattaLogDeviceMappingEvent<T> event) {
|
public static <T extends WithID> DeviceMapping<T> convertToDeviceMapping(RegattaLogDeviceMappingEvent<T> event) {
|
||||||
return new DeviceMappingImpl<T>(event.getMappedTo(), event.getDevice(), new TimeRangeImpl(event.getFrom(), event.getTo()),
|
return new DeviceMappingImpl<T>(event.getMappedTo(), event.getDevice(), new TimeRangeImpl(event.getFrom(), event.getTo()),
|
||||||
event.getId());
|
event.getId(), event.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package com.sap.sailing.domain.racelogtracking.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
|
import com.sap.sse.common.WithID;
|
||||||
|
|
||||||
|
public class DeviceMappingWithRegattaLogEventImpl<ItemType extends WithID> extends DeviceMappingImpl<ItemType>
|
||||||
|
implements DeviceMappingWithRegattaLogEvent<ItemType> {
|
||||||
|
private static final long serialVersionUID = 1495968054831506408L;
|
||||||
|
private final RegattaLogDeviceMappingEvent<ItemType> event;
|
||||||
|
|
||||||
|
public DeviceMappingWithRegattaLogEventImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange,
|
||||||
|
RegattaLogDeviceMappingEvent<ItemType> event) {
|
||||||
|
super(mappedTo, device, timeRange, event.getClass());
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceMappingWithRegattaLogEventImpl(ItemType mappedTo, DeviceIdentifier device, TimeRange timeRange,
|
||||||
|
List<Serializable> originalRaceLogEventIds, RegattaLogDeviceMappingEvent<ItemType> event) {
|
||||||
|
super(mappedTo, device, timeRange, originalRaceLogEventIds, event.getClass());
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RegattaLogDeviceMappingEvent<ItemType> getRegattaLogEvent() {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-3
@@ -8,7 +8,6 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
|||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingFactoryImpl;
|
import com.sap.sailing.domain.swisstimingadapter.impl.SwissTimingFactoryImpl;
|
||||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||||
@@ -53,14 +52,14 @@ public interface SwissTimingFactory {
|
|||||||
|
|
||||||
SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription,
|
SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription,
|
||||||
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
||||||
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore,
|
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
|
||||||
boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory,
|
boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws InterruptedException, UnknownHostException,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws InterruptedException, UnknownHostException,
|
||||||
IOException, ParseException;
|
IOException, ParseException;
|
||||||
|
|
||||||
RaceTracker createRaceTracker(Regatta regatta, String raceID, String raceName, String raceDescription,
|
RaceTracker createRaceTracker(Regatta regatta, String raceID, String raceName, String raceDescription,
|
||||||
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, boolean useInternalMarkPassingAlgorithm,
|
WindStore windStore, boolean useInternalMarkPassingAlgorithm,
|
||||||
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws UnknownHostException,
|
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws UnknownHostException,
|
||||||
InterruptedException, IOException, ParseException;
|
InterruptedException, IOException, ParseException;
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -11,7 +11,6 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
|||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.Race;
|
import com.sap.sailing.domain.swisstimingadapter.Race;
|
||||||
@@ -91,23 +90,24 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
|
|||||||
@Override
|
@Override
|
||||||
public SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription,
|
public SwissTimingRaceTracker createRaceTracker(String raceID, String raceName, String raceDescription,
|
||||||
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
||||||
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore,
|
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
|
||||||
boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory,
|
boolean useInternalMarkPassingAlgorithm, DomainFactory domainFactory,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||||
throws InterruptedException, UnknownHostException, IOException, ParseException {
|
throws InterruptedException, UnknownHostException, IOException, ParseException {
|
||||||
return new SwissTimingRaceTrackerImpl(raceID, raceName, raceDescription, boatClass, hostname, port, startList,
|
return new SwissTimingRaceTrackerImpl(raceID, raceName, raceDescription, boatClass, hostname, port, startList,
|
||||||
raceLogStore, regattaLogStore, windStore, gpsFixStore, domainFactory, this,
|
raceLogStore, regattaLogStore, windStore, domainFactory, this,
|
||||||
trackedRegattaRegistry, raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm);
|
trackedRegattaRegistry, raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(Regatta regatta, String raceID, String raceName, String raceDescription,
|
public RaceTracker createRaceTracker(Regatta regatta, String raceID, String raceName, String raceDescription,
|
||||||
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
BoatClass boatClass, String hostname, int port, StartList startList, long delayToLiveInMillis,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, boolean useInternalMarkPassingAlgorithm,
|
WindStore windStore, boolean useInternalMarkPassingAlgorithm,
|
||||||
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
DomainFactory domainFactory, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||||
throws UnknownHostException, InterruptedException, IOException, ParseException {
|
throws UnknownHostException, InterruptedException, IOException, ParseException {
|
||||||
return new SwissTimingRaceTrackerImpl(regatta, raceID, raceName, raceDescription, boatClass, hostname, port,
|
return new SwissTimingRaceTrackerImpl(regatta, raceID, raceName, raceDescription, boatClass, hostname, port,
|
||||||
startList, windStore, gpsFixStore, domainFactory, this, trackedRegattaRegistry, raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm);
|
startList, windStore, domainFactory, this, trackedRegattaRegistry, raceLogResolver, delayToLiveInMillis,
|
||||||
|
useInternalMarkPassingAlgorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+13
-16
@@ -36,7 +36,6 @@ import com.sap.sailing.domain.common.impl.WindImpl;
|
|||||||
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
|
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.Course;
|
import com.sap.sailing.domain.swisstimingadapter.Course;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
||||||
@@ -60,6 +59,7 @@ import com.sap.sailing.domain.tracking.RaceTracker;
|
|||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
import com.sap.sailing.domain.tracking.WindStore;
|
import com.sap.sailing.domain.tracking.WindStore;
|
||||||
import com.sap.sailing.domain.tracking.WindTrack;
|
import com.sap.sailing.domain.tracking.WindTrack;
|
||||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
||||||
@@ -69,7 +69,8 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
|||||||
|
|
||||||
import difflib.PatchFailedException;
|
import difflib.PatchFailedException;
|
||||||
|
|
||||||
public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implements SwissTimingRaceTracker, SailMasterListener {
|
public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||||
|
implements SwissTimingRaceTracker, SailMasterListener, TrackingDataLoader {
|
||||||
private static final Logger logger = Logger.getLogger(SwissTimingRaceTrackerImpl.class.getName());
|
private static final Logger logger = Logger.getLogger(SwissTimingRaceTrackerImpl.class.getName());
|
||||||
|
|
||||||
private final SailMasterConnector connector;
|
private final SailMasterConnector connector;
|
||||||
@@ -81,7 +82,6 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
private final com.sap.sse.common.Util.Triple<String, String, Integer> id;
|
private final com.sap.sse.common.Util.Triple<String, String, Integer> id;
|
||||||
private final Regatta regatta;
|
private final Regatta regatta;
|
||||||
private final WindStore windStore;
|
private final WindStore windStore;
|
||||||
private final GPSFixStore gpsFixStore;
|
|
||||||
private final boolean startListFromManage2Sail;
|
private final boolean startListFromManage2Sail;
|
||||||
private final boolean useInternalMarkPassingAlgorithm;
|
private final boolean useInternalMarkPassingAlgorithm;
|
||||||
|
|
||||||
@@ -111,18 +111,19 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
|
|
||||||
protected SwissTimingRaceTrackerImpl(String raceID, String raceName, String raceDescription, BoatClass boatClass,
|
protected SwissTimingRaceTrackerImpl(String raceID, String raceName, String raceDescription, BoatClass boatClass,
|
||||||
String hostname, int port, StartList startList, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
String hostname, int port, StartList startList, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, DomainFactory domainFactory, SwissTimingFactory factory,
|
WindStore windStore, DomainFactory domainFactory, SwissTimingFactory factory,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, long delayToLiveInMillis, boolean useInternalMarkPassingAlgorithm) throws InterruptedException,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver, long delayToLiveInMillis, boolean useInternalMarkPassingAlgorithm) throws InterruptedException,
|
||||||
UnknownHostException, IOException, ParseException {
|
UnknownHostException, IOException, ParseException {
|
||||||
this(domainFactory.getOrCreateDefaultRegatta(raceLogStore, regattaLogStore, raceID,
|
this(domainFactory.getOrCreateDefaultRegatta(raceLogStore, regattaLogStore, raceID,
|
||||||
boatClass, trackedRegattaRegistry), raceID, raceName,
|
boatClass, trackedRegattaRegistry), raceID, raceName,
|
||||||
raceDescription, boatClass, hostname, port, startList, windStore, gpsFixStore, domainFactory, factory, trackedRegattaRegistry,
|
raceDescription, boatClass, hostname, port, startList, windStore, domainFactory, factory,
|
||||||
|
trackedRegattaRegistry,
|
||||||
raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm);
|
raceLogResolver, delayToLiveInMillis, useInternalMarkPassingAlgorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SwissTimingRaceTrackerImpl(Regatta regatta, String raceID, String raceName, String raceDescription,
|
protected SwissTimingRaceTrackerImpl(Regatta regatta, String raceID, String raceName, String raceDescription,
|
||||||
BoatClass boatClass, String hostname, int port, StartList startList, WindStore windStore,
|
BoatClass boatClass, String hostname, int port, StartList startList, WindStore windStore,
|
||||||
GPSFixStore gpsFixStore, DomainFactory domainFactory, SwissTimingFactory factory,
|
DomainFactory domainFactory, SwissTimingFactory factory,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver,
|
||||||
long delayToLiveInMillis, boolean useInternalMarkPassingAlgorithm) throws InterruptedException, UnknownHostException, IOException,
|
long delayToLiveInMillis, boolean useInternalMarkPassingAlgorithm) throws InterruptedException, UnknownHostException, IOException,
|
||||||
ParseException {
|
ParseException {
|
||||||
@@ -139,13 +140,13 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
this.raceDescription = raceDescription;
|
this.raceDescription = raceDescription;
|
||||||
this.boatClass = boatClass;
|
this.boatClass = boatClass;
|
||||||
this.windStore = windStore;
|
this.windStore = windStore;
|
||||||
this.gpsFixStore = gpsFixStore;
|
|
||||||
this.id = createID(raceID, hostname, port);
|
this.id = createID(raceID, hostname, port);
|
||||||
connector.addSailMasterListener(this);
|
connector.addSailMasterListener(this);
|
||||||
trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(regatta);
|
trackedRegatta = trackedRegattaRegistry.getOrCreateTrackedRegatta(regatta);
|
||||||
this.delayToLiveInMillis = delayToLiveInMillis;
|
this.delayToLiveInMillis = delayToLiveInMillis;
|
||||||
this.competitorsByBoatId = new HashMap<String, Competitor>();
|
this.competitorsByBoatId = new HashMap<String, Competitor>();
|
||||||
this.useInternalMarkPassingAlgorithm = useInternalMarkPassingAlgorithm;
|
this.useInternalMarkPassingAlgorithm = useInternalMarkPassingAlgorithm;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -158,10 +159,10 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException {
|
protected void onStop(boolean preemptive) throws MalformedURLException, IOException, InterruptedException {
|
||||||
if (isTrackedRaceStillReachable()) {
|
if (isTrackedRaceStillReachable()) {
|
||||||
TrackedRaceStatus newStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, 1.0);
|
TrackedRaceStatus newStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.FINISHED, 1.0);
|
||||||
trackedRace.setStatus(newStatus);
|
trackedRace.onStatusChanged(this, newStatus);
|
||||||
}
|
}
|
||||||
connector.removeSailMasterListener(this);
|
connector.removeSailMasterListener(this);
|
||||||
}
|
}
|
||||||
@@ -238,11 +239,6 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
return windStore;
|
return windStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public GPSFixStore getGPSFixStore() {
|
|
||||||
return gpsFixStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Regatta getRegatta() {
|
public Regatta getRegatta() {
|
||||||
return regatta;
|
return regatta;
|
||||||
@@ -416,7 +412,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
} else {
|
} else {
|
||||||
newStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, progress);
|
newStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, progress);
|
||||||
}
|
}
|
||||||
trackedRace.setStatus(newStatus);
|
trackedRace.onStatusChanged(this, newStatus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,7 +468,8 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl implemen
|
|||||||
competitorsByBoatId.put(c.getBoatID(), existingCompetitor);
|
competitorsByBoatId.put(c.getBoatID(), existingCompetitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trackedRace = getTrackedRegatta().createTrackedRace(race, Collections.<Sideline> emptyList(), windStore, gpsFixStore, delayToLiveInMillis,
|
trackedRace = getTrackedRegatta().createTrackedRace(race, Collections.<Sideline> emptyList(), windStore,
|
||||||
|
delayToLiveInMillis,
|
||||||
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
|
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
|
||||||
/* time over which to average speed */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
/* time over which to average speed */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
||||||
new DynamicRaceDefinitionSet() {
|
new DynamicRaceDefinitionSet() {
|
||||||
|
|||||||
+5
-5
@@ -5,7 +5,6 @@ import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
|||||||
import com.sap.sailing.domain.base.BoatClass;
|
import com.sap.sailing.domain.base.BoatClass;
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
||||||
@@ -52,17 +51,18 @@ public class SwissTimingTrackingConnectivityParameters implements RaceTrackingCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
||||||
GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws Exception {
|
RaceLogResolver raceLogResolver) throws Exception {
|
||||||
return swissTimingFactory.createRaceTracker(raceID, raceName, raceDescription, boatClass, hostname, port,
|
return swissTimingFactory.createRaceTracker(raceID, raceName, raceDescription, boatClass, hostname, port,
|
||||||
startList, delayToLiveInMillis, raceLogStore, regattaLogStore, windStore, gpsFixStore, useInternalMarkPassingAlgorithm,
|
startList, delayToLiveInMillis, raceLogStore, regattaLogStore, windStore,
|
||||||
|
useInternalMarkPassingAlgorithm,
|
||||||
domainFactory, trackedRegattaRegistry, raceLogResolver);
|
domainFactory, trackedRegattaRegistry, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws Exception {
|
WindStore windStore, RaceLogResolver raceLogResolver) throws Exception {
|
||||||
return swissTimingFactory.createRaceTracker(regatta, raceID, raceName, raceDescription, boatClass, hostname,
|
return swissTimingFactory.createRaceTracker(regatta, raceID, raceName, raceDescription, boatClass, hostname,
|
||||||
port, startList, delayToLiveInMillis, windStore, gpsFixStore, useInternalMarkPassingAlgorithm,
|
port, startList, delayToLiveInMillis, windStore, useInternalMarkPassingAlgorithm,
|
||||||
domainFactory, trackedRegattaRegistry, raceLogResolver);
|
domainFactory, trackedRegattaRegistry, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-5
@@ -38,7 +38,6 @@ import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
|
|||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
||||||
import com.sap.sailing.domain.swisstimingreplayadapter.CompetitorStatus;
|
import com.sap.sailing.domain.swisstimingreplayadapter.CompetitorStatus;
|
||||||
@@ -48,6 +47,7 @@ import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
|||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
import com.sap.sailing.domain.tracking.WindTrack;
|
import com.sap.sailing.domain.tracking.WindTrack;
|
||||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
||||||
@@ -70,7 +70,7 @@ import difflib.PatchFailedException;
|
|||||||
* @author Axel Uhl (D043530)
|
* @author Axel Uhl (D043530)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter {
|
public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter implements TrackingDataLoader {
|
||||||
private static final int THRESHOLD_FOR_EARLIEST_MARK_PASSING_BEFORE_START_IN_MILLIS = 30000;
|
private static final int THRESHOLD_FOR_EARLIEST_MARK_PASSING_BEFORE_START_IN_MILLIS = 30000;
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(SwissTimingReplayToDomainAdapter.class.getName());
|
private static final Logger logger = Logger.getLogger(SwissTimingReplayToDomainAdapter.class.getName());
|
||||||
@@ -318,11 +318,12 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter {
|
|||||||
currentRaceID, competitorsPerRaceID.get(currentRaceID), currentCourseDefinition);
|
currentRaceID, competitorsPerRaceID.get(currentRaceID), currentCourseDefinition);
|
||||||
racePerRaceID.put(currentRaceID, race);
|
racePerRaceID.put(currentRaceID, race);
|
||||||
DynamicTrackedRace trackedRace = trackedRegattaRegistry.getOrCreateTrackedRegatta(myRegatta).
|
DynamicTrackedRace trackedRace = trackedRegattaRegistry.getOrCreateTrackedRegatta(myRegatta).
|
||||||
createTrackedRace(race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,TrackedRace.DEFAULT_LIVE_DELAY_IN_MILLISECONDS,
|
createTrackedRace(race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
||||||
|
TrackedRace.DEFAULT_LIVE_DELAY_IN_MILLISECONDS,
|
||||||
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
|
WindTrack.DEFAULT_MILLISECONDS_OVER_WHICH_TO_AVERAGE_WIND,
|
||||||
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
||||||
/* raceDefinitionSetToUpdate */ null, useInternalMarkPassingAlgorithm, raceLogResolver);
|
/* raceDefinitionSetToUpdate */ null, useInternalMarkPassingAlgorithm, raceLogResolver);
|
||||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0));
|
trackedRace.onStatusChanged(this, new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0));
|
||||||
TimePoint bestStartTimeKnownSoFar = bestStartTimePerRaceID.get(currentRaceID);
|
TimePoint bestStartTimeKnownSoFar = bestStartTimePerRaceID.get(currentRaceID);
|
||||||
if (bestStartTimeKnownSoFar != null) {
|
if (bestStartTimeKnownSoFar != null) {
|
||||||
trackedRace.setStartTimeReceived(bestStartTimeKnownSoFar);
|
trackedRace.setStartTimeReceived(bestStartTimeKnownSoFar);
|
||||||
@@ -392,7 +393,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter {
|
|||||||
} else {
|
} else {
|
||||||
newStatus = TrackedRaceStatusEnum.LOADING;
|
newStatus = TrackedRaceStatusEnum.LOADING;
|
||||||
}
|
}
|
||||||
trackedRace.setStatus(new TrackedRaceStatusImpl(newStatus, progress));
|
trackedRace.onStatusChanged(this, new TrackedRaceStatusImpl(newStatus, progress));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-2
@@ -31,7 +31,6 @@ import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
|||||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.markpassingcalculation.impl.WaypointPositionAndDistanceCache;
|
import com.sap.sailing.domain.markpassingcalculation.impl.WaypointPositionAndDistanceCache;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||||
@@ -76,7 +75,7 @@ public class WaypointPositionAndDistanceCacheTest {
|
|||||||
final Regatta regatta = mock(Regatta.class);
|
final Regatta regatta = mock(Regatta.class);
|
||||||
when(regatta.getName()).thenReturn("Regatta name");
|
when(regatta.getName()).thenReturn("Regatta name");
|
||||||
when(trackedRegatta.getRegatta()).thenReturn(regatta);
|
when(trackedRegatta.getRegatta()).thenReturn(regatta);
|
||||||
trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.emptyList(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,
|
trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.emptyList(), EmptyWindStore.INSTANCE,
|
||||||
/* delayToLiveInMillis */ 8000, /* millisecondsOverWhichToAverageWind */ 30000,
|
/* delayToLiveInMillis */ 8000, /* millisecondsOverWhichToAverageWind */ 30000,
|
||||||
/* millisecondsOverWhichToAverageSpeed */ 15000, /* delayForCacheInvalidationOfWindEstimation */ 10000,
|
/* millisecondsOverWhichToAverageSpeed */ 15000, /* delayForCacheInvalidationOfWindEstimation */ 10000,
|
||||||
/* useInternalMarkPassingAlgorithm */ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
/* useInternalMarkPassingAlgorithm */ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
|
|||||||
+1
-2
@@ -41,7 +41,6 @@ import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
|||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.test.TrackBasedTest;
|
import com.sap.sailing.domain.test.TrackBasedTest;
|
||||||
@@ -110,7 +109,7 @@ public class TestFarthestAheadWithSkippedMarkPassing {
|
|||||||
Course course = new CourseImpl("Test Course", waypoints);
|
Course course = new CourseImpl("Test Course", waypoints);
|
||||||
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, boatClass, competitors);
|
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, boatClass, competitors);
|
||||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 0,
|
/* delayToLiveInMillis */ 0,
|
||||||
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
||||||
/* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false,
|
/* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false,
|
||||||
tr->new OneDesignRankingMetric(tr), mock(RaceLogResolver.class));
|
tr->new OneDesignRankingMetric(tr), mock(RaceLogResolver.class));
|
||||||
|
|||||||
+1
-2
@@ -41,7 +41,6 @@ import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
|||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.test.TrackBasedTest;
|
import com.sap.sailing.domain.test.TrackBasedTest;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
@@ -88,7 +87,7 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
|
|||||||
Course course = new CourseImpl("Test Course", waypoints);
|
Course course = new CourseImpl("Test Course", waypoints);
|
||||||
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, boatClass, competitors);
|
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, boatClass, competitors);
|
||||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 0,
|
/* delayToLiveInMillis */ 0,
|
||||||
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
||||||
/* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false,
|
/* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false,
|
||||||
tr->new TimeOnTimeAndDistanceRankingMetric(tr,
|
tr->new TimeOnTimeAndDistanceRankingMetric(tr,
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
|||||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||||
import com.sap.sailing.domain.common.PassingInstruction;
|
import com.sap.sailing.domain.common.PassingInstruction;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
@@ -304,7 +303,7 @@ public class CourseTest {
|
|||||||
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(/* trackedRegatta */new DynamicTrackedRegattaImpl(
|
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(/* trackedRegatta */new DynamicTrackedRegattaImpl(
|
||||||
new RegattaImpl("test", null, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
|
new RegattaImpl("test", null, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
|
||||||
new RaceDefinitionImpl("Test Race", course, new BoatClassImpl("49er", /* upwind start */true), hasso),
|
new RaceDefinitionImpl("Test Race", course, new BoatClassImpl("49er", /* upwind start */true), hasso),
|
||||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,/* delayToLiveInMillis */3000,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, /* delayToLiveInMillis */3000,
|
||||||
/* millisecondsOverWhichToAverageWind */30000,
|
/* millisecondsOverWhichToAverageWind */30000,
|
||||||
/* millisecondsOverWhichToAverageSpeed */8000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
/* millisecondsOverWhichToAverageSpeed */8000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
||||||
mock(RaceLogResolver.class));
|
mock(RaceLogResolver.class));
|
||||||
@@ -336,7 +335,7 @@ public class CourseTest {
|
|||||||
new RegattaImpl("test", null, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
|
new RegattaImpl("test", null, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
|
||||||
new RaceDefinitionImpl("Test Race", course, new BoatClassImpl("49er", /* upwind start */ true),
|
new RaceDefinitionImpl("Test Race", course, new BoatClassImpl("49er", /* upwind start */ true),
|
||||||
hasso), Collections.<Sideline> emptyList(),
|
hasso), Collections.<Sideline> emptyList(),
|
||||||
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 3000,
|
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 3000,
|
||||||
/* millisecondsOverWhichToAverageWind */ 30000,
|
/* millisecondsOverWhichToAverageWind */ 30000,
|
||||||
/* millisecondsOverWhichToAverageSpeed */ 8000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
/* millisecondsOverWhichToAverageSpeed */ 8000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
||||||
mock(RaceLogResolver.class));
|
mock(RaceLogResolver.class));
|
||||||
|
|||||||
+1
-2
@@ -37,7 +37,6 @@ import com.sap.sailing.domain.base.impl.WaypointImpl;
|
|||||||
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
import com.sap.sailing.domain.common.BoatClassMasterdata;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||||
@@ -81,7 +80,7 @@ public class CourseUpdateDuringNonAtomicSerializationTest implements Serializabl
|
|||||||
TrackedRegatta trackedRegatta = new TrackedRegattaImpl(regatta);
|
TrackedRegatta trackedRegatta = new TrackedRegattaImpl(regatta);
|
||||||
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, regatta.getBoatClass(), Collections.<Competitor>emptySet());
|
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, regatta.getBoatClass(), Collections.<Competitor>emptySet());
|
||||||
trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptySet(),
|
trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptySet(),
|
||||||
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,
|
EmptyWindStore.INSTANCE,
|
||||||
/* delayToLiveInMillis */10000, /* millisecondsOverWhichToAverageWind */30000, /* millisecondsOverWhichToAverageSpeed */
|
/* delayToLiveInMillis */10000, /* millisecondsOverWhichToAverageWind */30000, /* millisecondsOverWhichToAverageSpeed */
|
||||||
7000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class)) {
|
7000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class)) {
|
||||||
private static final long serialVersionUID = 9114777576548711763L;
|
private static final long serialVersionUID = 9114777576548711763L;
|
||||||
|
|||||||
+4
-2
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.common.impl.DegreePosition;
|
|||||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
import com.sap.sailing.domain.tracking.impl.MarkPassingImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
import com.sap.sailing.domain.tracking.impl.TrackedRaceStatusImpl;
|
||||||
import com.sap.sse.common.Duration;
|
import com.sap.sse.common.Duration;
|
||||||
@@ -43,10 +44,11 @@ public class DistanceCacheInvalidationAfterLoadingFinishedTest extends TrackBase
|
|||||||
@Test
|
@Test
|
||||||
public void testDistanceCalculationWhileLoading() {
|
public void testDistanceCalculationWhileLoading() {
|
||||||
final TimePoint now = MillisecondsTimePoint.now();
|
final TimePoint now = MillisecondsTimePoint.now();
|
||||||
|
final TrackingDataLoader tdl = new TrackingDataLoader() {};
|
||||||
trackedRace.updateMarkPassings(competitor, Collections.singleton(new MarkPassingImpl(now, trackedRace.getRace().getCourse().getFirstWaypoint(), competitor)));
|
trackedRace.updateMarkPassings(competitor, Collections.singleton(new MarkPassingImpl(now, trackedRace.getRace().getCourse().getFirstWaypoint(), competitor)));
|
||||||
// no distance traveled yet because there is no fix yet; this may be cached for now
|
// no distance traveled yet because there is no fix yet; this may be cached for now
|
||||||
assertEquals(Distance.NULL, trackedRace.getDistanceTraveled(competitor, now));
|
assertEquals(Distance.NULL, trackedRace.getDistanceTraveled(competitor, now));
|
||||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, /* progress */ 0.1));
|
trackedRace.onStatusChanged(tdl, new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, /* progress */ 0.1));
|
||||||
assertEquals(Distance.NULL, trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))));
|
assertEquals(Distance.NULL, trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))));
|
||||||
final Position startPos = new DegreePosition(0, 0);
|
final Position startPos = new DegreePosition(0, 0);
|
||||||
final DegreeBearingImpl bearing = new DegreeBearingImpl(10);
|
final DegreeBearingImpl bearing = new DegreeBearingImpl(10);
|
||||||
@@ -54,7 +56,7 @@ public class DistanceCacheInvalidationAfterLoadingFinishedTest extends TrackBase
|
|||||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos, now, speed));
|
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos, now, speed));
|
||||||
final Distance distance = speed.travel(Duration.ONE_SECOND);
|
final Distance distance = speed.travel(Duration.ONE_SECOND);
|
||||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos.translateGreatCircle(bearing, distance), now.plus(Duration.ONE_SECOND), speed));
|
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos.translateGreatCircle(bearing, distance), now.plus(Duration.ONE_SECOND), speed));
|
||||||
trackedRace.setStatus(new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, /* progress */ 1.0));
|
trackedRace.onStatusChanged(tdl, new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, /* progress */ 1.0));
|
||||||
assertEquals(distance.getMeters(), trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))).getMeters(), 0.000001); // ask 1s after the second fix
|
assertEquals(distance.getMeters(), trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))).getMeters(), 0.000001); // ask 1s after the second fix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -47,7 +47,6 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
|
|||||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
|
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
|
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
@@ -139,7 +138,8 @@ public class LeaderboardCourseChangeTest {
|
|||||||
TrackedRegatta mockedTrackedRegatta = createMockedTrackedRegatta(regatta);
|
TrackedRegatta mockedTrackedRegatta = createMockedTrackedRegatta(regatta);
|
||||||
RaceDefinition mockedRace = createMockedRace(course, boatClass);
|
RaceDefinition mockedRace = createMockedRace(course, boatClass);
|
||||||
TrackedRace spyedTrackedRace = spy(new DynamicTrackedRaceImpl(mockedTrackedRegatta, mockedRace,
|
TrackedRace spyedTrackedRace = spy(new DynamicTrackedRaceImpl(mockedTrackedRegatta, mockedRace,
|
||||||
new HashSet<Sideline>(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, 5000, 20000, 20000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
new HashSet<Sideline>(), EmptyWindStore.INSTANCE, 5000, 20000, 20000,
|
||||||
|
/* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
|
||||||
mock(RaceLogResolver.class)));
|
mock(RaceLogResolver.class)));
|
||||||
|
|
||||||
return spyedTrackedRace;
|
return spyedTrackedRace;
|
||||||
|
|||||||
+2
-1
@@ -3,8 +3,8 @@ package com.sap.sailing.domain.test;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.anyObject;
|
|
||||||
import static org.mockito.Matchers.anyBoolean;
|
import static org.mockito.Matchers.anyBoolean;
|
||||||
|
import static org.mockito.Matchers.anyObject;
|
||||||
import static org.mockito.Matchers.same;
|
import static org.mockito.Matchers.same;
|
||||||
import static org.mockito.Mockito.doCallRealMethod;
|
import static org.mockito.Mockito.doCallRealMethod;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
@@ -38,6 +38,7 @@ public class MarkPositionTimeFilterTest {
|
|||||||
track = new DynamicGPSFixTrackImpl<Mark>(m, /* millisecondsOverWhichToAverage */ 5000);
|
track = new DynamicGPSFixTrackImpl<Mark>(m, /* millisecondsOverWhichToAverage */ 5000);
|
||||||
when(trackedRace.getOrCreateTrack(m)).thenReturn(track);
|
when(trackedRace.getOrCreateTrack(m)).thenReturn(track);
|
||||||
doCallRealMethod().when(trackedRace).recordFix(same(m), (GPSFixMoving) anyObject(), anyBoolean());
|
doCallRealMethod().when(trackedRace).recordFix(same(m), (GPSFixMoving) anyObject(), anyBoolean());
|
||||||
|
doCallRealMethod().when(trackedRace).isWithinStartAndEndOfTracking(anyObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+5
-7
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.test;
|
|||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotSame;
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,15 +11,12 @@ import java.net.URI;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||||
@@ -62,7 +60,7 @@ public class MultipleClassesInRegattaTest {
|
|||||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
tracTracUsername, tracTracPassword,
|
||||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||||
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
||||||
kiwotest2 = domainFactory
|
kiwotest2 = domainFactory
|
||||||
@@ -73,7 +71,7 @@ public class MultipleClassesInRegattaTest {
|
|||||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
tracTracUsername, tracTracPassword,
|
||||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||||
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
||||||
kiwotest3 = domainFactory
|
kiwotest3 = domainFactory
|
||||||
@@ -84,7 +82,7 @@ public class MultipleClassesInRegattaTest {
|
|||||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
tracTracUsername, tracTracPassword,
|
||||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||||
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
||||||
weym470may112014_2 = domainFactory
|
weym470may112014_2 = domainFactory
|
||||||
@@ -95,7 +93,7 @@ public class MultipleClassesInRegattaTest {
|
|||||||
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
|
||||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l, /* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword,
|
tracTracUsername, tracTracPassword,
|
||||||
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
|
||||||
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
|||||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
@@ -63,7 +64,7 @@ import com.tractrac.subscription.lib.api.event.IStoredDataEvent;
|
|||||||
* @author Axel Uhl (d043530)
|
* @author Axel Uhl (d043530)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
|
public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest implements TrackingDataLoader {
|
||||||
private final Logger logger = Logger.getLogger(OnlineTracTracBasedTest.class.getName());
|
private final Logger logger = Logger.getLogger(OnlineTracTracBasedTest.class.getName());
|
||||||
private DomainFactoryImpl domainFactory;
|
private DomainFactoryImpl domainFactory;
|
||||||
private Regatta domainEvent;
|
private Regatta domainEvent;
|
||||||
@@ -137,20 +138,20 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
|
|||||||
logger.info("Stored data begin");
|
logger.info("Stored data begin");
|
||||||
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0);
|
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, 0);
|
||||||
if (getTrackedRace() != null) {
|
if (getTrackedRace() != null) {
|
||||||
getTrackedRace().setStatus(lastStatus);
|
getTrackedRace().onStatusChanged(OnlineTracTracBasedTest.this, lastStatus);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case End:
|
case End:
|
||||||
logger.info("Stored data end");
|
logger.info("Stored data end");
|
||||||
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, 1);
|
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, 1);
|
||||||
if (getTrackedRace() != null) {
|
if (getTrackedRace() != null) {
|
||||||
getTrackedRace().setStatus(lastStatus);
|
getTrackedRace().onStatusChanged(OnlineTracTracBasedTest.this, lastStatus);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Progress:
|
case Progress:
|
||||||
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, storedDataEvent.getProgress());
|
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.LOADING, storedDataEvent.getProgress());
|
||||||
if (getTrackedRace() != null) {
|
if (getTrackedRace() != null) {
|
||||||
getTrackedRace().setStatus(lastStatus);
|
getTrackedRace().onStatusChanged(OnlineTracTracBasedTest.this, lastStatus);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
+1
-2
@@ -46,7 +46,6 @@ import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
|||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
@@ -108,7 +107,7 @@ public class ReachingLegTest extends TrackBasedTest {
|
|||||||
Course course = new CourseImpl(raceName, waypoints);
|
Course course = new CourseImpl(raceName, waypoints);
|
||||||
RaceDefinition race = new RaceDefinitionImpl(raceName, course, boatClass, competitors);
|
RaceDefinition race = new RaceDefinitionImpl(raceName, course, boatClass, competitors);
|
||||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 0,
|
/* delayToLiveInMillis */ 0,
|
||||||
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
||||||
/* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false,
|
/* delay for wind estimation cache invalidation */ 0, /*useMarkPassingCalculator*/ false,
|
||||||
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
|
|||||||
+1
-2
@@ -19,7 +19,6 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
|||||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||||
import com.sap.sailing.domain.ranking.TimeOnTimeAndDistanceRankingMetric;
|
import com.sap.sailing.domain.ranking.TimeOnTimeAndDistanceRankingMetric;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
@@ -38,7 +37,7 @@ public class SerializeRankingMetricTest extends AbstractSerializationTest {
|
|||||||
new LowPoint(), UUID.randomUUID(), /* courseArea */ null)),
|
new LowPoint(), UUID.randomUUID(), /* courseArea */ null)),
|
||||||
new RaceDefinitionImpl("Race", new CourseImpl("Course", Collections.<Waypoint>emptyList()) ,
|
new RaceDefinitionImpl("Race", new CourseImpl("Course", Collections.<Waypoint>emptyList()) ,
|
||||||
/* boatClass */ _49er, Collections.<Competitor>emptySet()),
|
/* boatClass */ _49er, Collections.<Competitor>emptySet()),
|
||||||
Collections.<Sideline>emptyList(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, 0l, 0l, 0l,
|
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0l, 0l, 0l,
|
||||||
false, TimeOnTimeAndDistanceRankingMetric::new, null);
|
false, TimeOnTimeAndDistanceRankingMetric::new, null);
|
||||||
RankingMetric clone = cloneBySerialization(trackedRace.getRankingMetric(), DomainFactory.INSTANCE);
|
RankingMetric clone = cloneBySerialization(trackedRace.getRankingMetric(), DomainFactory.INSTANCE);
|
||||||
assertNotNull(clone);
|
assertNotNull(clone);
|
||||||
|
|||||||
+1
-1
@@ -88,7 +88,7 @@ public class StarbordSideOfStartLineRecognitionTest {
|
|||||||
private static final long serialVersionUID = -8007932232555073829L;
|
private static final long serialVersionUID = -8007932232555073829L;
|
||||||
|
|
||||||
public MockedTrackedRaceImpl() {
|
public MockedTrackedRaceImpl() {
|
||||||
super(null, null, Collections.<Sideline> emptyList(), null, null, 0, 0, 0, 0, false, OneDesignRankingMetric::new,
|
super(null, null, Collections.<Sideline> emptyList(), null, 0, 0, 0, 0, false, OneDesignRankingMetric::new,
|
||||||
mock(RaceLogResolver.class));
|
mock(RaceLogResolver.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -54,7 +54,6 @@ import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
|||||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
@@ -160,7 +159,7 @@ public abstract class TrackBasedTest {
|
|||||||
Course course = new CourseImpl(raceName, waypoints);
|
Course course = new CourseImpl(raceName, waypoints);
|
||||||
RaceDefinition race = new RaceDefinitionImpl(raceName, course, boatClass, competitors);
|
RaceDefinition race = new RaceDefinitionImpl(raceName, course, boatClass, competitors);
|
||||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
||||||
EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 0,
|
/* delayToLiveInMillis */ 0,
|
||||||
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
/* millisecondsOverWhichToAverageWind */ 30000, /* millisecondsOverWhichToAverageSpeed */ 30000,
|
||||||
/* delay for wind estimation cache invalidation */ 0, useMarkPassingCalculator,
|
/* delay for wind estimation cache invalidation */ 0, useMarkPassingCalculator,
|
||||||
OneDesignRankingMetric::new, raceLogResolver);
|
OneDesignRankingMetric::new, raceLogResolver);
|
||||||
|
|||||||
+3
-3
@@ -1,7 +1,8 @@
|
|||||||
package com.sap.sailing.domain.test;
|
package com.sap.sailing.domain.test;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -19,7 +20,6 @@ import org.junit.rules.Timeout;
|
|||||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
import com.sap.sailing.domain.tractracadapter.DomainFactory;
|
||||||
@@ -69,7 +69,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
|
|||||||
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l,
|
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l,
|
||||||
/* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
/* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
|
||||||
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
|
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
|
||||||
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "", "",
|
EmptyWindStore.INSTANCE, "tracTest", "tracTest", "", "",
|
||||||
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
new DummyTrackedRegattaRegistry(), mock(RaceLogResolver.class));
|
||||||
|
|
||||||
Iterable<Competitor> competitors = fourtyninerYellow_2.getRacesHandle().getRace().getCompetitors();
|
Iterable<Competitor> competitors = fourtyninerYellow_2.getRacesHandle().getRace().getCompetitors();
|
||||||
|
|||||||
+2
-2
@@ -22,7 +22,6 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
|
|||||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||||
@@ -46,7 +45,8 @@ public class UpdateMarkPassingTest {
|
|||||||
when(race.getCompetitors()).thenReturn(Collections.singleton(competitor));
|
when(race.getCompetitors()).thenReturn(Collections.singleton(competitor));
|
||||||
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(
|
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(
|
||||||
/* trackedRegatta */new DynamicTrackedRegattaImpl(new RegattaImpl("test", null, null, null, new HashSet<Series>(), false, null,
|
/* trackedRegatta */new DynamicTrackedRegattaImpl(new RegattaImpl("test", null, null, null, new HashSet<Series>(), false, null,
|
||||||
"test", null, OneDesignRankingMetric::new)), race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,
|
"test", null, OneDesignRankingMetric::new)),
|
||||||
|
race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
|
||||||
/* delayToLiveInMillis */1000, /* millisecondsOverWhichToAverageWind */30000,
|
/* delayToLiveInMillis */1000, /* millisecondsOverWhichToAverageWind */30000,
|
||||||
/* millisecondsOverWhichToAverageSpeed */30000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
/* millisecondsOverWhichToAverageSpeed */30000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new, mock(RaceLogResolver.class));
|
||||||
TimePoint now = MillisecondsTimePoint.now();
|
TimePoint now = MillisecondsTimePoint.now();
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ import com.sap.sailing.domain.common.impl.WindImpl;
|
|||||||
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
|
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
|
||||||
import com.sap.sailing.domain.confidence.ConfidenceFactory;
|
import com.sap.sailing.domain.confidence.ConfidenceFactory;
|
||||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
@@ -287,7 +286,7 @@ public class WindTest {
|
|||||||
new RaceDefinitionImpl("Test Race",
|
new RaceDefinitionImpl("Test Race",
|
||||||
new CourseImpl("Test Course", Arrays.asList(new Waypoint[] { w1, w2, w3 })),
|
new CourseImpl("Test Course", Arrays.asList(new Waypoint[] { w1, w2, w3 })),
|
||||||
boatClass, Collections.singleton(competitor)), Collections.<Sideline> emptyList(),
|
boatClass, Collections.singleton(competitor)), Collections.<Sideline> emptyList(),
|
||||||
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, /* delayToLiveInMillis */ 1000,
|
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 1000,
|
||||||
/* millisecondsOverWhichToAverageWind */ 30000,
|
/* millisecondsOverWhichToAverageWind */ 30000,
|
||||||
/* millisecondsOverWhichToAverageSpeed */ 30000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
/* millisecondsOverWhichToAverageSpeed */ 30000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
||||||
mock(RaceLogResolver.class));
|
mock(RaceLogResolver.class));
|
||||||
|
|||||||
+5
-4
@@ -1,12 +1,12 @@
|
|||||||
package com.sap.sailing.domain.test.markpassing;
|
package com.sap.sailing.domain.test.markpassing;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||||
import com.sap.sailing.domain.base.Competitor;
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
||||||
@@ -34,7 +34,6 @@ import com.sap.sailing.domain.common.impl.DegreePosition;
|
|||||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
|
||||||
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
|
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||||
@@ -72,7 +71,9 @@ public class AbstractMockedRaceMarkPassingTest {
|
|||||||
new ArrayList<String>(), null)), true, new HighPoint(), "ID", new CourseAreaImpl("area", new UUID(5, 5)), OneDesignRankingMetric::new);
|
new ArrayList<String>(), null)), true, new HighPoint(), "ID", new CourseAreaImpl("area", new UUID(5, 5)), OneDesignRankingMetric::new);
|
||||||
Course course = new CourseImpl("course", waypoints);
|
Course course = new CourseImpl("course", waypoints);
|
||||||
RaceDefinition raceDef = new RaceDefinitionImpl("Performance Race", course, boatClass, Arrays.asList(ron, tom, ben));
|
RaceDefinition raceDef = new RaceDefinitionImpl("Performance Race", course, boatClass, Arrays.asList(ron, tom, ben));
|
||||||
race = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(r), raceDef, new ArrayList<Sideline>(), new EmptyWindStore(), EmptyGPSFixStore.INSTANCE, 0, 10000, 10000, /*useMarkPassingCalculator*/ false, OneDesignRankingMetric::new,
|
race = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(r), raceDef, new ArrayList<Sideline>(),
|
||||||
|
new EmptyWindStore(), 0, 10000, 10000, /* useMarkPassingCalculator */ false,
|
||||||
|
OneDesignRankingMetric::new,
|
||||||
mock(RaceLogResolver.class));
|
mock(RaceLogResolver.class));
|
||||||
race.setStartTimeReceived(new MillisecondsTimePoint(10000));
|
race.setStartTimeReceived(new MillisecondsTimePoint(10000));
|
||||||
TimePoint t = new MillisecondsTimePoint(30000);
|
TimePoint t = new MillisecondsTimePoint(30000);
|
||||||
|
|||||||
Executable → Regular
+59
-14
@@ -42,10 +42,10 @@ import com.sap.sailing.domain.common.WindSourceType;
|
|||||||
import com.sap.sailing.domain.common.racelog.Flags;
|
import com.sap.sailing.domain.common.racelog.Flags;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||||
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
||||||
@@ -55,6 +55,7 @@ import com.sap.sailing.domain.regattalike.RegattaLikeListener;
|
|||||||
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
||||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicSensorFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||||
@@ -65,11 +66,14 @@ import com.sap.sailing.domain.tracking.RaceAbortedListener;
|
|||||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||||
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
|
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
|
||||||
import com.sap.sailing.domain.tracking.RaceListener;
|
import com.sap.sailing.domain.tracking.RaceListener;
|
||||||
|
import com.sap.sailing.domain.tracking.SensorFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackFactory;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
import com.sap.sailing.domain.tracking.WindLegTypeAndLegBearingCache;
|
||||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||||
import com.sap.sailing.domain.tracking.WindStore;
|
import com.sap.sailing.domain.tracking.WindStore;
|
||||||
@@ -428,7 +432,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStartDate(TimePoint startDate) {
|
public void setStartDate(TimePoint startDate) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -438,7 +442,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEndDate(TimePoint startDate) {
|
public void setEndDate(TimePoint startDate) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -447,11 +451,11 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addListener(RegattaLikeListener listener) {
|
public void addListener(RegattaLikeListener listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeListener(RegattaLikeListener listener) {
|
public void removeListener(RegattaLikeListener listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -504,7 +508,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerCompetitor(Competitor competitor) {
|
public void registerCompetitor(Competitor competitor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -559,9 +563,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, Iterable<Sideline> sidelines,
|
public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, Iterable<Sideline> sidelines,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, long delayToLiveInMillis,
|
WindStore windStore, long delayToLiveInMillis,
|
||||||
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
|
long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed,
|
||||||
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingcalculator, RaceLogResolver raceLogResolver) {
|
DynamicRaceDefinitionSet raceDefinitionSetToUpdate, boolean useMarkPassingcalculator,
|
||||||
|
RaceLogResolver raceLogResolver) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,7 +647,8 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) {
|
public Distance getWindwardDistanceToCompetitorFarthestAhead(Competitor competitor, TimePoint timePoint,
|
||||||
|
WindPositionMode windPositionMode) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,7 +812,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setStatus(TrackedRaceStatus newStatus) {
|
public void onStatusChanged(TrackingDataLoader loader, TrackedRaceStatus status) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -915,9 +921,6 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GPSFixStore getGPSFixStore() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint,
|
public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint,
|
||||||
@@ -960,7 +963,7 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitForLoadingFromGPSFixStoreToFinishRunning(RegattaLog fromRegattaLog) throws InterruptedException {
|
public void waitForLoadingToFinish() throws InterruptedException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1048,4 +1051,46 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
|||||||
@Override
|
@Override
|
||||||
public void setFinishedTime(TimePoint newFinishedTime) {
|
public void setFinishedTime(TimePoint newFinishedTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends SensorFix, TrackT extends SensorFixTrack<Competitor, FixT>> TrackT getSensorTrack(
|
||||||
|
Competitor competitor, String trackName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends SensorFix, TrackT extends DynamicSensorFixTrack<Competitor, FixT>> TrackT getDynamicSensorTrack(
|
||||||
|
Competitor competitor, String trackName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends SensorFix, TrackT extends DynamicSensorFixTrack<Competitor, FixT>> TrackT getOrCreateSensorTrack(
|
||||||
|
Competitor competitor, String trackName, TrackFactory<TrackT> newTrackFactory) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinStartAndEndOfTracking(TimePoint timePoint) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<RegattaLog> getAttachedRegattaLogs() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recordSensorFix(Competitor competitor, String trackName, SensorFix fix,
|
||||||
|
boolean onlyWhenInTrackingTimeInterval) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addSensorTrack(Competitor trackedItem, String trackName, DynamicSensorFixTrack<Competitor, ?> track) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<RaceLog> getAttachedRaceLogs() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+19
-7
@@ -32,9 +32,9 @@ import com.sap.sailing.domain.common.WindSource;
|
|||||||
import com.sap.sailing.domain.common.WindSourceType;
|
import com.sap.sailing.domain.common.WindSourceType;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||||
import com.sap.sailing.domain.polars.PolarDataService;
|
import com.sap.sailing.domain.polars.PolarDataService;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||||
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
||||||
@@ -45,6 +45,7 @@ import com.sap.sailing.domain.tracking.MarkPassing;
|
|||||||
import com.sap.sailing.domain.tracking.RaceAbortedListener;
|
import com.sap.sailing.domain.tracking.RaceAbortedListener;
|
||||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||||
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
|
import com.sap.sailing.domain.tracking.RaceExecutionOrderProvider;
|
||||||
|
import com.sap.sailing.domain.tracking.SensorFixTrack;
|
||||||
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||||
@@ -560,11 +561,6 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public GPSFixStore getGPSFixStore() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addRaceAbortedListener(RaceAbortedListener listener) {
|
public void addRaceAbortedListener(RaceAbortedListener listener) {
|
||||||
}
|
}
|
||||||
@@ -579,7 +575,7 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void waitForLoadingFromGPSFixStoreToFinishRunning(RegattaLog fromRegattaLog) throws InterruptedException {
|
public void waitForLoadingToFinish() throws InterruptedException {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -664,4 +660,20 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
|||||||
@Override
|
@Override
|
||||||
public void updateStartAndEndOfTracking(boolean waitForGPSFixesToLoad) {
|
public void updateStartAndEndOfTracking(boolean waitForGPSFixesToLoad) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends SensorFix, TrackT extends SensorFixTrack<Competitor, FixT>> TrackT getSensorTrack(
|
||||||
|
Competitor competitor, String trackName) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<RegattaLog> getAttachedRegattaLogs() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<RaceLog> getAttachedRaceLogs() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+125
@@ -0,0 +1,125 @@
|
|||||||
|
package com.sap.sailing.domain.tracking.impl;
|
||||||
|
|
||||||
|
import static com.sap.sse.common.impl.MillisecondsTimePoint.now;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||||
|
import com.sap.sailing.domain.common.tracking.impl.BravoFixImpl;
|
||||||
|
import com.sap.sailing.domain.common.tracking.impl.DoubleVectorFixImpl;
|
||||||
|
import com.sap.sailing.domain.test.TrackBasedTest;
|
||||||
|
import com.sap.sailing.domain.tracking.BravoFixTrack;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicBravoFixTrack;
|
||||||
|
import com.sap.sse.common.Duration;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
|
||||||
|
public class BravoFixTrackSerializationTest {
|
||||||
|
|
||||||
|
private DynamicBravoFixTrack<Competitor> track;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
Competitor competitor = TrackBasedTest.createCompetitor("SAP Extreme Sailing Team");
|
||||||
|
track = new BravoFixTrackImpl<Competitor>(competitor, BravoFixTrack.TRACK_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithZeroValueFix() throws ClassNotFoundException, IOException {
|
||||||
|
addToTrackAndAssertRideHeight(new TestFixData(now().minus(Duration.ONE_MINUTE), 0.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithSingleFix() throws ClassNotFoundException, IOException {
|
||||||
|
addToTrackAndAssertRideHeight(new TestFixData(now().minus(Duration.ONE_MINUTE), 0.6543));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithMultipleFixes() throws ClassNotFoundException, IOException {
|
||||||
|
addToTrackAndAssertRideHeight(new TestFixData(now().minus(Duration.ONE_MINUTE), 1.0249),
|
||||||
|
new TestFixData(now().minus(Duration.ONE_MINUTE.times(2)), 0.9140),
|
||||||
|
new TestFixData(now().minus(Duration.ONE_MINUTE.times(3)), 0.3721),
|
||||||
|
new TestFixData(now().minus(Duration.ONE_MINUTE.times(4)), 0.7942),
|
||||||
|
new TestFixData(now().minus(Duration.ONE_MINUTE.times(5)), 0.6203));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithTwoFixesWithSameTimePointNoReplacement() throws ClassNotFoundException, IOException {
|
||||||
|
TimePoint timePoint = now().minus(Duration.ONE_MINUTE);
|
||||||
|
TestFixData testFixData1 = new TestFixData(timePoint, 1.0000);
|
||||||
|
TestFixData testFixData2 = new TestFixData(timePoint, 0.5000);
|
||||||
|
Arrays.asList(testFixData1, testFixData2).forEach(TestFixData::addBravoFixToTrack);
|
||||||
|
assertRideHeight(getDeserializedTrack(), testFixData1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWithTwoFixesWithSameTimePointWithReplacement() throws ClassNotFoundException, IOException {
|
||||||
|
TimePoint timePoint = now().minus(Duration.ONE_MINUTE);
|
||||||
|
TestFixData testFixData1 = new TestFixData(timePoint, 1.0000);
|
||||||
|
TestFixData testFixData2 = new TestFixData(timePoint, 0.5000);
|
||||||
|
Arrays.asList(testFixData1, testFixData2).forEach(TestFixData::replaceBravoFixOnTrack);
|
||||||
|
assertRideHeight(getDeserializedTrack(), testFixData2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToTrackAndAssertRideHeight(TestFixData... testFixData) throws ClassNotFoundException, IOException {
|
||||||
|
List<TestFixData> testFixDataList = Arrays.asList(testFixData);
|
||||||
|
testFixDataList.forEach(TestFixData::addBravoFixToTrack);
|
||||||
|
BravoFixTrack<Competitor> track = getDeserializedTrack();
|
||||||
|
testFixDataList.forEach(testData -> assertRideHeight(track, testData));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertRideHeight(BravoFixTrack<Competitor> track, TestFixData testFixData) {
|
||||||
|
assertRideHeight(track, testFixData.timePoint, testFixData.rideHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertRideHeight(BravoFixTrack<Competitor> track, TimePoint timePoint, double expected) {
|
||||||
|
assertEquals(expected, track.getRideHeight(timePoint), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private BravoFixTrack<Competitor> getDeserializedTrack() throws ClassNotFoundException, IOException {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ObjectOutputStream ous = new ObjectOutputStream(baos);
|
||||||
|
ous.writeObject(track);
|
||||||
|
ous.close();
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||||
|
BravoFixTrack<Competitor> deserializedInstance = (BravoFixTrack<Competitor>) ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
return deserializedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestFixData {
|
||||||
|
private final TimePoint timePoint;
|
||||||
|
private final double rideHeight;
|
||||||
|
|
||||||
|
private TestFixData(TimePoint timePoint, double rideHeight) {
|
||||||
|
this.timePoint = timePoint;
|
||||||
|
this.rideHeight = rideHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addBravoFixToTrack() {
|
||||||
|
addOrReplaceBravoFixToTrack(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replaceBravoFixOnTrack() {
|
||||||
|
addOrReplaceBravoFixToTrack(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addOrReplaceBravoFixToTrack(boolean replace) {
|
||||||
|
double[] fixData = new double[BravoSensorDataMetadata.INSTANCE.getColumns().size()];
|
||||||
|
fixData[BravoSensorDataMetadata.INSTANCE.rideHeightColumn] = rideHeight;
|
||||||
|
track.add(new BravoFixImpl(new DoubleVectorFixImpl(timePoint, fixData)), replace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+2
-3
@@ -27,7 +27,6 @@ import com.sap.sailing.domain.base.Waypoint;
|
|||||||
import com.sap.sailing.domain.common.PassingInstruction;
|
import com.sap.sailing.domain.common.PassingInstruction;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
@@ -142,7 +141,7 @@ public interface DomainFactory {
|
|||||||
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
|
WindStore windStore, String tracTracUsername, String tracTracPassword,
|
||||||
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException;
|
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException, SubscriberInitializationException;
|
||||||
|
|
||||||
@@ -156,7 +155,7 @@ public interface DomainFactory {
|
|||||||
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
|
WindStore windStore, String tracTracUsername, String tracTracPassword,
|
||||||
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
|
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
|
||||||
SubscriberInitializationException;
|
SubscriberInitializationException;
|
||||||
|
|||||||
+8
-9
@@ -53,8 +53,6 @@ import com.sap.sailing.domain.common.impl.DegreePosition;
|
|||||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
@@ -524,7 +522,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
|||||||
// add to existing regatta only if boat class matches
|
// add to existing regatta only if boat class matches
|
||||||
if (raceDefinition.getBoatClass() == trackedRegatta.getRegatta().getBoatClass()) {
|
if (raceDefinition.getBoatClass() == trackedRegatta.getRegatta().getBoatClass()) {
|
||||||
trackedRegatta.getRegatta().addRace(raceDefinition);
|
trackedRegatta.getRegatta().addRace(raceDefinition);
|
||||||
trackedRace = createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore, EmptyGPSFixStore.INSTANCE,
|
trackedRace = createTrackedRace(trackedRegatta, raceDefinition, sidelines, windStore,
|
||||||
delayToLiveInMillis, millisecondsOverWhichToAverageWind, raceDefinitionSetToUpdate, ignoreTracTracMarkPassings,
|
delayToLiveInMillis, millisecondsOverWhichToAverageWind, raceDefinitionSetToUpdate, ignoreTracTracMarkPassings,
|
||||||
raceLogResolver);
|
raceLogResolver);
|
||||||
logger.info("Added race " + raceDefinition + " to regatta " + trackedRegatta.getRegatta());
|
logger.info("Added race " + raceDefinition + " to regatta " + trackedRegatta.getRegatta());
|
||||||
@@ -562,11 +560,11 @@ public class DomainFactoryImpl implements DomainFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition race,
|
private DynamicTrackedRace createTrackedRace(TrackedRegatta trackedRegatta, RaceDefinition race,
|
||||||
Iterable<Sideline> sidelines, WindStore windStore, GPSFixStore gpsFixStore, long delayToLiveInMillis,
|
Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
|
||||||
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
|
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
|
||||||
boolean useMarkPassingCalculator, RaceLogResolver raceLogResolver) {
|
boolean useMarkPassingCalculator, RaceLogResolver raceLogResolver) {
|
||||||
return trackedRegatta.createTrackedRace(race, sidelines,
|
return trackedRegatta.createTrackedRace(race, sidelines,
|
||||||
windStore, gpsFixStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
|
windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
|
||||||
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
||||||
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver);
|
raceDefinitionSetToUpdate, useMarkPassingCalculator, raceLogResolver);
|
||||||
}
|
}
|
||||||
@@ -655,27 +653,28 @@ public class DomainFactoryImpl implements DomainFactory {
|
|||||||
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
public TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
|
||||||
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
|
||||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException,
|
||||||
URISyntaxException, CreateModelException, SubscriberInitializationException {
|
URISyntaxException, CreateModelException, SubscriberInitializationException {
|
||||||
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
|
return new TracTracRaceTrackerImpl(this, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
|
||||||
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
||||||
gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry,
|
||||||
|
raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI,
|
public RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI,
|
||||||
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
|
||||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||||
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
|
throws MalformedURLException, FileNotFoundException, URISyntaxException, CreateModelException,
|
||||||
SubscriberInitializationException {
|
SubscriberInitializationException {
|
||||||
return new TracTracRaceTrackerImpl(regatta, this, paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
return new TracTracRaceTrackerImpl(regatta, this, paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
||||||
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||||
regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
|
regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
|
||||||
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -18,7 +18,6 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
|||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.base.Sideline;
|
import com.sap.sailing.domain.base.Sideline;
|
||||||
import com.sap.sailing.domain.common.PassingInstruction;
|
import com.sap.sailing.domain.common.PassingInstruction;
|
||||||
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
|
|
||||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||||
@@ -225,7 +224,7 @@ public class RaceCourseReceiver extends AbstractReceiverWithQueue<IControlRoute,
|
|||||||
|
|
||||||
private DynamicTrackedRace createTrackedRace(RaceDefinition race, Iterable<Sideline> sidelines) {
|
private DynamicTrackedRace createTrackedRace(RaceDefinition race, Iterable<Sideline> sidelines) {
|
||||||
DynamicTrackedRace trackedRace = getTrackedRegatta().createTrackedRace(race, sidelines,
|
DynamicTrackedRace trackedRace = getTrackedRegatta().createTrackedRace(race, sidelines,
|
||||||
windStore, EmptyGPSFixStore.INSTANCE, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
|
windStore, delayToLiveInMillis, millisecondsOverWhichToAverageWind,
|
||||||
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
/* time over which to average speed: */ race.getBoatClass().getApproximateManeuverDurationInMilliseconds(),
|
||||||
raceDefinitionSetToUpdate, useInternalMarkPassingAlgorithm, raceLogResolver);
|
raceDefinitionSetToUpdate, useInternalMarkPassingAlgorithm, raceLogResolver);
|
||||||
getDomainFactory().addTracTracUpdateHandlers(tracTracUpdateURI, getTracTracEvent().getId(), tracTracUsername, tracTracPassword, race, trackedRace);
|
getDomainFactory().addTracTracUpdateHandlers(tracTracUpdateURI, getTracTracEvent().getId(), tracTracUsername, tracTracPassword, race, trackedRace);
|
||||||
|
|||||||
+4
-5
@@ -9,7 +9,6 @@ import java.net.URL;
|
|||||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogResolver;
|
||||||
import com.sap.sailing.domain.base.Regatta;
|
import com.sap.sailing.domain.base.Regatta;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||||
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
|
import com.sap.sailing.domain.tracking.RaceTrackingConnectivityParameters;
|
||||||
@@ -65,21 +64,21 @@ public class RaceTrackingConnectivityParametersImpl implements RaceTrackingConne
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
||||||
GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException, URISyntaxException,
|
RaceLogResolver raceLogResolver) throws MalformedURLException, FileNotFoundException, URISyntaxException,
|
||||||
CreateModelException, SubscriberInitializationException {
|
CreateModelException, SubscriberInitializationException {
|
||||||
RaceTracker tracker = domainFactory.createRaceTracker(paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
RaceTracker tracker = domainFactory.createRaceTracker(paramURL, liveURI, storedURI, courseDesignUpdateURI,
|
||||||
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore,
|
||||||
regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
|
regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
|
||||||
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||||
return tracker;
|
return tracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, RaceLogResolver raceLogResolver) throws Exception {
|
WindStore windStore, RaceLogResolver raceLogResolver) throws Exception {
|
||||||
RaceTracker tracker = domainFactory.createRaceTracker(regatta, paramURL, liveURI, storedURI,
|
RaceTracker tracker = domainFactory.createRaceTracker(regatta, paramURL, liveURI, storedURI,
|
||||||
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm,
|
courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm,
|
||||||
raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername, tracTracPassword, raceStatus,
|
raceLogStore, regattaLogStore, windStore, tracTracUsername, tracTracPassword, raceStatus,
|
||||||
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||||
return tracker;
|
return tracker;
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-18
@@ -30,7 +30,6 @@ import com.sap.sailing.domain.base.Regatta;
|
|||||||
import com.sap.sailing.domain.base.Series;
|
import com.sap.sailing.domain.base.Series;
|
||||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
|
||||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||||
import com.sap.sailing.domain.tracking.AbstractRaceTrackerImpl;
|
import com.sap.sailing.domain.tracking.AbstractRaceTrackerImpl;
|
||||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||||
@@ -41,6 +40,7 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
|||||||
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
import com.sap.sailing.domain.tracking.TrackedRaceStatus;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||||
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
|
||||||
|
import com.sap.sailing.domain.tracking.TrackingDataLoader;
|
||||||
import com.sap.sailing.domain.tracking.WindStore;
|
import com.sap.sailing.domain.tracking.WindStore;
|
||||||
import com.sap.sailing.domain.tracking.WindTrack;
|
import com.sap.sailing.domain.tracking.WindTrack;
|
||||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||||
@@ -69,7 +69,8 @@ import com.tractrac.subscription.lib.api.event.ILiveDataEvent;
|
|||||||
import com.tractrac.subscription.lib.api.event.IStoredDataEvent;
|
import com.tractrac.subscription.lib.api.event.IStoredDataEvent;
|
||||||
import com.tractrac.subscription.lib.api.race.IRacesListener;
|
import com.tractrac.subscription.lib.api.race.IRacesListener;
|
||||||
|
|
||||||
public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements IConnectionStatusListener, TracTracRaceTracker, DynamicRaceDefinitionSet {
|
public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl
|
||||||
|
implements IConnectionStatusListener, TracTracRaceTracker, DynamicRaceDefinitionSet, TrackingDataLoader {
|
||||||
private static final Logger logger = Logger.getLogger(TracTracRaceTrackerImpl.class.getName());
|
private static final Logger logger = Logger.getLogger(TracTracRaceTrackerImpl.class.getName());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,7 +194,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
private final Set<Receiver> receivers;
|
private final Set<Receiver> receivers;
|
||||||
private final DomainFactory domainFactory;
|
private final DomainFactory domainFactory;
|
||||||
private final WindStore windStore;
|
private final WindStore windStore;
|
||||||
private final GPSFixStore gpsFixStore;
|
|
||||||
private final Set<RaceDefinition> races;
|
private final Set<RaceDefinition> races;
|
||||||
private final DynamicTrackedRegatta trackedRegatta;
|
private final DynamicTrackedRegatta trackedRegatta;
|
||||||
private TrackedRaceStatus lastStatus;
|
private TrackedRaceStatus lastStatus;
|
||||||
@@ -255,26 +255,28 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI,
|
protected TracTracRaceTrackerImpl(DomainFactory domainFactory, URL paramURL, URI liveURI, URI storedURI,
|
||||||
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis,
|
||||||
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore, RegattaLogStore regattaLogStore,
|
||||||
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
|
WindStore windStore, String tracTracUsername, String tracTracPassword,
|
||||||
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver)
|
||||||
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException,
|
throws URISyntaxException, MalformedURLException, FileNotFoundException, CreateModelException,
|
||||||
SubscriberInitializationException {
|
SubscriberInitializationException {
|
||||||
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), domainFactory, paramURL, liveURI,
|
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), domainFactory, paramURL, liveURI,
|
||||||
storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
||||||
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
|
offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore,
|
||||||
|
windStore, tracTracUsername,
|
||||||
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TracTracRaceTrackerImpl(IRace tractracRace, DomainFactory domainFactory, URL paramURL, URI liveURI,
|
private TracTracRaceTrackerImpl(IRace tractracRace, DomainFactory domainFactory, URL paramURL, URI liveURI,
|
||||||
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
||||||
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm, RaceLogStore raceLogStore,
|
||||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
|
||||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
|
||||||
FileNotFoundException, SubscriberInitializationException {
|
FileNotFoundException, SubscriberInitializationException {
|
||||||
this(tractracRace, null, domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
|
this(tractracRace, null, domainFactory, paramURL, liveURI, storedURI, courseDesignUpdateURI, startOfTracking,
|
||||||
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
endOfTracking, delayToLiveInMillis, offsetToStartTimeOfSimulatedRace, useInternalMarkPassingAlgorithm, raceLogStore, regattaLogStore, windStore,
|
||||||
gpsFixStore, tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
tracTracUsername, tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry,
|
||||||
|
raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -286,13 +288,14 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI,
|
protected TracTracRaceTrackerImpl(Regatta regatta, DomainFactory domainFactory, URL paramURL, URI liveURI,
|
||||||
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking, TimePoint endOfTracking,
|
||||||
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
|
long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean ignoreTracTracMarkPassings, RaceLogStore raceLogStore,
|
||||||
RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername,
|
RegattaLogStore regattaLogStore, WindStore windStore, String tracTracUsername,
|
||||||
String tracTracPassword, String raceStatus, String raceVisibility,
|
String tracTracPassword, String raceStatus, String raceVisibility,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException,
|
||||||
MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
|
MalformedURLException, FileNotFoundException, CreateModelException, SubscriberInitializationException {
|
||||||
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), regatta, domainFactory, paramURL,
|
this(ModelLocator.getEventFactory().createRace(new URI(paramURL.toString())), regatta, domainFactory, paramURL,
|
||||||
liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
liveURI, storedURI, courseDesignUpdateURI, startOfTracking, endOfTracking, delayToLiveInMillis,
|
||||||
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore, gpsFixStore, tracTracUsername,
|
offsetToStartTimeOfSimulatedRace, ignoreTracTracMarkPassings, raceLogStore, regattaLogStore, windStore,
|
||||||
|
tracTracUsername,
|
||||||
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
tracTracPassword, raceStatus, raceVisibility, trackedRegattaRegistry, raceLogResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +313,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory,
|
private TracTracRaceTrackerImpl(IRace tractracRace, final Regatta regatta, DomainFactory domainFactory,
|
||||||
URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking,
|
URL paramURL, URI liveURI, URI storedURI, URI tracTracUpdateURI, TimePoint startOfTracking,
|
||||||
TimePoint endOfTracking, long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
|
TimePoint endOfTracking, long delayToLiveInMillis, Duration offsetToStartTimeOfSimulatedRace, boolean useInternalMarkPassingAlgorithm,
|
||||||
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore, GPSFixStore gpsFixStore,
|
RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, WindStore windStore,
|
||||||
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility,
|
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility,
|
||||||
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
|
TrackedRegattaRegistry trackedRegattaRegistry, RaceLogResolver raceLogResolver) throws URISyntaxException, MalformedURLException,
|
||||||
FileNotFoundException, SubscriberInitializationException {
|
FileNotFoundException, SubscriberInitializationException {
|
||||||
@@ -321,7 +324,6 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
this.id = createID(paramURL, liveURI, storedURI);
|
this.id = createID(paramURL, liveURI, storedURI);
|
||||||
isLiveTracking = liveURI != null;
|
isLiveTracking = liveURI != null;
|
||||||
this.races = new HashSet<RaceDefinition>();
|
this.races = new HashSet<RaceDefinition>();
|
||||||
this.gpsFixStore = gpsFixStore;
|
|
||||||
this.domainFactory = domainFactory;
|
this.domainFactory = domainFactory;
|
||||||
this.lastProgressPerID = new HashMap<>();
|
this.lastProgressPerID = new HashMap<>();
|
||||||
if (offsetToStartTimeOfSimulatedRace != null) {
|
if (offsetToStartTimeOfSimulatedRace != null) {
|
||||||
@@ -537,7 +539,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(boolean stopReceiversPreemtively) throws InterruptedException {
|
protected void onStop(boolean stopReceiversPreemtively) throws InterruptedException {
|
||||||
if (!stopped) {
|
if (!stopped) {
|
||||||
stopped = true;
|
stopped = true;
|
||||||
raceSubscriber.stop();
|
raceSubscriber.stop();
|
||||||
@@ -601,7 +603,7 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
} else {
|
} else {
|
||||||
status = lastStatus;
|
status = lastStatus;
|
||||||
}
|
}
|
||||||
trackedRace.setStatus(status);
|
trackedRace.onStatusChanged(this, status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,7 +625,8 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.ERROR, 0.0);
|
lastStatus = new TrackedRaceStatusImpl(TrackedRaceStatusEnum.ERROR, 0.0);
|
||||||
updateStatusOfTrackedRaces();
|
updateStatusOfTrackedRaces();
|
||||||
return;
|
return;
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
|
logger.severe("Exception stopping race tracker: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -709,8 +712,4 @@ public class TracTracRaceTrackerImpl extends AbstractRaceTrackerImpl implements
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public GPSFixStore getGPSFixStore() {
|
|
||||||
return gpsFixStore;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
+4
@@ -106,6 +106,10 @@ public abstract class AbstractRaceColumn extends SimpleAbstractRaceColumn implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (trackedRace != null) {
|
if (trackedRace != null) {
|
||||||
|
RegattaLog regattaLog = getRegattaLog();
|
||||||
|
if(regattaLog != null) {
|
||||||
|
trackedRace.attachRegattaLog(regattaLog);
|
||||||
|
}
|
||||||
final RaceLog raceLog = getRaceLog(fleet);
|
final RaceLog raceLog = getRaceLog(fleet);
|
||||||
if (raceLog != null) {
|
if (raceLog != null) {
|
||||||
trackedRace.attachRaceLog(raceLog);
|
trackedRace.attachRaceLog(raceLog);
|
||||||
|
|||||||
+1
-1
@@ -136,6 +136,6 @@ public class RaceColumnInSeriesImpl extends AbstractRaceColumn implements RaceCo
|
|||||||
@Override
|
@Override
|
||||||
public RegattaLog getRegattaLog() {
|
public RegattaLog getRegattaLog() {
|
||||||
Regatta regatta = getRegatta();
|
Regatta regatta = getRegatta();
|
||||||
return regatta.getRegattaLog();
|
return regatta == null ? null : regatta.getRegattaLog();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Executable → Regular
+1943
-1941
File diff suppressed because it is too large.
Load diff
+19
-41
@@ -16,7 +16,6 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
|||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
|
||||||
import com.sap.sailing.domain.base.CourseArea;
|
import com.sap.sailing.domain.base.CourseArea;
|
||||||
import com.sap.sailing.domain.base.Event;
|
import com.sap.sailing.domain.base.Event;
|
||||||
import com.sap.sailing.domain.base.Fleet;
|
import com.sap.sailing.domain.base.Fleet;
|
||||||
@@ -30,21 +29,15 @@ import com.sap.sailing.domain.common.RegattaIdentifier;
|
|||||||
import com.sap.sailing.domain.common.WindSource;
|
import com.sap.sailing.domain.common.WindSource;
|
||||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||||
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
|
||||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
import com.sap.sailing.domain.racelogtracking.impl.DeviceMappingImpl;
|
|
||||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
|
||||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
|
||||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
|
||||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||||
|
import com.sap.sse.common.Timed;
|
||||||
import com.sap.sse.common.Util;
|
import com.sap.sse.common.Util;
|
||||||
import com.sap.sse.common.WithID;
|
|
||||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds all information needed for a master data import.
|
* Holds all information needed for a master data import.
|
||||||
@@ -62,15 +55,16 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
private final Set<LeaderboardGroup> leaderboardGroups;
|
private final Set<LeaderboardGroup> leaderboardGroups;
|
||||||
private final Set<WindTrackMasterData> windTrackMasterData;
|
private final Set<WindTrackMasterData> windTrackMasterData;
|
||||||
private final Map<LeaderboardGroup, Set<Event>> eventForLeaderboardGroup;
|
private final Map<LeaderboardGroup, Set<Event>> eventForLeaderboardGroup;
|
||||||
private final Map<DeviceIdentifier, Set<GPSFix>> raceLogTrackingFixes;
|
private final Map<DeviceIdentifier, Set<Timed>> raceLogTrackingFixes;
|
||||||
private final Map<DeviceConfigurationMatcher, DeviceConfiguration> deviceConfigurations;
|
private final Map<DeviceConfigurationMatcher, DeviceConfiguration> deviceConfigurations;
|
||||||
|
|
||||||
public TopLevelMasterData(final Set<LeaderboardGroup> groupsToExport, final Iterable<Event> allEvents,
|
public TopLevelMasterData(final Set<LeaderboardGroup> groupsToExport, final Iterable<Event> allEvents,
|
||||||
final Map<String, Regatta> regattaForRaceIdString, final Iterable<MediaTrack> allMediaTracks,
|
final Map<String, Regatta> regattaForRaceIdString, final Iterable<MediaTrack> allMediaTracks,
|
||||||
GPSFixStore gpsFixStore, boolean exportWind, Map<DeviceConfigurationMatcher, DeviceConfiguration> deviceConfigurations) {
|
SensorFixStore sensorFixStore, boolean exportWind,
|
||||||
|
Map<DeviceConfigurationMatcher, DeviceConfiguration> deviceConfigurations) {
|
||||||
this.raceIdStringsForRegatta = convertToRaceIdStringsForRegattaMap(regattaForRaceIdString);
|
this.raceIdStringsForRegatta = convertToRaceIdStringsForRegattaMap(regattaForRaceIdString);
|
||||||
this.leaderboardGroups = groupsToExport;
|
this.leaderboardGroups = groupsToExport;
|
||||||
this.raceLogTrackingFixes = getAllRelevantRaceLogTrackingFixes(gpsFixStore);
|
this.raceLogTrackingFixes = getAllRelevantRaceLogTrackingFixes(sensorFixStore);
|
||||||
if (exportWind) {
|
if (exportWind) {
|
||||||
this.windTrackMasterData = fillWindMap(groupsToExport);
|
this.windTrackMasterData = fillWindMap(groupsToExport);
|
||||||
} else {
|
} else {
|
||||||
@@ -82,8 +76,8 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
filterMediaTracks(allMediaTracks, this.filteredMediaTracks);
|
filterMediaTracks(allMediaTracks, this.filteredMediaTracks);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<DeviceIdentifier, Set<GPSFix>> getAllRelevantRaceLogTrackingFixes(GPSFixStore gpsFixStore) {
|
private Map<DeviceIdentifier, Set<Timed>> getAllRelevantRaceLogTrackingFixes(SensorFixStore sensorFixStore) {
|
||||||
Map<DeviceIdentifier, Set<GPSFix>> relevantFixes = new HashMap<>();
|
Map<DeviceIdentifier, Set<Timed>> relevantFixes = new HashMap<>();
|
||||||
|
|
||||||
//Add fixes for regatta log mappings
|
//Add fixes for regatta log mappings
|
||||||
for (Regatta regatta : getAllRegattas()) {
|
for (Regatta regatta : getAllRegattas()) {
|
||||||
@@ -91,7 +85,7 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
try {
|
try {
|
||||||
regattaLog.lockForRead();
|
regattaLog.lockForRead();
|
||||||
for (RegattaLogEvent logEvent : regattaLog.getRawFixes()) {
|
for (RegattaLogEvent logEvent : regattaLog.getRawFixes()) {
|
||||||
addAllFixesIfMappingEvent(gpsFixStore, relevantFixes, logEvent);
|
addAllFixesIfMappingEvent(sensorFixStore, relevantFixes, logEvent);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
regattaLog.unlockAfterRead();
|
regattaLog.unlockAfterRead();
|
||||||
@@ -106,7 +100,7 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
try {
|
try {
|
||||||
raceLog.lockForRead();
|
raceLog.lockForRead();
|
||||||
for (RaceLogEvent logEvent : raceLog.getRawFixes()) {
|
for (RaceLogEvent logEvent : raceLog.getRawFixes()) {
|
||||||
addAllFixesIfMappingEvent(gpsFixStore, relevantFixes, logEvent);
|
addAllFixesIfMappingEvent(sensorFixStore, relevantFixes, logEvent);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
raceLog.unlockAfterRead();
|
raceLog.unlockAfterRead();
|
||||||
@@ -118,12 +112,13 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
return relevantFixes;
|
return relevantFixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAllFixesIfMappingEvent(GPSFixStore gpsFixStore, Map<DeviceIdentifier, Set<GPSFix>> relevantFixes,
|
private void addAllFixesIfMappingEvent(SensorFixStore sensorFixStore,
|
||||||
|
Map<DeviceIdentifier, Set<Timed>> relevantFixes,
|
||||||
AbstractLogEvent<?> logEvent) {
|
AbstractLogEvent<?> logEvent) {
|
||||||
if (logEvent instanceof RegattaLogDeviceMappingEvent<?>) {
|
if (logEvent instanceof RegattaLogDeviceMappingEvent<?>) {
|
||||||
RegattaLogDeviceMappingEvent<?> mappingEvent = (RegattaLogDeviceMappingEvent<?>) logEvent;
|
RegattaLogDeviceMappingEvent<?> mappingEvent = (RegattaLogDeviceMappingEvent<?>) logEvent;
|
||||||
try {
|
try {
|
||||||
addAllFixesForMappingEvent(gpsFixStore, relevantFixes, mappingEvent);
|
addAllFixesForMappingEvent(sensorFixStore, relevantFixes, mappingEvent);
|
||||||
} catch (NoCorrespondingServiceRegisteredException | TransformationException e) {
|
} catch (NoCorrespondingServiceRegisteredException | TransformationException e) {
|
||||||
logger.severe("Failed to add fixes to exportdata for mapping Event");
|
logger.severe("Failed to add fixes to exportdata for mapping Event");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -131,33 +126,16 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addAllFixesForMappingEvent(GPSFixStore gpsFixStore, Map<DeviceIdentifier, Set<GPSFix>> relevantFixes,
|
private void addAllFixesForMappingEvent(SensorFixStore sensorFixStore,
|
||||||
|
Map<DeviceIdentifier, Set<Timed>> relevantFixes,
|
||||||
RegattaLogDeviceMappingEvent<?> mappingEvent) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
RegattaLogDeviceMappingEvent<?> mappingEvent) throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||||
DynamicGPSFixTrack<WithID, ?> track;
|
|
||||||
if (isMarkMappingEvent(mappingEvent)) {
|
|
||||||
track = new DynamicGPSFixTrackImpl<WithID>(mappingEvent.getMappedTo(), 10000);
|
|
||||||
} else {
|
|
||||||
track = new DynamicGPSFixMovingTrackImpl<WithID>(mappingEvent.getMappedTo(), 1000);
|
|
||||||
}
|
|
||||||
DeviceIdentifier device = mappingEvent.getDevice();
|
DeviceIdentifier device = mappingEvent.getDevice();
|
||||||
gpsFixStore.loadTrack(track, new DeviceMappingImpl<WithID>(mappingEvent.getMappedTo(), device,
|
|
||||||
new TimeRangeImpl(mappingEvent.getFrom(), mappingEvent.getTo())));
|
|
||||||
if (!relevantFixes.containsKey(device)) {
|
if (!relevantFixes.containsKey(device)) {
|
||||||
relevantFixes.put(device, new HashSet<>());
|
relevantFixes.put(device, new HashSet<>());
|
||||||
}
|
}
|
||||||
Set<GPSFix> fixes = relevantFixes.get(device);
|
Set<Timed> fixes = relevantFixes.get(device);
|
||||||
try {
|
sensorFixStore.loadFixes(fixes::add, mappingEvent.getDevice(), mappingEvent.getFrom(), mappingEvent.getTo(),
|
||||||
track.lockForRead();
|
true);
|
||||||
for (GPSFix fix : track.getRawFixes()) {
|
|
||||||
fixes.add(fix);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
track.unlockAfterRead();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMarkMappingEvent(RegattaLogDeviceMappingEvent<?> mappingEvent) {
|
|
||||||
return mappingEvent instanceof RegattaLogDeviceMarkMappingEvent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -335,7 +313,7 @@ public class TopLevelMasterData implements Serializable {
|
|||||||
return raceIdentifiers;
|
return raceIdentifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<DeviceIdentifier, Set<GPSFix>> getRaceLogTrackingFixes() {
|
public Map<DeviceIdentifier, Set<Timed>> getRaceLogTrackingFixes() {
|
||||||
return raceLogTrackingFixes;
|
return raceLogTrackingFixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+144
@@ -0,0 +1,144 @@
|
|||||||
|
package com.sap.sailing.domain.racelog.impl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceCompetitorMappingFinder;
|
||||||
|
import com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl.RegattaLogDeviceMarkMappingFinder;
|
||||||
|
import com.sap.sailing.domain.base.Competitor;
|
||||||
|
import com.sap.sailing.domain.base.Mark;
|
||||||
|
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
|
||||||
|
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||||
|
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.FixReceivedListener;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||||
|
import com.sap.sailing.domain.racelog.tracking.SensorFixStore;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceIdentifier;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMapping;
|
||||||
|
import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent;
|
||||||
|
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||||
|
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||||
|
import com.sap.sse.common.TimePoint;
|
||||||
|
import com.sap.sse.common.TimeRange;
|
||||||
|
import com.sap.sse.common.Util;
|
||||||
|
import com.sap.sse.common.WithID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At the moment, the timerange covered by the fixes for a device, and the number of
|
||||||
|
* fixes for a device are stored in a metadata collection. Should be changed, see bug 1982.
|
||||||
|
* @author Fredrik Teschke
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GPSFixStoreImpl implements GPSFixStore {
|
||||||
|
private final SensorFixStore sensorFixStore;
|
||||||
|
|
||||||
|
public GPSFixStoreImpl(SensorFixStore sensorFixStore) {
|
||||||
|
this.sensorFixStore = sensorFixStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <FixT extends GPSFix> void loadTrack(DynamicGPSFixTrack<?, FixT> track, DeviceIdentifier device,
|
||||||
|
TimePoint from, TimePoint to, boolean inclusive) throws NoCorrespondingServiceRegisteredException,
|
||||||
|
TransformationException {
|
||||||
|
sensorFixStore.<FixT>loadFixes(track::add, device, from, to, inclusive);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track, RegattaLog log, Competitor competitor)
|
||||||
|
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
||||||
|
List<DeviceMappingWithRegattaLogEvent<Competitor>> mappings = new RegattaLogDeviceCompetitorMappingFinder(log)
|
||||||
|
.analyze().get(competitor);
|
||||||
|
if (mappings != null) {
|
||||||
|
for (DeviceMapping<Competitor> mapping : mappings) {
|
||||||
|
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark)
|
||||||
|
throws NoCorrespondingServiceRegisteredException, TransformationException{
|
||||||
|
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze()
|
||||||
|
.get(mark);
|
||||||
|
if (mappings != null) {
|
||||||
|
for (DeviceMapping<Mark> mapping : mappings) {
|
||||||
|
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true /*inclusive*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeFix(DeviceIdentifier device, GPSFix fix) {
|
||||||
|
sensorFixStore.storeFix(device, fix);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void addListener(FixReceivedListener<GPSFix> listener, DeviceIdentifier device) {
|
||||||
|
sensorFixStore.addListener(listener, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void removeListener(FixReceivedListener<GPSFix> listener) {
|
||||||
|
sensorFixStore.removeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadCompetitorTrack(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||||
|
DeviceMapping<Competitor> mapping, TimePoint start, TimePoint end)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
// loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true
|
||||||
|
// /*inclusive*/);
|
||||||
|
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||||
|
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||||
|
loadTrack(track, mapping.getDevice(), from, to, true /* inclusive */);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, DeviceMapping<Mark> mapping, TimePoint start,
|
||||||
|
TimePoint end)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||||
|
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||||
|
loadTrack(track, mapping.getDevice(), from, to, true /* inclusive */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadMarkTrack(DynamicGPSFixTrack<Mark, GPSFix> track, RegattaLog log, Mark mark,
|
||||||
|
TimePoint start, TimePoint end) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
List<DeviceMappingWithRegattaLogEvent<Mark>> mappings = new RegattaLogDeviceMarkMappingFinder(log).analyze()
|
||||||
|
.get(mark);
|
||||||
|
if (mappings != null) {
|
||||||
|
for (DeviceMapping<Mark> mapping : mappings) {
|
||||||
|
final TimePoint from = Util.getLatestOfTimePoints(start, mapping.getTimeRange().from());
|
||||||
|
final TimePoint to = Util.getEarliestOfTimePoints(end, mapping.getTimeRange().to());
|
||||||
|
loadTrack(track, mapping.getDevice(), from, to, true /*inclusive*/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadTrack(DynamicGPSFixTrack<WithID, ?> track, DeviceMapping<WithID> mapping)
|
||||||
|
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||||
|
loadTrack(track, mapping.getDevice(), mapping.getTimeRange().from(), mapping.getTimeRange().to(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeRange getTimeRangeCoveredByFixes(DeviceIdentifier device)
|
||||||
|
throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
return sensorFixStore.getTimeRangeCoveredByFixes(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getNumberOfFixes(DeviceIdentifier device) throws TransformationException, NoCorrespondingServiceRegisteredException {
|
||||||
|
return sensorFixStore.getNumberOfFixes(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <FixT extends GPSFix> void loadFixes(Consumer<FixT> consumer, DeviceIdentifier deviceIdentifier,
|
||||||
|
TimePoint start, TimePoint end, boolean inclusive)
|
||||||
|
throws NoCorrespondingServiceRegisteredException, TransformationException {
|
||||||
|
sensorFixStore.loadFixes(consumer, deviceIdentifier, start, end, inclusive);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loaded 100 of 215 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user