mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-08 13:20:57 +00:00
Merge commit 'origin/master'
Conflicts: home.md
This commit is contained in:
commit
36c55714f3
794 files changed
+88964
-42207
No files matched your search
@@ -277,7 +277,9 @@ if [[ "$@" == "build" ]] || [[ "$@" == "all" ]]; then
|
||||
|
||||
if [ $testing -eq 0 ]; then
|
||||
echo "INFO: Skipping tests"
|
||||
extra="$extra -Dmaven.test.skip=true"
|
||||
extra="$extra -Dmaven.test.skip=true -DskipTests=true"
|
||||
else
|
||||
extra="$extra -DskipTests=false"
|
||||
fi
|
||||
|
||||
if [ $offline -eq 1 ]; then
|
||||
@@ -342,11 +344,14 @@ if [[ "$@" == "install" ]] || [[ "$@" == "all" ]]; then
|
||||
rm -rf $ACDIR/org.eclipse.*
|
||||
rm -rf $ACDIR/configuration/org.eclipse.*
|
||||
|
||||
# always overwrite start and stop scripts as they
|
||||
# should never contain any custom logic
|
||||
cp -v $PROJECT_HOME/java/target/start $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/stop $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/status $ACDIR/
|
||||
|
||||
if [ ! -f "$ACDIR/env.sh" ]; then
|
||||
cp -v $PROJECT_HOME/java/target/env.sh $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/start $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/stop $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/status $ACDIR/
|
||||
fi
|
||||
|
||||
if [ ! -f $ACDIR/no-overwrite ]; then
|
||||
@@ -354,14 +359,13 @@ if [[ "$@" == "install" ]] || [[ "$@" == "all" ]]; then
|
||||
|
||||
mkdir -p configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/jetty.xml configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/jetty-selector.xml configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/jetty-deployer.xml configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/jetty/etc/realm.properties configuration/jetty/etc
|
||||
cp -v $PROJECT_HOME/java/target/configuration/monitoring.properties configuration/
|
||||
cp -v $PROJECT_HOME/configuration/mongodb.cfg $ACDIR/
|
||||
|
||||
cp -v $PROJECT_HOME/java/target/env.sh $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/start $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/stop $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/status $ACDIR/
|
||||
cp -v $PROJECT_HOME/java/target/udpmirror $ACDIR/
|
||||
|
||||
cp -v $PROJECT_HOME/java/target/http2udpmirror $ACDIR
|
||||
|
||||
@@ -508,7 +508,9 @@ into one in the future.
|
||||
structure:
|
||||
{ "name": ..., // race name
|
||||
"startoftracking": ..., // millisecond timestamp
|
||||
"endoftracking": ..., // millisecond timestamp
|
||||
"start": ..., // millisecond timestamp
|
||||
"end": ..., // millisecond timestamp
|
||||
"timeofnewestevent": ...,// greatest millisecond timestamp
|
||||
// of any event received so far
|
||||
"timeoflastevent": ..., // millisecond timestamp
|
||||
|
||||
BIN
Binary file not shown.
Binary file not shown.
@@ -30,8 +30,12 @@ Like businesses, sailors need the latest information to make strategic decisions
|
||||
* [[Sailing Domain Algorithms|wiki/sailing-domain-algorithms]]
|
||||
* [[Inventory|wiki/inventar-liste]]
|
||||
* [[Smartphone Tracking|wiki/smartphone-tracking]]
|
||||
<<<<<<< HEAD:home.md
|
||||
* [[Racecommittee App|wiki/racecommittee-app]]
|
||||
* [[Web Services API|wiki/sailing-webservices]]
|
||||
=======
|
||||
* [[Theses (Bachelor, Master, ...)|wiki/theses]]
|
||||
>>>>>>> origin/master:home.md
|
||||
* Planning and Event Information
|
||||
* [[Project Planning (bigger development)|wiki/planning]]
|
||||
* [[General Event Planning|wiki/general-event-planning]]
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
<classpath>
|
||||
<classpathentry exported="true" kind="lib" path="lib/gwt-dev.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/gwt-user.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/validation-api-1.0.0.GA-sources.jar"/>
|
||||
<classpathentry exported="true" kind="lib" path="lib/validation-api-1.0.0.GA.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<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"/>
|
||||
|
||||
@@ -7,10 +7,7 @@ Bundle-Vendor: GOOGLE
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ClassPath: lib/gwt-dev.jar,
|
||||
lib/gwt-user.jar,
|
||||
lib/validation-api-1.0.0.GA-sources.jar,
|
||||
lib/validation-api-1.0.0.GA.jar,
|
||||
.
|
||||
Eclipse-BuddyPolicy: registered
|
||||
Export-Package: com.gargoylesoftware.htmlunit,
|
||||
com.gargoylesoftware.htmlunit.attachment,
|
||||
com.gargoylesoftware.htmlunit.gae,
|
||||
@@ -601,4 +598,6 @@ Export-Package: com.gargoylesoftware.htmlunit,
|
||||
org.mortbay.util,
|
||||
org.mortbay.util.ajax,
|
||||
org.mortbay.xml
|
||||
Require-Bundle: javax.servlet;bundle-version="2.5.0";visibility:=reexport
|
||||
Require-Bundle: javax.validation;bundle-version="1.0.0"
|
||||
Import-Package: javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0"
|
||||
@@ -1,6 +1,4 @@
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
lib/gwt-dev.jar,\
|
||||
lib/gwt-user.jar,\
|
||||
lib/validation-api-1.0.0.GA-sources.jar,\
|
||||
lib/validation-api-1.0.0.GA.jar
|
||||
lib/gwt-user.jar
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.google.gwt.user.osgi</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
+1
-1
@@ -23,11 +23,11 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.barbados.resultimport.impl.BarbadosResultSpreadsheet;
|
||||
import com.sap.sailing.barbados.resultimport.impl.ScoreCorrectionProviderImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.RegattaScoreCorrections;
|
||||
import com.sap.sailing.domain.common.RegattaScoreCorrections.ScoreCorrectionsForRace;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.resultimport.RegattaResults;
|
||||
import com.sap.sailing.resultimport.ResultDocumentDescriptor;
|
||||
|
||||
@@ -6,8 +6,7 @@ Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Fragment-Host: com.sap.sailing.declination
|
||||
Require-Bundle: org.junit4;bundle-version="4.8.2"
|
||||
Import-Package: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.common.impl,
|
||||
com.sap.sailing.domain.common.quadtree,
|
||||
junit.framework;version="4.8.1",
|
||||
org.junit;version="4.8.1"
|
||||
com.sap.sailing.domain.common.quadtree
|
||||
+1
-1
@@ -14,8 +14,8 @@ import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class DeclinationImportTest extends AbstractDeclinationTest {
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -13,9 +13,9 @@ import org.junit.Test;
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.declination.impl.DeclinationServiceImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.CentralAngleDistance;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class DeclinationServiceTest extends AbstractDeclinationTest {
|
||||
private DeclinationService service;
|
||||
|
||||
+10
-10
@@ -30,12 +30,12 @@ import org.junit.Test;
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.declination.impl.DeclinationRecordImpl;
|
||||
import com.sap.sailing.declination.impl.DeclinationStore;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.quadtree.QuadTree;
|
||||
|
||||
public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
@@ -70,7 +70,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
oos1.close();
|
||||
ByteArrayOutputStream bos2 = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos2 = new ObjectOutputStream(bos2);
|
||||
oos2.writeUTF("Tätäräää");
|
||||
oos2.writeUTF("T�t�r���");
|
||||
oos2.close();
|
||||
byte[] bos1Arr = bos1.toByteArray();
|
||||
byte[] bos2Arr = bos2.toByteArray();
|
||||
@@ -103,7 +103,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
// don't write a second header
|
||||
}
|
||||
};
|
||||
oos2.writeUTF("Tätäräää");
|
||||
oos2.writeUTF("T�t�r���");
|
||||
oos2.close();
|
||||
byte[] bos1Arr = bos1.toByteArray();
|
||||
byte[] bos2Arr = bos2.toByteArray();
|
||||
@@ -115,7 +115,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
String s1 = ois.readUTF();
|
||||
assertEquals("Humba Humba", s1);
|
||||
String s2 = ois.readUTF();
|
||||
assertEquals("Tätäräää", s2);
|
||||
assertEquals("T�t�r���", s2);
|
||||
ois.close();
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
// don't write a second header
|
||||
}
|
||||
};
|
||||
oos2.writeUTF("Tätäräää");
|
||||
oos2.writeUTF("T�t�r���");
|
||||
oos2.writeDouble(1.);
|
||||
oos2.writeDouble(2.);
|
||||
oos2.writeDouble(3.);
|
||||
@@ -156,7 +156,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
assertEquals(3., ois.readDouble(), 0.000000001);
|
||||
assertEquals(4., ois.readDouble(), 0.000000001);
|
||||
String s2 = ois.readUTF();
|
||||
assertEquals("Tätäräää", s2);
|
||||
assertEquals("T�t�r���", s2);
|
||||
assertEquals(1., ois.readDouble(), 0.000000001);
|
||||
assertEquals(2., ois.readDouble(), 0.000000001);
|
||||
assertEquals(3., ois.readDouble(), 0.000000001);
|
||||
@@ -182,7 +182,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
// don't write a second header
|
||||
}
|
||||
};
|
||||
oos2.writeUTF("Tätäräää");
|
||||
oos2.writeUTF("T�t�r���");
|
||||
oos2.writeDouble(1.);
|
||||
oos2.writeDouble(2.);
|
||||
oos2.writeDouble(3.);
|
||||
@@ -202,7 +202,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
assertEquals(3., ois.readDouble(), 0.000000001);
|
||||
assertEquals(4., ois.readDouble(), 0.000000001);
|
||||
String s2 = ois.readUTF();
|
||||
assertEquals("Tätäräää", s2);
|
||||
assertEquals("T�t�r���", s2);
|
||||
assertEquals(1., ois.readDouble(), 0.000000001);
|
||||
assertEquals(2., ois.readDouble(), 0.000000001);
|
||||
assertEquals(3., ois.readDouble(), 0.000000001);
|
||||
@@ -233,7 +233,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
// don't write a second header
|
||||
}
|
||||
};
|
||||
oos2.writeUTF("Tätäräää");
|
||||
oos2.writeUTF("T�t�r���");
|
||||
oos2.writeDouble(1.);
|
||||
oos2.writeDouble(2.);
|
||||
oos2.writeDouble(3.);
|
||||
@@ -253,7 +253,7 @@ public class DeclinationStoreTest extends AbstractDeclinationTest {
|
||||
assertEquals(3., ois.readDouble(), 0.000000001);
|
||||
assertEquals(4., ois.readDouble(), 0.000000001);
|
||||
String s2 = ois.readUTF();
|
||||
assertEquals("Tätäräää", s2);
|
||||
assertEquals("T�t�r���", s2);
|
||||
assertEquals(1., ois.readDouble(), 0.000000001);
|
||||
assertEquals(2., ois.readDouble(), 0.000000001);
|
||||
assertEquals(3., ois.readDouble(), 0.000000001);
|
||||
|
||||
+1
-1
@@ -11,10 +11,10 @@ import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class SimpleDeclinationTest extends AbstractDeclinationTest {
|
||||
@Test
|
||||
|
||||
+1
-1
@@ -19,12 +19,12 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.quadtree.QuadTree;
|
||||
|
||||
/**
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
package com.sap.sailing.domain.common;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
+1
-5
@@ -1,9 +1,5 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
package com.sap.sailing.domain.common;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
|
||||
|
||||
public interface SpeedWithBearing extends Speed {
|
||||
+3
-4
@@ -1,14 +1,13 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.CourseChange;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.AbstractSpeedImpl;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.CourseChange;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
|
||||
public abstract class AbstractSpeedWithAbstractBearingImpl extends AbstractSpeedImpl implements SpeedWithBearing {
|
||||
private static final long serialVersionUID = 6136100417593538013L;
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
|
||||
public abstract class AbstractSpeedWithBearingImpl extends AbstractSpeedWithAbstractBearingImpl implements SpeedWithBearing {
|
||||
private static final long serialVersionUID = -8594305027333573010L;
|
||||
+2
-6
@@ -1,17 +1,13 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.util.SerializableComparator;
|
||||
|
||||
public abstract class AbstractTimePoint implements TimePoint {
|
||||
private static final long serialVersionUID = 8825508619301420378L;
|
||||
|
||||
public static SimpleDateFormat TIMEPOINT_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
public static Comparator<TimePoint> TIMEPOINT_COMPARATOR = new SerializableComparator<TimePoint>() {
|
||||
private static final long serialVersionUID = 7644726881387366025L;
|
||||
|
||||
@@ -69,7 +65,7 @@ public abstract class AbstractTimePoint implements TimePoint {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TIMEPOINT_FORMATTER.format(asDate());
|
||||
return asDate().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.CourseChange;
|
||||
import com.sap.sailing.domain.common.CourseChange;
|
||||
|
||||
public class CourseChangeImpl implements CourseChange {
|
||||
private final double courseChangeInDegrees;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
|
||||
+5
@@ -21,4 +21,9 @@ public class MeterDistance extends AbstractDistance {
|
||||
return new MeterDistance(factor * meters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getCentralAngleDeg() {
|
||||
return getGeographicalMiles() / 60.;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -18,6 +18,6 @@ public class MeterPerSecondSpeedImpl extends AbstractSpeedImpl implements Speed
|
||||
|
||||
@Override
|
||||
public double getKilometersPerHour() {
|
||||
return metersPerSecond/3.6;
|
||||
return metersPerSecond*3.6;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
|
||||
public class MeterPerSecondSpeedWithDegreeBearingImpl extends AbstractSpeedWithAbstractBearingImpl {
|
||||
private static final long serialVersionUID = -524654796500981303L;
|
||||
private final double metersPerSecond;
|
||||
private final Bearing bearing;
|
||||
|
||||
public MeterPerSecondSpeedWithDegreeBearingImpl(double metersPerSecond, Bearing bearing) {
|
||||
this.metersPerSecond = metersPerSecond;
|
||||
this.bearing = bearing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMetersPerSecond() {
|
||||
return metersPerSecond;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getKilometersPerHour() {
|
||||
return metersPerSecond*3.6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getBearing() {
|
||||
return bearing;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.domain.base.impl;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.sap.sailing.util;
|
||||
package com.sap.sailing.domain.common.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
+24
-13
@@ -35,14 +35,11 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.RegattaRegistry;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.CourseDataImpl;
|
||||
import com.sap.sailing.domain.base.impl.EventImpl;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.SeriesImpl;
|
||||
import com.sap.sailing.domain.base.impl.VenueImpl;
|
||||
@@ -56,11 +53,14 @@ import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaName;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.RGBColor;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
@@ -142,7 +142,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
}
|
||||
|
||||
private TimePoint loadTimePoint(DBObject object, FieldNames field) {
|
||||
return new MillisecondsTimePoint((Long) object.get(field.name()));
|
||||
return new MillisecondsTimePoint(((Number) object.get(field.name())).longValue());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1006,14 +1006,15 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
RaceLog result = new RaceLogImpl(RaceLogImpl.class.getSimpleName(), identifier.getIdentifier());
|
||||
try {
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(identifier.getIdentifier().toString()));
|
||||
DBCollection raceLog = database.getCollection(CollectionNames.RACE_LOGS.name());
|
||||
for (DBObject o : raceLog.find(query)) {
|
||||
RaceLogEvent raceLogEvent = loadRaceLogEvent((DBObject) o.get(FieldNames.RACE_LOG_EVENT.name()));
|
||||
|
||||
if (raceLogEvent != null)
|
||||
result.add(raceLogEvent);
|
||||
}
|
||||
query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(identifier.getIdentifier()));
|
||||
loadRaceLogEvents(result, query);
|
||||
|
||||
// query for obsolete events
|
||||
query.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(String.format("%s.%s.%s",
|
||||
identifier.getTemplate().getParentObjectName(),
|
||||
identifier.getRaceColumnName(),
|
||||
identifier.getFleetName())));
|
||||
loadRaceLogEvents(result, query);
|
||||
} catch (Throwable t) {
|
||||
// something went wrong during DB access; report, then use empty new race log
|
||||
logger.log(Level.SEVERE, "Error connecting to MongoDB, unable to load recorded race log data. Check MongoDB settings.");
|
||||
@@ -1022,6 +1023,16 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
private void loadRaceLogEvents(RaceLog result, BasicDBObject query) {
|
||||
DBCollection raceLog = database.getCollection(CollectionNames.RACE_LOGS.name());
|
||||
for (DBObject o : raceLog.find(query)) {
|
||||
RaceLogEvent raceLogEvent = loadRaceLogEvent((DBObject) o.get(FieldNames.RACE_LOG_EVENT.name()));
|
||||
if (raceLogEvent != null) {
|
||||
result.add(raceLogEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RaceLogEvent loadRaceLogEvent(DBObject dbObject) {
|
||||
TimePoint timePoint = loadTimePoint(dbObject);
|
||||
TimePoint createdAt = loadTimePoint(dbObject, FieldNames.RACE_LOG_EVENT_CREATED_AT);
|
||||
@@ -1190,7 +1201,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
|
||||
private CourseBase loadCourseData(BasicDBList dbCourseList, String courseName) {
|
||||
if (courseName == null) {
|
||||
courseName = "Course template";
|
||||
courseName = "Course";
|
||||
}
|
||||
CourseBase courseData = new CourseDataImpl(courseName);
|
||||
int i = 0;
|
||||
|
||||
+15
-15
@@ -1,5 +1,5 @@
|
||||
package com.sap.sailing.domain.persistence.impl;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
@@ -24,7 +24,6 @@ import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Timed;
|
||||
import com.sap.sailing.domain.base.Venue;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
@@ -34,6 +33,7 @@ import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
@@ -536,7 +536,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFlagEvent flagEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFlagEvent(flagEvent));
|
||||
return result;
|
||||
@@ -544,7 +544,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartTimeEvent startTimeEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartTimeEvent(startTimeEvent));
|
||||
return result;
|
||||
@@ -552,7 +552,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogPassChangeEvent passChangeEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogPassChangeEvent(passChangeEvent));
|
||||
return result;
|
||||
@@ -560,7 +560,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogRaceStatusEvent raceStatusEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogRaceStatusEvent(raceStatusEvent));
|
||||
return result;
|
||||
@@ -568,63 +568,63 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogCourseAreaChangedEvent courseAreaChangedEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCourseAreaChangedEvent(courseAreaChangedEvent));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogCourseDesignChangedEvent courseDesignChangedEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogCourseDesignChangedEvent(courseDesignChangedEvent));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFinishPositioningListChangedEvent finishPositioningListChangedEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFinishPositioningListChangedEvent(finishPositioningListChangedEvent));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogFinishPositioningConfirmedEvent finishPositioningConfirmedEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogFinishPositioningConfirmedEvent(finishPositioningConfirmedEvent));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogPathfinderEvent pathfinderEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogPathfinderEvent(pathfinderEvent));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogGateLineOpeningTimeEvent gateLineOpeningTimeEvent) {
|
||||
BasicDBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogGateLineOpeningTimeEvent(gateLineOpeningTimeEvent));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartProcedureChangedEvent event) {
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartProcedureChangedEvent(event));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogProtestStartTimeEvent event) {
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogProtestStartTimeEvent(event));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogWindFixEvent event) {
|
||||
DBObject result = new BasicDBObject();
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
|
||||
result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), TripleSerializer.serialize(raceLogIdentifier.getIdentifier()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogWindFix(event));
|
||||
return result;
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.sap.sailing.domain.persistence.impl;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.DBObject;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
|
||||
public class TripleSerializer {
|
||||
public static DBObject serialize(Triple<String, String, String> value) {
|
||||
DBObject container = new BasicDBObject();
|
||||
container.put("a", value.getA());
|
||||
container.put("b", value.getB());
|
||||
container.put("c", value.getC());
|
||||
return container;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import java.util.UUID;
|
||||
|
||||
import org.junit.Before;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.analyzing.impl.RaceLogAnalyzer;
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ import static org.mockito.Mockito.when;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
import com.sap.sailing.domain.racelog.impl.RaceLogEventComparator;
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
import com.sap.sailing.domain.racelog.RaceLogEvent;
|
||||
|
||||
@@ -15,5 +15,4 @@ Export-Package: com.sap.sailing.domain.base,
|
||||
com.sap.sailing.domain.racelog.impl,
|
||||
com.sap.sailing.domain.tracking,
|
||||
com.sap.sailing.domain.tracking.impl,
|
||||
com.sap.sailing.util,
|
||||
com.sap.sailing.util.impl
|
||||
+1
-1
@@ -73,6 +73,6 @@ public class MarkImpl extends NamedImpl implements Mark {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getId() + " " + getColor() + super.toString();
|
||||
return getId() + " " + (getColor()==null?"":(getColor()+" ")) + super.toString();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,9 +7,9 @@ import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package com.sap.sailing.domain.tracking;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Timed;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
|
||||
/**
|
||||
* Records a wind observation made at a certain position at a given time with an observed speed and a bearing.
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
public class WindImpl extends KnotSpeedWithBearingImpl implements Wind {
|
||||
|
||||
+1
-1
@@ -11,8 +11,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
|
||||
/**
|
||||
|
||||
+21
-1
@@ -12,7 +12,7 @@ import com.mongodb.DB;
|
||||
import com.mongodb.DBCollection;
|
||||
import com.mongodb.DBCursor;
|
||||
import com.mongodb.DBObject;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.swisstimingadapter.MessageType;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Race;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SailMasterMessage;
|
||||
@@ -185,6 +185,26 @@ public class SwissTimingAdapterPersistenceImpl implements SwissTimingAdapterPers
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRaceStartlist(String raceID) {
|
||||
DBCollection races = database.getCollection(CollectionNames.RACES_MESSAGES.name());
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.append(FieldNames.RACE_ID.name(), raceID);
|
||||
query.append(FieldNames.MESSAGE_COMMAND.name(), MessageType.STL.name());
|
||||
DBObject object = races.findOne(query);
|
||||
return object != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRaceCourse(String raceID) {
|
||||
DBCollection races = database.getCollection(CollectionNames.RACES_MESSAGES.name());
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.append(FieldNames.RACE_ID.name(), raceID);
|
||||
query.append(FieldNames.MESSAGE_COMMAND.name(), MessageType.CCG.name());
|
||||
DBObject object = races.findOne(query);
|
||||
return object != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Race> getRaces() {
|
||||
DBCollection races = database.getCollection(CollectionNames.RACES_MASTERDATA.name());
|
||||
|
||||
@@ -16,9 +16,8 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.domain.persistence,
|
||||
com.sap.sailing.domain.tractracadapter,
|
||||
com.sap.sailing.domain.swisstimingadapter.persistence;bundle-version="1.0.0",
|
||||
org.junit4;bundle-version="4.8.2",
|
||||
org.hamcrest.core;bundle-version="1.1.0"
|
||||
Bundle-ClassPath: resources/,
|
||||
.
|
||||
Import-Package: com.sap.sailing.server,
|
||||
junit.framework;version="4.8.1",
|
||||
org.junit;version="4.8.1"
|
||||
Import-Package: com.sap.sailing.server
|
||||
+2
-2
@@ -14,12 +14,12 @@ import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Competitor;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Mark;
|
||||
|
||||
-8
@@ -47,14 +47,6 @@ public class DomainFactoryTest {
|
||||
assertThat(raceType.getRaceCode(), is(OlympicRaceCode._470_WOMEN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGet470WomenBoatClass2() throws Exception {
|
||||
String raceID = "SAW005_xxx";
|
||||
RaceType raceType = swissTimingDomainFactory.getRaceTypeFromRaceID(raceID );
|
||||
assertThat(raceType, is(notNullValue()));
|
||||
assertThat(raceType.getRaceCode(), is(OlympicRaceCode._470_WOMEN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDontGetWrongBoatClass() throws Exception {
|
||||
String raceID = "ABC";
|
||||
|
||||
+12
@@ -208,4 +208,16 @@ public class OverlappingStoredAndReceivedMessagesTest implements RaceSpecificMes
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRaceStartlist(String raceID) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRaceCourse(String raceID) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -18,9 +18,9 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Competitor;
|
||||
|
||||
+16
@@ -11,6 +11,7 @@ import java.util.List;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
@@ -24,6 +25,7 @@ import com.sap.sailing.domain.swisstimingadapter.Course;
|
||||
import com.sap.sailing.domain.swisstimingadapter.DomainFactory;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Mark;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Race;
|
||||
import com.sap.sailing.domain.swisstimingadapter.RaceType;
|
||||
import com.sap.sailing.domain.swisstimingadapter.StartList;
|
||||
import com.sap.sailing.domain.swisstimingadapter.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.swisstimingadapter.impl.MarkImpl;
|
||||
@@ -34,6 +36,20 @@ import com.sap.sailing.server.impl.RacingEventServiceImpl;
|
||||
import difflib.PatchFailedException;
|
||||
|
||||
public class SimpleDomainFactoryTest {
|
||||
@Test
|
||||
public void testExtractBoatClassFromSimpleRaceID() {
|
||||
String raceID = "SAW005901";
|
||||
RaceType raceType = DomainFactory.INSTANCE.getRaceTypeFromRaceID(raceID);
|
||||
assertEquals("470", raceType.getBoatClass().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractBoatClassFromRaceIDWithEventID() {
|
||||
String raceID = "QINSWC12013_SAW005901";
|
||||
RaceType raceType = DomainFactory.INSTANCE.getRaceTypeFromRaceID(raceID);
|
||||
assertEquals("470", raceType.getBoatClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that an unknown boat class encoded in a regular "SA" format race ID is returned as the unknown boat class
|
||||
* instead of null.
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
|
||||
/**
|
||||
* Data fix transmitted periodically from the SwissTiming Sail Master system, telling boat position and speed
|
||||
|
||||
+12
-1
@@ -7,11 +7,15 @@ public class RaceRecord {
|
||||
private String raceID;
|
||||
private String description;
|
||||
private Date startTime;
|
||||
private boolean hasCourse;
|
||||
private boolean hasStartlist;
|
||||
|
||||
public RaceRecord(String raceID, String description, Date startTime) {
|
||||
public RaceRecord(String raceID, String description, Date startTime, boolean hasCourse, boolean hasStartlist) {
|
||||
this.raceID = raceID;
|
||||
this.description = description;
|
||||
this.startTime = startTime;
|
||||
this.hasCourse = hasCourse;
|
||||
this.hasStartlist = hasStartlist;
|
||||
}
|
||||
|
||||
public String getRaceID() {
|
||||
@@ -26,4 +30,11 @@ public class RaceRecord {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public boolean hasCourse() {
|
||||
return hasCourse;
|
||||
}
|
||||
|
||||
public boolean hasStartlist() {
|
||||
return hasStartlist;
|
||||
}
|
||||
}
|
||||
+4
@@ -21,4 +21,8 @@ public interface RaceSpecificMessageLoader {
|
||||
Iterable<Race> getRaces();
|
||||
|
||||
Race getRace(String raceID);
|
||||
|
||||
boolean hasRaceStartlist(String raceID);
|
||||
|
||||
boolean hasRaceCourse(String raceID);
|
||||
}
|
||||
+3
-3
@@ -26,12 +26,12 @@ public interface RaceType {
|
||||
_470_MEN("SAM005", "470", Gender.male),
|
||||
STAR("SAM007", "Star", Gender.male),
|
||||
_49ER("SAM009", "49er", Gender.male),
|
||||
_49ERFX("SAW009", "49erFX", Gender.female),
|
||||
ELLIOTT6M("SAW007", "Elliott 6M", Gender.female),
|
||||
RSX_WOMEN("SAW102", "RS:X", Gender.female),
|
||||
RSX_MEN("SAM102", "RS:X", Gender.male),
|
||||
LASER_RADIAL("SAW103", "Laser Radial", Gender.female),
|
||||
_49ERFX_TODO("xxxxx_TODO_xxxxx", "49er FX", Gender.female),
|
||||
NACRA17_TOTO("xxxxx_TODO_xxxxx", "Nacra 17", Gender.mixed);
|
||||
NACRA17("SAX017", "Nacra 17", Gender.mixed),
|
||||
LASER_RADIAL("SAW103", "Laser Radial", Gender.female);
|
||||
|
||||
enum Gender {
|
||||
male, female, mixed, unspecified;
|
||||
|
||||
+5
-1
@@ -19,8 +19,12 @@ public interface SailMasterConnector {
|
||||
|
||||
Course getCourse(String raceID) throws UnknownHostException, IOException, InterruptedException;
|
||||
|
||||
boolean hasCourse(String raceID);
|
||||
|
||||
StartList getStartList(String raceID) throws UnknownHostException, IOException, InterruptedException;
|
||||
|
||||
|
||||
boolean hasStartlist(String raceID);
|
||||
|
||||
TimePoint getStartTime(String raceID) throws UnknownHostException, IOException, ParseException, InterruptedException;
|
||||
|
||||
Distance getDistanceToMark(String raceID, int markIndex, String boatID) throws UnknownHostException, IOException, InterruptedException;
|
||||
|
||||
+36
-8
@@ -21,7 +21,6 @@ import com.sap.sailing.domain.base.Team;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.PersonImpl;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
@@ -31,6 +30,7 @@ import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WithID;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
@@ -177,19 +177,47 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
|
||||
/**
|
||||
* Returns the SwissTiming olympic race type or race type "UNKNOWN" when no corresponding olympic race type can be found.
|
||||
* Will never return null neither throw a content-related exception.
|
||||
* Will never return <code>null</code> neither throw a content-related exception.<p>
|
||||
*
|
||||
* The <code>raceID</code> format from which the race type can be inferred either has to be of the form<pre>
|
||||
*
|
||||
* DDGEEEPUU
|
||||
*
|
||||
* D = discipline - in this case sailing or SA
|
||||
* G = gender - M, F or X
|
||||
* E = event - a three digit code for each event (known as class in sailing)
|
||||
* P = phase - 1 being the grand final or medal working back to 9 as the first qualification step, generally sailing only uses 1 and 9 but we are investigating using 8 depending on the exact competition format
|
||||
* U = event unit - race 1 through to 99 in the phase
|
||||
* </pre>
|
||||
*
|
||||
* for example "SAW005901" or of the form <pre>
|
||||
* CCCRRRNYYYY;DDGEEEPUU
|
||||
*
|
||||
* C = City
|
||||
* R = Regatta
|
||||
* N = Regatta Number
|
||||
* Y = Year
|
||||
* </pre>
|
||||
*
|
||||
* which allows for a globally-unique race ID as it includes a specification of the event / regatta at which the race
|
||||
* took place.
|
||||
*/
|
||||
@Override
|
||||
public RaceType getRaceTypeFromRaceID(String raceID) {
|
||||
final RaceType result;
|
||||
if (raceID != null && raceID.length() >= 6) {
|
||||
String swissTimingRaceCode = raceID.substring(0, 6).toUpperCase();
|
||||
RaceType result = raceTypeByID.get(swissTimingRaceCode);
|
||||
if (result != null) {
|
||||
return result;
|
||||
final String[] optionalEventIDAndMandatoryRaceID = raceID.split("_");
|
||||
final String swissTimingRaceCode = optionalEventIDAndMandatoryRaceID[optionalEventIDAndMandatoryRaceID.length-1].substring(0, 6).toUpperCase();
|
||||
RaceType raceType = raceTypeByID.get(swissTimingRaceCode);
|
||||
if (raceType == null) {
|
||||
result = unknownRaceType;
|
||||
} else {
|
||||
result = raceType;
|
||||
}
|
||||
} else {
|
||||
result = unknownRaceType;
|
||||
}
|
||||
//else
|
||||
return unknownRaceType;
|
||||
return result;
|
||||
}
|
||||
|
||||
private Iterable<Competitor> createCompetitorList(StartList startList, RaceType raceType) {
|
||||
|
||||
+1
-1
@@ -1,9 +1,9 @@
|
||||
package com.sap.sailing.domain.swisstimingadapter.impl;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Fix;
|
||||
import com.sap.sailing.domain.swisstimingadapter.TrackerType;
|
||||
|
||||
|
||||
+21
-3
@@ -25,18 +25,18 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KilometersPerHourSpeedImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.swisstimingadapter.Competitor;
|
||||
@@ -606,6 +606,24 @@ public class SailMasterConnectorImpl extends SailMasterTransceiverImpl implement
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCourse(String raceID) {
|
||||
boolean result = false;
|
||||
if (messageLoader != null) {
|
||||
result = messageLoader.hasRaceCourse(raceID);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStartlist(String raceID) {
|
||||
boolean result = false;
|
||||
if (messageLoader != null) {
|
||||
result = messageLoader.hasRaceStartlist(raceID);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Race> parseAvailableRacesMessage(SailMasterMessage availableRacesMessage) {
|
||||
assertMessageType(MessageType.RAC, availableRacesMessage);
|
||||
int count = Integer.valueOf(availableRacesMessage.getSections()[1]);
|
||||
|
||||
+1
-1
@@ -3,9 +3,9 @@ package com.sap.sailing.domain.swisstimingadapter.impl;
|
||||
import java.net.DatagramPacket;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.KilometersPerHourSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingFormatException;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessage;
|
||||
import com.sap.sailing.domain.swisstimingadapter.SwissTimingMessageParser;
|
||||
|
||||
+1
-1
@@ -19,10 +19,10 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Sideline;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
|
||||
@@ -7,6 +7,6 @@ Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Fragment-Host: com.sap.sailing.domain.swisstimingreplayadapter
|
||||
Import-Package: org.json.simple,
|
||||
org.json.simple.parser,
|
||||
org.junit;version="4.8.2"
|
||||
Require-Bundle: com.sap.sailing.domain.test
|
||||
org.json.simple.parser
|
||||
Require-Bundle: com.sap.sailing.domain.test,
|
||||
org.junit4;bundle-version="4.8.2"
|
||||
+3
-3
@@ -22,18 +22,18 @@ import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Sideline;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.TrackedRaceStatusEnum;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceWithAdditionalID;
|
||||
|
||||
@@ -14,10 +14,8 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
org.mockito.mockito-core;bundle-version="1.9.5",
|
||||
com.sap.sailing.domain.test,
|
||||
org.hamcrest;bundle-version="1.1.0",
|
||||
org.objenesis;bundle-version="1.3.0"
|
||||
org.objenesis;bundle-version="1.3.0",
|
||||
org.junit4;bundle-version="4.8.2",
|
||||
org.json.simple;bundle-version="1.1.0"
|
||||
Export-Package: com.sap.sailing.domain.test,
|
||||
com.sap.sailing.domain.test.mock
|
||||
Import-Package: junit.framework;version="4.8.1",
|
||||
org.json.simple,
|
||||
org.json.simple.parser,
|
||||
org.junit;version="4.8.1"
|
||||
+1
-1
@@ -20,7 +20,6 @@ import java.util.Map;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Cloner;
|
||||
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
@@ -33,6 +32,7 @@ import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
|
||||
import com.sap.sailing.domain.common.dto.LegEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceDTO;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.test.StoredTrackBasedTest;
|
||||
|
||||
+2
-3
@@ -9,9 +9,9 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
|
||||
public abstract class AbstractManeuverDetectionTestCase extends OnlineTracTracBasedTest {
|
||||
@@ -64,8 +64,7 @@ public abstract class AbstractManeuverDetectionTestCase extends OnlineTracTracBa
|
||||
* The maneuvers of the types listed in <code>maneuverTypesFound</code> that where not detected by
|
||||
* {@link ManeuverAnalysisIDMChampionsFinalTest#assertManeuver(List, ManeuverType, MillisecondsTimePoint, int)}
|
||||
*/
|
||||
protected void assertAllManeuversOfTypesDetected(List<ManeuverType> maneuverTypesFound,
|
||||
List<Maneuver> maneuversNotDetected) {
|
||||
protected void assertAllManeuversOfTypesDetected(List<ManeuverType> maneuverTypesFound, List<Maneuver> maneuversNotDetected) {
|
||||
for (Maneuver maneuver : maneuversNotDetected) {
|
||||
for (ManeuverType type : maneuverTypesFound) {
|
||||
if (maneuver.getType().equals(type)) {
|
||||
|
||||
+2
-2
@@ -16,11 +16,11 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.DouglasPeucker;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
|
||||
+2
-2
@@ -14,8 +14,6 @@ import org.junit.Test;
|
||||
import com.sap.sailing.domain.base.BearingWithConfidence;
|
||||
import com.sap.sailing.domain.base.PositionWithConfidence;
|
||||
import com.sap.sailing.domain.base.impl.BearingWithConfidenceImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.PositionWithConfidenceImpl;
|
||||
import com.sap.sailing.domain.base.impl.ScalablePosition;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
@@ -23,6 +21,8 @@ import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.RadianBearingImpl;
|
||||
import com.sap.sailing.domain.confidence.ConfidenceBasedAverager;
|
||||
import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager;
|
||||
|
||||
+7
@@ -1,6 +1,8 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -50,4 +52,9 @@ public class DummyTrackedRegattaRegistry implements TrackedRegattaRegistry {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTracking(Regatta regatta, RaceDefinition race) throws MalformedURLException, IOException,
|
||||
InterruptedException {
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -13,11 +13,11 @@ import org.junit.Test;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
|
||||
|
||||
+7
-1
@@ -8,7 +8,9 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -27,11 +29,11 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
@@ -142,6 +144,10 @@ public class LeaderboardOfflineTest extends AbstractLeaderboardTest {
|
||||
public boolean isRaceBeingTracked(RaceDefinition r) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public void stopTracking(Regatta regatta, RaceDefinition race) throws MalformedURLException, IOException,
|
||||
InterruptedException {
|
||||
}
|
||||
};
|
||||
LeaderboardDTO leaderboardDTO = leaderboard.getLeaderboardDTO(now, emptySet, trackedRegattaRegistry, DomainFactory.INSTANCE);
|
||||
assertNotNull(leaderboardDTO);
|
||||
|
||||
+1
-1
@@ -27,7 +27,6 @@ import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sailing.domain.base.impl.GateImpl;
|
||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.SeriesImpl;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
@@ -35,6 +34,7 @@ import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
|
||||
+2
-2
@@ -15,12 +15,12 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
|
||||
+4
-4
@@ -20,8 +20,6 @@ import org.junit.Test;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
@@ -29,6 +27,8 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
@@ -65,8 +65,8 @@ public class ManeuverAnalysisIDMChampionsFinalTest extends AbstractManeuverDetec
|
||||
TimePoint epoch = new MillisecondsTimePoint(0l);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
Map<String, Position> markPositions = new HashMap<String, Position>();
|
||||
markPositions.put("G2 Start", new DegreePosition(53.96003300000019, 10.878697000000084));
|
||||
markPositions.put("Finish", new DegreePosition(53.9674420000693, 10.894410000058738));
|
||||
markPositions.put("G2 Start-Finish (1)", new DegreePosition(53.96003300000019, 10.878697000000084));
|
||||
markPositions.put("G2 Start-Finish (2)", new DegreePosition(53.9674420000693, 10.894410000058738));
|
||||
markPositions.put("G2 Mark4 (2)", new DegreePosition(53.96002200000019, 10.878875000000063));
|
||||
markPositions.put("G2 Mark4 (1)", new DegreePosition(53.9599880000002, 10.878665000000069));
|
||||
markPositions.put("G2 Mark1", new DegreePosition(53.96355800000006, 10.885751999999806));
|
||||
|
||||
+4
-4
@@ -19,15 +19,15 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.DouglasPeucker;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
@@ -62,7 +62,7 @@ public class ManeuverDetectionOnKielerWoche505Race2DataTest extends OnlineTracTr
|
||||
TimePoint firstWindwardMarkPassing = hassosMarkPassingsIter.next().getTimePoint();
|
||||
List<GPSFixMoving> firstLegFineApproximation = dp.approximate(new MeterDistance(20), startMarkPassing, firstWindwardMarkPassing);
|
||||
assertNotNull(firstLegFineApproximation);
|
||||
assertEquals(9, firstLegFineApproximation.size());
|
||||
assertEquals(11, firstLegFineApproximation.size());
|
||||
List<GPSFixMoving> firstLegCoarseApproximation = dp.approximate(new MeterDistance(50), startMarkPassing, firstWindwardMarkPassing);
|
||||
assertNotNull(firstLegCoarseApproximation);
|
||||
assertEquals(4, firstLegCoarseApproximation.size());
|
||||
@@ -85,7 +85,7 @@ public class ManeuverDetectionOnKielerWoche505Race2DataTest extends OnlineTracTr
|
||||
c.clear();
|
||||
c.set(2011, 6-1, 23, 16, 5, 47);
|
||||
assertManeuver(maneuvers, ManeuverType.TACK, Tack.PORT, new MillisecondsTimePoint(c.getTime()), /* tolerance in milliseconds */ 3000);
|
||||
c.set(2011, 6-1, 23, 16, 8, 31);
|
||||
c.set(2011, 6-1, 23, 16, 8, 33);
|
||||
assertManeuver(maneuvers, ManeuverType.TACK, Tack.STARBOARD, new MillisecondsTimePoint(c.getTime()), /* tolerance in milliseconds */ 3000);
|
||||
c.set(2011, 6-1, 23, 16, 11, 03);
|
||||
assertManeuver(maneuvers, ManeuverType.TACK, Tack.PORT, new MillisecondsTimePoint(c.getTime()), /* tolerance in milliseconds */ 3000);
|
||||
|
||||
+2
-2
@@ -19,8 +19,6 @@ import org.junit.Test;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
@@ -29,6 +27,8 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
|
||||
+2
-1
@@ -19,15 +19,16 @@ import java.util.regex.Pattern;
|
||||
import org.junit.Before;
|
||||
|
||||
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.tracking.DynamicRaceDefinitionSet;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
|
||||
+3
-3
@@ -15,21 +15,21 @@ import org.junit.Test;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
import com.sap.sailing.domain.common.PolarSheetsData;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.polarsheets.PerRaceAndCompetitorPolarSheetGenerationWorker;
|
||||
import com.sap.sailing.domain.polarsheets.PolarSheetGenerationWorker;
|
||||
import com.sap.sailing.domain.test.mock.MockedTrackedRace;
|
||||
|
||||
@@ -6,15 +6,15 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Mile;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sailing.domain.tracking.impl.CompactGPSFixImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.CompactGPSFixMovingImpl;
|
||||
@@ -82,7 +82,7 @@ public class PositionTest {
|
||||
@Test
|
||||
public void translateTest() {
|
||||
Position p1 = new DegreePosition(0, 0);
|
||||
// now travel to 123° for 0.001 nautical miles (~ 1.852m)
|
||||
// now travel to 123� for 0.001 nautical miles (~ 1.852m)
|
||||
Position p2 = p1.translateGreatCircle(new DegreeBearingImpl(123), new NauticalMileDistance(0.001));
|
||||
assertEquals(123, p1.getBearingGreatCircle(p2).getDegrees(), 0.0000001);
|
||||
assertEquals(0.001, p1.getDistance(p2).getNauticalMiles(), 0.0000001);
|
||||
|
||||
@@ -12,8 +12,8 @@ import java.util.UUID;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.racelog.Flags;
|
||||
import com.sap.sailing.domain.racelog.RaceLog;
|
||||
|
||||
+2
-2
@@ -25,9 +25,7 @@ import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.GateImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
@@ -41,6 +39,8 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
|
||||
+2
-2
@@ -16,10 +16,10 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.sap.sailing.domain.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.impl.MeterPerSecondSpeedImpl;
|
||||
|
||||
public class SpeedUnitTest {
|
||||
@Test
|
||||
public void testMeterPerSecondSpeedToKnots() {
|
||||
Speed s = new MeterPerSecondSpeedImpl(1852./3600.);
|
||||
assertEquals(1, s.getKnots(), 0.0000001);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -17,10 +17,10 @@ import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Sideline;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
|
||||
|
||||
+3
-3
@@ -18,19 +18,19 @@ import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Person;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.Team;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.PersonImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import java.util.Map;
|
||||
import org.junit.Before;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
|
||||
@@ -12,8 +12,6 @@ import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.NationalityImpl;
|
||||
import com.sap.sailing.domain.base.impl.PersonImpl;
|
||||
import com.sap.sailing.domain.base.impl.TeamImpl;
|
||||
@@ -21,6 +19,8 @@ import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
|
||||
+2
-2
@@ -19,9 +19,7 @@ import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.GateImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.NationalityImpl;
|
||||
import com.sap.sailing.domain.base.impl.PersonImpl;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
@@ -33,6 +31,8 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
|
||||
@@ -23,19 +23,21 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.MeterPerSecondSpeedWithDegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
@@ -97,8 +99,15 @@ public class TrackTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* A test regarding bug 968. Three subsequent fixes at the same position with increasing time stamps each, then jumping
|
||||
* to the next position for three seconds. Let's see what distance and SOG do...
|
||||
* A test regarding bug 968. Three subsequent fixes at the same position with increasing time stamps each, then
|
||||
* jumping to the next position for three seconds. Let's see what distance and SOG do...
|
||||
* <p>
|
||||
*
|
||||
* TODO bug 1504 The challenge with this is that the equal fixes all have a wrong speed value compared to at least
|
||||
* one of their neighbors. They are hence all considered outliers, and no fix remains. There is however a possible
|
||||
* sub-sequence of fixes that constitutes a sequence of all-valid fixes when only valid fixes are checked for
|
||||
* validity with their valid neighbors. But this, at first glance, sounds like an ugly NP-complete problem: find the
|
||||
* longest possible sub-sequence such that all fixes in the sub-sequence are valid w.r.t. their neighbors.
|
||||
*/
|
||||
@Test
|
||||
public void testJumpyFixes() {
|
||||
@@ -498,41 +507,45 @@ public class TrackTest {
|
||||
assertEquals(timePointOfLastOriginalFix, newFullIntervalCacheEntry.getA());
|
||||
assertEquals(now, newFullIntervalCacheEntry.getB().getA());
|
||||
TimePoint timePointForLateOutlier = new MillisecondsTimePoint(now.asMillis() + (steps-1)*timeBetweenFixesInMillis + timeBetweenFixesInMillis/2);
|
||||
Position lateOutlierPosition = new DegreePosition(90, 90);
|
||||
Position lateOutlierPosition = new DegreePosition(-90, 90);
|
||||
GPSFix lateOutlier = new GPSFixImpl(lateOutlierPosition, timePointForLateOutlier);
|
||||
// adding the outlier invalidates the fix just before the outlier because it now has a single successor that is in range but not reachable
|
||||
track.addGPSFix(lateOutlier);
|
||||
assertEquals(1, invalidationCalls.size());
|
||||
TimePoint timePointOfLastFixBeforeLateOutlier = track.getLastFixBefore(timePointForLateOutlier).getTimePoint();
|
||||
assertTrue(invalidationCalls.iterator().next().after(timePointOfLastFixBeforeLateOutlier));
|
||||
TimePoint timePointOfLastRawFixBeforeLateOutlier = track.getLastRawFixBefore(timePointForLateOutlier).getTimePoint();
|
||||
// assert that adding the outlier invalidated the distance cache starting from the raw fix before the late outlier
|
||||
// because its validity changed from true to false
|
||||
assertTrue(invalidationCalls.iterator().next().equals(timePointOfLastRawFixBeforeLateOutlier));
|
||||
invalidationCalls.clear();
|
||||
// expect the invalidation to have started after the single cache entry, so the cache entry still has to be there:
|
||||
final Pair<TimePoint, Pair<TimePoint, Distance>> stillPresentFullIntervalCacheEntry = distanceCache
|
||||
.getEarliestFromAndDistanceAtOrAfterFrom(now, timePointOfLastOriginalFix);
|
||||
assertNotNull(stillPresentFullIntervalCacheEntry); // no more entry for "to"-value start in cache
|
||||
assertEquals(timePointOfLastOriginalFix, stillPresentFullIntervalCacheEntry.getA());
|
||||
assertEquals(now, stillPresentFullIntervalCacheEntry.getB().getA());
|
||||
assertNull(stillPresentFullIntervalCacheEntry); // no more entry for "to"-value start in cache because new temporary outlier lies in previously cached interval
|
||||
GPSFix polishedLastFix = track.getLastFixBefore(new MillisecondsTimePoint(Long.MAX_VALUE)); // get the last smoothened fix...
|
||||
// ...which now still is expected to be the lateOutlier because no succeeding fix qualifies it as outlier:
|
||||
assertEquals(lateOutlier, polishedLastFix);
|
||||
// ...which now is expected to be two fixes before lateOutlier because lateOutlier has previous fixes within the time range
|
||||
// but none of them is reachable with max speed, and the raw fix right before lateOutlier is currently temporarily an outlier too
|
||||
assertEquals(track.getLastRawFixBefore(timePointOfLastRawFixBeforeLateOutlier), polishedLastFix);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(steps+1, Util.size(track.getFixes())); // what will later be detected as outlier is now an additional fix
|
||||
assertEquals(steps-1, Util.size(track.getFixes())); // the lateOutlier and its predecessor are currently detected as outlier, so it's not steps+1
|
||||
// which would include the lateOutlier, but it's already only steps-1 valid fixes.
|
||||
} finally {
|
||||
track.unlockAfterRead();
|
||||
}
|
||||
// now add another "normal" fix, making the lateOutlier really an outlier
|
||||
// now add another "normal" fix, making the lateOutlier really an outlier; invalidation starts 1ms after the last previously valid
|
||||
// fix before the fix added, or at the earliest fix that changes its validity, whichever is earlier. In this case the earlier time point
|
||||
// is 1ms after the last *valid* fix before the fix inserted because that's the fix two before the lateOutlier, and that fix and all other
|
||||
// earlier fixes don't change their validity
|
||||
GPSFix fix = new GPSFixImpl(p, start); // the "overshoot" from the previous loop can be used to generate the next "regular" fix
|
||||
track.addGPSFix(fix);
|
||||
assertEquals(1, invalidationCalls.size());
|
||||
// now assert that the fix addition also invalidated what is now detected as an outlier
|
||||
assertEquals(timePointForLateOutlier, invalidationCalls.iterator().next());
|
||||
// the lateOutlier's predecessor now is expected to have changed validity again, causing a distance cache invalidation at its time
|
||||
assertEquals(track.getLastFixBefore(timePointOfLastRawFixBeforeLateOutlier).getTimePoint().plus(1), invalidationCalls.iterator().next());
|
||||
assertTrue(timePointForLateOutlier.compareTo(fix.getTimePoint()) < 0);
|
||||
// expect the invalidation to have started at the outlier, leaving the previous result ending at the fix right before the outlier intact
|
||||
// expect the invalidation to have started at the fix before the outlier, leaving the previous result ending at the fix right before the outlier intact
|
||||
final Pair<TimePoint, Pair<TimePoint, Distance>> stillStillPresentFullIntervalCacheEntry = distanceCache
|
||||
.getEarliestFromAndDistanceAtOrAfterFrom(now, timePointOfLastOriginalFix);
|
||||
assertNotNull(stillStillPresentFullIntervalCacheEntry); // no more entry for "to"-value start in cache
|
||||
assertEquals(timePointOfLastOriginalFix, stillStillPresentFullIntervalCacheEntry.getA());
|
||||
assertEquals(now, stillStillPresentFullIntervalCacheEntry.getB().getA());
|
||||
assertNull(stillStillPresentFullIntervalCacheEntry); // still nothing in the cache
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(steps+1, Util.size(track.getFixes())); // the one "normal" late fix is added on top of the <steps> fixes, but the two outliers should now be removed
|
||||
@@ -688,6 +701,69 @@ public class TrackTest {
|
||||
assertEquals(estimatedSpeed.getBearing().getDegrees(), estimatedSpeedNew.getBearing().getDegrees(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidCheckForFixThatSaysItsAsFastAsItWas() {
|
||||
DynamicGPSFixMovingTrackImpl<Boat> myTrack = new DynamicGPSFixMovingTrackImpl<Boat>(new BoatImpl("MyFirstBoat", new BoatClassImpl("505", /* typicallyStartsUpwind */
|
||||
true), null), /* millisecondsOverWhichToAverage */5000, /* no smoothening */null);
|
||||
TimePoint now1 = MillisecondsTimePoint.now();
|
||||
TimePoint now2 = addMillisToTimepoint(now1, 1000); // 1s
|
||||
DegreeBearingImpl bearing = new DegreeBearingImpl(90);
|
||||
Position position1 = new DegreePosition(1, 2);
|
||||
Position position2 = position1.translateGreatCircle(bearing, new MeterDistance(1));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(1, bearing));
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(1, bearing));
|
||||
myTrack.addGPSFix(myGpsFix1);
|
||||
myTrack.addGPSFix(myGpsFix2);
|
||||
myTrack.lockForRead();
|
||||
try {
|
||||
assertEquals(2, myTrack.getFixes().size()); // expecting both fixes to be valid
|
||||
} finally {
|
||||
myTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidCheckForFixThatSaysItsFasterThanItActuallyWas() {
|
||||
DynamicGPSFixMovingTrackImpl<Boat> myTrack = new DynamicGPSFixMovingTrackImpl<Boat>(new BoatImpl("MyFirstBoat", new BoatClassImpl("505", /* typicallyStartsUpwind */
|
||||
true), null), /* millisecondsOverWhichToAverage */5000, /* no smoothening */null);
|
||||
TimePoint now1 = MillisecondsTimePoint.now();
|
||||
TimePoint now2 = addMillisToTimepoint(now1, 1000); // 1s
|
||||
DegreeBearingImpl bearing = new DegreeBearingImpl(90);
|
||||
Position position1 = new DegreePosition(1, 2);
|
||||
Position position2 = position1.translateGreatCircle(bearing, new MeterDistance(1));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(10, bearing));
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(10, bearing));
|
||||
myTrack.addGPSFix(myGpsFix1);
|
||||
myTrack.addGPSFix(myGpsFix2);
|
||||
myTrack.lockForRead();
|
||||
try {
|
||||
assertTrue(myTrack.getFixes().size() < 2); // at least one fix must be classified as outlier
|
||||
} finally {
|
||||
myTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidCheckForFixThatSaysItsSlowerThanItActuallyWas() {
|
||||
DynamicGPSFixMovingTrackImpl<Boat> myTrack = new DynamicGPSFixMovingTrackImpl<Boat>(new BoatImpl("MyFirstBoat", new BoatClassImpl("505", /* typicallyStartsUpwind */
|
||||
true), null), /* millisecondsOverWhichToAverage */5000, /* no smoothening */null);
|
||||
TimePoint now1 = MillisecondsTimePoint.now();
|
||||
TimePoint now2 = addMillisToTimepoint(now1, 1000); // 1s
|
||||
DegreeBearingImpl bearing = new DegreeBearingImpl(90);
|
||||
Position position1 = new DegreePosition(1, 2);
|
||||
Position position2 = position1.translateGreatCircle(bearing, new MeterDistance(1));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(0.1, bearing));
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(0.1, bearing));
|
||||
myTrack.addGPSFix(myGpsFix1);
|
||||
myTrack.addGPSFix(myGpsFix2);
|
||||
myTrack.lockForRead();
|
||||
try {
|
||||
assertTrue(myTrack.getFixes().size() < 2); // at least one fix must be classified as outlier
|
||||
} finally {
|
||||
myTrack.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidationIntervalBeginningForPositionEstimation() {
|
||||
track.lockForRead();
|
||||
|
||||
+1
-1
@@ -16,9 +16,9 @@ import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.MarkImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
|
||||
+17
-4
@@ -20,8 +20,6 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
@@ -30,6 +28,8 @@ import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
@@ -82,8 +82,21 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
|
||||
|
||||
private void setBearingForCompetitor(Competitor competitor, TimePoint timePoint, double bearingDeg) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorTrack = getTrackedRace().getTrack(competitor);
|
||||
competitorTrack.addGPSFix(new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint,
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(bearingDeg))));
|
||||
final KnotSpeedWithBearingImpl speed = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(bearingDeg));
|
||||
final Position position;
|
||||
competitorTrack.lockForRead();
|
||||
try {
|
||||
GPSFixMoving lastFixBefore = competitorTrack.getLastFixBefore(timePoint);
|
||||
if (lastFixBefore != null) {
|
||||
position = lastFixBefore.getPosition().translateGreatCircle(speed.getBearing(), speed.travel(lastFixBefore.getTimePoint(), timePoint));
|
||||
} else {
|
||||
position = new DegreePosition(54.4680424, 10.234451);
|
||||
}
|
||||
// now infer a position that makes sense with the speed
|
||||
} finally {
|
||||
competitorTrack.unlockAfterRead();
|
||||
}
|
||||
competitorTrack.addGPSFix(new GPSFixMovingImpl(position, timePoint, speed));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+4
-4
@@ -13,12 +13,12 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
|
||||
@@ -57,7 +57,7 @@ public class WindEstimationOnKielerWoche505Race2DataTest extends OnlineTracTracB
|
||||
*/
|
||||
@Test
|
||||
public void testSimpleWindEstimationThroughEstimationTrack() throws NoWindException {
|
||||
// at this point in time, most boats are already going upwind again, and Köchlin, Neulen and Findel are tacking,
|
||||
// at this point in time, most boats are already going upwind again, and K�chlin, Neulen and Findel are tacking,
|
||||
// hence have a direction change.
|
||||
TimePoint middle = new MillisecondsTimePoint(1308839492322l);
|
||||
TrackBasedEstimationWindTrackImpl estimatedWindTrack = new TrackBasedEstimationWindTrackImpl(getTrackedRace(),
|
||||
@@ -94,7 +94,7 @@ public class WindEstimationOnKielerWoche505Race2DataTest extends OnlineTracTracB
|
||||
|
||||
@Test
|
||||
public void testAnotherSimpleWindEstimation() throws NoWindException {
|
||||
// at this point in time, most boats are already going upwind again, and Köchlin, Neulen and Findel are tacking,
|
||||
// at this point in time, most boats are already going upwind again, and K�chlin, Neulen and Findel are tacking,
|
||||
// hence have a direction change.
|
||||
TimePoint middle = new MillisecondsTimePoint(1308839492322l);
|
||||
assertTrue(getTrackedRace().getTrack(getCompetitorByName("K.chlin")).hasDirectionChange(middle, /* minimumDegreeDifference */ 15.));
|
||||
|
||||
+2
-2
@@ -12,14 +12,14 @@ import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.tracking.GPSFixMoving;
|
||||
|
||||
@@ -25,8 +25,6 @@ import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.base.impl.NationalityImpl;
|
||||
import com.sap.sailing.domain.base.impl.PersonImpl;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
@@ -36,6 +34,8 @@ import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
|
||||
|
||||
+19
@@ -41,6 +41,7 @@ import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.RaceListener;
|
||||
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -818,4 +819,22 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTimeChangedByRaceCommittee(TimePoint newStartTime) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStartTimeChangedListener(StartTimeChangedListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getStartTimeReceived() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+13
@@ -31,6 +31,7 @@ import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.RaceChangeListener;
|
||||
import com.sap.sailing.domain.tracking.StartTimeChangedListener;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
@@ -532,4 +533,16 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStartTimeChangedListener(StartTimeChangedListener listener) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimePoint getStartTimeReceived() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+13
-12
@@ -179,25 +179,26 @@ public interface DomainFactory {
|
||||
/**
|
||||
* Creates a {@link RaceDefinition} from a TracTrac {@link Race} and a domain {@link Course} definition. The
|
||||
* resulting {@link RaceDefinition} is added to the {@link com.sap.sailing.domain.base.Regatta} to which
|
||||
* <code>trackedRegatta</code> belongs (see {@link TrackedRegatta#getRegatta()}). It is added to the internal race cache.
|
||||
* The corresponding {@link TrackedRace} object is also created, and the notification of threads waiting on the race
|
||||
* cache such as a blocking {@link #getAndWaitForRaceDefinition(UUID)} happens only <em>after</em> the tracked race
|
||||
* has been created and the {@link RaceDefinition} was
|
||||
* <code>trackedRegatta</code> belongs (see {@link TrackedRegatta#getRegatta()}). It is added to the internal race
|
||||
* cache. The corresponding {@link TrackedRace} object is also created, and the notification of threads waiting on
|
||||
* the race cache such as a blocking {@link #getAndWaitForRaceDefinition(UUID)} happens only <em>after</em> the
|
||||
* tracked race has been created and the {@link RaceDefinition} was
|
||||
* {@link com.sap.sailing.domain.base.Regatta#addRace(RaceDefinition) added} to the domain event. This ensures that
|
||||
* waiters for the {@link RaceDefinition} are guaranteed to obtain a valid, non- <code>null</code> tracked race
|
||||
* waiters for the {@link RaceDefinition} are guaranteed to obtain a valid, non-<code>null</code> tracked race
|
||||
* already immediately after the notification was sent, and that the {@link RaceDefinition} is already
|
||||
* {@link com.sap.sailing.domain.base.Regatta#getAllRaces() known} by its containing
|
||||
* {@link com.sap.sailing.domain.base.Regatta}.
|
||||
* @param raceName TODO
|
||||
* @param competitors TODO
|
||||
* @param boatClass TODO
|
||||
*
|
||||
* @param raceDefinitionSetToUpdate
|
||||
* if not <code>null</code>, after creating the {@link TrackedRace}, the {@link RaceDefinition} is
|
||||
* {@link DynamicRaceDefinitionSet#addRaceDefinition(RaceDefinition, DynamicTrackedRace) added} to that object.
|
||||
* {@link DynamicRaceDefinitionSet#addRaceDefinition(RaceDefinition, DynamicTrackedRace) added} to that
|
||||
* object.
|
||||
*/
|
||||
DynamicTrackedRace getOrCreateRaceDefinitionAndTrackedRace(TrackedRegatta trackedRegatta, UUID raceId,
|
||||
String raceName, Iterable<com.sap.sailing.domain.base.Competitor> competitors, BoatClass boatClass, Course course, Iterable<Sideline> sidelines,
|
||||
WindStore windStore, long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate, URI courseDesignUpdateURI, UUID tracTracEventUuid, String tracTracUsername, String tracTracPassword);
|
||||
DynamicTrackedRace getOrCreateRaceDefinitionAndTrackedRace(DynamicTrackedRegatta trackedRegatta, UUID raceId,
|
||||
String raceName, Iterable<com.sap.sailing.domain.base.Competitor> competitors, BoatClass boatClass,
|
||||
Course course, Iterable<Sideline> sidelines, WindStore windStore, long delayToLiveInMillis,
|
||||
long millisecondsOverWhichToAverageWind, DynamicRaceDefinitionSet raceDefinitionSetToUpdate,
|
||||
URI courseDesignUpdateURI, UUID tracTracEventUuid, String tracTracUsername, String tracTracPassword);
|
||||
|
||||
/**
|
||||
* The record may be for a single mark or a gate. If for a gate, the
|
||||
|
||||
+1
-1
@@ -15,8 +15,8 @@ import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.util.DateParser;
|
||||
import com.sap.sailing.util.InvalidDateException;
|
||||
|
||||
|
||||
+1
@@ -11,5 +11,6 @@ public interface TracTracConnectionConstants {
|
||||
final int PORT_STORED = PORT_LIVE + 1; //For official usage use 4401;
|
||||
|
||||
final String HIDDEN_STATUS = "HIDDEN";
|
||||
final Object REPLAY_STATUS = "REPLAY";
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package com.sap.sailing.domain.tractracadapter;
|
||||
|
||||
public interface CourseUpdateResponse {
|
||||
public interface UpdateResponse {
|
||||
|
||||
String getStatus();
|
||||
|
||||
+1
-1
@@ -21,10 +21,10 @@ import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.tractracadapter.TracTracControlPoint;
|
||||
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
package com.sap.sailing.domain.tractracadapter.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.ProtocolException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
import com.sap.sailing.domain.tracking.CourseDesignChangedListener;
|
||||
import com.sap.sailing.domain.tractracadapter.CourseUpdateResponse;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializationException;
|
||||
import com.sap.sailing.server.gateway.deserialization.JsonDeserializer;
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.Helpers;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.ControlPointJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseBaseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.CourseJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.GateJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.MarkJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.coursedata.impl.WaypointJsonSerializer;
|
||||
|
||||
public class CourseDesignChangedByRaceCommitteeHandler implements CourseDesignChangedListener {
|
||||
|
||||
private final static Logger logger = Logger.getLogger(CourseDesignChangedByRaceCommitteeHandler.class.getName());
|
||||
|
||||
private JsonSerializer<CourseBase> courseSerializer;
|
||||
private JsonDeserializer<CourseUpdateResponse> courseUpdateDeserializer;
|
||||
private final URI courseDesignUpdateURI;
|
||||
private final String tracTracUsername;
|
||||
private final String tracTracPassword;
|
||||
private final Serializable tracTracEventId;
|
||||
private final Serializable raceId;
|
||||
|
||||
private final static String HttpPostRequestMethod = "POST";
|
||||
private final static String ContentType = "Content-Type";
|
||||
private final static String ContentLength = "Content-Length";
|
||||
private final static String ContentTypeApplicationJson = "application/json";
|
||||
private final static String EncodingUtf8 = "UTF-8";
|
||||
private final static String CourseUpdateUrlTemplate = "%s?eventid=%s&raceid=%s&username=%s&password=%s";
|
||||
private final static String ResponseCodeForFailure = "FAILURE";
|
||||
|
||||
public CourseDesignChangedByRaceCommitteeHandler(URI courseDesignUpdateURI, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId) {
|
||||
this.courseDesignUpdateURI = courseDesignUpdateURI;
|
||||
this.tracTracUsername = tracTracUsername;
|
||||
this.tracTracPassword = tracTracPassword;
|
||||
this.tracTracEventId = tracTracEventId;
|
||||
this.raceId = raceId;
|
||||
this.courseSerializer = new CourseJsonSerializer(
|
||||
new CourseBaseJsonSerializer(
|
||||
new WaypointJsonSerializer(
|
||||
new ControlPointJsonSerializer(
|
||||
new MarkJsonSerializer(),
|
||||
new GateJsonSerializer(new MarkJsonSerializer())))));
|
||||
this.courseUpdateDeserializer = new CourseUpdateResponseDeserializer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void courseDesignChanged(CourseBase newCourseDesign) throws MalformedURLException, IOException {
|
||||
JSONObject serializedCourseDesign = courseSerializer.serialize(newCourseDesign);
|
||||
String payload = serializedCourseDesign.toJSONString();
|
||||
URL currentCourseDesignURL = buildCourseUpdateURL();
|
||||
logger.info("Using " + currentCourseDesignURL.toString() + " for the course update!");
|
||||
logger.info("Payload is " + payload);
|
||||
HttpURLConnection connection = (HttpURLConnection) currentCourseDesignURL.openConnection();
|
||||
try {
|
||||
setConnectionProperties(connection, payload);
|
||||
sendWithPayload(connection, payload);
|
||||
BufferedReader reader = getResponseOnCourseUpdateFromTracTrac(connection);
|
||||
try {
|
||||
Object responseBody = JSONValue.parseWithException(reader);
|
||||
JSONObject responseObject = Helpers.toJSONObjectSafe(responseBody);
|
||||
|
||||
checkAndLogCourseUpdateResponse(responseObject);
|
||||
} catch (ParseException pe) {
|
||||
pe.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
} else {
|
||||
logger.severe("Connection to TracTrac Course Update URL " + currentCourseDesignURL.toString() + " could not be established");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAndLogCourseUpdateResponse(JSONObject responseObject) throws JsonDeserializationException {
|
||||
CourseUpdateResponse courseUpdateResponse = courseUpdateDeserializer.deserialize(responseObject);
|
||||
if (courseUpdateResponse.getStatus().equals(ResponseCodeForFailure)) {
|
||||
logger.severe("Failed to send new course to TracTrac, got following response: " + courseUpdateResponse.getMessage());
|
||||
} else {
|
||||
logger.info("Successfully sent course update to TracTrac with response: " + courseUpdateResponse.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedReader getResponseOnCourseUpdateFromTracTrac(HttpURLConnection connection) throws IOException {
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
return reader;
|
||||
}
|
||||
|
||||
private void sendWithPayload(HttpURLConnection connection, String payload) throws IOException {
|
||||
DataOutputStream writer = new DataOutputStream(connection.getOutputStream());
|
||||
writer.writeBytes(payload);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
|
||||
private void setConnectionProperties(HttpURLConnection connection, String payload) throws ProtocolException {
|
||||
connection.setRequestMethod(HttpPostRequestMethod);
|
||||
connection.setDoOutput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setRequestProperty(ContentType, ContentTypeApplicationJson);
|
||||
connection.addRequestProperty(ContentLength, String.valueOf(payload.getBytes().length));
|
||||
}
|
||||
|
||||
private URL buildCourseUpdateURL() throws MalformedURLException, UnsupportedEncodingException {
|
||||
String url = String.format(CourseUpdateUrlTemplate,
|
||||
this.courseDesignUpdateURI.toString(),
|
||||
URLEncoder.encode(this.tracTracEventId.toString(), EncodingUtf8),
|
||||
URLEncoder.encode(this.raceId.toString(), EncodingUtf8),
|
||||
URLEncoder.encode(tracTracUsername, EncodingUtf8),
|
||||
URLEncoder.encode(tracTracPassword, EncodingUtf8));
|
||||
return new URL(url);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 794 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user