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

This commit is contained in:
fmittag committed 2014-10-13 14:09:05 +02:00
commit 4b2d2aeb6e
20 files changed
+378 -105

No files matched your search

@@ -14,7 +14,7 @@ public class SmartphoneUUIDSerializationHandler {
}
public Util.Pair<String, String> serialize(DeviceIdentifier deviceIdentifier) throws TransformationException {
return new Util.Pair<String, String>(castIdentifier(deviceIdentifier).getUUID().toString(), SmartphoneUUIDIdentifier.TYPE);
return new Util.Pair<String, String>(SmartphoneUUIDIdentifier.TYPE, castIdentifier(deviceIdentifier).getUUID().toString());
}
public DeviceIdentifier deserialize(String input, String type, String stringRep) throws TransformationException {
+29 -28
View File
@@ -18,34 +18,35 @@
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
</listAttribute>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#13;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#13;&#10;&lt;/runtimeClasspathEntry&gt;&#13;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.gwt.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.googlecode.java-diff-utils/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.json.simple/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.expeditionconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.declination/resources&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.udpconnector/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.mongodb/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.swisstimingadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.operationaltransformation/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.domain.tractracadapter.persistence/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/org.moxieapps.gwt.highcharts/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.geocoding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.server.replication/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sailing.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.datamining.shared/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.gwt/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.google.gwt.osgi/lib/gwt-user.jar&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.security.ui/src/main/java&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
</listAttribute>
<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"/>
@@ -79,6 +79,9 @@
<source path='ui/shared' />
<source path='ui/actions' />
<source path='ui/simulator' />
<source path='ui/adminconsole' />
<source path='ui/usermanagement' />
<source path='ui/masterdataimport' />
<source path='ui/regattaoverview' />
<source path='ui/leaderboard'/>
<source path='home' />
@@ -34,6 +34,9 @@
<source path='common'/>
<source path="client" />
<source path="datamining" />
<source path="adminconsole" />
<source path="masterdataimport" />
<source path="usermanagement" />
<source path="simulator" />
<source path='shared' />
<source path='common' />
@@ -52,6 +52,9 @@
<source path='common'/>
<source path='client'/>
<source path='controls'/>
<source path='adminconsole'/>
<source path='usermanagement'/>
<source path='masterdataimport'/>
<source path='components'/>
<source path='leaderboard'/>
<source path='regattaoverview'/>
@@ -37,7 +37,7 @@
<!-- Specify the app entry point class. -->
<entry-point class='com.sap.sailing.gwt.ui.simulator.SimulatorEntryPoint'/>
<!-- Specify the paths for translatable code -->
<extend-property name="locale" values="de"/>
<extend-property name="locale" values="de"/>
<extend-property name="locale" values="ru"/>
<source path='common'/>
@@ -46,7 +46,10 @@
<source path='actions'/>
<source path='simulator'/>
<source path='leaderboard'/>
<source path='adminconsole'/>
<source path='usermanagement'/>
<source path='masterdataimport'/>
<inherits name='com.google.gwt.logging.Logging'/>
<set-property name="gwt.logging.enabled" value="FALSE"/>
<!-- Set logging level to INFO -->
@@ -37,6 +37,8 @@
<source path='client'/>
<source path='simulator'/>
<source path='usermanagement'/>
<source path='masterdataimport'/>
<source path='adminconsole'/>
<source path='shared'/>
<source path='leaderboard'/>
</module>
@@ -10,6 +10,11 @@
<inherits name="com.sap.sse.SSECommon" />
<inherits name="com.sap.sailing.domain.SailingDomain" />
<!-- Fancy DateTimePicker (without the rest of Bootstrap!) -->
<!-- GWT-Bootstrap License: Apache License, Version 2.0 -->
<inherits name="com.github.gwtbootstrap.BootstrapNoResources" />
<inherits name='com.github.gwtbootstrap.datetimepicker.DatetimepickerNoResources' />
<!-- Highcharts API -->
<inherits name="org.moxieapps.gwt.highcharts.Highcharts" />
<!-- Google Maps API -->
@@ -23,7 +28,11 @@
<extend-property name="locale" values="de"/>
<source path='client' />
<source path='actions'/>
<source path='shared'/>
<source path='common'/>
<source path='adminconsole'/>
<source path='usermanagement'/>
<source path='masterdataimport'/>
<source path='simulator'/>
<source path='leaderboard'/>
</module>
@@ -11,7 +11,11 @@
<inherits name="com.sap.sailing.domain.SailingDomain" />
<!-- Highcharts API -->
<inherits name="org.moxieapps.gwt.highcharts.Highcharts" />
<!-- Google Maps API -->
<!-- Fancy DateTimePicker (without the rest of Bootstrap!) -->
<!-- GWT-Bootstrap License: Apache License, Version 2.0 -->
<inherits name="com.github.gwtbootstrap.BootstrapNoResources" />
<inherits name='com.github.gwtbootstrap.datetimepicker.DatetimepickerNoResources' />
<!-- Google Maps API -->
<inherits name='com.google.gwt.ajaxloader.AjaxLoader' />
<inherits name='com.google.gwt.maps.Maps' />
<!-- GWT JSON Support -->
@@ -25,5 +29,8 @@
<source path='actions'/>
<source path='common'/>
<source path='simulator'/>
<source path='adminconsole'/>
<source path='usermanagement'/>
<source path='masterdataimport'/>
<source path='leaderboard'/>
</module>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -1,12 +1,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.compiler.source=1.7
@@ -4,7 +4,7 @@ Bundle-Name: Shared
Bundle-SymbolicName: com.sap.sse.datamining.shared
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Export-Package: com.sap.sse.datamining.shared,
com.sap.sse.datamining.shared.annotations,
com.sap.sse.datamining.shared.components,
@@ -0,0 +1,130 @@
package com.sap.sse.gwt.client;
import java.util.HashSet;
import java.util.Set;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.shared.HandlerRegistration;
/**
* Represents the browser's localStorage and sessionStorage objects and provides eventing support.
*
* @author Axel Uhl (D043530)
*
*/
public class Storage extends JavaScriptObject {
private static final Set<StorageEvent.Handler> storageEventHandlers = new HashSet<>();
static {
registerAsStorageEventHandler();
}
protected Storage() {
super();
}
private static void registerAsStorageEventHandler() {
if (isSupported()) {
registerAsStorageEventHandlerImpl();
}
}
private static native void registerAsStorageEventHandlerImpl() /*-{
$wnd.addEventListener("storage", function(e) {
@com.sap.sse.gwt.client.Storage::onStorageEvent(Lcom/google/gwt/core/client/JavaScriptObject;)(e);
});
}-*/;
public static HandlerRegistration addStorageEventHandler(final StorageEvent.Handler handler) {
storageEventHandlers.add(handler);
return new HandlerRegistration() {
@Override
public void removeHandler() {
storageEventHandlers.remove(handler);
}
};
}
public static void removeStorageEventHandler(StorageEvent.Handler handler) {
storageEventHandlers.remove(handler);
}
private static void onStorageEvent(JavaScriptObject event) {
StorageEvent storageEvent = event.cast();
for (StorageEvent.Handler handler : storageEventHandlers) {
handler.onStorageChange(storageEvent);
}
}
private native static JavaScriptObject getLocalStorageIfSupportedImpl() /*-{
return $wnd.localStorage;
}-*/;
private native static JavaScriptObject getSessionStorageIfSupportedImpl() /*-{
return $wnd.sessionStorage;
}-*/;
public native static boolean isLocalStorageSupported() /*-{
try {
return "localStorage" in $wnd && $wnd["localStorage"] !== null;
} catch (e) {
return false;
}
}-*/;
public native static boolean isSessionStorageSupported() /*-{
try {
return "sessionStorage" in $wnd && $wnd["sessionStorage"] !== null;
} catch (e) {
return false;
}
}-*/;
public static boolean isSupported() {
return isLocalStorageSupported() && isSessionStorageSupported();
}
public static Storage getLocalStorageIfSupported() {
final Storage result;
if (isLocalStorageSupported()) {
result = getLocalStorageIfSupportedImpl().cast();
} else {
result = null;
}
return result;
}
public static Storage getSessionStorageIfSupported() {
final Storage result;
if (isSessionStorageSupported()) {
result = getSessionStorageIfSupportedImpl().cast();
} else {
result = null;
}
return result;
}
public final native void setItem(String key, String value) /*-{
this.setItem(key, value);
}-*/;
public final native String getItem(String key) /*-{
return this.getItem(key);
}-*/;
public final native void removeItem(String key) /*-{
return this.removeItem(key);
}-*/;
public final native void clear() /*-{
this.clear();
}-*/;
public final native String getKey(int index) /*-{
return this.key(index);
}-*/;
public final native int getLength() /*-{
return this.length;
}-*/;
}
@@ -0,0 +1,46 @@
package com.sap.sse.gwt.client;
import com.google.gwt.core.client.JavaScriptObject;
/**
* A change event sent to a {@link Handler} object that has been {@link Storage#addStorageEventHandler(Handler) registered}
* with the browser's {@link Storage}. It will receive events from both, the session storage and the local storage. Which one
* the event came from can be determined by calling {@link #getStorageArea()} on the event and comparing with either
* {@link Storage#getLocalStorageIfSupported()} or {@link Storage#getSessionStorageIfSupported()}.
*
* @author Axel Uhl (D043530)
*
*/
public class StorageEvent extends JavaScriptObject {
protected StorageEvent() {
super();
}
public static interface Handler {
void onStorageChange(StorageEvent event);
}
public final native String getKey() /*-{
return this.key;
}-*/;
public final native String getNewValue() /*-{
return this.newValue;
}-*/;
public final native String getOldValue() /*-{
return this.oldValue;
}-*/;
public final Storage getStorageArea() {
return getStorageAreaImpl().cast();
}
private final native JavaScriptObject getStorageAreaImpl() /*-{
return this.storageArea;
}-*/;
public final native String getUrl() /*-{
return this.url;
}-*/;
}
+3 -1
View File
@@ -9,7 +9,9 @@ The script `/home/gollum/wiki/serve.sh` can be executed to either start or resta
Accessing this wiki is normally only allowed for authenticated users. If you want to share your work with others not having an account here then you can just request making a given url publicly available. On the server this is done by simply putting a new line to `/home/gollum/wiki/public.txt`.
### Creating a New Account
A new account can be created by adding a new entry to `/home/gollum/wiki/users.yml`. The password there is encrypted using sha1sum (`echo -n "password" | sha1sum`) or, for those who don't happen to have sha1sum available, using an online SHA1 generator such as [this one](http://www.sha1-online.com/).
Send a request to Axel Uhl or Simon Marcel Pamies that includes the SHA1 hash of your desired password. Obtain such an SHA1 hash for your password here: http://www.sha1-online.com/.
A Wiki administrator can add a new account by adding a new entry to `/home/gollum/wiki/users.yml`. The password there is encrypted using sha1sum (`echo -n "password" | sha1sum`) or, for those who don't happen to have sha1sum available, using an online SHA1 generator such as [this one](http://www.sha1-online.com/).
### Editing
You can edit information here freely but do not leave any nonsense here.
+15 -1
View File
@@ -1,3 +1,17 @@
# Live Audio Streaming
See also [Bug 1522](http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=1522). We currently have the ManyPlayers Race Viewer that supports this use case. It is based on Flash and requires several additional server-side components. Adding live audio support to the HTML-based SAP Sailing Analytics could simplify the consumption of live audio streams for certain use cases and could ease server administration considerably.
See also [Bug 1522](http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=1522). We currently have the ManyPlayers Race Viewer that supports this use case. It is based on Flash and requires several additional server-side components. Adding live audio support to the HTML-based SAP Sailing Analytics could simplify the consumption of live audio streams for certain use cases and could ease server administration considerably.
# Update Oct 13 2014
With commit 11d7a168 we support Youtube live streaming. This can be used as replacement for audio-only streaming.
## Benefits
- Recording and streaming is all provided by Youtube.
- Can be complemented with video and other Youtube gimmicks (live pictures, stills, user notifications, user links)
## Shortcomings
- 4h max. duration per session. Otherwise Youtube's rolling storage starts overwriting old content.
- Audio-only not yet possible. But hiding the video panel should be not too much effort.
+1 -1
View File
@@ -14,6 +14,6 @@ We need easy to use and manage sign up, sign on, sign out and manage user accoun
See also bug 27 (http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=27).
There is a branch `usermanagement` that contains Benjamin Ebling's contributions to the subject, namely a set of bundles that integrate Apache Shiro with the SAP Sailing Analytics, providing the necessary sign-up, sign-on and sign-out functionality and allowing front end and back end to identify the current user.
There is a branch `usermanagement` that contains Benjamin Ebling's contributions to the subject, namely a set of bundles that integrate Apache Shiro with the SAP Sailing Analytics, providing the necessary sign-up, sign-on and sign-out functionality and allowing front end and back end to identify the current user. This branch has been forked to `axel-usermanagement` which is the continuation of Benjamin's work, working towards master mergability.
On top of that we need to implement account management where users can be assigned to specific accounts, such as a club or event of regatta account. Access by users to administrative features of regattas and events and analytics visibility could then be nicely restricted to users belonging to the right accounts. Technically, an account could probably be implemented as a role, and events, regattas or races could use such special roles to control access to their data.
+4 -65
View File
@@ -5,69 +5,8 @@ The term itself should be revised at some point, and currently refers to the tec
This is the second iteration of implementing this idea. For previous documentation, see [[smartphone tracking|wiki/smartphone-tracking]].
[[_TOC_]]
## Server Architecture
[[Server Architecture|wiki/racelog-tracking/server]]
# Development Infos
RaceLog tracking has been merged into the master branch with commit 4b4b61b6c518139f4389aabd73c282621711855a. It was developed on the following branches:
* ``ftes-rltracking``: The main RaceLog-tracking development
* ``ftes-rltracking-equestrian``: Serves as a reference implementation of a tracking adapter built for RaceLog-tracking.
# Architectural Overview
The basic architecture of Racelog-tracking is presented in this diagram (download as [[PDF|racelog-tracking/architecture.pdf]]):
[[racelog-tracking/architecture.svg]]
Following the numbers in the diagram, this is a possible race log tracking scenario:
1. The race is defined through events that are added to the RaceLog.
2. The RaceTracker is created.
3. As soon as the "StartTrackingEvent" is added to the RaceLog, the RaceTracker creates the TrackedRace.
4. Tracking devices submit GPS fixes to the tracking adapter. This adds these fixes to the global GPSFixStore.
5. The GPSFixStore notifies its listeners - among them the RaceTrackers - of new fixes. Each RaceTracker checks whether a new fix matches the mappings defined in its RaceLog, and if so adds it to the TrackedRace.
Not all identifiers represent actual class or bundle names. For a more technical documentation, refer to the JavaDoc in the various ``*.racelog.tracking`` packages and the ``com.sap.sailing.domain.racelogtrackingadapter`` bundle. The following interfaces and classes are good starting points:
* DeviceIdentifier
* DeviceIdentifierSerializationHandler
* Revokable
* DeviceMappingFinder
* PingDeviceIdentifier, PlaceHolderDeviceIdentifier
# AdminConsole Components
Currently, RaceLogs can be filled with the race metadata via the _RaceLog Tracking_ panel in the AdminConsole. Here one can denote RaceColumn/Fleet combinations within RegattaLeaderboards for RaceLog-tracking, register competitors, define the course layout, add device mappings, and finally start tracking.
When thinking about smartphone tracking, it would of course be a good idea to also integrate similar functionality into the tracking app. Some parts of the communication (registering competitors, defining the course, mapping devices) can be handled via the existing RaceLog communication mechanism. Other parts (creating the Leaderboard structure in the first place, adding the RaceLog tracker) have to be dealt with separately, e.g. via a REST API.
## Steps for setting up a racelog-tracked race in the AdminConsole
[[Walkthrough with screenshots|wiki/racelog-tracking/walkthrough]]
## Reloading a race that has already been tracked
Technically, the entire race is loaded as soon as the RaceLogRaceTracker is attached to the RaceLog, as it will find the already existing StartTrackingEvent and load all fixes that correspond to the mappings.
In the AdminConsole, triggering this step is no different from adding the tracker for the very first time, do so with the _start tracking_ button the the RaceLog Tracking Panel.
# ToDos
## Archiving old Races
Since RaceLog-tracking allows for fully independent tracking, storing and reloading of races, it may be a good foundation for archiving old races. Currently, we rely on tracking providers to retain all data indefinitely, so that it can be reloaded, e.g., after restarting the server. Also see [[bug 2|http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=2]] for more details.
## Smartphone Tracking
RaceLog-tracking provides the server-side abilities for independent tracking. Therefore, using smartphones for tracking is one possible application. So far, there is no implementation in terms of a smartphone app. The relation to the existing RaceCommittee app has be be considered, as both should share a common code base, and as there should be certain points of integration (e.g., first defining the race in the tracking app, then setting the start time in the RC-app, and finally tracking one boat with that smartphone - again with the tracking app).
The first option is to simply share code through a Android library module, the second option is integrating everything into one app with two launchers (one for tracking, one for the RaceCommittee functionality).
# How to create a Tracking Adapter
By using the OSGi service registry, adapters are completely decoupled from the Sailing Analytics code. In future, it should be possible to simply deploy one additional bundle to the OSGi server in addition to the Sailing Analytics bundles. This requires provisioning the relevant bundles containing interfaces for the development of the adapter.
The first attempt so far (``ftes-rltracking-equestrian`` branch) is completely restricted to one bundle. However, this is a branch branched from ``master``, and the new bundle has been added to the existing launch configurations and build and deployment descriptors (``pom.xml``, ``feature.xml``, ``raceanalysis.product``). This makes developing and testing easy, but is not in line with the goal stated above.
Steps for creating an adapter:
1. Create a new project: ``com.sap.sailing.domain.<adaptername>``. Think about duplicating an existing project, such as ``com.sap.sailing.domain.racelogtrackingadapter``. In this case, don't forget to adapt the project's ``pom.xml``, ``META-INF/MANIFEST.MF`` and ``.project`` files.
2. Add the new project to the maven build in ``java/pom.xml``.
3. Add the project as an auto-start bundle to the eclipse launch configs. The bundle needs to be started before the central ``com.sap.sailing.server`` bundle, for which currently a startup-level of ``3`` is sufficient.
4. Add the bundle to the ``com.sap.sailing.feature/feature.xml``, and also to the ``com.sap.sailing.feature.p2build/raceanalysis.product`` with the same startup properties as before.
5. Implement a ``DeviceIdentifier`` and the appropriate ``DeviceIdentifierSerializationHandler``s (refer to the JavaDoc of ``DeviceIdentifier``).
6. Register your serialization handlers through the OSGi service registry (refer to the JavaDoc of ``DeviceIdentifierSerializationHandler`` for an example on how to do so).
7. Add some kind of Servlet or similar that adds fixes to the GPSFixStore by calling ``storeFix(DeviceIdentifier device, GPSFix fix)`` on the `GPSFixStore` which can be obtained from `RacingEventService.getGPSFixStore()`.
8. Fire up the server, let OSGi work its magic, define the race metadata and start adding fixes.
## App Architecture
[[App Architecture|wiki/racelog-tracking/app]]
+43
View File
@@ -0,0 +1,43 @@
# RaceLog Tracking App Architecture
[[_TOC_]]
# Development Info
Development is currently underway on the following branches:
* ``ftes-rltracking-app``
* ``jbross-rltracking-app``
# Project and Build structure
## Projects
* ``com.sap.sailing.android.shared`` contains shared code and resources between the Android apps (tracking and [[RCApp|wiki/racecommittee-app]])
* ``com.sap.sailing.android.tracking.app`` is the main project for the app
## Maven
The app cannot only be built and deployed via the Android Eclipse tooling, but is also integrated into the maven build.
## Deployment
# Sending Fixes
* currently to the ``RecordFixesFlatJsonPostServlet`` in the ``racelogtrackingadapter``
```
{ deviceUuid: ...,
timeMillis: ...,
latDeg: ...,
lonDeg: ...,
speedMperS: ...,
bearingDeg: ... }
```
# Mapping to a Competitor
We use a QRCode to transfer the necessary server, race and competitor data to the smartphone. The app can then add the mapping to the RaceLog (the race data is necessary to determine which RaceLog to add to, and the MappingEvent that is added to the RaceLog then contains the DeviceIdentifier and Competitor ID).
Structure of the URL encoded in the QRCode:
```
<serverURL-and-port>/apps/com.sap.sailing.android.tracking.app.apk
?leaderboard=<...>
&raceColumn=<...>
&fleet=<...>
&competitor=<...>
```
By beginning the URL with ``<serverURL-and-port>/apps/com.sap.sailing.android.tracking.app.apk`` it is possible to download and install the app directly, if the QRCode is scanned with a barcode-scanner app.
+68
View File
@@ -0,0 +1,68 @@
# RaceLog Tracking Server Architecture
[[_TOC_]]
# Development Infos
RaceLog tracking has been merged into the master branch with commit 4b4b61b6c518139f4389aabd73c282621711855a. It was developed on the following branches:
* ``ftes-rltracking``: The main RaceLog-tracking development
* ``ftes-rltracking-equestrian``: Serves as a reference implementation of a tracking adapter built for RaceLog-tracking.
# Architectural Overview
The basic architecture of Racelog-tracking is presented in this diagram (download as [[PDF|/wiki/racelog-tracking/architecture.pdf]]):
[[/wiki/racelog-tracking/architecture.svg]]
Following the numbers in the diagram, this is a possible race log tracking scenario:
1. The race is defined through events that are added to the RaceLog.
2. The RaceTracker is created.
3. As soon as the "StartTrackingEvent" is added to the RaceLog, the RaceTracker creates the TrackedRace.
4. Tracking devices submit GPS fixes to the tracking adapter. This adds these fixes to the global GPSFixStore.
5. The GPSFixStore notifies its listeners - among them the RaceTrackers - of new fixes. Each RaceTracker checks whether a new fix matches the mappings defined in its RaceLog, and if so adds it to the TrackedRace.
Not all identifiers represent actual class or bundle names. For a more technical documentation, refer to the JavaDoc in the various ``*.racelog.tracking`` packages and the ``com.sap.sailing.domain.racelogtrackingadapter`` bundle. The following interfaces and classes are good starting points:
* DeviceIdentifier
* DeviceIdentifierSerializationHandler
* Revokable
* DeviceMappingFinder
* PingDeviceIdentifier, PlaceHolderDeviceIdentifier
# AdminConsole Components
Currently, RaceLogs can be filled with the race metadata via the _RaceLog Tracking_ panel in the AdminConsole. Here one can denote RaceColumn/Fleet combinations within RegattaLeaderboards for RaceLog-tracking, register competitors, define the course layout, add device mappings, and finally start tracking.
When thinking about smartphone tracking, it would of course be a good idea to also integrate similar functionality into the tracking app. Some parts of the communication (registering competitors, defining the course, mapping devices) can be handled via the existing RaceLog communication mechanism. Other parts (creating the Leaderboard structure in the first place, adding the RaceLog tracker) have to be dealt with separately, e.g. via a REST API.
## Steps for setting up a racelog-tracked race in the AdminConsole
[[Walkthrough with screenshots|wiki/racelog-tracking/walkthrough]]
## Reloading a race that has already been tracked
Technically, the entire race is loaded as soon as the RaceLogRaceTracker is attached to the RaceLog, as it will find the already existing StartTrackingEvent and load all fixes that correspond to the mappings.
In the AdminConsole, triggering this step is no different from adding the tracker for the very first time, do so with the _start tracking_ button the the RaceLog Tracking Panel.
# ToDos
## Archiving old Races
Since RaceLog-tracking allows for fully independent tracking, storing and reloading of races, it may be a good foundation for archiving old races. Currently, we rely on tracking providers to retain all data indefinitely, so that it can be reloaded, e.g., after restarting the server. Also see [[bug 2|http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=2]] for more details.
## Smartphone Tracking
RaceLog-tracking provides the server-side abilities for independent tracking. Therefore, using smartphones for tracking is one possible application. So far, there is no implementation in terms of a smartphone app. The relation to the existing RaceCommittee app has be be considered, as both should share a common code base, and as there should be certain points of integration (e.g., first defining the race in the tracking app, then setting the start time in the RC-app, and finally tracking one boat with that smartphone - again with the tracking app).
The first option is to simply share code through a Android library module, the second option is integrating everything into one app with two launchers (one for tracking, one for the RaceCommittee functionality).
# How to create a Tracking Adapter
By using the OSGi service registry, adapters are completely decoupled from the Sailing Analytics code. In future, it should be possible to simply deploy one additional bundle to the OSGi server in addition to the Sailing Analytics bundles. This requires provisioning the relevant bundles containing interfaces for the development of the adapter.
The first attempt so far (``ftes-rltracking-equestrian`` branch) is completely restricted to one bundle. However, this is a branch branched from ``master``, and the new bundle has been added to the existing launch configurations and build and deployment descriptors (``pom.xml``, ``feature.xml``, ``raceanalysis.product``). This makes developing and testing easy, but is not in line with the goal stated above.
Steps for creating an adapter:
1. Create a new project: ``com.sap.sailing.domain.<adaptername>``. Think about duplicating an existing project, such as ``com.sap.sailing.domain.racelogtrackingadapter``. In this case, don't forget to adapt the project's ``pom.xml``, ``META-INF/MANIFEST.MF`` and ``.project`` files.
2. Add the new project to the maven build in ``java/pom.xml``.
3. Add the project as an auto-start bundle to the eclipse launch configs. The bundle needs to be started before the central ``com.sap.sailing.server`` bundle, for which currently a startup-level of ``3`` is sufficient.
4. Add the bundle to the ``com.sap.sailing.feature/feature.xml``, and also to the ``com.sap.sailing.feature.p2build/raceanalysis.product`` with the same startup properties as before.
5. Implement a ``DeviceIdentifier`` and the appropriate ``DeviceIdentifierSerializationHandler``s (refer to the JavaDoc of ``DeviceIdentifier``).
6. Register your serialization handlers through the OSGi service registry (refer to the JavaDoc of ``DeviceIdentifierSerializationHandler`` for an example on how to do so).
7. Add some kind of Servlet or similar that adds fixes to the GPSFixStore by calling ``storeFix(DeviceIdentifier device, GPSFix fix)`` on the `GPSFixStore` which can be obtained from `RacingEventService.getGPSFixStore()`.
8. Fire up the server, let OSGi work its magic, define the race metadata and start adding fixes.