mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 14:12:11 +00:00
Merge branch 'master' into bug4425
Conflicts: java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/LeaderboardEntryDTO.java java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardWithCache.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/autoplay/client/nodes/IdleOverallLeaderBoardNode.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/LeaderboardSettingsDialogComponent.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardPanelLifecycle.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/MultiRaceLeaderboardSettingsDialogComponent.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/OverallLeaderboardSettingsDialogComponent.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/settings/client/leaderboard/SingleRaceLeaderboardSettingsDialogComponent.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardConfigPanel.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/MultiRaceLeaderboardPanel.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardEntryPoint.java
This commit is contained in:
commit
8a9137e600
840 files changed
+182611
-43851
No files matched your search
+7
-1
@@ -1,9 +1,13 @@
|
||||
package com.sap.sailing.dashboards.gwt.client.actions;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.shared.GwtIncompatible;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardAction;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dto.LeaderboardCompetitorsDTO;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.dto.CompetitorDTO;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.gwt.dispatch.shared.exceptions.DispatchException;
|
||||
@@ -29,7 +33,9 @@ public class GetCompetitorInLeaderboardAction implements DashboardAction<Leaderb
|
||||
public LeaderboardCompetitorsDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
|
||||
LeaderboardCompetitorsDTO result = new LeaderboardCompetitorsDTO();
|
||||
Leaderboard lb = dashboardDispatchContext.getRacingEventService().getLeaderboardByName(this.leaderboarName);
|
||||
result.setCompetitors(dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorDTOList(lb.getCompetitorsFromBestToWorst(MillisecondsTimePoint.now())));
|
||||
List<Competitor> competitorsFromBestToWorst = lb.getCompetitorsFromBestToWorst(MillisecondsTimePoint.now());
|
||||
List<CompetitorDTO> competitorDTOs = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorDTOList(competitorsFromBestToWorst);
|
||||
result.setCompetitors(competitorDTOs);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -26,7 +26,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProvider;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorColorProviderImpl;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.RaceCompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -74,7 +74,7 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna
|
||||
|
||||
private SailingServiceAsync sailingServiceAsync;
|
||||
private StringMessages stringMessages;
|
||||
private final CompetitorSelectionModel competitorSelectionModel;
|
||||
private final RaceCompetitorSelectionModel competitorSelectionModel;
|
||||
private final CompetitorColorProvider colorProvider;
|
||||
|
||||
private final double WIND_LINE_ADVANTAGE_DIV_WIDTH_IN_PT = 185;
|
||||
@@ -88,7 +88,7 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna
|
||||
this.sailingServiceAsync = sailingServiceAsync;
|
||||
this.raceMapResources = raceMapResources;
|
||||
colorProvider = new CompetitorColorProviderImpl();
|
||||
competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */true, colorProvider);
|
||||
competitorSelectionModel = new RaceCompetitorSelectionModel(/* hasMultiSelection */true, colorProvider);
|
||||
competitorSelectionModel.setCompetitors(startAnalysisDTO.getCompetitorDTOsFromStartAnaylsisCompetitorDTOs(),
|
||||
raceMap);
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
|
||||
+5
-2
@@ -15,6 +15,7 @@ import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisRankingTableEntryDTO;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO;
|
||||
import com.sap.sailing.dashboards.gwt.shared.dto.WindAndAdvantagesInfoForStartLineDTO;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
@@ -59,7 +60,8 @@ public final class StartAnalysisDTOFactory extends AbstractStartAnalysisCreation
|
||||
competitors.add(createStartAnalysisCompetitorDTO(dashboardDispatchContext, trackedRace, rankOfCompetitorWhilePassingSecondWaypoint, competitor));
|
||||
}
|
||||
if (competitor != null) {
|
||||
startAnalysisDTO.competitor = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore().convertToCompetitorDTO(competitor);
|
||||
Boat boatOfCompetitor = trackedRace.getBoatOfCompetitor(competitor);
|
||||
startAnalysisDTO.competitor = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore().convertToCompetitorWithBoatDTO(competitor, boatOfCompetitor);
|
||||
logger.log(Level.INFO, "Created startanalysis for competitor"+competitor);
|
||||
}
|
||||
startAnalysisDTO.startAnalysisCompetitorDTOs = competitors;
|
||||
@@ -191,8 +193,9 @@ public final class StartAnalysisDTOFactory extends AbstractStartAnalysisCreation
|
||||
|
||||
private static StartAnalysisCompetitorDTO createStartAnalysisCompetitorDTO(DashboardDispatchContext dashboardDispatchContext, TrackedRace trackedRace, int rank, Competitor competitor) {
|
||||
StartAnalysisCompetitorDTO startAnalysisCompetitorDTOsForRace = new StartAnalysisCompetitorDTO();
|
||||
Boat boatOfCompetitor = trackedRace.getBoatOfCompetitor(competitor);
|
||||
startAnalysisCompetitorDTOsForRace.competitorDTO = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore()
|
||||
.convertToCompetitorDTO(competitor);
|
||||
.convertToCompetitorWithBoatDTO(competitor, boatOfCompetitor);
|
||||
startAnalysisCompetitorDTOsForRace.rankingTableEntryDTO = createRankTableEntry(trackedRace, rank, competitor);
|
||||
return startAnalysisCompetitorDTOsForRace;
|
||||
}
|
||||
|
||||
+16
-3
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.datamining.shared;
|
||||
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.settings.SerializableSettings;
|
||||
|
||||
/**
|
||||
@@ -11,9 +12,9 @@ public abstract class ManeuverSettings extends SerializableSettings {
|
||||
|
||||
private static final long serialVersionUID = -393430331972342L;
|
||||
|
||||
public abstract Double getMinManeuverDuration();
|
||||
public abstract Duration getMinManeuverDuration();
|
||||
|
||||
public abstract Double getMaxManeuverDuration();
|
||||
public abstract Duration getMaxManeuverDuration();
|
||||
|
||||
public abstract Double getMinManeuverEnteringSpeedInKnots();
|
||||
|
||||
@@ -30,7 +31,19 @@ public abstract class ManeuverSettings extends SerializableSettings {
|
||||
public abstract Double getMinManeuverExitingAbsTWA();
|
||||
|
||||
public abstract Double getMaxManeuverExitingAbsTWA();
|
||||
|
||||
|
||||
public abstract Double getMinAbsCourseChangeInDegrees();
|
||||
|
||||
public abstract Double getMaxAbsCourseChangeInDegrees();
|
||||
|
||||
public abstract Duration getMinDurationFromPrecedingManeuver();
|
||||
|
||||
public abstract Duration getMaxDurationFromPrecedingManeuver();
|
||||
|
||||
public abstract Duration getMinDurationToFollowingManeuver();
|
||||
|
||||
public abstract Duration getMaxDurationToFollowingManeuver();
|
||||
|
||||
public abstract boolean isMainCurveAnalysis();
|
||||
|
||||
}
|
||||
+90
-8
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.datamining.shared;
|
||||
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
@@ -9,8 +11,8 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
|
||||
private static final long serialVersionUID = 69258712144L;
|
||||
|
||||
private Double minManeuverDuration;
|
||||
private Double maxManeuverDuration;
|
||||
private Duration minManeuverDuration;
|
||||
private Duration maxManeuverDuration;
|
||||
private Double minManeuverEnteringSpeedInKnots;
|
||||
private Double maxManeuverEnteringSpeedInKnots;
|
||||
private Double minManeuverExitingSpeedInKnots;
|
||||
@@ -19,20 +21,30 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
private Double maxManeuverEnteringAbsTWA;
|
||||
private Double minManeuverExitingAbsTWA;
|
||||
private Double maxManeuverExitingAbsTWA;
|
||||
private Double minAbsCourseChangeInDegrees;
|
||||
private Double maxAbsCourseChangeInDegrees;
|
||||
private Duration minDurationFromPrecedingManeuver;
|
||||
private Duration maxDurationFromPrecedingManeuver;
|
||||
private Duration minDurationToFollowingManeuver;
|
||||
private Duration maxDurationToFollowingManeuver;
|
||||
private boolean mainCurveAnalysis;
|
||||
|
||||
public static ManeuverSettingsImpl createDefault() {
|
||||
return new ManeuverSettingsImpl(1.0, null, 2.0, null, 1.0, null, null, null, null, null, false);
|
||||
return new ManeuverSettingsImpl(Duration.ONE_SECOND, null, 2.0, null, 1.0, null, null, null, null, null, false,
|
||||
null, null, null, null, null, null);
|
||||
}
|
||||
|
||||
public ManeuverSettingsImpl() {
|
||||
}
|
||||
|
||||
public ManeuverSettingsImpl(Double minManeuverDuration, Double maxManeuverDuration,
|
||||
public ManeuverSettingsImpl(Duration minManeuverDuration, Duration maxManeuverDuration,
|
||||
Double minManeuverEnteringSpeedInKnots, Double maxManeuverEnteringSpeedInKnots,
|
||||
Double minManeuverExitingSpeedInKnots, Double maxManeuverExitingSpeedInKnots,
|
||||
Double minManeuverEnteringAbsTWA, Double maxManeuverEnteringAbsTWA, Double minManeuverExitingAbsTWA,
|
||||
Double maxManeuverExitingAbsTWA, boolean mainCurveAnalysis) {
|
||||
Double maxManeuverExitingAbsTWA, boolean mainCurveAnalysis, Double minAbsCourseChangeInDegrees,
|
||||
Double maxAbsCourseChangeInDegrees, Duration minDurationFromPrecedingManeuver,
|
||||
Duration maxDurationFromPrecedingManeuver, Duration minDurationToFollowingManeuver,
|
||||
Duration maxDurationToFollowingManeuver) {
|
||||
super();
|
||||
this.minManeuverDuration = minManeuverDuration;
|
||||
this.maxManeuverDuration = maxManeuverDuration;
|
||||
@@ -45,13 +57,43 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
this.minManeuverExitingAbsTWA = minManeuverExitingAbsTWA;
|
||||
this.maxManeuverExitingAbsTWA = maxManeuverExitingAbsTWA;
|
||||
this.mainCurveAnalysis = mainCurveAnalysis;
|
||||
this.minAbsCourseChangeInDegrees = minAbsCourseChangeInDegrees;
|
||||
this.maxAbsCourseChangeInDegrees = maxAbsCourseChangeInDegrees;
|
||||
this.minDurationFromPrecedingManeuver = minDurationFromPrecedingManeuver;
|
||||
this.maxDurationFromPrecedingManeuver = maxDurationFromPrecedingManeuver;
|
||||
this.minDurationToFollowingManeuver = minDurationToFollowingManeuver;
|
||||
this.maxDurationToFollowingManeuver = maxDurationToFollowingManeuver;
|
||||
}
|
||||
|
||||
public Double getMinManeuverDuration() {
|
||||
public Double getMinAbsCourseChangeInDegrees() {
|
||||
return minAbsCourseChangeInDegrees;
|
||||
}
|
||||
|
||||
public Double getMaxAbsCourseChangeInDegrees() {
|
||||
return maxAbsCourseChangeInDegrees;
|
||||
}
|
||||
|
||||
public Duration getMinDurationFromPrecedingManeuver() {
|
||||
return minDurationFromPrecedingManeuver;
|
||||
}
|
||||
|
||||
public Duration getMaxDurationFromPrecedingManeuver() {
|
||||
return maxDurationFromPrecedingManeuver;
|
||||
}
|
||||
|
||||
public Duration getMinDurationToFollowingManeuver() {
|
||||
return minDurationToFollowingManeuver;
|
||||
}
|
||||
|
||||
public Duration getMaxDurationToFollowingManeuver() {
|
||||
return maxDurationToFollowingManeuver;
|
||||
}
|
||||
|
||||
public Duration getMinManeuverDuration() {
|
||||
return minManeuverDuration;
|
||||
}
|
||||
|
||||
public Double getMaxManeuverDuration() {
|
||||
public Duration getMaxManeuverDuration() {
|
||||
return maxManeuverDuration;
|
||||
}
|
||||
|
||||
@@ -86,7 +128,7 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
public Double getMaxManeuverExitingAbsTWA() {
|
||||
return maxManeuverExitingAbsTWA;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isMainCurveAnalysis() {
|
||||
return mainCurveAnalysis;
|
||||
@@ -97,6 +139,11 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + (mainCurveAnalysis ? 1231 : 1237);
|
||||
result = prime * result + ((maxAbsCourseChangeInDegrees == null) ? 0 : maxAbsCourseChangeInDegrees.hashCode());
|
||||
result = prime * result
|
||||
+ ((maxDurationFromPrecedingManeuver == null) ? 0 : maxDurationFromPrecedingManeuver.hashCode());
|
||||
result = prime * result
|
||||
+ ((maxDurationToFollowingManeuver == null) ? 0 : maxDurationToFollowingManeuver.hashCode());
|
||||
result = prime * result + ((maxManeuverDuration == null) ? 0 : maxManeuverDuration.hashCode());
|
||||
result = prime * result + ((maxManeuverEnteringAbsTWA == null) ? 0 : maxManeuverEnteringAbsTWA.hashCode());
|
||||
result = prime * result
|
||||
@@ -104,6 +151,11 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
result = prime * result + ((maxManeuverExitingAbsTWA == null) ? 0 : maxManeuverExitingAbsTWA.hashCode());
|
||||
result = prime * result
|
||||
+ ((maxManeuverExitingSpeedInKnots == null) ? 0 : maxManeuverExitingSpeedInKnots.hashCode());
|
||||
result = prime * result + ((minAbsCourseChangeInDegrees == null) ? 0 : minAbsCourseChangeInDegrees.hashCode());
|
||||
result = prime * result
|
||||
+ ((minDurationFromPrecedingManeuver == null) ? 0 : minDurationFromPrecedingManeuver.hashCode());
|
||||
result = prime * result
|
||||
+ ((minDurationToFollowingManeuver == null) ? 0 : minDurationToFollowingManeuver.hashCode());
|
||||
result = prime * result + ((minManeuverDuration == null) ? 0 : minManeuverDuration.hashCode());
|
||||
result = prime * result + ((minManeuverEnteringAbsTWA == null) ? 0 : minManeuverEnteringAbsTWA.hashCode());
|
||||
result = prime * result
|
||||
@@ -125,6 +177,21 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
ManeuverSettingsImpl other = (ManeuverSettingsImpl) obj;
|
||||
if (mainCurveAnalysis != other.mainCurveAnalysis)
|
||||
return false;
|
||||
if (maxAbsCourseChangeInDegrees == null) {
|
||||
if (other.maxAbsCourseChangeInDegrees != null)
|
||||
return false;
|
||||
} else if (!maxAbsCourseChangeInDegrees.equals(other.maxAbsCourseChangeInDegrees))
|
||||
return false;
|
||||
if (maxDurationFromPrecedingManeuver == null) {
|
||||
if (other.maxDurationFromPrecedingManeuver != null)
|
||||
return false;
|
||||
} else if (!maxDurationFromPrecedingManeuver.equals(other.maxDurationFromPrecedingManeuver))
|
||||
return false;
|
||||
if (maxDurationToFollowingManeuver == null) {
|
||||
if (other.maxDurationToFollowingManeuver != null)
|
||||
return false;
|
||||
} else if (!maxDurationToFollowingManeuver.equals(other.maxDurationToFollowingManeuver))
|
||||
return false;
|
||||
if (maxManeuverDuration == null) {
|
||||
if (other.maxManeuverDuration != null)
|
||||
return false;
|
||||
@@ -150,6 +217,21 @@ public class ManeuverSettingsImpl extends ManeuverSettings {
|
||||
return false;
|
||||
} else if (!maxManeuverExitingSpeedInKnots.equals(other.maxManeuverExitingSpeedInKnots))
|
||||
return false;
|
||||
if (minAbsCourseChangeInDegrees == null) {
|
||||
if (other.minAbsCourseChangeInDegrees != null)
|
||||
return false;
|
||||
} else if (!minAbsCourseChangeInDegrees.equals(other.minAbsCourseChangeInDegrees))
|
||||
return false;
|
||||
if (minDurationFromPrecedingManeuver == null) {
|
||||
if (other.minDurationFromPrecedingManeuver != null)
|
||||
return false;
|
||||
} else if (!minDurationFromPrecedingManeuver.equals(other.minDurationFromPrecedingManeuver))
|
||||
return false;
|
||||
if (minDurationToFollowingManeuver == null) {
|
||||
if (other.minDurationToFollowingManeuver != null)
|
||||
return false;
|
||||
} else if (!minDurationToFollowingManeuver.equals(other.minDurationToFollowingManeuver))
|
||||
return false;
|
||||
if (minManeuverDuration == null) {
|
||||
if (other.minManeuverDuration != null)
|
||||
return false;
|
||||
|
||||
+26
-4
@@ -128,7 +128,7 @@ AbsoluteTrueWindAngle=Absolute true wind angle (TWA)
|
||||
TrueWindAngle=True wind angle (TWA)
|
||||
Wind=Wind
|
||||
VMG=Velocity Made Good
|
||||
MaxAngularVelocityInDegreesPerSecond=Maximal angular velocity in deg/s
|
||||
MaxTurningRateInDegreesPerSecond=Max. turning rate in deg/s
|
||||
ManeuverEnteringAbsTWA=Absolute TWA before maneuver
|
||||
ManeuverExitingAbsTWA=Absolute TWA after maneuver
|
||||
ManeuverSpeedDetailsRetrieverChain=Maneuver speed details
|
||||
@@ -149,8 +149,8 @@ AbsTWAAtManeuverClimax=Absolute TWA at maneuver climax
|
||||
ManeuverEnteringSpeedInKnots=Maneuver entering speed (kts)
|
||||
ManeuverExitingSpeedInKnots=Maneuver exiting speed (kts)
|
||||
TackBeforeManeuver=Tack before maneuver
|
||||
ManeuverBoundariesRetrieverChain=Maneuver boundaries
|
||||
ManeuverBoundaries=Maneuver boundaries
|
||||
CompleteManeuverCurveWithEstimationDataRetrieverChain=Complete maneuver curves with estimation data
|
||||
CompleteManeuverCurveWithEstimationData=Complete maneuver curves with estimation data
|
||||
ManeuverStartSpeedDeviationRatioFromAvg=Speed deviation ratio of maneuver start with avg speed before maneuver
|
||||
ManeuverStartCogDeviationFromAvgInDegrees=COG deviation of maneuver start with avg COG before maneuver in degrees
|
||||
ManeuverEndSpeedDeviationRatioFromAvg=Speed deviation ratio of maneuver end with avg speed after maneuver
|
||||
@@ -166,4 +166,26 @@ DurationBetweenStableSpeedWithCourseAndMainCurveEndInSeconds=Duration between st
|
||||
SpeedRatioBetweenStableSpeedWithCourseAndMainCurveEnd=Speed ratio between stable speed with course and main curve end
|
||||
AbsCourseDifferenceBetweenStableSpeedWithCourseAndMainCurveEndInDegrees=Abs. course difference between stable speed with course and main curve end in degrees
|
||||
AbsTwaAtLowestRatioToEnteringSpeed=Abs. TWA at lowest ratio to entering speed
|
||||
AbsTwaAtHighestRatioToEnteringSpeed=Abs. TWA at highest ratio to entering speed
|
||||
AbsTwaAtHighestRatioToEnteringSpeed=Abs. TWA at highest ratio to entering speed
|
||||
TypeOfPreviousManeuver=Type of the previous maneuver
|
||||
TypeOfNextManeuver=Type of the next maneuver
|
||||
AvgTurningRateInDegreesPerSecond=Avg turning rate in deg/s
|
||||
ManeuverStartsByRunningAwayFromTheWind=Maneuver starts by running away from the wind
|
||||
RelativeBearingToNextMarkBeforeManeuver=Relative bearing to the next mark before maneuver
|
||||
RelativeBearingToNextMarkAfterManeuver=Relative bearing to the next mark after maneuver
|
||||
AbsRelativeBearingToNextMarkBeforeManeuver=Abs. relative bearing to the next mark before maneuver
|
||||
AbsRelativeBearingToNextMarkAfterManeuver=Abs. relative bearing to the next mark after maneuver
|
||||
RatioBetweenDistanceSailedWithAndWithoutManeuver=Ratio between distance sailed with and without maneuver
|
||||
RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver=Ratio between distance sailed toward middle angle projection with and without maneuver
|
||||
DurationLostByManeuver=Duration lost by maneuver
|
||||
DurationLostByManeuverTowardMiddleAngleProjection=duration lost by maneuver toward middle angle projection
|
||||
JibingCount=Jibing count
|
||||
TackingCount=Tacking count
|
||||
AbsTwaAtMaxTurningRate=Abs. TWA at max. turning rate
|
||||
AbsTwaAtLowestSpeed=Abs. TWA at lowest speed
|
||||
AbsTwaAtHighestSpeed=Abs. TWA at highest speed
|
||||
PercentageOfMainCurveProgressUntilLowestSpeed=Percentage of main curve progress until lowest speed
|
||||
PercentageOfMainCurveProgressUntilHighestSpeed=Percentage of main curve progress until highest speed
|
||||
PercentageOfMainCurveProgressUntilMaxTurningRate=Percentage of main curve progress until max. turning rate speed
|
||||
AbsTwaAtManeuverMiddle=Abs. TWA at maneuver middle
|
||||
GpsSamplingRate=GPS sampling rate
|
||||
+33
-8
@@ -128,7 +128,7 @@ AbsoluteTrueWindAngle=Absoluter Winkel zum wahren Wind (TWA)
|
||||
TrueWindAngle=Winkel zum wahren Wind (TWA)
|
||||
Wind=Wind
|
||||
VMG=Luv-/Leegeschwindigkeit (VMG)
|
||||
MaxAngularVelocityInDegreesPerSecond=Maximale Winkelgeschwindigkeit in Grad/Sek.
|
||||
MaxTurningRateInDegreesPerSecond=Max. Drehrate in deg/s
|
||||
ManeuverEnteringAbsTWA=Absolutes TWA vor Manöver
|
||||
ManeuverExitingAbsTWA=Absolutes TWA nach Manöver
|
||||
ManeuverSpeedDetailsRetrieverChain=Manöver-Geschwindigkeitsdetails
|
||||
@@ -149,12 +149,12 @@ AbsTWAAtManeuverClimax=Absolutes TWA während Manöver-Höhepunkt
|
||||
ManeuverEnteringSpeedInKnots=Manöver Anfangsgeschwindigkeit (kn)
|
||||
ManeuverExitingSpeedInKnots=Manöver Endgeschwindigkeit (kn)
|
||||
TackBeforeManeuver=Bug vor Manöver-Eintritt
|
||||
ManeuverBoundariesRetrieverChain=Manöver Grenzen
|
||||
ManeuverBoundaries=Manöver Grenzen
|
||||
ManeuverStartSpeedDeviationRatioFromAvg=Verhältnis der Geschwindigkeitabweichung an Manöver-Anfang mit avg Geschwindigkeit vor Manöver
|
||||
ManeuverStartCogDeviationFromAvgInDegrees=COG-Abweichung an Manöver-Anfang mit avg COG vor Manöver in Grad
|
||||
ManeuverEndSpeedDeviationRatioFromAvg=Verhältnis der Geschwindigkeitabweichung an Manöver-Ende mit avg Geschwindigkeit nach Manöver
|
||||
ManeuverEndCogDeviationFromAvgInDegrees=COG-Abweichung an Manöver-Ende mit avg COG nach Manöver in Grad
|
||||
CompleteManeuverCurveWithEstimationDataRetrieverChain=Komplette Manöverkurven mit Schätzungsdaten
|
||||
CompleteManeuverCurveWithEstimationData=Komplette Manöverkurven mit Schätzungsdaten
|
||||
ManeuverStartSpeedDeviationRatioFromAvg=Verhältnis der Geschwindigkeitabweichung an Manöver-Anfang mit durchschnittlicher Geschwindigkeit vor Manöver
|
||||
ManeuverStartCogDeviationFromAvgInDegrees=COG-Abweichung an Manöver-Anfang mit durchschnittlichem COG vor Manöver in Grad
|
||||
ManeuverEndSpeedDeviationRatioFromAvg=Verhältnis der Geschwindigkeitabweichung an Manöver-Ende mit durchschnittlicher Geschwindigkeit nach Manöver
|
||||
ManeuverEndCogDeviationFromAvgInDegrees=COG-Abweichung an Manöver-Ende mit durchschnittlichem COG nach Manöver in Grad
|
||||
DurationToNextManeuverInSeconds=Dauer vom Ende des aktuellen Manövers bis zum Anfang des nächsten Manövers in Sekunden
|
||||
DurationFromPreviousManeuverInSeconds=Dauer vom Ende des letzten Manövers bis zum Anfang des aktuellen Manövers in Sekunden
|
||||
NextManeuverAtLeastOneSecondInFront=Anfang des nächsten Manövers ist mindestens eine Sekunde weiter als das Ende des aktuellen Manövers
|
||||
@@ -166,4 +166,29 @@ DurationBetweenStableSpeedWithCourseAndMainCurveEndInSeconds=Dauer zwischen stab
|
||||
SpeedRatioBetweenStableSpeedWithCourseAndMainCurveEnd=Geschwindigkeitsverhältnis zwischen stabiler Geschwindigkeit mit Kurs und Ende der Hauptkurve in Sekunden
|
||||
AbsCourseDifferenceBetweenStableSpeedWithCourseAndMainCurveEndInDegrees=Abs. Kursunterschied zwischen stabiler Geschwindigkeit mit Kurs und Ende der Hauptkurve in Grad
|
||||
AbsTwaAtLowestRatioToEnteringSpeed=Abs. TWA an Stelle mit kleinstem Verhältnis zu Anfangsgeschwindigkeit
|
||||
AbsTwaAtHighestRatioToEnteringSpeed=Abs. TWA an Stelle mit höchstem Verhältnis zu Anfangsgeschwindigkeit
|
||||
AbsTwaAtHighestRatioToEnteringSpeed=Abs. TWA an Stelle mit höchstem Verhältnis zu Anfangsgeschwindigkeit
|
||||
TypeOfPreviousManeuver=Typ des vorigen Manövers
|
||||
TypeOfNextManeuver=Typ des nächsten Manövers
|
||||
AvgTurningRateInDegreesPerSecond=Durchschnitliche Drehrate in deg/s
|
||||
ManeuverStartsByRunningAwayFromTheWind=Manöver beginnt in Abfall-Richtung
|
||||
RelativeBearingToNextMarkBeforeManeuver=Relative Richtung zur nächsten Marke vor dem Manöver
|
||||
RelativeBearingToNextMarkAfterManeuver=Relative Richtung zur nächsten Marke nach dem Manöver
|
||||
AbsRelativeBearingToNextMarkBeforeManeuver=Abs. relative Richtung zur nächsten Marke vor dem Manöver
|
||||
AbsRelativeBearingToNextMarkAfterManeuver=Abs. relative Richtung zur nächsten Marke nach dem Manöver
|
||||
RatioBetweenDistanceSailedWithAndWithoutManeuver=Verhältnis zwischen gesegelter Distanz mit und ohne Manövrierung
|
||||
RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver=Verhältnis zwischen gesegelter Distanz von Mittelwinkel-Projektion mit und ohne Manövrierung
|
||||
DurationLostByManeuver=Verlorene Zeit
|
||||
DurationLostByManeuverTowardMiddleAngleProjection=Verlorene Zeit anhand der Mittelwinkel-Projektion
|
||||
CurveWithUnstableCourseAndSpeed=Kurve mit instabilem Kurs und Geschwindigkeit
|
||||
MainCurve=Hauptkurve
|
||||
JibingCount=Anzahl Halsen
|
||||
TackingCount=Anzahl Wenden
|
||||
AbsTwaAtMaxTurningRate=Abs. TWA bei max. Drehrate
|
||||
AbsTwaAtLowestSpeed=Abs. TWA bei geringster Geschwindigkeit
|
||||
AbsTwaAtHighestSpeed=Abs. TWA bei höchster Geschwindigkeit
|
||||
PercentageOfMainCurveProgressUntilLowestSpeed=Prozentualer Fortschritt der Hauptkurve bis zum Erreichen von geringster Geschwindigkeit
|
||||
PercentageOfMainCurveProgressUntilHighestSpeed=Prozentualer Fortschritt der Hauptkurve bis zum Erreichen von höchster Geschwindigkeit
|
||||
PercentageOfMainCurveProgressUntilMaxTurningRate=Prozentualer Fortschritt der Hauptkurve bis zum Erreichen von max. Drehrate
|
||||
ManeuverTypeForCompleteManeuverCurve=Manövertyp für komplette Manöverkurve
|
||||
AbsTwaAtManeuverMiddle=Abs. TWA während Manövermitte
|
||||
GpsSamplingRate=GPS-Samplingrate
|
||||
@@ -14,7 +14,7 @@ import com.sap.sailing.datamining.data.HasFoilingSegmentContext;
|
||||
import com.sap.sailing.datamining.data.HasGPSFixContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverBoundariesContext;
|
||||
import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverSpeedDetailsContext;
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
@@ -107,7 +107,7 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
|
||||
internalClasses.add(HasFoilingSegmentContext.class);
|
||||
internalClasses.add(HasManeuverContext.class);
|
||||
internalClasses.add(HasManeuverSpeedDetailsContext.class);
|
||||
internalClasses.add(HasManeuverBoundariesContext.class);
|
||||
internalClasses.add(HasCompleteManeuverCurveWithEstimationDataContext.class);
|
||||
internalClasses.add(HasMarkPassingContext.class);
|
||||
internalClasses.add(HasRaceOfCompetitorContext.class);
|
||||
internalClasses.add(HasLeaderboardGroupContext.class);
|
||||
|
||||
+9
-9
@@ -10,7 +10,7 @@ import com.sap.sailing.datamining.data.HasGPSFixContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverSpeedDetailsContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverBoundariesContext;
|
||||
import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext;
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext;
|
||||
@@ -28,7 +28,7 @@ import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProce
|
||||
import com.sap.sailing.datamining.impl.components.LeaderboardRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.ManeuverRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.ManeuverSpeedDetailsRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.ManeuverBoundariesRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.CompleteManeuverCurveWithEstimationDataRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.MarkPassingRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.RaceOfCompetitorRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor;
|
||||
@@ -128,13 +128,13 @@ public class SailingDataRetrievalChainDefinitions {
|
||||
"ManeuverSpeedDetails");
|
||||
dataRetrieverChainDefinitions.add(speedDetailsDataRetrieverChainDefinition);
|
||||
|
||||
DataRetrieverChainDefinition<RacingEventService, HasManeuverBoundariesContext> maneuverBoundariesRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
raceOfCompetitorRetrieverChainDefinition, HasManeuverBoundariesContext.class,
|
||||
"ManeuverBoundariesRetrieverChain");
|
||||
maneuverBoundariesRetrieverChainDefinition.endWith(RaceOfCompetitorRetrievalProcessor.class,
|
||||
ManeuverBoundariesRetrievalProcessor.class, HasManeuverBoundariesContext.class,
|
||||
"ManeuverBoundaries");
|
||||
dataRetrieverChainDefinitions.add(maneuverBoundariesRetrieverChainDefinition);
|
||||
DataRetrieverChainDefinition<RacingEventService, HasCompleteManeuverCurveWithEstimationDataContext> completeManeuverCurveWithEstimationDataRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
raceOfCompetitorRetrieverChainDefinition, HasCompleteManeuverCurveWithEstimationDataContext.class,
|
||||
"CompleteManeuverCurveWithEstimationDataRetrieverChain");
|
||||
completeManeuverCurveWithEstimationDataRetrieverChainDefinition.endWith(RaceOfCompetitorRetrievalProcessor.class,
|
||||
CompleteManeuverCurveWithEstimationDataRetrievalProcessor.class, HasCompleteManeuverCurveWithEstimationDataContext.class, ManeuverSettings.class, ManeuverSettingsImpl.createDefault(),
|
||||
"CompleteManeuverCurveWithEstimationData");
|
||||
dataRetrieverChainDefinitions.add(completeManeuverCurveWithEstimationDataRetrieverChainDefinition);
|
||||
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasMarkPassingContext> markPassingRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
legOfCompetitorRetrieverChainDefinition, HasMarkPassingContext.class, "MarkPassingSailingDomainRetrieverChain");
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public interface HasCompleteManeuverCurveWithEstimationDataContext {
|
||||
|
||||
@Connector(scanForStatistics = false)
|
||||
HasRaceOfCompetitorContext getRaceOfCompetitorContext();
|
||||
|
||||
@Connector
|
||||
CompleteManeuverCurveWithEstimationData getCompleteManeuverCurveWithEstimationData();
|
||||
|
||||
@Dimension(messageKey = "ToSide")
|
||||
NauticalSide getToSide();
|
||||
|
||||
@Statistic(messageKey = "ManeuverStartSpeedDeviationRatioFromAvg", ordinal = 1, resultDecimals = 4)
|
||||
Double getManeuverStartSpeedDeviationRatioFromAvgStatistic();
|
||||
|
||||
@Statistic(messageKey = "ManeuverStartCogDeviationFromAvgInDegrees", ordinal = 2, resultDecimals = 4)
|
||||
Double getManeuverStartCogDeviationFromAvgInDegreesStatistic();
|
||||
|
||||
@Statistic(messageKey = "ManeuverEndSpeedDeviationRatioFromAvg", ordinal = 3, resultDecimals = 4)
|
||||
Double getManeuverEndSpeedDeviationRatioFromAvgStatistic();
|
||||
|
||||
@Statistic(messageKey = "ManeuverEndCogDeviationFromAvgInDegrees", ordinal = 4, resultDecimals = 4)
|
||||
Double getManeuverEndCogDeviationFromAvgInDegreesStatistic();
|
||||
|
||||
@Statistic(messageKey = "DurationToNextManeuverInSeconds", ordinal = 5, resultDecimals = 4)
|
||||
Double getDurationToNextManeuverInSecondsStatistic();
|
||||
|
||||
@Statistic(messageKey = "DurationFromPreviousManeuverInSeconds", ordinal = 6, resultDecimals = 4)
|
||||
Double getDurationFromPreviousManeuverInSecondsStatistic();
|
||||
|
||||
@Dimension(messageKey = "NextManeuverAtLeastOneSecondInFront", ordinal = 7)
|
||||
boolean isNextManeuverAtLeastOneSecondInFront();
|
||||
|
||||
@Dimension(messageKey = "PreviousManeuverAtLeastOneSecondBehind", ordinal = 8)
|
||||
boolean isPreviousManeuverAtLeastOneSecondBehind();
|
||||
|
||||
@Dimension(messageKey = "JibingCount")
|
||||
ClusterDTO getJibingCount();
|
||||
|
||||
@Dimension(messageKey = "TackingCount")
|
||||
ClusterDTO getTackingCount();
|
||||
|
||||
@Statistic(messageKey = "AbsTwaAtMaxTurningRate")
|
||||
double getAbsTwaAtMaxTurningRate();
|
||||
|
||||
@Statistic(messageKey = "AbsTwaAtLowestSpeed")
|
||||
double getAbsTwaAtLowestSpeed();
|
||||
|
||||
@Statistic(messageKey = "AbsTwaAtHighestSpeed")
|
||||
double getAbsTwaAtHighestSpeed();
|
||||
|
||||
@Statistic(messageKey = "AbsTwaAtManeuverMiddle")
|
||||
double getAbsTwaAtManeuverMiddle();
|
||||
|
||||
@Statistic(messageKey = "GpsSamplingRate")
|
||||
double getGpsSamplingRate();
|
||||
|
||||
@Statistic(messageKey = "ManeuverEnteringAbsTWA")
|
||||
Double getEnteringAbsTWA();
|
||||
|
||||
@Statistic(messageKey = "ManeuverExitingAbsTWA")
|
||||
Double getExitingAbsTWA();
|
||||
|
||||
@Dimension(messageKey = "TypeOfPreviousManeuver")
|
||||
ManeuverType getTypeOfPreviousManeuver();
|
||||
|
||||
@Dimension(messageKey = "TypeOfNextManeuver")
|
||||
ManeuverType getTypeOfNextManeuver();
|
||||
|
||||
@Statistic(messageKey = "AbsoluteDirectionChange", resultDecimals = 2)
|
||||
Double getAbsoluteDirectionChangeInDegrees();
|
||||
|
||||
@Statistic(messageKey = "RatioBetweenDistanceSailedWithAndWithoutManeuver", resultDecimals = 4)
|
||||
double getRatioBetweenDistanceSailedWithAndWithoutManeuver();
|
||||
|
||||
@Statistic(messageKey = "DurationLostByManeuver", resultDecimals = 4)
|
||||
double getDurationLostByManeuver();
|
||||
|
||||
@Statistic(messageKey = "DurationLostByManeuverTowardMiddleAngleProjection", resultDecimals = 4)
|
||||
double getDurationLostByManeuverTowardMiddleAngleProjection();
|
||||
|
||||
@Statistic(messageKey = "RatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver", resultDecimals = 4)
|
||||
double getRatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver();
|
||||
|
||||
@Statistic(messageKey = "RelativeBearingToNextMarkBeforeManeuver", resultDecimals = 1)
|
||||
Double getRelativeBearingToNextMarkBeforeManeuver();
|
||||
|
||||
@Statistic(messageKey = "RelativeBearingToNextMarkAfterManeuver", resultDecimals = 1)
|
||||
Double getRelativeBearingToNextMarkAfterManeuver();
|
||||
|
||||
@Statistic(messageKey = "AbsRelativeBearingToNextMarkBeforeManeuver", resultDecimals = 1)
|
||||
Double getAbsRelativeBearingToNextMarkBeforeManeuver();
|
||||
|
||||
@Statistic(messageKey = "AbsRelativeBearingToNextMarkAfterManeuver", resultDecimals = 1)
|
||||
Double getAbsRelativeBearingToNextMarkAfterManeuver();
|
||||
|
||||
@Statistic(messageKey = "ManeuverEnteringSpeedInKnots", resultDecimals = 2)
|
||||
Double getManeuverEnteringSpeed();
|
||||
|
||||
@Statistic(messageKey = "ManeuverExitingSpeedInKnots", resultDecimals = 2)
|
||||
Double getManeuverExitingSpeed();
|
||||
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
/**
|
||||
* Contains statistics for analysis of computation correctness of maneuver boundaries.
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public interface HasManeuverBoundariesContext {
|
||||
|
||||
@Connector(scanForStatistics = false)
|
||||
HasRaceOfCompetitorContext getRaceOfCompetitorContext();
|
||||
|
||||
// FIXME due to UI bug there is at least one dimension per fact required
|
||||
@Dimension(messageKey = "ManeuverDirection", ordinal = 3)
|
||||
NauticalSide getToSide();
|
||||
|
||||
@Dimension(messageKey = "ManeuverType", ordinal = 4)
|
||||
ManeuverType getManeuverType();
|
||||
|
||||
@Statistic(messageKey = "ManeuverStartSpeedDeviationRatioFromAvg", ordinal = 1, resultDecimals = 4)
|
||||
Double getManeuverStartSpeedDeviationRatioFromAvgStatistic();
|
||||
|
||||
@Statistic(messageKey = "ManeuverStartCogDeviationFromAvgInDegrees", ordinal = 2, resultDecimals = 4)
|
||||
Double getManeuverStartCogDeviationFromAvgInDegreesStatistic();
|
||||
|
||||
@Statistic(messageKey = "ManeuverEndSpeedDeviationRatioFromAvg", ordinal = 3, resultDecimals = 4)
|
||||
Double getManeuverEndSpeedDeviationRatioFromAvgStatistic();
|
||||
|
||||
@Statistic(messageKey = "ManeuverEndCogDeviationFromAvgInDegrees", ordinal = 4, resultDecimals = 4)
|
||||
Double getManeuverEndCogDeviationFromAvgInDegreesStatistic();
|
||||
|
||||
@Statistic(messageKey = "DurationToNextManeuverInSeconds", ordinal = 5, resultDecimals = 4)
|
||||
Double getDurationToNextManeuverInSecondsStatistic();
|
||||
|
||||
@Statistic(messageKey = "DurationFromPreviousManeuverInSeconds", ordinal = 6, resultDecimals = 4)
|
||||
Double getDurationFromPreviousManeuverInSecondsStatistic();
|
||||
|
||||
@Statistic(messageKey = "NextManeuverAtLeastOneSecondInFront", ordinal = 7)
|
||||
boolean isNextManeuverAtLeastOneSecondInFront();
|
||||
|
||||
@Statistic(messageKey = "PreviousManeuverAtLeastOneSecondBehind", ordinal = 8)
|
||||
boolean isPreviousManeuverAtLeastOneSecondBehind();
|
||||
|
||||
}
|
||||
+8
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
@@ -13,6 +14,12 @@ public interface HasManeuverContext extends HasManeuver, HasTrackedLegOfCompetit
|
||||
|
||||
@Dimension(messageKey = "TackBeforeManeuver")
|
||||
Tack getTackBeforeManeuver();
|
||||
|
||||
@Dimension(messageKey = "TypeOfPreviousManeuver")
|
||||
ManeuverType getTypeOfPreviousManeuver();
|
||||
|
||||
@Dimension(messageKey = "TypeOfNextManeuver")
|
||||
ManeuverType getTypeOfNextManeuver();
|
||||
|
||||
@Statistic(messageKey = "AbsoluteDirectionChange", resultDecimals = 2, ordinal = 3)
|
||||
Double getAbsoluteDirectionChangeInDegrees();
|
||||
@@ -61,7 +68,7 @@ public interface HasManeuverContext extends HasManeuver, HasTrackedLegOfCompetit
|
||||
|
||||
@Statistic(messageKey = "AbsCourseDifferenceBetweenStableSpeedWithCourseAndMainCurveEndInDegrees", ordinal = 25, resultDecimals = 2)
|
||||
Double getAbsCourseDifferenceBetweenStableSpeedWithCourseAndMainCurveEndInDegrees();
|
||||
|
||||
|
||||
TimePoint getTimePointBeforeForAnalysis();
|
||||
|
||||
TimePoint getTimePointAfterForAnalysis();
|
||||
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.data.CompleteManeuverCurveWithEstimationDataWithContext;
|
||||
import com.sap.sailing.datamining.shared.ManeuverSettings;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData;
|
||||
import com.sap.sailing.domain.maneuverdetection.ManeuverDetector;
|
||||
import com.sap.sailing.domain.maneuverdetection.impl.ManeuverDetectorImpl;
|
||||
import com.sap.sailing.domain.tracking.CompleteManeuverCurve;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public class CompleteManeuverCurveWithEstimationDataRetrievalProcessor extends
|
||||
AbstractRetrievalProcessor<HasRaceOfCompetitorContext, HasCompleteManeuverCurveWithEstimationDataContext> {
|
||||
|
||||
private final ManeuverSettings settings;
|
||||
|
||||
public CompleteManeuverCurveWithEstimationDataRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasCompleteManeuverCurveWithEstimationDataContext, ?>> resultReceivers,
|
||||
ManeuverSettings settings, int retrievalLevel) {
|
||||
super(HasRaceOfCompetitorContext.class, HasCompleteManeuverCurveWithEstimationDataContext.class, executor,
|
||||
resultReceivers, retrievalLevel);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<HasCompleteManeuverCurveWithEstimationDataContext> retrieveData(
|
||||
HasRaceOfCompetitorContext element) {
|
||||
List<HasCompleteManeuverCurveWithEstimationDataContext> result = new ArrayList<>();
|
||||
TrackedRace trackedRace = element.getTrackedRaceContext().getTrackedRace();
|
||||
Competitor competitor = element.getCompetitor();
|
||||
ManeuverDetector maneuverDetector = new ManeuverDetectorImpl(trackedRace, competitor);
|
||||
Iterable<Maneuver> maneuvers = trackedRace.getManeuvers(competitor, false);
|
||||
Iterable<CompleteManeuverCurve> maneuverCurves = maneuverDetector.getCompleteManeuverCurves(maneuvers);
|
||||
Iterable<CompleteManeuverCurveWithEstimationData> maneuversWithEstimationData = maneuverDetector
|
||||
.getCompleteManeuverCurvesWithEstimationData(maneuverCurves);
|
||||
|
||||
CompleteManeuverCurveWithEstimationData previousManeuver = null;
|
||||
CompleteManeuverCurveWithEstimationData currentManeuver = null;
|
||||
for (CompleteManeuverCurveWithEstimationData nextManeuver : maneuversWithEstimationData) {
|
||||
if (currentManeuver != null) {
|
||||
CompleteManeuverCurveWithEstimationDataWithContext maneuverWithContext = new CompleteManeuverCurveWithEstimationDataWithContext(
|
||||
element, currentManeuver, settings, previousManeuver, nextManeuver);
|
||||
if (currentManeuver.getWind() != null
|
||||
&& isManeuverCompliantWithSettings(previousManeuver, maneuverWithContext, nextManeuver)) {
|
||||
result.add(maneuverWithContext);
|
||||
}
|
||||
}
|
||||
previousManeuver = currentManeuver;
|
||||
currentManeuver = nextManeuver;
|
||||
}
|
||||
if (currentManeuver != null) {
|
||||
CompleteManeuverCurveWithEstimationDataWithContext maneuverWithContext = new CompleteManeuverCurveWithEstimationDataWithContext(
|
||||
element, currentManeuver, settings, previousManeuver, null);
|
||||
if (currentManeuver.getWind() != null
|
||||
&& isManeuverCompliantWithSettings(previousManeuver, maneuverWithContext, null)) {
|
||||
result.add(maneuverWithContext);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isManeuverCompliantWithSettings(CompleteManeuverCurveWithEstimationData previousManeuver,
|
||||
CompleteManeuverCurveWithEstimationDataWithContext currentManeuverWithContext,
|
||||
CompleteManeuverCurveWithEstimationData nextManeuver) {
|
||||
boolean mainCurveAnalysis = settings.isMainCurveAnalysis();
|
||||
// Compute only numbers which are really required for filtering
|
||||
Duration maneuverDuration = settings.getMinManeuverDuration() != null
|
||||
|| settings.getMaxManeuverDuration() != null
|
||||
? currentManeuverWithContext.getTimePointBeforeForAnalysis()
|
||||
.until(currentManeuverWithContext.getTimePointAfterForAnalysis())
|
||||
: null;
|
||||
double maneuverEnteringSpeed = settings.getMinManeuverEnteringSpeedInKnots() != null
|
||||
|| settings.getMaxManeuverEnteringSpeedInKnots() != null
|
||||
? currentManeuverWithContext.getManeuverEnteringSpeed() : 0;
|
||||
double maneuverExitingSpeed = settings.getMinManeuverExitingSpeedInKnots() != null
|
||||
|| settings.getMaxManeuverExitingSpeedInKnots() != null
|
||||
? currentManeuverWithContext.getManeuverExitingSpeed() : 0;
|
||||
double maneuverEnteringAbsTWA = settings.getMinManeuverEnteringAbsTWA() != null
|
||||
? currentManeuverWithContext.getEnteringAbsTWA() : 0;
|
||||
double maneuverExitingAbsTWA = settings.getMinManeuverExitingAbsTWA() != null
|
||||
? currentManeuverWithContext.getExitingAbsTWA() : 0;
|
||||
|
||||
Duration durationToPreviousManeuver = previousManeuver != null
|
||||
? getManeuverBoundariesForAnalysis(previousManeuver, mainCurveAnalysis).getTimePointAfter()
|
||||
.until(currentManeuverWithContext.getTimePointBeforeForAnalysis())
|
||||
: null;
|
||||
Duration durationToNextManeuver = nextManeuver != null
|
||||
? currentManeuverWithContext.getTimePointAfterForAnalysis().until(
|
||||
getManeuverBoundariesForAnalysis(nextManeuver, mainCurveAnalysis).getTimePointBefore())
|
||||
: null;
|
||||
if (!(settings.getMinManeuverDuration() != null
|
||||
&& maneuverDuration.compareTo(settings.getMinManeuverDuration()) < 0
|
||||
|| settings.getMaxManeuverDuration() != null
|
||||
&& maneuverDuration.compareTo(settings.getMaxManeuverDuration()) > 0
|
||||
|| settings.getMinManeuverEnteringSpeedInKnots() != null
|
||||
&& maneuverEnteringSpeed < settings.getMinManeuverEnteringSpeedInKnots()
|
||||
|| settings.getMaxManeuverEnteringSpeedInKnots() != null
|
||||
&& maneuverEnteringSpeed > settings.getMaxManeuverEnteringSpeedInKnots()
|
||||
|| settings.getMinManeuverExitingSpeedInKnots() != null
|
||||
&& maneuverExitingSpeed < settings.getMinManeuverExitingSpeedInKnots()
|
||||
|| settings.getMaxManeuverExitingSpeedInKnots() != null
|
||||
&& maneuverExitingSpeed > settings.getMaxManeuverExitingSpeedInKnots()
|
||||
|| settings.getMinManeuverEnteringAbsTWA() != null
|
||||
&& maneuverEnteringAbsTWA < settings.getMinManeuverEnteringAbsTWA()
|
||||
|| settings.getMaxManeuverEnteringAbsTWA() != null
|
||||
&& maneuverEnteringAbsTWA > settings.getMaxManeuverEnteringAbsTWA()
|
||||
|| settings.getMinManeuverExitingAbsTWA() != null
|
||||
&& maneuverExitingAbsTWA < settings.getMinManeuverExitingAbsTWA()
|
||||
|| settings.getMaxManeuverExitingAbsTWA() != null
|
||||
&& maneuverExitingAbsTWA > settings.getMaxManeuverExitingAbsTWA()
|
||||
|| settings.getMinAbsCourseChangeInDegrees() != null && currentManeuverWithContext
|
||||
.getAbsoluteDirectionChangeInDegrees() < settings.getMinAbsCourseChangeInDegrees()
|
||||
|| settings.getMaxAbsCourseChangeInDegrees() != null && currentManeuverWithContext
|
||||
.getAbsoluteDirectionChangeInDegrees() > settings.getMaxAbsCourseChangeInDegrees()
|
||||
|| settings.getMinDurationFromPrecedingManeuver() != null && (previousManeuver == null
|
||||
|| durationToPreviousManeuver.compareTo(settings.getMinDurationFromPrecedingManeuver()) < 0)
|
||||
|| settings.getMaxDurationFromPrecedingManeuver() != null && (previousManeuver == null
|
||||
|| durationToPreviousManeuver.compareTo(settings.getMaxDurationFromPrecedingManeuver()) > 0)
|
||||
|| settings.getMinDurationToFollowingManeuver() != null && (nextManeuver == null
|
||||
|| durationToNextManeuver.compareTo(settings.getMinDurationToFollowingManeuver()) < 0)
|
||||
|| settings.getMaxDurationToFollowingManeuver() != null && (nextManeuver == null
|
||||
|| durationToNextManeuver.compareTo(settings.getMaxDurationToFollowingManeuver()) > 0))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private ManeuverCurveBoundaries getManeuverBoundariesForAnalysis(CompleteManeuverCurveWithEstimationData maneuver,
|
||||
boolean mainCurveAnalysis) {
|
||||
return mainCurveAnalysis ? maneuver.getMainCurve() : maneuver.getCurveWithUnstableCourseAndSpeed();
|
||||
}
|
||||
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasManeuverBoundariesContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.data.ManeuverBoundariesWithContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.maneuverdetection.ManeuverWithEstimationData;
|
||||
import com.sap.sailing.domain.maneuverdetection.ManeuverWithEstimationDataCalculator;
|
||||
import com.sap.sailing.domain.maneuverdetection.impl.ManeuverWithEstimationDataCalculatorImpl;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public class ManeuverBoundariesRetrievalProcessor
|
||||
extends AbstractRetrievalProcessor<HasRaceOfCompetitorContext, HasManeuverBoundariesContext> {
|
||||
|
||||
public ManeuverBoundariesRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasManeuverBoundariesContext, ?>> resultReceivers, int retrievalLevel) {
|
||||
super(HasRaceOfCompetitorContext.class, HasManeuverBoundariesContext.class, executor, resultReceivers,
|
||||
retrievalLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<HasManeuverBoundariesContext> retrieveData(HasRaceOfCompetitorContext element) {
|
||||
List<HasManeuverBoundariesContext> result = new ArrayList<>();
|
||||
TrackedRace trackedRace = element.getTrackedRaceContext().getTrackedRace();
|
||||
Competitor competitor = element.getCompetitor();
|
||||
ManeuverWithEstimationDataCalculator calculator = new ManeuverWithEstimationDataCalculatorImpl();
|
||||
Iterable<Maneuver> maneuvers = trackedRace.getManeuvers(competitor, false);
|
||||
Iterable<ManeuverWithEstimationData> maneuversWithEstimationData = calculator
|
||||
.computeEstimationDataForManeuvers(trackedRace, competitor, maneuvers, true);
|
||||
for (ManeuverWithEstimationData maneuverWithEstimationData : maneuversWithEstimationData) {
|
||||
result.add(new ManeuverBoundariesWithContext(element, maneuverWithEstimationData));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+94
-39
@@ -11,6 +11,8 @@ import com.sap.sailing.datamining.impl.data.TrackedLegOfCompetitorWithSpecificTi
|
||||
import com.sap.sailing.datamining.shared.ManeuverSettings;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
@@ -33,53 +35,106 @@ public class ManeuverRetrievalProcessor
|
||||
Collection<HasManeuverContext> maneuversWithContext = new ArrayList<>();
|
||||
TimePoint finishTime = element.getTrackedLegOfCompetitor().getFinishTime();
|
||||
if (finishTime != null) {
|
||||
Iterable<Maneuver> maneuvers = null;
|
||||
try {
|
||||
Iterable<Maneuver> maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false);
|
||||
for (Maneuver maneuver : maneuvers) {
|
||||
maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false);
|
||||
} catch (NoWindException e) {
|
||||
throw new IllegalStateException("No wind retrieving the maneuvers", e);
|
||||
}
|
||||
Maneuver previousManeuver = null;
|
||||
Maneuver currentManeuver = null;
|
||||
for (Maneuver nextManeuver : maneuvers) {
|
||||
if (currentManeuver != null) {
|
||||
ManeuverWithContext maneuverWithContext = new ManeuverWithContext(new TrackedLegOfCompetitorWithSpecificTimePointWithContext(
|
||||
element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), maneuver.getTimePoint()), maneuver, settings.isMainCurveAnalysis());
|
||||
// Compute only numbers which are really required for filtering
|
||||
double maneuverDuration = settings.getMinManeuverDuration() != null
|
||||
|| settings.getMaxManeuverDuration() != null ? maneuverWithContext.getManeuverDurationInSeconds()
|
||||
: 0;
|
||||
double maneuverEnteringSpeed = settings.getMinManeuverEnteringSpeedInKnots() != null
|
||||
|| settings.getMaxManeuverEnteringSpeedInKnots() != null
|
||||
? maneuverWithContext.getManeuverEnteringSpeed() : 0;
|
||||
double maneuverExitingSpeed = settings.getMinManeuverExitingSpeedInKnots() != null
|
||||
|| settings.getMaxManeuverExitingSpeedInKnots() != null
|
||||
? maneuverWithContext.getManeuverExitingSpeed() : 0;
|
||||
double maneuverEnteringAbsTWA = settings.getMinManeuverEnteringAbsTWA() != null
|
||||
? maneuverWithContext.getEnteringAbsTWA() : 0;
|
||||
double maneuverExitingAbsTWA = settings.getMinManeuverExitingAbsTWA() != null
|
||||
? maneuverWithContext.getExitingAbsTWA() : 0;
|
||||
if (!(settings.getMinManeuverDuration() != null
|
||||
&& maneuverDuration < settings.getMinManeuverDuration()
|
||||
|| settings.getMaxManeuverDuration() != null
|
||||
&& maneuverDuration > settings.getMaxManeuverDuration()
|
||||
|| settings.getMinManeuverEnteringSpeedInKnots() != null
|
||||
&& maneuverEnteringSpeed < settings.getMinManeuverEnteringSpeedInKnots()
|
||||
|| settings.getMaxManeuverEnteringSpeedInKnots() != null
|
||||
&& maneuverEnteringSpeed > settings.getMaxManeuverEnteringSpeedInKnots()
|
||||
|| settings.getMinManeuverExitingSpeedInKnots() != null
|
||||
&& maneuverExitingSpeed < settings.getMinManeuverExitingSpeedInKnots()
|
||||
|| settings.getMaxManeuverExitingSpeedInKnots() != null
|
||||
&& maneuverExitingSpeed > settings.getMaxManeuverExitingSpeedInKnots()
|
||||
|| settings.getMinManeuverEnteringAbsTWA() != null
|
||||
&& maneuverEnteringAbsTWA < settings.getMinManeuverEnteringAbsTWA()
|
||||
|| settings.getMaxManeuverEnteringAbsTWA() != null
|
||||
&& maneuverEnteringAbsTWA > settings.getMaxManeuverEnteringAbsTWA()
|
||||
|| settings.getMinManeuverExitingAbsTWA() != null
|
||||
&& maneuverExitingAbsTWA < settings.getMinManeuverExitingAbsTWA()
|
||||
|| settings.getMaxManeuverExitingAbsTWA() != null
|
||||
&& maneuverExitingAbsTWA > settings.getMaxManeuverExitingAbsTWA())) {
|
||||
element.getTrackedLegContext(), element.getTrackedLegOfCompetitor(), currentManeuver.getTimePoint()), currentManeuver,
|
||||
settings.isMainCurveAnalysis(), previousManeuver, nextManeuver);
|
||||
if (isManeuverCompliantWithSettings(previousManeuver, maneuverWithContext, nextManeuver)) {
|
||||
maneuversWithContext.add(maneuverWithContext);
|
||||
}
|
||||
}
|
||||
} catch (NoWindException e) {
|
||||
throw new IllegalStateException("No wind retrieving the maneuvers", e);
|
||||
previousManeuver = currentManeuver;
|
||||
currentManeuver = nextManeuver;
|
||||
}
|
||||
if (currentManeuver != null) {
|
||||
ManeuverWithContext maneuverWithContext = new ManeuverWithContext(element, currentManeuver,
|
||||
settings.isMainCurveAnalysis(), previousManeuver, null);
|
||||
if (isManeuverCompliantWithSettings(previousManeuver, maneuverWithContext, null)) {
|
||||
maneuversWithContext.add(maneuverWithContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
return maneuversWithContext;
|
||||
}
|
||||
|
||||
private boolean isManeuverCompliantWithSettings(Maneuver previousManeuver,
|
||||
ManeuverWithContext currentManeuverWithContext, Maneuver nextManeuver) {
|
||||
boolean mainCurveAnalysis = settings.isMainCurveAnalysis();
|
||||
// Compute only numbers which are really required for filtering
|
||||
Duration maneuverDuration = settings.getMinManeuverDuration() != null
|
||||
|| settings.getMaxManeuverDuration() != null
|
||||
? currentManeuverWithContext.getTimePointBeforeForAnalysis()
|
||||
.until(currentManeuverWithContext.getTimePointAfterForAnalysis())
|
||||
: null;
|
||||
double maneuverEnteringSpeed = settings.getMinManeuverEnteringSpeedInKnots() != null
|
||||
|| settings.getMaxManeuverEnteringSpeedInKnots() != null
|
||||
? currentManeuverWithContext.getManeuverEnteringSpeed() : 0;
|
||||
double maneuverExitingSpeed = settings.getMinManeuverExitingSpeedInKnots() != null
|
||||
|| settings.getMaxManeuverExitingSpeedInKnots() != null
|
||||
? currentManeuverWithContext.getManeuverExitingSpeed() : 0;
|
||||
double maneuverEnteringAbsTWA = settings.getMinManeuverEnteringAbsTWA() != null
|
||||
? currentManeuverWithContext.getEnteringAbsTWA() : 0;
|
||||
double maneuverExitingAbsTWA = settings.getMinManeuverExitingAbsTWA() != null
|
||||
? currentManeuverWithContext.getExitingAbsTWA() : 0;
|
||||
|
||||
Duration durationToPreviousManeuver = previousManeuver != null
|
||||
? getManeuverBoundariesForAnalysis(previousManeuver, mainCurveAnalysis).getTimePointAfter()
|
||||
.until(currentManeuverWithContext.getTimePointBeforeForAnalysis())
|
||||
: null;
|
||||
Duration durationToNextManeuver = nextManeuver != null
|
||||
? currentManeuverWithContext.getTimePointAfterForAnalysis().until(
|
||||
getManeuverBoundariesForAnalysis(nextManeuver, mainCurveAnalysis).getTimePointBefore())
|
||||
: null;
|
||||
if (!(settings.getMinManeuverDuration() != null
|
||||
&& maneuverDuration.compareTo(settings.getMinManeuverDuration()) < 0
|
||||
|| settings.getMaxManeuverDuration() != null
|
||||
&& maneuverDuration.compareTo(settings.getMaxManeuverDuration()) > 0
|
||||
|| settings.getMinManeuverEnteringSpeedInKnots() != null
|
||||
&& maneuverEnteringSpeed < settings.getMinManeuverEnteringSpeedInKnots()
|
||||
|| settings.getMaxManeuverEnteringSpeedInKnots() != null
|
||||
&& maneuverEnteringSpeed > settings.getMaxManeuverEnteringSpeedInKnots()
|
||||
|| settings.getMinManeuverExitingSpeedInKnots() != null
|
||||
&& maneuverExitingSpeed < settings.getMinManeuverExitingSpeedInKnots()
|
||||
|| settings.getMaxManeuverExitingSpeedInKnots() != null
|
||||
&& maneuverExitingSpeed > settings.getMaxManeuverExitingSpeedInKnots()
|
||||
|| settings.getMinManeuverEnteringAbsTWA() != null
|
||||
&& maneuverEnteringAbsTWA < settings.getMinManeuverEnteringAbsTWA()
|
||||
|| settings.getMaxManeuverEnteringAbsTWA() != null
|
||||
&& maneuverEnteringAbsTWA > settings.getMaxManeuverEnteringAbsTWA()
|
||||
|| settings.getMinManeuverExitingAbsTWA() != null
|
||||
&& maneuverExitingAbsTWA < settings.getMinManeuverExitingAbsTWA()
|
||||
|| settings.getMaxManeuverExitingAbsTWA() != null
|
||||
&& maneuverExitingAbsTWA > settings.getMaxManeuverExitingAbsTWA()
|
||||
|| settings.getMinAbsCourseChangeInDegrees() != null && currentManeuverWithContext
|
||||
.getAbsoluteDirectionChangeInDegrees() < settings.getMinAbsCourseChangeInDegrees()
|
||||
|| settings.getMaxAbsCourseChangeInDegrees() != null && currentManeuverWithContext
|
||||
.getAbsoluteDirectionChangeInDegrees() > settings.getMaxAbsCourseChangeInDegrees()
|
||||
|| settings.getMinDurationFromPrecedingManeuver() != null && (previousManeuver == null
|
||||
|| durationToPreviousManeuver.compareTo(settings.getMinDurationFromPrecedingManeuver()) < 0)
|
||||
|| settings.getMaxDurationFromPrecedingManeuver() != null && (previousManeuver == null
|
||||
|| durationToPreviousManeuver.compareTo(settings.getMaxDurationFromPrecedingManeuver()) > 0)
|
||||
|| settings.getMinDurationToFollowingManeuver() != null && (nextManeuver == null
|
||||
|| durationToNextManeuver.compareTo(settings.getMinDurationToFollowingManeuver()) < 0)
|
||||
|| settings.getMaxDurationToFollowingManeuver() != null && (nextManeuver == null
|
||||
|| durationToNextManeuver.compareTo(settings.getMaxDurationToFollowingManeuver()) > 0))) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private ManeuverCurveBoundaries getManeuverBoundariesForAnalysis(Maneuver maneuver, boolean mainCurveAnalysis) {
|
||||
return mainCurveAnalysis ? maneuver.getMainCurveBoundaries()
|
||||
: maneuver.getManeuverCurveWithStableSpeedAndCourseBoundaries();
|
||||
}
|
||||
|
||||
}
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasCompleteManeuverCurveWithEstimationDataContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.shared.ManeuverSettings;
|
||||
import com.sap.sailing.domain.common.Bearing;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData;
|
||||
import com.sap.sailing.domain.maneuverdetection.HasDetailedManeuverLoss;
|
||||
import com.sap.sailing.domain.tracking.ManeuverCurveBoundaries;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public class CompleteManeuverCurveWithEstimationDataWithContext
|
||||
implements HasCompleteManeuverCurveWithEstimationDataContext {
|
||||
|
||||
private final CompleteManeuverCurveWithEstimationData maneuverWithEstimationData;
|
||||
private final HasRaceOfCompetitorContext raceOfCompetitorContext;
|
||||
private final ManeuverSettings maneuverSettings;
|
||||
private final CompleteManeuverCurveWithEstimationData previousManeuverCurve;
|
||||
private final CompleteManeuverCurveWithEstimationData nextManeuverCurve;
|
||||
|
||||
public CompleteManeuverCurveWithEstimationDataWithContext(HasRaceOfCompetitorContext raceOfCompetitorContext,
|
||||
CompleteManeuverCurveWithEstimationData maneuverWithEstimationData, ManeuverSettings maneuverSettings,
|
||||
CompleteManeuverCurveWithEstimationData previousManeuverCurve,
|
||||
CompleteManeuverCurveWithEstimationData nextManeuverCurve) {
|
||||
this.raceOfCompetitorContext = raceOfCompetitorContext;
|
||||
this.maneuverWithEstimationData = maneuverWithEstimationData;
|
||||
this.maneuverSettings = maneuverSettings;
|
||||
this.previousManeuverCurve = previousManeuverCurve;
|
||||
this.nextManeuverCurve = nextManeuverCurve;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasRaceOfCompetitorContext getRaceOfCompetitorContext() {
|
||||
return raceOfCompetitorContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverStartSpeedDeviationRatioFromAvgStatistic() {
|
||||
SpeedWithBearing speedWithBearingBeforeManeuver = getManeuverCurveBoundariesForAnalysis()
|
||||
.getSpeedWithBearingBefore();
|
||||
SpeedWithBearing averageSpeedWithBearingBeforeManeuver = maneuverWithEstimationData
|
||||
.getCurveWithUnstableCourseAndSpeed().getAverageSpeedWithBearingBefore();
|
||||
if (speedWithBearingBeforeManeuver != null && averageSpeedWithBearingBeforeManeuver != null) {
|
||||
if (speedWithBearingBeforeManeuver.getKnots() < averageSpeedWithBearingBeforeManeuver.getKnots()) {
|
||||
return averageSpeedWithBearingBeforeManeuver.getKnots() / speedWithBearingBeforeManeuver.getKnots();
|
||||
} else {
|
||||
return speedWithBearingBeforeManeuver.getKnots() / averageSpeedWithBearingBeforeManeuver.getKnots();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverStartCogDeviationFromAvgInDegreesStatistic() {
|
||||
SpeedWithBearing speedWithBearingBeforeManeuver = getManeuverCurveBoundariesForAnalysis()
|
||||
.getSpeedWithBearingBefore();
|
||||
SpeedWithBearing averageSpeedWithBearingBeforeManeuver = maneuverWithEstimationData
|
||||
.getCurveWithUnstableCourseAndSpeed().getAverageSpeedWithBearingBefore();
|
||||
if (speedWithBearingBeforeManeuver != null && averageSpeedWithBearingBeforeManeuver != null) {
|
||||
return Math.abs(averageSpeedWithBearingBeforeManeuver.getBearing()
|
||||
.getDifferenceTo(speedWithBearingBeforeManeuver.getBearing()).getDegrees());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverEndSpeedDeviationRatioFromAvgStatistic() {
|
||||
SpeedWithBearing speedWithBearingAfterManeuver = getManeuverCurveBoundariesForAnalysis()
|
||||
.getSpeedWithBearingAfter();
|
||||
SpeedWithBearing averageSpeedWithBearingAfterManeuver = maneuverWithEstimationData
|
||||
.getCurveWithUnstableCourseAndSpeed().getAverageSpeedWithBearingAfter();
|
||||
if (speedWithBearingAfterManeuver != null && averageSpeedWithBearingAfterManeuver != null) {
|
||||
if (speedWithBearingAfterManeuver.getKnots() < averageSpeedWithBearingAfterManeuver.getKnots()) {
|
||||
return averageSpeedWithBearingAfterManeuver.getKnots() / speedWithBearingAfterManeuver.getKnots();
|
||||
} else {
|
||||
return speedWithBearingAfterManeuver.getKnots() / averageSpeedWithBearingAfterManeuver.getKnots();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverEndCogDeviationFromAvgInDegreesStatistic() {
|
||||
SpeedWithBearing speedWithBearingAfterManeuver = maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getSpeedWithBearingAfter();
|
||||
SpeedWithBearing averageSpeedWithBearingAfterManeuver = maneuverWithEstimationData
|
||||
.getCurveWithUnstableCourseAndSpeed().getAverageSpeedWithBearingAfter();
|
||||
if (speedWithBearingAfterManeuver != null && averageSpeedWithBearingAfterManeuver != null) {
|
||||
return Math.abs(averageSpeedWithBearingAfterManeuver.getBearing()
|
||||
.getDifferenceTo(speedWithBearingAfterManeuver.getBearing()).getDegrees());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDurationToNextManeuverInSecondsStatistic() {
|
||||
Duration duration = maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getDurationFromManeuverEndToNextManeuverStart();
|
||||
if (duration != null) {
|
||||
return duration.asSeconds();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDurationFromPreviousManeuverInSecondsStatistic() {
|
||||
Duration duration = maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getDurationFromPreviousManeuverEndToManeuverStart();
|
||||
if (duration != null) {
|
||||
return duration.asSeconds();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isNextManeuverAtLeastOneSecondInFront() {
|
||||
return maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getDurationFromManeuverEndToNextManeuverStart() != null
|
||||
&& maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getDurationFromManeuverEndToNextManeuverStart().asSeconds() >= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreviousManeuverAtLeastOneSecondBehind() {
|
||||
return maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getDurationFromPreviousManeuverEndToManeuverStart() != null
|
||||
&& maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed()
|
||||
.getDurationFromPreviousManeuverEndToManeuverStart().asSeconds() >= 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompleteManeuverCurveWithEstimationData getCompleteManeuverCurveWithEstimationData() {
|
||||
return maneuverWithEstimationData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterDTO getJibingCount() {
|
||||
return new ClusterDTO(maneuverWithEstimationData.getJibingCount() + "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterDTO getTackingCount() {
|
||||
return new ClusterDTO(maneuverWithEstimationData.getTackingCount() + "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAbsTwaAtMaxTurningRate() {
|
||||
return getAbsTwaFromCourse(maneuverWithEstimationData.getMainCurve().getCourseAtMaxTurningRate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAbsTwaAtLowestSpeed() {
|
||||
return getAbsTwaFromCourse(maneuverWithEstimationData.getMainCurve().getLowestSpeed().getBearing());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAbsTwaAtHighestSpeed() {
|
||||
return getAbsTwaFromCourse(maneuverWithEstimationData.getMainCurve().getHighestSpeed().getBearing());
|
||||
}
|
||||
|
||||
private double getAbsTwaFromCourse(Bearing course) {
|
||||
double twa = maneuverWithEstimationData.getWind().getFrom().getDifferenceTo(course).getDegrees();
|
||||
return Math.abs(twa);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NauticalSide getToSide() {
|
||||
return maneuverWithEstimationData.getMainCurve().getDirectionChangeInDegrees() < 0 ? NauticalSide.PORT
|
||||
: NauticalSide.STARBOARD;
|
||||
}
|
||||
|
||||
private ManeuverCurveBoundaries getManeuverCurveBoundariesForAnalysis() {
|
||||
return maneuverSettings.isMainCurveAnalysis() ? maneuverWithEstimationData.getMainCurve()
|
||||
: maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getEnteringAbsTWA() {
|
||||
return getAbsTwaFromCourse(getManeuverCurveBoundariesForAnalysis().getSpeedWithBearingBefore().getBearing());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getExitingAbsTWA() {
|
||||
return getAbsTwaFromCourse(getManeuverCurveBoundariesForAnalysis().getSpeedWithBearingAfter().getBearing());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManeuverType getTypeOfPreviousManeuver() {
|
||||
return previousManeuverCurve == null ? ManeuverType.UNKNOWN
|
||||
: previousManeuverCurve.getManeuverTypeForCompleteManeuverCurve();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManeuverType getTypeOfNextManeuver() {
|
||||
return nextManeuverCurve == null ? ManeuverType.UNKNOWN
|
||||
: nextManeuverCurve.getManeuverTypeForCompleteManeuverCurve();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAbsoluteDirectionChangeInDegrees() {
|
||||
return Math.abs(getManeuverCurveBoundariesForAnalysis().getDirectionChangeInDegrees());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRatioBetweenDistanceSailedWithAndWithoutManeuver() {
|
||||
return ((HasDetailedManeuverLoss) getManeuverCurveBoundariesForAnalysis())
|
||||
.getRatioBetweenDistanceSailedWithAndWithoutManeuver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDurationLostByManeuver() {
|
||||
return ((HasDetailedManeuverLoss) getManeuverCurveBoundariesForAnalysis()).getDurationLostByManeuver()
|
||||
.asSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDurationLostByManeuverTowardMiddleAngleProjection() {
|
||||
return ((HasDetailedManeuverLoss) getManeuverCurveBoundariesForAnalysis())
|
||||
.getDurationLostByManeuverTowardMiddleAngleProjection().asSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver() {
|
||||
return ((HasDetailedManeuverLoss) getManeuverCurveBoundariesForAnalysis())
|
||||
.getRatioBetweenDistanceSailedTowardMiddleAngleProjectionWithAndWithoutManeuver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRelativeBearingToNextMarkBeforeManeuver() {
|
||||
return maneuverWithEstimationData.getRelativeBearingToNextMarkBeforeManeuver() == null ? null
|
||||
: maneuverWithEstimationData.getRelativeBearingToNextMarkBeforeManeuver().getDegrees();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRelativeBearingToNextMarkAfterManeuver() {
|
||||
return maneuverWithEstimationData.getRelativeBearingToNextMarkAfterManeuver() == null ? null
|
||||
: maneuverWithEstimationData.getRelativeBearingToNextMarkAfterManeuver().getDegrees();
|
||||
}
|
||||
|
||||
public TimePoint getTimePointBeforeForAnalysis() {
|
||||
return getManeuverCurveBoundariesForAnalysis().getTimePointBefore();
|
||||
}
|
||||
|
||||
public TimePoint getTimePointAfterForAnalysis() {
|
||||
return getManeuverCurveBoundariesForAnalysis().getTimePointAfter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverEnteringSpeed() {
|
||||
return getManeuverCurveBoundariesForAnalysis().getSpeedWithBearingBefore().getKnots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverExitingSpeed() {
|
||||
return getManeuverCurveBoundariesForAnalysis().getSpeedWithBearingAfter().getKnots();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getAbsTwaAtManeuverMiddle() {
|
||||
ManeuverCurveBoundaries boundariesForAnalysis = getManeuverCurveBoundariesForAnalysis();
|
||||
Bearing middleCourse = boundariesForAnalysis.getSpeedWithBearingBefore().getBearing()
|
||||
.add(new DegreeBearingImpl(boundariesForAnalysis.getDirectionChangeInDegrees() / 2));
|
||||
return getAbsTwaFromCourse(middleCourse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getGpsSamplingRate() {
|
||||
return maneuverSettings.isMainCurveAnalysis()
|
||||
? maneuverWithEstimationData.getMainCurve().getGpsFixesCount()
|
||||
/ maneuverWithEstimationData.getMainCurve().getDuration().asSeconds()
|
||||
: maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed().getGpsFixesCount()
|
||||
/ maneuverWithEstimationData.getCurveWithUnstableCourseAndSpeed().getDuration().asSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAbsRelativeBearingToNextMarkBeforeManeuver() {
|
||||
Double bearing = getRelativeBearingToNextMarkBeforeManeuver();
|
||||
return bearing == null ? null : Math.abs(bearing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAbsRelativeBearingToNextMarkAfterManeuver() {
|
||||
Double bearing = getRelativeBearingToNextMarkAfterManeuver();
|
||||
return bearing == null ? null : Math.abs(bearing);
|
||||
}
|
||||
|
||||
}
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasManeuverBoundariesContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.maneuverdetection.ManeuverWithEstimationData;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public class ManeuverBoundariesWithContext implements HasManeuverBoundariesContext {
|
||||
|
||||
private final ManeuverWithEstimationData maneuverWithEstimationData;
|
||||
private HasRaceOfCompetitorContext raceOfCompetitorContext;
|
||||
|
||||
public ManeuverBoundariesWithContext(HasRaceOfCompetitorContext raceOfCompetitorContext, ManeuverWithEstimationData maneuverWithEstimationData) {
|
||||
this.raceOfCompetitorContext = raceOfCompetitorContext;
|
||||
this.maneuverWithEstimationData = maneuverWithEstimationData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasRaceOfCompetitorContext getRaceOfCompetitorContext() {
|
||||
return raceOfCompetitorContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NauticalSide getToSide() {
|
||||
return maneuverWithEstimationData.getManeuver().getDirectionChangeInDegrees() >= 0 ? NauticalSide.STARBOARD
|
||||
: NauticalSide.PORT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManeuverType getManeuverType() {
|
||||
return maneuverWithEstimationData.getManeuver().getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverStartSpeedDeviationRatioFromAvgStatistic() {
|
||||
SpeedWithBearing speedWithBearingBeforeManeuver = maneuverWithEstimationData.getManeuver()
|
||||
.getManeuverCurveWithStableSpeedAndCourseBoundaries().getSpeedWithBearingBefore();
|
||||
SpeedWithBearing averageSpeedWithBearingBeforeManeuver = maneuverWithEstimationData
|
||||
.getAverageSpeedWithBearingBefore();
|
||||
if (speedWithBearingBeforeManeuver != null && averageSpeedWithBearingBeforeManeuver != null) {
|
||||
if(speedWithBearingBeforeManeuver.getKnots() < averageSpeedWithBearingBeforeManeuver.getKnots()) {
|
||||
return averageSpeedWithBearingBeforeManeuver.getKnots() / speedWithBearingBeforeManeuver.getKnots();
|
||||
} else {
|
||||
return speedWithBearingBeforeManeuver.getKnots() / averageSpeedWithBearingBeforeManeuver.getKnots();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverStartCogDeviationFromAvgInDegreesStatistic() {
|
||||
SpeedWithBearing speedWithBearingBeforeManeuver = maneuverWithEstimationData.getManeuver()
|
||||
.getManeuverCurveWithStableSpeedAndCourseBoundaries().getSpeedWithBearingBefore();
|
||||
SpeedWithBearing averageSpeedWithBearingBeforeManeuver = maneuverWithEstimationData
|
||||
.getAverageSpeedWithBearingBefore();
|
||||
if (speedWithBearingBeforeManeuver != null && averageSpeedWithBearingBeforeManeuver != null) {
|
||||
return Math.abs(averageSpeedWithBearingBeforeManeuver.getBearing().getDifferenceTo(speedWithBearingBeforeManeuver.getBearing()).getDegrees());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverEndSpeedDeviationRatioFromAvgStatistic() {
|
||||
SpeedWithBearing speedWithBearingAfterManeuver = maneuverWithEstimationData.getManeuver()
|
||||
.getManeuverCurveWithStableSpeedAndCourseBoundaries().getSpeedWithBearingAfter();
|
||||
SpeedWithBearing averageSpeedWithBearingAfterManeuver = maneuverWithEstimationData
|
||||
.getAverageSpeedWithBearingAfter();
|
||||
if (speedWithBearingAfterManeuver != null && averageSpeedWithBearingAfterManeuver != null) {
|
||||
if(speedWithBearingAfterManeuver.getKnots() < averageSpeedWithBearingAfterManeuver.getKnots()) {
|
||||
return averageSpeedWithBearingAfterManeuver.getKnots() / speedWithBearingAfterManeuver.getKnots();
|
||||
} else {
|
||||
return speedWithBearingAfterManeuver.getKnots() / averageSpeedWithBearingAfterManeuver.getKnots();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverEndCogDeviationFromAvgInDegreesStatistic() {
|
||||
SpeedWithBearing speedWithBearingAfterManeuver = maneuverWithEstimationData.getManeuver()
|
||||
.getManeuverCurveWithStableSpeedAndCourseBoundaries().getSpeedWithBearingAfter();
|
||||
SpeedWithBearing averageSpeedWithBearingAfterManeuver = maneuverWithEstimationData
|
||||
.getAverageSpeedWithBearingAfter();
|
||||
if (speedWithBearingAfterManeuver != null && averageSpeedWithBearingAfterManeuver != null) {
|
||||
return Math.abs(averageSpeedWithBearingAfterManeuver.getBearing().getDifferenceTo(speedWithBearingAfterManeuver.getBearing()).getDegrees());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDurationToNextManeuverInSecondsStatistic() {
|
||||
Duration duration = maneuverWithEstimationData.getDurationFromManeuverEndToNextManeuverStart();
|
||||
if (duration != null) {
|
||||
return duration.asSeconds();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDurationFromPreviousManeuverInSecondsStatistic() {
|
||||
Duration duration = maneuverWithEstimationData.getDurationFromPreviousManeuverEndToManeuverStart();
|
||||
if (duration != null) {
|
||||
return duration.asSeconds();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isNextManeuverAtLeastOneSecondInFront() {
|
||||
return maneuverWithEstimationData.getDurationFromManeuverEndToNextManeuverStart() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreviousManeuverAtLeastOneSecondBehind() {
|
||||
return maneuverWithEstimationData.getDurationFromPreviousManeuverEndToManeuverStart() != null;
|
||||
}
|
||||
|
||||
}
|
||||
+19
-4
@@ -4,6 +4,7 @@ import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.Wind;
|
||||
@@ -23,14 +24,18 @@ public class ManeuverWithContext implements HasManeuverContext {
|
||||
private static final long serialVersionUID = 7717196485074392156L;
|
||||
private final HasTrackedLegOfCompetitorContext trackedLegOfCompetitor;
|
||||
private final Maneuver maneuver;
|
||||
private TimePoint timePointBeforeForAnalysis;
|
||||
private TimePoint timePointAfterForAnalysis;
|
||||
private double directionChangeInDegreesForAnalysis;
|
||||
private final TimePoint timePointBeforeForAnalysis;
|
||||
private final TimePoint timePointAfterForAnalysis;
|
||||
private final double directionChangeInDegreesForAnalysis;
|
||||
private final Maneuver previousManeuver;
|
||||
private final Maneuver nextManeuver;
|
||||
|
||||
public ManeuverWithContext(HasTrackedLegOfCompetitorContext trackedLegOfCompetitor, Maneuver maneuver,
|
||||
boolean mainCurveAnalysis) {
|
||||
boolean mainCurveAnalysis, Maneuver previousManeuver, Maneuver nextManeuver) {
|
||||
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
|
||||
this.maneuver = maneuver;
|
||||
this.previousManeuver = previousManeuver;
|
||||
this.nextManeuver = nextManeuver;
|
||||
ManeuverCurveBoundaries enteringAndExistingDetails = mainCurveAnalysis ? maneuver.getMainCurveBoundaries()
|
||||
: maneuver.getManeuverCurveWithStableSpeedAndCourseBoundaries();
|
||||
this.timePointBeforeForAnalysis = enteringAndExistingDetails.getTimePointBefore();
|
||||
@@ -50,6 +55,16 @@ public class ManeuverWithContext implements HasManeuverContext {
|
||||
return directionChangeInDegreesForAnalysis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManeuverType getTypeOfPreviousManeuver() {
|
||||
return previousManeuver != null ? previousManeuver.getType() : ManeuverType.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManeuverType getTypeOfNextManeuver() {
|
||||
return nextManeuver != null ? nextManeuver.getType() : ManeuverType.UNKNOWN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getManeuverEnteringSpeed() {
|
||||
return getSpeedInKnotsAtTimePoint(getTimePointBeforeForAnalysis());
|
||||
|
||||
+27
-7
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.common.dto.PersonDTO;
|
||||
import com.sap.sse.common.CountryCode;
|
||||
@@ -14,6 +15,9 @@ import com.sap.sse.common.impl.NamedImpl;
|
||||
public class CompetitorDescriptor extends NamedImpl implements Named {
|
||||
private static final long serialVersionUID = -6645726854552711646L;
|
||||
|
||||
private final UUID competitorUUID;
|
||||
private final UUID boatUUID;
|
||||
private final String shortName;
|
||||
private final String eventName;
|
||||
private final String regattaName;
|
||||
private final String boatClassName;
|
||||
@@ -27,23 +31,27 @@ public class CompetitorDescriptor extends NamedImpl implements Named {
|
||||
private final Double timeOnTimeFactor;
|
||||
private final Duration timeOnDistanceAllowancePerNauticalMile;
|
||||
|
||||
public CompetitorDescriptor(String eventName, String regattaName, String boatClassName, String raceName,
|
||||
String fleetName, String sailNumber, String name, String teamName, String boatName, CountryCode countryCode,
|
||||
Iterable<PersonDTO> persons, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile) {
|
||||
super(name);
|
||||
public CompetitorDescriptor(String eventName, String regattaName, String raceName, String fleetName,
|
||||
UUID competitorUUID, String fullName, String shortName, String teamName, Iterable<PersonDTO> persons,
|
||||
CountryCode countryCode, Double timeOnTimeFactor,
|
||||
Duration timeOnDistanceAllowancePerNauticalMile, UUID boatUUID, String boatName, String boatClassName, String sailNumber) {
|
||||
super(fullName);
|
||||
this.shortName = shortName;
|
||||
this.eventName = eventName;
|
||||
this.regattaName = regattaName;
|
||||
this.boatClassName = boatClassName;
|
||||
this.boatName = boatName;
|
||||
this.raceName = raceName;
|
||||
this.fleetName = fleetName;
|
||||
this.sailNumber = sailNumber;
|
||||
this.competitorUUID = competitorUUID;
|
||||
this.teamName = teamName;
|
||||
this.countryCode = countryCode;
|
||||
this.persons = new ArrayList<>();
|
||||
Util.addAll(persons, this.persons);
|
||||
this.timeOnTimeFactor = timeOnTimeFactor;
|
||||
this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile;
|
||||
this.boatUUID = boatUUID;
|
||||
this.boatName = boatName;
|
||||
this.boatClassName = boatClassName;
|
||||
this.sailNumber = sailNumber;
|
||||
}
|
||||
|
||||
public String getEventName() {
|
||||
@@ -90,10 +98,22 @@ public class CompetitorDescriptor extends NamedImpl implements Named {
|
||||
return teamName;
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public Duration getTimeOnDistanceAllowancePerNauticalMile() {
|
||||
return timeOnDistanceAllowancePerNauticalMile;
|
||||
}
|
||||
|
||||
public UUID getCompetitorUUID() {
|
||||
return competitorUUID;
|
||||
}
|
||||
|
||||
public UUID getBoatUUID() {
|
||||
return boatUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CompetitorDescriptor [eventName=" + eventName + ", regattaName=" + regattaName + ", boatClassName="
|
||||
|
||||
+1
@@ -37,6 +37,7 @@ public abstract class AbstractLeaderboardDTO implements Serializable {
|
||||
public String defaultCourseAreaName;
|
||||
public ScoringSchemeType scoringScheme;
|
||||
public LeaderboardType type;
|
||||
public boolean canBoatsOfCompetitorsChangePerRace;
|
||||
|
||||
private Long delayToLiveInMillisForLatestRace;
|
||||
|
||||
|
||||
Regular → Executable
+52
-5
@@ -2,23 +2,28 @@ package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.MappableToDevice;
|
||||
import com.sap.sse.common.Color;
|
||||
|
||||
public class BoatDTO extends NamedDTO implements Serializable {
|
||||
public class BoatDTO extends NamedDTO implements Serializable, MappableToDevice {
|
||||
private static final long serialVersionUID = -4076992788294272162L;
|
||||
|
||||
private String idAsString;
|
||||
private BoatClassDTO boatClass;
|
||||
private String sailId;
|
||||
private Color color;
|
||||
|
||||
// for GWT
|
||||
BoatDTO() {}
|
||||
public BoatDTO() {}
|
||||
|
||||
public BoatDTO(String name, String sailId) {
|
||||
this(name, sailId, null);
|
||||
public BoatDTO(String idAsString, String name, BoatClassDTO boatClass, String sailId) {
|
||||
this(idAsString, name, boatClass, sailId, null);
|
||||
}
|
||||
|
||||
public BoatDTO(String name, String sailId, Color color) {
|
||||
public BoatDTO(String idAsString, String name, BoatClassDTO boatClass, String sailId, Color color) {
|
||||
super(name);
|
||||
this.idAsString = idAsString;
|
||||
this.boatClass = boatClass;
|
||||
this.sailId = sailId;
|
||||
this.color = color;
|
||||
}
|
||||
@@ -31,10 +36,37 @@ public class BoatDTO extends NamedDTO implements Serializable {
|
||||
return sailId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdAsString() {
|
||||
return idAsString;
|
||||
}
|
||||
|
||||
public BoatClassDTO getBoatClass() {
|
||||
return boatClass;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final boolean hasSailId = sailId != null && !sailId.isEmpty();
|
||||
if (getName() != null) {
|
||||
sb.append(getName());
|
||||
if (hasSailId) {
|
||||
sb.append(" (").append(sailId).append(')');
|
||||
}
|
||||
} else if (hasSailId) {
|
||||
sb.append(sailId);
|
||||
} else {
|
||||
sb.append(idAsString);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((boatClass == null) ? 0 : boatClass.hashCode());
|
||||
result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode());
|
||||
result = prime * result + ((color == null) ? 0 : color.hashCode());
|
||||
result = prime * result + ((sailId == null) ? 0 : sailId.hashCode());
|
||||
return result;
|
||||
@@ -49,6 +81,16 @@ public class BoatDTO extends NamedDTO implements Serializable {
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
BoatDTO other = (BoatDTO) obj;
|
||||
if (boatClass == null) {
|
||||
if (other.boatClass != null)
|
||||
return false;
|
||||
} else if (!boatClass.equals(other.boatClass))
|
||||
return false;
|
||||
if (idAsString == null) {
|
||||
if (other.idAsString != null)
|
||||
return false;
|
||||
} else if (!idAsString.equals(other.idAsString))
|
||||
return false;
|
||||
if (color == null) {
|
||||
if (other.color != null)
|
||||
return false;
|
||||
@@ -61,4 +103,9 @@ public class BoatDTO extends NamedDTO implements Serializable {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName() == null ? (getBoatClass().getName() + " / " + getSailId()) : getName();
|
||||
}
|
||||
}
|
||||
+20
-39
@@ -1,55 +1,36 @@
|
||||
package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.MappableToDevice;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
public interface CompetitorDTO extends Serializable, MappableToDevice {
|
||||
|
||||
String getTwoLetterIsoCountryCode();
|
||||
|
||||
String getThreeLetterIocCountryCode();
|
||||
|
||||
String getCountryName();
|
||||
|
||||
String getIdAsString();
|
||||
|
||||
/**
|
||||
* Equality and hash code are based on the {@link #getIdAsString() ID}, the {@link #getSailID() sail number}, the
|
||||
* {@link #getBoatClass() boat class} (whose equality and hash code, in turn, depends on its name) and the
|
||||
* {@link #getThreeLetterIocCountryCode() IOC country code}. Note that the three latter properties are subject
|
||||
* to change for a competitor while the ID remains unchanged.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public interface CompetitorDTO extends CompetitorWithoutBoatDTO {
|
||||
// TODO bug2822: Should we remove this?
|
||||
String getSailID();
|
||||
|
||||
String getSearchTag();
|
||||
|
||||
/**
|
||||
* If the {@code searchTag} is not {@link String#contains(CharSequence) contained} in {@link #getSearchTag()},
|
||||
* appends it to the search tag, separated by a space character
|
||||
* Returns a derived short information about a competitor depending on the information available
|
||||
* If we have a short name set on the competitor this name will be returned.
|
||||
* If no short name exist but a boat the either the sailId or the boat name will returned.
|
||||
* If all these attributes have no value null is returned.
|
||||
*/
|
||||
void addToSearchTag(String searchTag);
|
||||
|
||||
String getShortInfo();
|
||||
|
||||
BoatDTO getBoat();
|
||||
|
||||
void setBoat(BoatDTO boat);
|
||||
|
||||
// TODO bug2822: Should we remove this?
|
||||
BoatClassDTO getBoatClass();
|
||||
|
||||
String getName();
|
||||
|
||||
Color getColor();
|
||||
|
||||
String getEmail();
|
||||
|
||||
boolean hasEmail();
|
||||
|
||||
/**
|
||||
* A regular instance will simply return this object. A compacted version may compute the result by looking it up
|
||||
* from the previous version of the enclosing leaderboard.
|
||||
*/
|
||||
CompetitorDTO getCompetitorFromPrevious(LeaderboardDTO previousVersion);
|
||||
|
||||
String getFlagImageURL();
|
||||
|
||||
String getImageURL();
|
||||
|
||||
Double getTimeOnTimeFactor();
|
||||
|
||||
Duration getTimeOnDistanceAllowancePerNauticalMile();
|
||||
|
||||
}
|
||||
+32
-166
@@ -5,67 +5,36 @@ import java.io.Serializable;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
* Equality and hash code are based on the {@link #getIdAsString() ID}, the {@link #getSailID() sail number}, the
|
||||
* {@link #getBoatClass() boat class} (whose equality and hash code, in turn, depends on its name) and the
|
||||
* {@link #getThreeLetterIocCountryCode() IOC country code}. Note that the three latter properties are subject
|
||||
* to change for a competitor while the ID remains unchanged.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serializable {
|
||||
public class CompetitorDTOImpl extends CompetitorWithoutBoatDTOImpl implements CompetitorDTO, Serializable {
|
||||
private static final long serialVersionUID = -4997852354821083154L;
|
||||
private String countryName;
|
||||
private String twoLetterIsoCountryCode;
|
||||
private String threeLetterIocCountryCode;
|
||||
private Color color;
|
||||
private String email;
|
||||
private String searchTag;
|
||||
private String idAsString;
|
||||
private BoatClassDTO boatClass;
|
||||
private BoatDTO boat;
|
||||
private String imageURL;
|
||||
private String flagImageURL;
|
||||
private Double timeOnTimeFactor;
|
||||
private Duration timeOnDistanceAllowancePerNauticalMile;
|
||||
|
||||
public CompetitorDTOImpl() {}
|
||||
public CompetitorDTOImpl() {
|
||||
boat = new BoatDTO();
|
||||
}
|
||||
|
||||
public CompetitorDTOImpl(String name, Color color, String email, String twoLetterIsoCountryCode, String threeLetterIocCountryCode,
|
||||
public CompetitorDTOImpl(String name, String shortName, Color color, String email, String twoLetterIsoCountryCode, String threeLetterIocCountryCode,
|
||||
String countryName, String idAsString, String imageURL, String flagImageURL,
|
||||
BoatDTO boat, BoatClassDTO boatClass, Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
|
||||
super(name);
|
||||
this.color = color;
|
||||
this.email = email;
|
||||
this.twoLetterIsoCountryCode = twoLetterIsoCountryCode;
|
||||
this.threeLetterIocCountryCode = threeLetterIocCountryCode;
|
||||
this.countryName = countryName;
|
||||
this.idAsString = idAsString;
|
||||
this.imageURL = imageURL;
|
||||
this.flagImageURL = flagImageURL;
|
||||
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag, BoatDTO boat) {
|
||||
super(name, shortName, color, email, twoLetterIsoCountryCode, threeLetterIocCountryCode,
|
||||
countryName, idAsString, imageURL, flagImageURL,
|
||||
timeOnTimeFactor, timeOnDistanceAllowancePerNauticalMile, searchTag);
|
||||
this.boat = boat;
|
||||
}
|
||||
|
||||
public CompetitorDTOImpl(CompetitorWithoutBoatDTO c, BoatDTO boat) {
|
||||
super(c.getName(), c.getShortName(), c.getColor(), c.getEmail(),
|
||||
c.getTwoLetterIsoCountryCode(), c.getThreeLetterIocCountryCode(), c.getCountryName(), c.getIdAsString(),
|
||||
c.getImageURL(), c.getFlagImageURL(), c.getTimeOnTimeFactor(),
|
||||
c.getTimeOnDistanceAllowancePerNauticalMile(), c.getSearchTag());
|
||||
this.boat = boat;
|
||||
this.boatClass = boatClass;
|
||||
this.timeOnTimeFactor = timeOnTimeFactor;
|
||||
this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile;
|
||||
this.searchTag = searchTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((boatClass == null) ? 0 : boatClass.hashCode());
|
||||
result = prime * result + ((boat == null) ? 0 : boat.hashCode());
|
||||
result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode());
|
||||
result = prime * result + ((color == null) ? 0 : color.hashCode());
|
||||
result = prime * result + ((email == null) ? 0 : email.hashCode());
|
||||
result = prime * result + ((threeLetterIocCountryCode == null) ? 0 : threeLetterIocCountryCode.hashCode());
|
||||
result = prime * result + ((imageURL == null) ? 0 : imageURL.hashCode());
|
||||
result = prime * result + ((flagImageURL == null) ? 0 : flagImageURL.hashCode());
|
||||
result = prime * result + ((timeOnTimeFactor == null) ? 0 : timeOnTimeFactor.hashCode());
|
||||
result = prime * result + ((timeOnDistanceAllowancePerNauticalMile == null) ? 0 : timeOnDistanceAllowancePerNauticalMile.hashCode());
|
||||
result = prime * result + ((searchTag == null) ? 0 : searchTag.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -78,150 +47,47 @@ public class CompetitorDTOImpl extends NamedDTO implements CompetitorDTO, Serial
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CompetitorDTOImpl other = (CompetitorDTOImpl) obj;
|
||||
if (boatClass == null) {
|
||||
if (other.boatClass != null)
|
||||
return false;
|
||||
} else if (!boatClass.equals(other.boatClass))
|
||||
return false;
|
||||
if (boat == null) {
|
||||
if (other.boat != null)
|
||||
return false;
|
||||
} else if (!boat.equals(other.boat))
|
||||
return false;
|
||||
if (idAsString == null) {
|
||||
if (other.idAsString != null)
|
||||
return false;
|
||||
} else if (!idAsString.equals(other.idAsString))
|
||||
return false;
|
||||
if (threeLetterIocCountryCode == null) {
|
||||
if (other.threeLetterIocCountryCode != null)
|
||||
return false;
|
||||
} else if (!threeLetterIocCountryCode.equals(other.threeLetterIocCountryCode))
|
||||
return false;
|
||||
if (color == null) {
|
||||
if (other.color != null)
|
||||
return false;
|
||||
} else if (!color.equals(other.color))
|
||||
return false;
|
||||
if (email == null) {
|
||||
if (other.email != null)
|
||||
return false;
|
||||
} else if (!email.equals(other.email))
|
||||
return false;
|
||||
if (imageURL == null) {
|
||||
if (other.imageURL != null)
|
||||
return false;
|
||||
} else if (!imageURL.equals(other.imageURL))
|
||||
return false;
|
||||
if (flagImageURL == null) {
|
||||
if (other.flagImageURL != null)
|
||||
return false;
|
||||
} else if (!flagImageURL.equals(other.flagImageURL))
|
||||
return false;
|
||||
if (timeOnTimeFactor == null) {
|
||||
if (other.timeOnTimeFactor != null)
|
||||
return false;
|
||||
} else if (!timeOnTimeFactor.equals(other.timeOnTimeFactor))
|
||||
return false;
|
||||
if (timeOnDistanceAllowancePerNauticalMile == null) {
|
||||
if (other.timeOnDistanceAllowancePerNauticalMile != null)
|
||||
return false;
|
||||
} else if (!timeOnDistanceAllowancePerNauticalMile.equals(other.timeOnDistanceAllowancePerNauticalMile))
|
||||
return false;
|
||||
if (searchTag == null) {
|
||||
if (other.searchTag != null)
|
||||
return false;
|
||||
} else if (!searchTag.equals(other.searchTag))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTwoLetterIsoCountryCode() {
|
||||
return twoLetterIsoCountryCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThreeLetterIocCountryCode() {
|
||||
return threeLetterIocCountryCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCountryName() {
|
||||
return countryName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSailID() {
|
||||
return boat==null?null:boat.getSailId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageURL() {
|
||||
return imageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFlagImageURL() {
|
||||
return flagImageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdAsString() {
|
||||
return idAsString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoatClassDTO getBoatClass() {
|
||||
return boatClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompetitorDTO getCompetitorFromPrevious(LeaderboardDTO previousVersion) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSearchTag() {
|
||||
return searchTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToSearchTag(String searchTag) {
|
||||
if (this.searchTag == null) {
|
||||
this.searchTag = searchTag;
|
||||
} else if (!this.searchTag.contains(searchTag)) {
|
||||
this.searchTag += " "+searchTag;
|
||||
public String getShortInfo() {
|
||||
String result = null;
|
||||
if (getShortName() != null) {
|
||||
result = getShortName();
|
||||
} else if (getBoat() != null) {
|
||||
result = getBoat().getSailId() != null ? getBoat().getSailId() : getBoat().getName();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return email;
|
||||
public String getSailID() {
|
||||
return boat == null ? null : boat.getSailId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEmail() {
|
||||
return email != null && !email.isEmpty();
|
||||
public BoatClassDTO getBoatClass() {
|
||||
return boat == null ? null : boat.getBoatClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getTimeOnTimeFactor() {
|
||||
return timeOnTimeFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getTimeOnDistanceAllowancePerNauticalMile() {
|
||||
return timeOnDistanceAllowancePerNauticalMile;
|
||||
}
|
||||
public void setBoat(BoatDTO boat) {
|
||||
this.boat = boat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoatDTO getBoat() {
|
||||
return boat;
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.common.racelog.tracking.MappableToDevice;
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
* Equality and hash code are based on the {@link #getIdAsString() ID} and all contained attributes like name, shortName, email, etc.
|
||||
*/
|
||||
public interface CompetitorWithoutBoatDTO extends Serializable, MappableToDevice {
|
||||
|
||||
String getTwoLetterIsoCountryCode();
|
||||
|
||||
String getThreeLetterIocCountryCode();
|
||||
|
||||
String getCountryName();
|
||||
|
||||
String getIdAsString();
|
||||
|
||||
String getSearchTag();
|
||||
|
||||
/**
|
||||
* If the {@code searchTag} is not contained in {@link #getSearchTag()}, appends it to the search tag, separated by a space character
|
||||
*/
|
||||
void addToSearchTag(String searchTag);
|
||||
|
||||
String getName();
|
||||
|
||||
String getShortName();
|
||||
|
||||
Color getColor();
|
||||
|
||||
String getEmail();
|
||||
|
||||
boolean hasEmail();
|
||||
|
||||
String getFlagImageURL();
|
||||
|
||||
String getImageURL();
|
||||
|
||||
Double getTimeOnTimeFactor();
|
||||
|
||||
Duration getTimeOnDistanceAllowancePerNauticalMile();
|
||||
|
||||
}
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
* Equality and hash code are based on the {@link #getIdAsString() ID}, the {@link #getSailID() sail number}, the
|
||||
* {@link #getBoatClass() boat class} (whose equality and hash code, in turn, depends on its name) and the
|
||||
* {@link #getThreeLetterIocCountryCode() IOC country code}. Note that the three latter properties are subject
|
||||
* to change for a competitor while the ID remains unchanged.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class CompetitorWithoutBoatDTOImpl extends NamedDTO implements CompetitorWithoutBoatDTO, Serializable {
|
||||
private static final long serialVersionUID = 3019126418065082622L;
|
||||
private String countryName;
|
||||
private String twoLetterIsoCountryCode;
|
||||
private String threeLetterIocCountryCode;
|
||||
private Color color;
|
||||
private String shortName;
|
||||
private String email;
|
||||
private String searchTag;
|
||||
private String idAsString;
|
||||
private String imageURL;
|
||||
private String flagImageURL;
|
||||
private Double timeOnTimeFactor;
|
||||
private Duration timeOnDistanceAllowancePerNauticalMile;
|
||||
|
||||
public CompetitorWithoutBoatDTOImpl() {}
|
||||
|
||||
public CompetitorWithoutBoatDTOImpl(String name, String shortName, Color color, String email, String twoLetterIsoCountryCode, String threeLetterIocCountryCode,
|
||||
String countryName, String idAsString, String imageURL, String flagImageURL,
|
||||
Double timeOnTimeFactor, Duration timeOnDistanceAllowancePerNauticalMile, String searchTag) {
|
||||
super(name);
|
||||
this.shortName = shortName;
|
||||
this.color = color;
|
||||
this.email = email;
|
||||
this.twoLetterIsoCountryCode = twoLetterIsoCountryCode;
|
||||
this.threeLetterIocCountryCode = threeLetterIocCountryCode;
|
||||
this.countryName = countryName;
|
||||
this.idAsString = idAsString;
|
||||
this.imageURL = imageURL;
|
||||
this.flagImageURL = flagImageURL;
|
||||
this.timeOnTimeFactor = timeOnTimeFactor;
|
||||
this.timeOnDistanceAllowancePerNauticalMile = timeOnDistanceAllowancePerNauticalMile;
|
||||
this.searchTag = searchTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + ((idAsString == null) ? 0 : idAsString.hashCode());
|
||||
result = prime * result + ((color == null) ? 0 : color.hashCode());
|
||||
result = prime * result + ((email == null) ? 0 : email.hashCode());
|
||||
result = prime * result + ((shortName == null) ? 0 : shortName.hashCode());
|
||||
result = prime * result + ((threeLetterIocCountryCode == null) ? 0 : threeLetterIocCountryCode.hashCode());
|
||||
result = prime * result + ((imageURL == null) ? 0 : imageURL.hashCode());
|
||||
result = prime * result + ((flagImageURL == null) ? 0 : flagImageURL.hashCode());
|
||||
result = prime * result + ((timeOnTimeFactor == null) ? 0 : timeOnTimeFactor.hashCode());
|
||||
result = prime * result + ((timeOnDistanceAllowancePerNauticalMile == null) ? 0 : timeOnDistanceAllowancePerNauticalMile.hashCode());
|
||||
result = prime * result + ((searchTag == null) ? 0 : searchTag.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
CompetitorWithoutBoatDTOImpl other = (CompetitorWithoutBoatDTOImpl) obj;
|
||||
if (idAsString == null) {
|
||||
if (other.idAsString != null)
|
||||
return false;
|
||||
} else if (!idAsString.equals(other.idAsString))
|
||||
return false;
|
||||
if (threeLetterIocCountryCode == null) {
|
||||
if (other.threeLetterIocCountryCode != null)
|
||||
return false;
|
||||
} else if (!threeLetterIocCountryCode.equals(other.threeLetterIocCountryCode))
|
||||
return false;
|
||||
if (color == null) {
|
||||
if (other.color != null)
|
||||
return false;
|
||||
} else if (!color.equals(other.color))
|
||||
return false;
|
||||
if (email == null) {
|
||||
if (other.email != null)
|
||||
return false;
|
||||
} else if (!email.equals(other.email))
|
||||
return false;
|
||||
if (shortName == null) {
|
||||
if (other.shortName != null)
|
||||
return false;
|
||||
} else if (!shortName.equals(other.shortName))
|
||||
return false;
|
||||
if (imageURL == null) {
|
||||
if (other.imageURL != null)
|
||||
return false;
|
||||
} else if (!imageURL.equals(other.imageURL))
|
||||
return false;
|
||||
if (flagImageURL == null) {
|
||||
if (other.flagImageURL != null)
|
||||
return false;
|
||||
} else if (!flagImageURL.equals(other.flagImageURL))
|
||||
return false;
|
||||
if (timeOnTimeFactor == null) {
|
||||
if (other.timeOnTimeFactor != null)
|
||||
return false;
|
||||
} else if (!timeOnTimeFactor.equals(other.timeOnTimeFactor))
|
||||
return false;
|
||||
if (timeOnDistanceAllowancePerNauticalMile == null) {
|
||||
if (other.timeOnDistanceAllowancePerNauticalMile != null)
|
||||
return false;
|
||||
} else if (!timeOnDistanceAllowancePerNauticalMile.equals(other.timeOnDistanceAllowancePerNauticalMile))
|
||||
return false;
|
||||
if (searchTag == null) {
|
||||
if (other.searchTag != null)
|
||||
return false;
|
||||
} else if (!searchTag.equals(other.searchTag))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTwoLetterIsoCountryCode() {
|
||||
return twoLetterIsoCountryCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThreeLetterIocCountryCode() {
|
||||
return threeLetterIocCountryCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCountryName() {
|
||||
return countryName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortName() {
|
||||
return shortName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageURL() {
|
||||
return imageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFlagImageURL() {
|
||||
return flagImageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdAsString() {
|
||||
return idAsString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSearchTag() {
|
||||
return searchTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToSearchTag(String searchTag) {
|
||||
if (this.searchTag == null) {
|
||||
this.searchTag = searchTag;
|
||||
} else if (!this.searchTag.contains(searchTag)) {
|
||||
this.searchTag += " "+searchTag;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEmail() {
|
||||
return email != null && !email.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getTimeOnTimeFactor() {
|
||||
return timeOnTimeFactor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getTimeOnDistanceAllowancePerNauticalMile() {
|
||||
return timeOnDistanceAllowancePerNauticalMile;
|
||||
}
|
||||
}
|
||||
+39
@@ -117,6 +117,45 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements Serializab
|
||||
return higherScoresIsBetter;
|
||||
}
|
||||
|
||||
public BoatDTO getBoatOfCompetitor(String raceColumnName, CompetitorDTO competitor) {
|
||||
BoatDTO result = null;
|
||||
if (rows != null) {
|
||||
LeaderboardRowDTO leaderboardRow = rows.get(competitor);
|
||||
if (leaderboardRow != null) {
|
||||
if (this.canBoatsOfCompetitorsChangePerRace == false) {
|
||||
result = leaderboardRow.boat;
|
||||
} else {
|
||||
LeaderboardEntryDTO leaderboardEntry = leaderboardRow.fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (leaderboardEntry != null) {
|
||||
result = leaderboardEntry.boat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setBoatOfCompetitor(CompetitorDTO competitor, BoatDTO boat) {
|
||||
if (rows != null && this.canBoatsOfCompetitorsChangePerRace == false) {
|
||||
LeaderboardRowDTO leaderboardRowDTO = rows.get(competitor);
|
||||
if (leaderboardRowDTO != null) {
|
||||
leaderboardRowDTO.boat = boat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setBoatOfCompetitorForRace(String raceColumnName, CompetitorDTO competitor, BoatDTO boat) {
|
||||
if (rows != null && this.canBoatsOfCompetitorsChangePerRace == true) {
|
||||
LeaderboardRowDTO leaderboardRow = rows.get(competitor);
|
||||
if (leaderboardRow != null) {
|
||||
LeaderboardEntryDTO leaderboardEntry = leaderboardRow.fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (leaderboardEntry != null) {
|
||||
leaderboardEntry.boat = boat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCompetitorsFromBestToWorst(String raceColumnName, List<CompetitorDTO> orderedCompetitors) {
|
||||
competitorOrderingPerRaceColumnName.put(raceColumnName, orderedCompetitors);
|
||||
}
|
||||
|
||||
+210
-201
@@ -28,7 +28,10 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
* fleet the competitor started in this column.
|
||||
*/
|
||||
public RaceIdentifier race;
|
||||
|
||||
|
||||
/** the boat of the competitor in case of regattas where boat can change during racing, null otherwise */
|
||||
public BoatDTO boat;
|
||||
|
||||
/**
|
||||
* Either <code>null</code> in case no max points, or one of "DNS", "DNF", "OCS", "DND", "RAF", "BFD", "DNC", or "DSQ"
|
||||
*/
|
||||
@@ -237,206 +240,7 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((averageAbsoluteCrossTrackErrorInMeters == null) ? 0
|
||||
: averageAbsoluteCrossTrackErrorInMeters.hashCode());
|
||||
result = prime * result + ((averageRideHeightInMeters == null) ? 0 : averageRideHeightInMeters.hashCode());
|
||||
result = prime * result + ((averageSamplingInterval == null) ? 0 : averageSamplingInterval.hashCode());
|
||||
result = prime * result + ((averageSignedCrossTrackErrorInMeters == null) ? 0
|
||||
: averageSignedCrossTrackErrorInMeters.hashCode());
|
||||
result = prime * result + ((calculatedTime == null) ? 0 : calculatedTime.hashCode());
|
||||
result = prime * result + ((calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) ? 0
|
||||
: calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.hashCode());
|
||||
result = prime * result + (discarded ? 1231 : 1237);
|
||||
result = prime * result + ((distanceToStarboardSideOfStartLineInMeters == null) ? 0
|
||||
: distanceToStarboardSideOfStartLineInMeters.hashCode());
|
||||
result = prime * result + ((distanceToStartLineAtStartOfRaceInMeters == null) ? 0
|
||||
: distanceToStartLineAtStartOfRaceInMeters.hashCode());
|
||||
result = prime * result + ((distanceToStartLineFiveSecondsBeforeStartInMeters == null) ? 0
|
||||
: distanceToStartLineFiveSecondsBeforeStartInMeters.hashCode());
|
||||
result = prime * result + ((expeditionDataHolder == null) ? 0 : expeditionDataHolder.hashCode());
|
||||
result = prime * result + ((fleet == null) ? 0 : fleet.hashCode());
|
||||
result = prime * result + ((gapToLeaderInOwnTime == null) ? 0 : gapToLeaderInOwnTime.hashCode());
|
||||
result = prime * result + ((heel == null) ? 0 : heel.hashCode());
|
||||
result = prime * result + ((legDetails == null) ? 0 : legDetails.hashCode());
|
||||
result = prime * result + ((netPoints == null) ? 0 : netPoints.hashCode());
|
||||
result = prime * result + ((pitch == null) ? 0 : pitch.hashCode());
|
||||
result = prime * result + ((race == null) ? 0 : race.hashCode());
|
||||
result = prime * result + ((reasonForMaxPoints == null) ? 0 : reasonForMaxPoints.hashCode());
|
||||
result = prime * result + ((speedOverGroundAtPassingStartWaypointInKnots == null) ? 0
|
||||
: speedOverGroundAtPassingStartWaypointInKnots.hashCode());
|
||||
result = prime * result
|
||||
+ ((speedOverGroundAtStartOfRaceInKnots == null) ? 0 : speedOverGroundAtStartOfRaceInKnots.hashCode());
|
||||
result = prime * result + ((speedOverGroundFiveSecondsBeforeStartInKnots == null) ? 0
|
||||
: speedOverGroundFiveSecondsBeforeStartInKnots.hashCode());
|
||||
result = prime * result + ((startTack == null) ? 0 : startTack.hashCode());
|
||||
result = prime * result + ((timeBetweenRaceStartAndCompetitorStartInSeconds == null) ? 0
|
||||
: timeBetweenRaceStartAndCompetitorStartInSeconds.hashCode());
|
||||
result = prime * result
|
||||
+ ((timeSinceLastPositionFixInSeconds == null) ? 0 : timeSinceLastPositionFixInSeconds.hashCode());
|
||||
result = prime * result + ((totalPoints == null) ? 0 : totalPoints.hashCode());
|
||||
result = prime * result + (totalPointsCorrected ? 1231 : 1237);
|
||||
result = prime * result + ((totalPointsUncorrected == null) ? 0 : totalPointsUncorrected.hashCode());
|
||||
result = prime * result + ((windwardDistanceToCompetitorFarthestAheadInMeters == null) ? 0
|
||||
: windwardDistanceToCompetitorFarthestAheadInMeters.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LeaderboardEntryDTO other = (LeaderboardEntryDTO) obj;
|
||||
if (averageAbsoluteCrossTrackErrorInMeters == null) {
|
||||
if (other.averageAbsoluteCrossTrackErrorInMeters != null)
|
||||
return false;
|
||||
} else if (!averageAbsoluteCrossTrackErrorInMeters.equals(other.averageAbsoluteCrossTrackErrorInMeters))
|
||||
return false;
|
||||
if (averageRideHeightInMeters == null) {
|
||||
if (other.averageRideHeightInMeters != null)
|
||||
return false;
|
||||
} else if (!averageRideHeightInMeters.equals(other.averageRideHeightInMeters))
|
||||
return false;
|
||||
if (averageSamplingInterval == null) {
|
||||
if (other.averageSamplingInterval != null)
|
||||
return false;
|
||||
} else if (!averageSamplingInterval.equals(other.averageSamplingInterval))
|
||||
return false;
|
||||
if (averageSignedCrossTrackErrorInMeters == null) {
|
||||
if (other.averageSignedCrossTrackErrorInMeters != null)
|
||||
return false;
|
||||
} else if (!averageSignedCrossTrackErrorInMeters.equals(other.averageSignedCrossTrackErrorInMeters))
|
||||
return false;
|
||||
if (calculatedTime == null) {
|
||||
if (other.calculatedTime != null)
|
||||
return false;
|
||||
} else if (!calculatedTime.equals(other.calculatedTime))
|
||||
return false;
|
||||
if (calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) {
|
||||
if (other.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead != null)
|
||||
return false;
|
||||
} else if (!calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead
|
||||
.equals(other.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead))
|
||||
return false;
|
||||
if (discarded != other.discarded)
|
||||
return false;
|
||||
if (distanceToStarboardSideOfStartLineInMeters == null) {
|
||||
if (other.distanceToStarboardSideOfStartLineInMeters != null)
|
||||
return false;
|
||||
} else if (!distanceToStarboardSideOfStartLineInMeters.equals(other.distanceToStarboardSideOfStartLineInMeters))
|
||||
return false;
|
||||
if (distanceToStartLineAtStartOfRaceInMeters == null) {
|
||||
if (other.distanceToStartLineAtStartOfRaceInMeters != null)
|
||||
return false;
|
||||
} else if (!distanceToStartLineAtStartOfRaceInMeters.equals(other.distanceToStartLineAtStartOfRaceInMeters))
|
||||
return false;
|
||||
if (distanceToStartLineFiveSecondsBeforeStartInMeters == null) {
|
||||
if (other.distanceToStartLineFiveSecondsBeforeStartInMeters != null)
|
||||
return false;
|
||||
} else if (!distanceToStartLineFiveSecondsBeforeStartInMeters
|
||||
.equals(other.distanceToStartLineFiveSecondsBeforeStartInMeters))
|
||||
return false;
|
||||
if (expeditionDataHolder == null) {
|
||||
if (other.expeditionDataHolder != null)
|
||||
return false;
|
||||
} else if (!expeditionDataHolder.equals(other.expeditionDataHolder))
|
||||
return false;
|
||||
if (fleet == null) {
|
||||
if (other.fleet != null)
|
||||
return false;
|
||||
} else if (!fleet.equals(other.fleet))
|
||||
return false;
|
||||
if (gapToLeaderInOwnTime == null) {
|
||||
if (other.gapToLeaderInOwnTime != null)
|
||||
return false;
|
||||
} else if (!gapToLeaderInOwnTime.equals(other.gapToLeaderInOwnTime))
|
||||
return false;
|
||||
if (heel == null) {
|
||||
if (other.heel != null)
|
||||
return false;
|
||||
} else if (!heel.equals(other.heel))
|
||||
return false;
|
||||
if (legDetails == null) {
|
||||
if (other.legDetails != null)
|
||||
return false;
|
||||
} else if (!legDetails.equals(other.legDetails))
|
||||
return false;
|
||||
if (netPoints == null) {
|
||||
if (other.netPoints != null)
|
||||
return false;
|
||||
} else if (!netPoints.equals(other.netPoints))
|
||||
return false;
|
||||
if (pitch == null) {
|
||||
if (other.pitch != null)
|
||||
return false;
|
||||
} else if (!pitch.equals(other.pitch))
|
||||
return false;
|
||||
if (race == null) {
|
||||
if (other.race != null)
|
||||
return false;
|
||||
} else if (!race.equals(other.race))
|
||||
return false;
|
||||
if (reasonForMaxPoints != other.reasonForMaxPoints)
|
||||
return false;
|
||||
if (speedOverGroundAtPassingStartWaypointInKnots == null) {
|
||||
if (other.speedOverGroundAtPassingStartWaypointInKnots != null)
|
||||
return false;
|
||||
} else if (!speedOverGroundAtPassingStartWaypointInKnots
|
||||
.equals(other.speedOverGroundAtPassingStartWaypointInKnots))
|
||||
return false;
|
||||
if (speedOverGroundAtStartOfRaceInKnots == null) {
|
||||
if (other.speedOverGroundAtStartOfRaceInKnots != null)
|
||||
return false;
|
||||
} else if (!speedOverGroundAtStartOfRaceInKnots.equals(other.speedOverGroundAtStartOfRaceInKnots))
|
||||
return false;
|
||||
if (speedOverGroundFiveSecondsBeforeStartInKnots == null) {
|
||||
if (other.speedOverGroundFiveSecondsBeforeStartInKnots != null)
|
||||
return false;
|
||||
} else if (!speedOverGroundFiveSecondsBeforeStartInKnots
|
||||
.equals(other.speedOverGroundFiveSecondsBeforeStartInKnots))
|
||||
return false;
|
||||
if (startTack != other.startTack)
|
||||
return false;
|
||||
if (timeBetweenRaceStartAndCompetitorStartInSeconds == null) {
|
||||
if (other.timeBetweenRaceStartAndCompetitorStartInSeconds != null)
|
||||
return false;
|
||||
} else if (!timeBetweenRaceStartAndCompetitorStartInSeconds
|
||||
.equals(other.timeBetweenRaceStartAndCompetitorStartInSeconds))
|
||||
return false;
|
||||
if (timeSinceLastPositionFixInSeconds == null) {
|
||||
if (other.timeSinceLastPositionFixInSeconds != null)
|
||||
return false;
|
||||
} else if (!timeSinceLastPositionFixInSeconds.equals(other.timeSinceLastPositionFixInSeconds))
|
||||
return false;
|
||||
if (totalPoints == null) {
|
||||
if (other.totalPoints != null)
|
||||
return false;
|
||||
} else if (!totalPoints.equals(other.totalPoints))
|
||||
return false;
|
||||
if (totalPointsCorrected != other.totalPointsCorrected)
|
||||
return false;
|
||||
if (totalPointsUncorrected == null) {
|
||||
if (other.totalPointsUncorrected != null)
|
||||
return false;
|
||||
} else if (!totalPointsUncorrected.equals(other.totalPointsUncorrected))
|
||||
return false;
|
||||
if (windwardDistanceToCompetitorFarthestAheadInMeters == null) {
|
||||
if (other.windwardDistanceToCompetitorFarthestAheadInMeters != null)
|
||||
return false;
|
||||
} else if (!windwardDistanceToCompetitorFarthestAheadInMeters
|
||||
.equals(other.windwardDistanceToCompetitorFarthestAheadInMeters))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void ensureExpeditionHolder() {
|
||||
if (expeditionDataHolder == null) {
|
||||
expeditionDataHolder = new ExpeditionDataHolder();
|
||||
@@ -778,6 +582,211 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
public Double getExpeditionMastButt() {
|
||||
return expeditionDataHolder == null ? null : expeditionDataHolder.expeditionMastButt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((averageAbsoluteCrossTrackErrorInMeters == null) ? 0
|
||||
: averageAbsoluteCrossTrackErrorInMeters.hashCode());
|
||||
result = prime * result + ((averageRideHeightInMeters == null) ? 0 : averageRideHeightInMeters.hashCode());
|
||||
result = prime * result + ((averageSamplingInterval == null) ? 0 : averageSamplingInterval.hashCode());
|
||||
result = prime * result + ((averageSignedCrossTrackErrorInMeters == null) ? 0
|
||||
: averageSignedCrossTrackErrorInMeters.hashCode());
|
||||
result = prime * result + ((boat == null) ? 0 : boat.hashCode());
|
||||
result = prime * result + ((calculatedTime == null) ? 0 : calculatedTime.hashCode());
|
||||
result = prime * result + ((calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) ? 0
|
||||
: calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead.hashCode());
|
||||
result = prime * result + (discarded ? 1231 : 1237);
|
||||
result = prime * result + ((distanceToStarboardSideOfStartLineInMeters == null) ? 0
|
||||
: distanceToStarboardSideOfStartLineInMeters.hashCode());
|
||||
result = prime * result + ((distanceToStartLineAtStartOfRaceInMeters == null) ? 0
|
||||
: distanceToStartLineAtStartOfRaceInMeters.hashCode());
|
||||
result = prime * result + ((distanceToStartLineFiveSecondsBeforeStartInMeters == null) ? 0
|
||||
: distanceToStartLineFiveSecondsBeforeStartInMeters.hashCode());
|
||||
result = prime * result + ((expeditionDataHolder == null) ? 0 : expeditionDataHolder.hashCode());
|
||||
result = prime * result + ((fleet == null) ? 0 : fleet.hashCode());
|
||||
result = prime * result + ((gapToLeaderInOwnTime == null) ? 0 : gapToLeaderInOwnTime.hashCode());
|
||||
result = prime * result + ((heel == null) ? 0 : heel.hashCode());
|
||||
result = prime * result + ((legDetails == null) ? 0 : legDetails.hashCode());
|
||||
result = prime * result + ((netPoints == null) ? 0 : netPoints.hashCode());
|
||||
result = prime * result + ((pitch == null) ? 0 : pitch.hashCode());
|
||||
result = prime * result + ((race == null) ? 0 : race.hashCode());
|
||||
result = prime * result + ((reasonForMaxPoints == null) ? 0 : reasonForMaxPoints.hashCode());
|
||||
result = prime * result + ((speedOverGroundAtPassingStartWaypointInKnots == null) ? 0
|
||||
: speedOverGroundAtPassingStartWaypointInKnots.hashCode());
|
||||
result = prime * result
|
||||
+ ((speedOverGroundAtStartOfRaceInKnots == null) ? 0 : speedOverGroundAtStartOfRaceInKnots.hashCode());
|
||||
result = prime * result + ((speedOverGroundFiveSecondsBeforeStartInKnots == null) ? 0
|
||||
: speedOverGroundFiveSecondsBeforeStartInKnots.hashCode());
|
||||
result = prime * result + ((startTack == null) ? 0 : startTack.hashCode());
|
||||
result = prime * result + ((timeBetweenRaceStartAndCompetitorStartInSeconds == null) ? 0
|
||||
: timeBetweenRaceStartAndCompetitorStartInSeconds.hashCode());
|
||||
result = prime * result
|
||||
+ ((timeSinceLastPositionFixInSeconds == null) ? 0 : timeSinceLastPositionFixInSeconds.hashCode());
|
||||
result = prime * result + ((totalPoints == null) ? 0 : totalPoints.hashCode());
|
||||
result = prime * result + (totalPointsCorrected ? 1231 : 1237);
|
||||
result = prime * result + ((totalPointsUncorrected == null) ? 0 : totalPointsUncorrected.hashCode());
|
||||
result = prime * result + ((windwardDistanceToCompetitorFarthestAheadInMeters == null) ? 0
|
||||
: windwardDistanceToCompetitorFarthestAheadInMeters.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
LeaderboardEntryDTO other = (LeaderboardEntryDTO) obj;
|
||||
if (averageAbsoluteCrossTrackErrorInMeters == null) {
|
||||
if (other.averageAbsoluteCrossTrackErrorInMeters != null)
|
||||
return false;
|
||||
} else if (!averageAbsoluteCrossTrackErrorInMeters.equals(other.averageAbsoluteCrossTrackErrorInMeters))
|
||||
return false;
|
||||
if (averageRideHeightInMeters == null) {
|
||||
if (other.averageRideHeightInMeters != null)
|
||||
return false;
|
||||
} else if (!averageRideHeightInMeters.equals(other.averageRideHeightInMeters))
|
||||
return false;
|
||||
if (averageSamplingInterval == null) {
|
||||
if (other.averageSamplingInterval != null)
|
||||
return false;
|
||||
} else if (!averageSamplingInterval.equals(other.averageSamplingInterval))
|
||||
return false;
|
||||
if (averageSignedCrossTrackErrorInMeters == null) {
|
||||
if (other.averageSignedCrossTrackErrorInMeters != null)
|
||||
return false;
|
||||
} else if (!averageSignedCrossTrackErrorInMeters.equals(other.averageSignedCrossTrackErrorInMeters))
|
||||
return false;
|
||||
if (boat == null) {
|
||||
if (other.boat != null)
|
||||
return false;
|
||||
} else if (!boat.equals(other.boat))
|
||||
return false;
|
||||
if (calculatedTime == null) {
|
||||
if (other.calculatedTime != null)
|
||||
return false;
|
||||
} else if (!calculatedTime.equals(other.calculatedTime))
|
||||
return false;
|
||||
if (calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead == null) {
|
||||
if (other.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead != null)
|
||||
return false;
|
||||
} else if (!calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead
|
||||
.equals(other.calculatedTimeAtEstimatedArrivalAtCompetitorFarthestAhead))
|
||||
return false;
|
||||
if (discarded != other.discarded)
|
||||
return false;
|
||||
if (distanceToStarboardSideOfStartLineInMeters == null) {
|
||||
if (other.distanceToStarboardSideOfStartLineInMeters != null)
|
||||
return false;
|
||||
} else if (!distanceToStarboardSideOfStartLineInMeters.equals(other.distanceToStarboardSideOfStartLineInMeters))
|
||||
return false;
|
||||
if (distanceToStartLineAtStartOfRaceInMeters == null) {
|
||||
if (other.distanceToStartLineAtStartOfRaceInMeters != null)
|
||||
return false;
|
||||
} else if (!distanceToStartLineAtStartOfRaceInMeters.equals(other.distanceToStartLineAtStartOfRaceInMeters))
|
||||
return false;
|
||||
if (distanceToStartLineFiveSecondsBeforeStartInMeters == null) {
|
||||
if (other.distanceToStartLineFiveSecondsBeforeStartInMeters != null)
|
||||
return false;
|
||||
} else if (!distanceToStartLineFiveSecondsBeforeStartInMeters
|
||||
.equals(other.distanceToStartLineFiveSecondsBeforeStartInMeters))
|
||||
return false;
|
||||
if (expeditionDataHolder == null) {
|
||||
if (other.expeditionDataHolder != null)
|
||||
return false;
|
||||
} else if (!expeditionDataHolder.equals(other.expeditionDataHolder))
|
||||
return false;
|
||||
if (fleet == null) {
|
||||
if (other.fleet != null)
|
||||
return false;
|
||||
} else if (!fleet.equals(other.fleet))
|
||||
return false;
|
||||
if (gapToLeaderInOwnTime == null) {
|
||||
if (other.gapToLeaderInOwnTime != null)
|
||||
return false;
|
||||
} else if (!gapToLeaderInOwnTime.equals(other.gapToLeaderInOwnTime))
|
||||
return false;
|
||||
if (heel == null) {
|
||||
if (other.heel != null)
|
||||
return false;
|
||||
} else if (!heel.equals(other.heel))
|
||||
return false;
|
||||
if (legDetails == null) {
|
||||
if (other.legDetails != null)
|
||||
return false;
|
||||
} else if (!legDetails.equals(other.legDetails))
|
||||
return false;
|
||||
if (netPoints == null) {
|
||||
if (other.netPoints != null)
|
||||
return false;
|
||||
} else if (!netPoints.equals(other.netPoints))
|
||||
return false;
|
||||
if (pitch == null) {
|
||||
if (other.pitch != null)
|
||||
return false;
|
||||
} else if (!pitch.equals(other.pitch))
|
||||
return false;
|
||||
if (race == null) {
|
||||
if (other.race != null)
|
||||
return false;
|
||||
} else if (!race.equals(other.race))
|
||||
return false;
|
||||
if (reasonForMaxPoints != other.reasonForMaxPoints)
|
||||
return false;
|
||||
if (speedOverGroundAtPassingStartWaypointInKnots == null) {
|
||||
if (other.speedOverGroundAtPassingStartWaypointInKnots != null)
|
||||
return false;
|
||||
} else if (!speedOverGroundAtPassingStartWaypointInKnots
|
||||
.equals(other.speedOverGroundAtPassingStartWaypointInKnots))
|
||||
return false;
|
||||
if (speedOverGroundAtStartOfRaceInKnots == null) {
|
||||
if (other.speedOverGroundAtStartOfRaceInKnots != null)
|
||||
return false;
|
||||
} else if (!speedOverGroundAtStartOfRaceInKnots.equals(other.speedOverGroundAtStartOfRaceInKnots))
|
||||
return false;
|
||||
if (speedOverGroundFiveSecondsBeforeStartInKnots == null) {
|
||||
if (other.speedOverGroundFiveSecondsBeforeStartInKnots != null)
|
||||
return false;
|
||||
} else if (!speedOverGroundFiveSecondsBeforeStartInKnots
|
||||
.equals(other.speedOverGroundFiveSecondsBeforeStartInKnots))
|
||||
return false;
|
||||
if (startTack != other.startTack)
|
||||
return false;
|
||||
if (timeBetweenRaceStartAndCompetitorStartInSeconds == null) {
|
||||
if (other.timeBetweenRaceStartAndCompetitorStartInSeconds != null)
|
||||
return false;
|
||||
} else if (!timeBetweenRaceStartAndCompetitorStartInSeconds
|
||||
.equals(other.timeBetweenRaceStartAndCompetitorStartInSeconds))
|
||||
return false;
|
||||
if (timeSinceLastPositionFixInSeconds == null) {
|
||||
if (other.timeSinceLastPositionFixInSeconds != null)
|
||||
return false;
|
||||
} else if (!timeSinceLastPositionFixInSeconds.equals(other.timeSinceLastPositionFixInSeconds))
|
||||
return false;
|
||||
if (totalPoints == null) {
|
||||
if (other.totalPoints != null)
|
||||
return false;
|
||||
} else if (!totalPoints.equals(other.totalPoints))
|
||||
return false;
|
||||
if (totalPointsCorrected != other.totalPointsCorrected)
|
||||
return false;
|
||||
if (totalPointsUncorrected == null) {
|
||||
if (other.totalPointsUncorrected != null)
|
||||
return false;
|
||||
} else if (!totalPointsUncorrected.equals(other.totalPointsUncorrected))
|
||||
return false;
|
||||
if (windwardDistanceToCompetitorFarthestAheadInMeters == null) {
|
||||
if (other.windwardDistanceToCompetitorFarthestAheadInMeters != null)
|
||||
return false;
|
||||
} else if (!windwardDistanceToCompetitorFarthestAheadInMeters
|
||||
.equals(other.windwardDistanceToCompetitorFarthestAheadInMeters))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to ensure that only one null value needs to be transmitted, if no expedition data exists
|
||||
|
||||
+7
@@ -16,6 +16,7 @@ import com.sap.sse.common.Duration;
|
||||
public class LeaderboardRowDTO implements Serializable {
|
||||
private static final long serialVersionUID = -5421934148931661900L;
|
||||
public CompetitorDTO competitor;
|
||||
public BoatDTO boat;
|
||||
public Map<String, LeaderboardEntryDTO> fieldsByRaceColumnName;
|
||||
public Double carriedPoints;
|
||||
public Double netPoints;
|
||||
@@ -36,6 +37,7 @@ public class LeaderboardRowDTO implements Serializable {
|
||||
int result = 1;
|
||||
result = prime * result + ((carriedPoints == null) ? 0 : carriedPoints.hashCode());
|
||||
result = prime * result + ((competitor == null) ? 0 : competitor.hashCode());
|
||||
result = prime * result + ((boat == null) ? 0 : boat.hashCode());
|
||||
result = prime * result + ((fieldsByRaceColumnName == null) ? 0 : fieldsByRaceColumnName.hashCode());
|
||||
result = prime * result
|
||||
+ ((maximumSpeedOverGroundInKnots == null) ? 0 : maximumSpeedOverGroundInKnots.hashCode());
|
||||
@@ -79,6 +81,11 @@ public class LeaderboardRowDTO implements Serializable {
|
||||
return false;
|
||||
} else if (!competitor.equals(other.competitor))
|
||||
return false;
|
||||
if (boat == null) {
|
||||
if (other.boat != null)
|
||||
return false;
|
||||
} else if (!boat.equals(other.boat))
|
||||
return false;
|
||||
if (fieldsByRaceColumnName == null) {
|
||||
if (other.fieldsByRaceColumnName != null)
|
||||
return false;
|
||||
|
||||
+7
-7
@@ -6,31 +6,31 @@ import java.util.List;
|
||||
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
|
||||
public class PairingListDTO implements Serializable{
|
||||
public class PairingListDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 102220422437194196L;
|
||||
private List<List<List<Pair<CompetitorDTO, BoatDTO>>>> pairingList;
|
||||
private List<List<List<Pair<CompetitorWithoutBoatDTO, BoatDTO>>>> pairingList;
|
||||
private List<String> raceColumnNames;
|
||||
|
||||
public PairingListDTO() { }
|
||||
|
||||
public PairingListDTO(List<List<List<Pair<CompetitorDTO, BoatDTO>>>> result) {
|
||||
public PairingListDTO(List<List<List<Pair<CompetitorWithoutBoatDTO, BoatDTO>>>> result) {
|
||||
this(result, null);
|
||||
}
|
||||
|
||||
public PairingListDTO(List<List<List<Pair<CompetitorDTO, BoatDTO>>>> result, List<String> raceColumnNames) {
|
||||
public PairingListDTO(List<List<List<Pair<CompetitorWithoutBoatDTO, BoatDTO>>>> result, List<String> raceColumnNames) {
|
||||
this.pairingList = result;
|
||||
this.raceColumnNames = raceColumnNames;
|
||||
}
|
||||
|
||||
public List<List<List<Pair<CompetitorDTO, BoatDTO>>>> getPairingList() {
|
||||
public List<List<List<Pair<CompetitorWithoutBoatDTO, BoatDTO>>>> getPairingList() {
|
||||
return pairingList;
|
||||
}
|
||||
|
||||
public List<BoatDTO> getBoats() {
|
||||
List<BoatDTO> boats = new ArrayList<>();
|
||||
for (List<Pair<CompetitorDTO, BoatDTO>> fleet : this.pairingList.get(0)) {
|
||||
for (Pair<CompetitorDTO, BoatDTO> competitorAndBoatPair : fleet) {
|
||||
for (List<Pair<CompetitorWithoutBoatDTO, BoatDTO>> fleet : this.pairingList.get(0)) {
|
||||
for (Pair<CompetitorWithoutBoatDTO, BoatDTO> competitorAndBoatPair : fleet) {
|
||||
if (!boats.contains(competitorAndBoatPair.getB())) {
|
||||
boats.add(competitorAndBoatPair.getB());
|
||||
}
|
||||
|
||||
+7
-5
@@ -18,22 +18,23 @@ public class PairingListTemplateDTO implements Serializable {
|
||||
public PairingListTemplateDTO() { }
|
||||
|
||||
public PairingListTemplateDTO(int competitorCount, int flightMultiplier) {
|
||||
this(0, 0, competitorCount, flightMultiplier, null, 0.0, null);
|
||||
this(0, 0, competitorCount, flightMultiplier, null, 0.0, /* selected flight names */ null);
|
||||
}
|
||||
|
||||
public PairingListTemplateDTO(int competitorCount, int flightMultiplier, int[][] pairingListTemplate, double quality) {
|
||||
this(0, 0, competitorCount, flightMultiplier, pairingListTemplate, quality, null);
|
||||
this(0, 0, competitorCount, flightMultiplier, pairingListTemplate, quality, /* selected flight names */ null);
|
||||
}
|
||||
|
||||
public PairingListTemplateDTO(int competitorCount, int[][] pairingListTemplate, double quality) {
|
||||
this(0, 0, competitorCount, 0, pairingListTemplate, quality, null);
|
||||
this(0, 0, competitorCount, 0, pairingListTemplate, quality, /* selected flight names */ null);
|
||||
}
|
||||
|
||||
public PairingListTemplateDTO(int flightCount, int groupCount, int competitorCount, int flightMultiplier, int[][] pairingListTemplate, double quality) {
|
||||
this(flightCount, groupCount, competitorCount, flightMultiplier, pairingListTemplate, quality, null);
|
||||
this(flightCount, groupCount, competitorCount, flightMultiplier, pairingListTemplate, quality, /* selected flight names */ null);
|
||||
}
|
||||
|
||||
public PairingListTemplateDTO(int flightCount, int groupCount, int competitorCount, int flightMultiplier, int[][] pairingListTemplate, double quality, Iterable<String> selectedFlightNames) {
|
||||
public PairingListTemplateDTO(int flightCount, int groupCount, int competitorCount, int flightMultiplier,
|
||||
int[][] pairingListTemplate, double quality, Iterable<String> selectedFlightNames) {
|
||||
this.flightCount = flightCount;
|
||||
this.groupCount = groupCount;
|
||||
this.competitorCount = competitorCount;
|
||||
@@ -46,6 +47,7 @@ public class PairingListTemplateDTO implements Serializable {
|
||||
public void setFlightCount(int flightCount){
|
||||
this.flightCount=flightCount;
|
||||
}
|
||||
|
||||
public void setGroupCount(int groupCount) {
|
||||
this.groupCount = groupCount;
|
||||
}
|
||||
|
||||
+18
@@ -64,6 +64,18 @@ public class PreviousCompetitorDTOImpl implements CompetitorDTO {
|
||||
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortName() {
|
||||
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
|
||||
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
|
||||
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSailID() {
|
||||
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
|
||||
@@ -76,6 +88,12 @@ public class PreviousCompetitorDTOImpl implements CompetitorDTO {
|
||||
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoat(BoatDTO boat) {
|
||||
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
|
||||
" need to be replaced by an object of "+CompetitorDTOImpl.class.getName()+" after deserialization");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
throw new RuntimeException("Internal error. Objects of type "+PreviousCompetitorDTOImpl.class.getName()+
|
||||
|
||||
+2
@@ -26,11 +26,13 @@ public class DeviceMappingConstants {
|
||||
public static final String URL_EVENT_ID = "event_id";
|
||||
public static final String URL_LEADERBOARD_NAME = "leaderboard_name";
|
||||
public static final String URL_COMPETITOR_ID_AS_STRING = "competitor_id";
|
||||
public static final String URL_BOAT_ID_AS_STRING = "boat_id";
|
||||
public static final String URL_MARK_ID_AS_STRING = "mark_id";
|
||||
public static final String URL_FROM_MILLIS = "from_millis";
|
||||
public static final String URL_TO_MILLIS = "to_millis";
|
||||
|
||||
public static final String JSON_COMPETITOR_ID_AS_STRING = "competitorId";
|
||||
public static final String JSON_BOAT_ID_AS_STRING = "boatId";
|
||||
public static final String JSON_MARK_ID_AS_STRING = "markId";
|
||||
public static final String JSON_DEVICE_UUID = "deviceUuid";
|
||||
public static final String JSON_DEVICE_TYPE = "deviceType";
|
||||
|
||||
+1
@@ -12,6 +12,7 @@ public enum Permission implements com.sap.sse.security.shared.Permission {
|
||||
SHOW_TRACKED_RACES,
|
||||
MANAGE_RACELOG_TRACKING,
|
||||
MANAGE_ALL_COMPETITORS,
|
||||
MANAGE_ALL_BOATS,
|
||||
MANAGE_COURSE_LAYOUT,
|
||||
MANAGE_WIND,
|
||||
MANAGE_IGTIMI_ACCOUNTS,
|
||||
|
||||
+1
@@ -23,6 +23,7 @@ public class SailingPermissionsForRoleProvider implements PermissionsForRoleProv
|
||||
|
||||
// AdminConsole:
|
||||
Permission.MANAGE_ALL_COMPETITORS,
|
||||
Permission.MANAGE_ALL_BOATS,
|
||||
Permission.MANAGE_COURSE_LAYOUT,
|
||||
Permission.MANAGE_DEVICE_CONFIGURATION,
|
||||
Permission.MANAGE_EVENTS,
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.sap.sailing.domain.common.tracking.impl;
|
||||
|
||||
/**
|
||||
* Used to assemble a compatible JSON string by themselves, using the constants from here.The field identified by this
|
||||
* name tells the fully-qualified class name from which the value of the field identified by {@link #FIELD_ID} has been
|
||||
* created. When deserializing, the ID needs to be re-constructed as an instance of that type.
|
||||
*/
|
||||
public class BoatJsonConstants {
|
||||
public static final String FIELD_ID = "id";
|
||||
public static final String FIELD_NAME = "name";
|
||||
public static final String FIELD_SAIL_ID = "sailID";
|
||||
public static final String FIELD_COLOR = "color";
|
||||
public static final String FIELD_BOAT_CLASS_NAME = "boatClassName";
|
||||
}
|
||||
+3
@@ -8,6 +8,7 @@ package com.sap.sailing.domain.common.tracking.impl;
|
||||
public class CompetitorJsonConstants {
|
||||
public static final String FIELD_ID = "id";
|
||||
public static final String FIELD_NAME = "name";
|
||||
public static final String FIELD_SHORT_NAME = "shortName";
|
||||
public static final String FIELD_SAIL_ID = "sailID";
|
||||
public static final String FIELD_NATIONALITY = "nationality";
|
||||
public static final String FIELD_COUNTRY_CODE = "countryCode";
|
||||
@@ -20,6 +21,8 @@ public class CompetitorJsonConstants {
|
||||
public static final String FIELD_NATIONALITY_ISO3 = "nationalityISO3";
|
||||
public static final String FIELD_TEAM = "team";
|
||||
public static final String FIELD_BOAT = "boat";
|
||||
public static final String FIELD_BOAT_ID_TYPE = "boatidtype";
|
||||
public static final String FIELD_BOAT_ID = "boatId";
|
||||
public static final String FIELD_DISPLAY_COLOR = "displayColor";
|
||||
public static final String FIELD_EMAIL = "email";
|
||||
public static final String FIELD_SEARCHTAG = "searchTag";
|
||||
|
||||
+17
-3
@@ -12,8 +12,10 @@ import java.util.function.Consumer;
|
||||
import com.mongodb.DBObject;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.anniversary.DetailedRaceInfo;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
@@ -129,13 +131,25 @@ public interface DomainObjectFactory {
|
||||
RaceLog loadRaceLog(RaceLogIdentifier identifier);
|
||||
|
||||
RegattaLog loadRegattaLog(RegattaLikeIdentifier identifier);
|
||||
|
||||
|
||||
/**
|
||||
* Loads all competitors, and resolves them via the domain factory.
|
||||
* @return
|
||||
* Migrates the old COMPETITORS collection and the new BOATS collection.
|
||||
* The old COLLECTION is will be renamed to COMPETITORS_BAK for deveopment and test purposes
|
||||
* @return a collection of the old type where all competitors contain their boats or null if migration was not required.
|
||||
*/
|
||||
Iterable<CompetitorWithBoat> migrateLegacyCompetitorsIfRequired();
|
||||
|
||||
/**
|
||||
* Loads all competitors (with and without embedded boats) and resolves them via the domain factory.
|
||||
* Returns a collection of {@link Competitor} or {@link CompetitorWithBoat} objects.
|
||||
*/
|
||||
Collection<Competitor> loadAllCompetitors();
|
||||
|
||||
/**
|
||||
* Loads all boats and resolves them via the domain factory.
|
||||
*/
|
||||
Collection<Boat> loadAllBoats();
|
||||
|
||||
DomainFactory getBaseDomainFactory();
|
||||
|
||||
Iterable<Entry<DeviceConfigurationMatcher, DeviceConfiguration>> loadAllDeviceConfigurations();
|
||||
|
||||
+22
-3
@@ -8,6 +8,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import com.mongodb.DB;
|
||||
import com.mongodb.DBObject;
|
||||
import com.sap.sailing.domain.anniversary.DetailedRaceInfo;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
@@ -122,9 +123,9 @@ public interface MongoObjectFactory {
|
||||
void storeRegattaForRaceID(String id, Regatta regatta);
|
||||
|
||||
void removeRegattaForRaceID(String raceIDAsString, Regatta regatta);
|
||||
|
||||
|
||||
/**
|
||||
* Stores a competitor, including the team and boat. This should not be done for competitors for which
|
||||
* Stores a competitor. This should not be done for competitors for which
|
||||
* the master data is supplied by other systems, such as TracTrac, but rather for smartphone tracking,
|
||||
* where this data is otherwise not recoverable.
|
||||
* @param competitor the competitor to store/update in the database
|
||||
@@ -135,11 +136,29 @@ public interface MongoObjectFactory {
|
||||
* Like {@link #storeCompetitor(Competitor)}, but for a collection of competitors that are all
|
||||
* expected to be new, having a unique {@link Competitor#getId() ID}.
|
||||
*/
|
||||
void storeCompetitors(Iterable<Competitor> competitors);
|
||||
void storeCompetitors(Iterable<? extends Competitor> competitors);
|
||||
|
||||
void removeAllCompetitors();
|
||||
|
||||
void removeCompetitor(Competitor competitor);
|
||||
|
||||
/**
|
||||
* Stores a boat. This should not be done for boats for which
|
||||
* the master data is supplied by other systems, such as TracTrac, but rather for smartphone tracking,
|
||||
* where this data is otherwise not recoverable.
|
||||
* @param boat the boat to store/update in the database
|
||||
*/
|
||||
void storeBoat(Boat boat);
|
||||
|
||||
/**
|
||||
* Like {@link #storeBoat(Boat)}, but for a collection of boats that are all
|
||||
* expected to be new, having a unique {@link Boat#getId() ID}.
|
||||
*/
|
||||
void storeBoats(Iterable<Boat> boats);
|
||||
|
||||
void removeAllBoats();
|
||||
|
||||
void removeBoat(Boat boat);
|
||||
|
||||
DB getDatabase();
|
||||
|
||||
|
||||
+16
-5
@@ -68,16 +68,27 @@ public enum CollectionNames {
|
||||
*/
|
||||
REGATTA_FOR_RACE_ID,
|
||||
|
||||
/**
|
||||
* Stores the race log events for a tracked race.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Stores competitors for smartphone tracking.
|
||||
* Legacy store for competitors before implementation of bug2822
|
||||
* Contains the old competitors with contained boats.
|
||||
*/
|
||||
COMPETITORS_BAK,
|
||||
|
||||
/**
|
||||
* Stores competitors with or without boat references.
|
||||
*/
|
||||
COMPETITORS,
|
||||
|
||||
|
||||
/**
|
||||
* Stores boats.
|
||||
*/
|
||||
BOATS,
|
||||
|
||||
/**
|
||||
* Stores the race log events for a tracked race.
|
||||
*/
|
||||
RACE_LOGS,
|
||||
|
||||
REGATTA_LOGS,
|
||||
|
||||
+828
-436
File diff suppressed because it is too large.
Load diff
+3
-2
@@ -38,6 +38,7 @@ public enum FieldNames {
|
||||
REGATTA_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS,
|
||||
REGATTA_USE_START_TIME_INFERENCE,
|
||||
REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES,
|
||||
REGATTA_CAN_BOATS_OF_COMPETITORS_CHANGE_PER_RACE,
|
||||
SERIES_NAME,
|
||||
SERIES_IS_MEDAL,
|
||||
SERIES_IS_FLEETS_CAN_RUN_IN_PARALLEL,
|
||||
@@ -102,7 +103,7 @@ public enum FieldNames {
|
||||
RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME, RACE_LOG_GOLF_DOWN_TIME, RACE_LOG_START_PROCEDURE_TYPE,
|
||||
RACE_LOG_PROTEST_START_TIME, RACE_LOG_PROTEST_END_TIME, RACE_LOG_COURSE_DESIGN_NAME, RACE_LOG_REVOKED_EVENT_ID, RACE_LOG_REVOKED_EVENT_TYPE,
|
||||
RACE_LOG_REVOKED_EVENT_SHORT_INFO, RACE_LOG_REVOKED_REASON, RACE_LOG_DEVICE_MAPPING_EVENT_ID,
|
||||
RACE_LOG_CLOSING_TIMEPOINT, TIMEPOINT_OF_FIXED_MARKPASSING, INDEX_OF_PASSED_WAYPOINT,INDEX_OF_FIRST_SUPPRESSED_WAYPOINT, MARK, RACE_LOG_COMPETITOR_ID,
|
||||
RACE_LOG_CLOSING_TIMEPOINT, TIMEPOINT_OF_FIXED_MARKPASSING, INDEX_OF_PASSED_WAYPOINT,INDEX_OF_FIRST_SUPPRESSED_WAYPOINT, MARK, RACE_LOG_COMPETITOR_ID, RACE_LOG_BOAT_ID,
|
||||
RACE_LOG_DEPDENDENT_ON_FLEET, RACE_LOG_DEPDENDENT_ON_RACECOLUMN, RACE_LOG_DEPDENDENT_ON_REGATTALIKE,
|
||||
RACE_LOG_START_TIME_DIFFERENCE_IN_MS, RACE_LOG_FINISHING_TIME_AS_MILLIS,
|
||||
/** @deprecated Replaced by {@link #REGATTA_LOG_FROM}; auto-migration from race log device mappings to regatta log is implemented */ @Deprecated RACE_LOG_FROM,
|
||||
@@ -118,7 +119,7 @@ public enum FieldNames {
|
||||
// did not reuse RACE_LOG* types, as this would require handling old versions of all events
|
||||
REGATTA_LOG_IDENTIFIER_TYPE, REGATTA_LOG_IDENTIFIER_NAME, REGATTA_LOG_EVENT_ID, REGATTA_LOG_EVENT_CREATED_AT, REGATTA_LOG_EVENT_AUTHOR_NAME,
|
||||
REGATTA_LOG_EVENT_AUTHOR_PRIORITY, REGATTA_LOG_EVENT_CLASS, REGATTA_LOG_REVOKED_EVENT_ID, REGATTA_LOG_REVOKED_EVENT_TYPE, REGATTA_LOG_REVOKED_EVENT_SHORT_INFO,
|
||||
REGATTA_LOG_REVOKED_REASON, REGATTA_LOG_COMPETITOR_ID, REGATTA_LOG_DEVICE_MAPPING_EVENT_ID, REGATTA_LOG_CLOSING_TIMEPOINT,
|
||||
REGATTA_LOG_REVOKED_REASON, REGATTA_LOG_COMPETITOR_ID, REGATTA_LOG_BOAT_ID, REGATTA_LOG_DEVICE_MAPPING_EVENT_ID, REGATTA_LOG_CLOSING_TIMEPOINT,
|
||||
REGATTA_LOG_FROM, REGATTA_LOG_TO, REGATTA_LOG_EVENT, REGATTA_LOG_MARK,
|
||||
|
||||
// remote server reference fields
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package com.sap.sailing.domain.persistence.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.MigratableRegatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.racelog.RaceLogStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetricConstructor;
|
||||
import com.sap.sailing.domain.regattalog.RegattaLogStore;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class MigratableRegattaImpl extends RegattaImpl implements MigratableRegatta {
|
||||
private static final long serialVersionUID = -3545488249832218320L;
|
||||
private static final Logger logger = Logger.getLogger(MigratableRegattaImpl.class.getName());
|
||||
|
||||
/**
|
||||
* To be used for storing a migrated regatta
|
||||
*/
|
||||
private transient final MongoObjectFactory mongoObjectFactory;
|
||||
|
||||
public <S extends Series> MigratableRegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, String name,
|
||||
BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate,
|
||||
Iterable<S> series, boolean persistent, ScoringScheme scoringScheme, Serializable id, CourseArea courseArea,
|
||||
Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
|
||||
boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor, MongoObjectFactory mongoObjectFactory) {
|
||||
super(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, startDate, endDate, series,
|
||||
persistent, scoringScheme, id, courseArea, buoyZoneRadiusInHullLengths, useStartTimeInference,
|
||||
controlTrackingFromStartAndFinishTimes, rankingMetricConstructor);
|
||||
this.mongoObjectFactory = mongoObjectFactory;
|
||||
mongoObjectFactory.storeRegatta(this); // make sure the canBoatsOfCompetitorsChangePerRace flag makes it into the DB
|
||||
}
|
||||
|
||||
public synchronized void migrateCanBoatsOfCompetitorsChangePerRace() {
|
||||
// It should not be possible to call this after races have been already added to this regatta.
|
||||
assert !canBoatsOfCompetitorsChangePerRace() && Util.size(getAllRaces()) == 0;
|
||||
super.setCanBoatsOfCompetitorsChangePerRace(true);
|
||||
if (mongoObjectFactory != null) {
|
||||
logger.log(Level.INFO, "Bug2822 DB-Migration: Store migrated regatta '" + getName() + "' having now canBoatsOfCompetitorsChangePerRace=true.");
|
||||
mongoObjectFactory.storeRegatta(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
+123
-4
@@ -55,16 +55,21 @@ import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogUseCompetitorsFro
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnTimeFactorEvent;
|
||||
import com.sap.sailing.domain.anniversary.DetailedRaceInfo;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
import com.sap.sailing.domain.base.ControlPointWithTwoMarks;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
@@ -116,7 +121,9 @@ import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.TrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.server.gateway.serialization.JsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.BoatJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.CompetitorJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.CompetitorWithBoatRefJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.DeviceConfigurationJsonSerializer;
|
||||
import com.sap.sailing.server.gateway.serialization.impl.RegattaConfigurationJsonSerializer;
|
||||
import com.sap.sse.common.Duration;
|
||||
@@ -135,7 +142,9 @@ import com.sap.sse.shared.media.VideoDescriptor;
|
||||
public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
private static Logger logger = Logger.getLogger(MongoObjectFactoryImpl.class.getName());
|
||||
private final DB database;
|
||||
private final CompetitorWithBoatRefJsonSerializer competitorWithBoatRefSerializer = CompetitorWithBoatRefJsonSerializer.create();
|
||||
private final CompetitorJsonSerializer competitorSerializer = CompetitorJsonSerializer.create();
|
||||
private final BoatJsonSerializer boatSerializer = BoatJsonSerializer.create();
|
||||
private final TypeBasedServiceFinder<DeviceIdentifierMongoHandler> deviceIdentifierServiceFinder;
|
||||
private final TypeBasedServiceFinder<RaceTrackingConnectivityParametersHandler> raceTrackingConnectivityParamsServiceFinder;
|
||||
|
||||
@@ -706,6 +715,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
dbRegatta.put(FieldNames.REGATTA_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS.name(), regatta.getBuoyZoneRadiusInHullLengths());
|
||||
dbRegatta.put(FieldNames.REGATTA_USE_START_TIME_INFERENCE.name(), regatta.useStartTimeInference());
|
||||
dbRegatta.put(FieldNames.REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES.name(), regatta.isControlTrackingFromStartAndFinishTimes());
|
||||
dbRegatta.put(FieldNames.REGATTA_CAN_BOATS_OF_COMPETITORS_CHANGE_PER_RACE.name(), regatta.canBoatsOfCompetitorsChangePerRace());
|
||||
dbRegatta.put(FieldNames.REGATTA_RANKING_METRIC.name(), storeRankingMetric(regatta));
|
||||
boolean success = false;
|
||||
final int MAX_TRIES = 3;
|
||||
@@ -1067,6 +1077,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
storeRaceLogEventProperties(event, result);
|
||||
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogRegisterCompetitorEvent.class.getSimpleName());
|
||||
result.put(FieldNames.RACE_LOG_COMPETITOR_ID.name(), event.getCompetitor().getId());
|
||||
result.put(FieldNames.RACE_LOG_BOAT_ID.name(), event.getBoat().getId());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1126,7 +1137,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
storeTimePoint(event.getCreatedAt(), result, FieldNames.RACE_LOG_EVENT_CREATED_AT);
|
||||
result.put(FieldNames.RACE_LOG_EVENT_ID.name(), event.getId());
|
||||
result.put(FieldNames.RACE_LOG_EVENT_PASS_ID.name(), event.getPassId());
|
||||
result.put(FieldNames.RACE_LOG_EVENT_INVOLVED_BOATS.name(), storeInvolvedBoatsForRaceLogEvent(event.getInvolvedBoats()));
|
||||
result.put(FieldNames.RACE_LOG_EVENT_INVOLVED_BOATS.name(), storeInvolvedBoatsForRaceLogEvent(event.getInvolvedCompetitors()));
|
||||
storeRaceLogEventAuthor(result, event.getAuthor());
|
||||
}
|
||||
|
||||
@@ -1290,8 +1301,17 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
}
|
||||
return passing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeCompetitor(Competitor competitor) {
|
||||
if (competitor.hasBoat()) {
|
||||
storeCompetitorWithBoat((CompetitorWithBoat) competitor);
|
||||
} else {
|
||||
storeCompetitorWithoutBoat(competitor);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeCompetitorWithoutBoat(Competitor competitor) {
|
||||
DBCollection collection = database.getCollection(CollectionNames.COMPETITORS.name());
|
||||
JSONObject json = competitorSerializer.serialize(competitor);
|
||||
DBObject query = (DBObject) JSON.parse(CompetitorJsonSerializer.getCompetitorIdQuery(competitor).toString());
|
||||
@@ -1299,9 +1319,33 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
collection.update(query, entry, /* upsrt */true, /* multi */false, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
private void storeCompetitorWithBoat(CompetitorWithBoat competitor) {
|
||||
DBCollection collection = database.getCollection(CollectionNames.COMPETITORS.name());
|
||||
JSONObject json = competitorWithBoatRefSerializer.serialize(competitor);
|
||||
DBObject query = (DBObject) JSON.parse(CompetitorJsonSerializer.getCompetitorIdQuery(competitor).toString());
|
||||
DBObject entry = (DBObject) JSON.parse(json.toString());
|
||||
collection.update(query, entry, /* upsrt */true, /* multi */false, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeCompetitors(Iterable<Competitor> competitors) {
|
||||
public void storeCompetitors(Iterable<? extends Competitor> competitors) {
|
||||
if (competitors != null && !Util.isEmpty(competitors)) {
|
||||
List<Competitor> competitorsWithoutBoat = new ArrayList<>();
|
||||
List<CompetitorWithBoat> competitorsWithBoat = new ArrayList<>();
|
||||
for (Competitor competitor : competitors) {
|
||||
if (competitor.hasBoat()) {
|
||||
competitorsWithBoat.add((CompetitorWithBoat) competitor);
|
||||
} else {
|
||||
competitorsWithoutBoat.add(competitor);
|
||||
}
|
||||
}
|
||||
storeCompetitorsWithBoat(competitorsWithBoat);
|
||||
storeCompetitorsWithoutBoat(competitorsWithoutBoat);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeCompetitorsWithoutBoat(Iterable<Competitor> competitors) {
|
||||
if (!Util.isEmpty(competitors)) {
|
||||
DBCollection collection = database.getCollection(CollectionNames.COMPETITORS.name());
|
||||
List<DBObject> competitorsDB = new ArrayList<>();
|
||||
for (Competitor competitor : competitors) {
|
||||
@@ -1313,9 +1357,22 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private void storeCompetitorsWithBoat(Iterable<CompetitorWithBoat> competitors) {
|
||||
if (!Util.isEmpty(competitors)) {
|
||||
DBCollection collection = database.getCollection(CollectionNames.COMPETITORS.name());
|
||||
List<DBObject> competitorsDB = new ArrayList<>();
|
||||
for (CompetitorWithBoat competitor : competitors) {
|
||||
JSONObject json = competitorWithBoatRefSerializer.serialize(competitor);
|
||||
DBObject entry = (DBObject) JSON.parse(json.toString());
|
||||
competitorsDB.add(entry);
|
||||
}
|
||||
collection.insert(competitorsDB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllCompetitors() {
|
||||
logger.info("Removing all persistent competitor info");
|
||||
logger.info("Removing all persistent competitors");
|
||||
DBCollection collection = database.getCollection(CollectionNames.COMPETITORS.name());
|
||||
collection.drop();
|
||||
}
|
||||
@@ -1327,7 +1384,45 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
DBObject query = (DBObject) JSON.parse(CompetitorJsonSerializer.getCompetitorIdQuery(competitor).toString());
|
||||
collection.remove(query, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void storeBoat(Boat boat) {
|
||||
DBCollection collection = database.getCollection(CollectionNames.BOATS.name());
|
||||
JSONObject json = boatSerializer.serialize(boat);
|
||||
DBObject query = (DBObject) JSON.parse(BoatJsonSerializer.getBoatIdQuery(boat).toString());
|
||||
DBObject entry = (DBObject) JSON.parse(json.toString());
|
||||
collection.update(query, entry, /* upsrt */true, /* multi */false, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeBoats(Iterable<Boat> boats) {
|
||||
if (boats != null && !Util.isEmpty(boats)) {
|
||||
DBCollection collection = database.getCollection(CollectionNames.BOATS.name());
|
||||
List<DBObject> boatsDB = new ArrayList<>();
|
||||
for (Boat boat : boats) {
|
||||
JSONObject json = boatSerializer.serialize(boat);
|
||||
DBObject entry = (DBObject) JSON.parse(json.toString());
|
||||
boatsDB.add(entry);
|
||||
}
|
||||
collection.insert(boatsDB);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllBoats() {
|
||||
logger.info("Removing all persistent boats");
|
||||
DBCollection collection = database.getCollection(CollectionNames.BOATS.name());
|
||||
collection.drop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBoat(Boat boat) {
|
||||
logger.info("Removing persistent boat "+boat.getName()+" with ID "+boat.getId());
|
||||
DBCollection collection = database.getCollection(CollectionNames.BOATS.name());
|
||||
DBObject query = (DBObject) JSON.parse(BoatJsonSerializer.getBoatIdQuery(boat).toString());
|
||||
collection.remove(query, WriteConcern.SAFE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeDeviceConfiguration(DeviceConfigurationMatcher matcher, DeviceConfiguration configuration) {
|
||||
DBCollection configurationsCollections = database.getCollection(CollectionNames.CONFIGURATIONS.name());
|
||||
@@ -1463,6 +1558,14 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
result.put(FieldNames.COMPETITOR_ID.name(), event.getMappedTo().getId());
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogDeviceBoatMappingEvent event) {
|
||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogDeviceBoatMappingEvent.class.getSimpleName());
|
||||
storeDeviceMappingEvent(event, result, FieldNames.REGATTA_LOG_FROM, FieldNames.REGATTA_LOG_TO);
|
||||
result.put(FieldNames.RACE_LOG_BOAT_ID.name(), event.getMappedTo().getId());
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId,
|
||||
RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
@@ -1472,6 +1575,15 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
result.put(FieldNames.COMPETITOR_ID.name(), event.getMappedTo().getId());
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId,
|
||||
RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), event.getClass().getSimpleName());
|
||||
storeDeviceMappingEvent(event, result, FieldNames.REGATTA_LOG_FROM, FieldNames.REGATTA_LOG_TO);
|
||||
result.put(FieldNames.RACE_LOG_BOAT_ID.name(), event.getMappedTo().getId());
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogDeviceMarkMappingEvent event) {
|
||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||
@@ -1491,6 +1603,13 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogRegisterBoatEvent event) {
|
||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogRegisterBoatEvent.class.getSimpleName());
|
||||
result.put(FieldNames.REGATTA_LOG_BOAT_ID.name(), event.getBoat().getId());
|
||||
storeRegattaLogEvent(regattaLikeId, result);
|
||||
}
|
||||
|
||||
public void storeRegattaLogEvent(RegattaLikeIdentifier regattaLikeId, RegattaLogRegisterCompetitorEvent event) {
|
||||
DBObject result = createBasicRegattaLogEventDBObject(event);
|
||||
result.put(FieldNames.REGATTA_LOG_EVENT_CLASS.name(), RegattaLogRegisterCompetitorEvent.class.getSimpleName());
|
||||
|
||||
+19
@@ -5,9 +5,12 @@ import java.util.logging.Logger;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
||||
@@ -43,15 +46,31 @@ public class MongoRegattaLogStoreVisitor implements RegattaLogEventVisitor {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterBoatEvent event) {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterCompetitorEvent event) {
|
||||
mongoObjectFactory.storeRegattaLogEvent(regattaLikeIdentifier, event);
|
||||
|
||||
@@ -14,6 +14,7 @@ Require-Bundle: org.junit;bundle-version="4.8.2",
|
||||
org.mongodb.mongo-java-driver;bundle-version="2.13.0",
|
||||
com.sap.sse.common
|
||||
Import-Package: com.sap.sailing.domain.abstractlog.regatta.events,
|
||||
com.sap.sailing.domain.base,
|
||||
com.sap.sailing.domain.persistence.impl,
|
||||
com.sap.sailing.domain.persistence.racelog.tracking.impl,
|
||||
com.sap.sailing.domain.tractracadapter,
|
||||
|
||||
+4
-1
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMa
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
@@ -59,7 +60,9 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
|
||||
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
|
||||
protected RegattaLog regattaLog;
|
||||
protected SensorFixStore store;
|
||||
protected final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
protected final Boat boat = DomainFactory.INSTANCE.getOrCreateBoat("boat", "boat", boatClass, "GER 234", null);
|
||||
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
|
||||
|
||||
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
||||
@@ -121,7 +124,7 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
|
||||
protected DynamicTrackedRaceImpl createDynamicTrackedRace(BoatClass boatClass, RaceDefinition raceDefinition) {
|
||||
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
return new DynamicTrackedRaceImpl(regatta, raceDefinition, Collections.<Sideline> emptyList(),
|
||||
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
|
||||
mock(RaceLogResolver.class));
|
||||
|
||||
+15
-6
@@ -28,12 +28,18 @@ import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogUseCompetito
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.DomainFactory;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.base.Series;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.DynamicBoat;
|
||||
import com.sap.sailing.domain.base.impl.FleetImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.SeriesImpl;
|
||||
@@ -67,7 +73,7 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
private RacingEventService service;
|
||||
|
||||
private final static BoatClass boatClass = new BoatClassImpl("505", /* typicallyStartsUpwind */ true);
|
||||
private final Fleet fleet = new FleetImpl("fleet");
|
||||
private final String columnName = "column";
|
||||
private RegattaLeaderboard leaderboard;
|
||||
@@ -89,7 +95,8 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
Series series = new SeriesImpl("series", /* isMedal */ false, /* isFleetsCanRunInParallel */ true, Collections.singletonList(fleet), Collections.emptySet(),
|
||||
service);
|
||||
regatta = service.createRegatta(RegattaImpl.getDefaultName("regatta", "Laser"), "Laser",
|
||||
/* startDate */null, /* endDate */null, UUID.randomUUID(), Collections.<Series> singletonList(series), /* persistent */ true,
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
|
||||
UUID.randomUUID(), Collections.<Series> singletonList(series), /* persistent */ true,
|
||||
new HighPoint(), UUID.randomUUID(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
|
||||
series.addRaceColumn(columnName, /* trackedRegattaRegistry */null);
|
||||
leaderboard = service.addRegattaLeaderboard(regatta.getRegattaIdentifier(), "RegattaLeaderboard", new int[] {});
|
||||
@@ -184,13 +191,14 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
assertFalse(raceLog.isEmpty());
|
||||
|
||||
// add a mapping and one fix in, one out of mapping
|
||||
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null, null, null,
|
||||
Boat boat1 = new BoatImpl("id12345", "boat1", boatClass, /* sailID */ null);
|
||||
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", "c", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
|
||||
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, 0, comp1, dev1, t(0), t(10)));
|
||||
addFixes0(dev1);
|
||||
raceLog.add(new RaceLogUseCompetitorsFromRaceLogEventImpl(t(), author, t(), UUID.randomUUID(), 0));
|
||||
raceLog.add(new RaceLogRegisterCompetitorEventImpl(t(), author, 0, comp1));
|
||||
raceLog.add(new RaceLogRegisterCompetitorEventImpl(t(), author, 0, comp1, boat1));
|
||||
raceLog.add(new RaceLogStartOfTrackingEventImpl(t(0), author, /* passId */ 0));
|
||||
// start tracking
|
||||
trackRace(column);
|
||||
@@ -281,8 +289,9 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
adapter.denoteRaceForRaceLogTracking(service, leaderboard, column, fleet, "race");
|
||||
|
||||
// add a mapping and one fix in, one out of mapping
|
||||
Competitor comp1 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp1", "comp1", null, null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Boat boat1 = new BoatImpl("id12345", "boat1", boatClass, /* sailID */ null);
|
||||
CompetitorWithBoat comp1 = DomainFactory.INSTANCE.getOrCreateCompetitorWithBoat("comp1", "comp1", "c1", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) boat1);
|
||||
DeviceIdentifier dev1 = new SmartphoneImeiIdentifier("dev1");
|
||||
regattaLog.add(new RegattaLogDeviceCompetitorMappingEventImpl(t(), t(), author, UUID.randomUUID(), comp1, dev1,
|
||||
t(0), t(10)));
|
||||
|
||||
+11
-5
@@ -6,6 +6,8 @@ import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -19,6 +21,7 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
@@ -66,11 +69,12 @@ public class RaceLogFixTrackerManagerTest {
|
||||
protected RaceLog raceLog2;
|
||||
protected RegattaLog regattaLog;
|
||||
protected SensorFixStore store;
|
||||
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null,
|
||||
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", "c2", null, null, null,
|
||||
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
protected final Boat boat = DomainFactory.INSTANCE.getOrCreateBoat("boat", "boat", boatClass, "USA 123", null);
|
||||
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
|
||||
protected final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
|
||||
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
||||
private DynamicTrackedRace trackedRace;
|
||||
@@ -92,10 +96,12 @@ public class RaceLogFixTrackerManagerTest {
|
||||
|
||||
Course course = new CourseImpl("course",
|
||||
Arrays.asList(new Waypoint[] { new WaypointImpl(mark), new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp));
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
|
||||
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
|
||||
mock(RaceLogResolver.class));
|
||||
|
||||
+29
-20
@@ -12,8 +12,10 @@ import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
|
||||
@@ -42,6 +44,7 @@ import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMa
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRevokeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
@@ -120,15 +123,17 @@ public class SensorFixStoreAndLoadTest {
|
||||
protected RaceLog raceLog;
|
||||
protected RegattaLog regattaLog;
|
||||
protected SensorFixStore store;
|
||||
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null,
|
||||
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
protected final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null,
|
||||
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
private final Competitor compNotPartOfRace = DomainFactory.INSTANCE.getOrCreateCompetitor("comp3", "comp3", null, null, null,
|
||||
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
protected final Competitor comp = DomainFactory.INSTANCE.getOrCreateCompetitor("comp", "comp", null, null, null, null,
|
||||
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
protected final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null,
|
||||
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowanceInSecondsPerNauticalMile */ null, null);
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
protected final Boat boat1 = DomainFactory.INSTANCE.getOrCreateBoat("Boat1", "Boat1", boatClass, "GER 1", null);
|
||||
protected final Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("Boat2", "Boat2", boatClass, "GER 2", null);
|
||||
private final Competitor compNotPartOfRace = DomainFactory.INSTANCE.getOrCreateCompetitor("comp3", "comp3", null, null, null, null,
|
||||
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
protected final Mark mark = DomainFactory.INSTANCE.getOrCreateMark("mark");
|
||||
protected final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
|
||||
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
||||
private DynamicTrackedRace trackedRace;
|
||||
@@ -156,10 +161,13 @@ public class SensorFixStoreAndLoadTest {
|
||||
new MillisecondsTimePoint(1), 0, mark2));
|
||||
Course course = new CourseImpl("course",
|
||||
Arrays.asList(new Waypoint[] { new WaypointImpl(mark), new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp, comp2));
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat1);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
|
||||
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
|
||||
mock(RaceLogResolver.class));
|
||||
@@ -412,7 +420,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP2, FIX_RIDE_HEIGHT2.getMeters()));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP3, FIX_RIDE_HEIGHT3.getMeters()));
|
||||
}
|
||||
|
||||
|
||||
private void addMoreBravoFixes() {
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP + 1, FIX_RIDE_HEIGHT.getMeters()));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP2 + 1, FIX_RIDE_HEIGHT2.getMeters()));
|
||||
@@ -428,10 +436,10 @@ public class SensorFixStoreAndLoadTest {
|
||||
@Override
|
||||
public <FixT extends Timed, TrackT extends DynamicTrack<FixT>> SensorFixMapper<FixT, TrackT, Competitor> createCompetitorMapper(
|
||||
Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
|
||||
if (bravoDataFixMapper.isResponsibleFor(eventType)) {
|
||||
if(bravoDataFixMapper.isResponsibleFor(eventType)) {
|
||||
return (SensorFixMapper) bravoDataFixMapper;
|
||||
}
|
||||
if (testDataFixMapper.isResponsibleFor(eventType)) {
|
||||
if(testDataFixMapper.isResponsibleFor(eventType)) {
|
||||
return (SensorFixMapper) testDataFixMapper;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown event type");
|
||||
@@ -442,7 +450,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
protected void testNumberOfRawFixes(Track<?> track, long expected) {
|
||||
if (expected == 0) {
|
||||
if (track != null) {
|
||||
track.lockForRead();
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertTrue(size(track.getRawFixes()) == 0);
|
||||
} finally {
|
||||
@@ -452,10 +460,10 @@ public class SensorFixStoreAndLoadTest {
|
||||
} else {
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(expected, size(track.getRawFixes()));
|
||||
assertEquals(expected, size(track.getRawFixes()));
|
||||
} finally {
|
||||
track.unlockAfterRead();
|
||||
}
|
||||
track.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,6 +571,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
implements RegattaLogDeviceCompetitorSensorDataMappingEvent {
|
||||
private static final long serialVersionUID = -14940305448048753L;
|
||||
|
||||
|
||||
public RegattaLogDeviceCompetitorTestMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
@@ -618,7 +627,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
assertNull(trackedRace.getSensorTrack(compNotPartOfRace, BravoFixTrack.TRACK_NAME));
|
||||
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/** Test for changes of bug 4044 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4044 */
|
||||
public void testThatNoSensorFixesAreLoadedAsLongAsStartOfTrackingIsNull() throws InterruptedException {
|
||||
@@ -637,7 +646,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
testNumberOfRawFixes(trackedRace.getSensorTrack(comp, BravoFixTrack.TRACK_NAME), 3);
|
||||
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/** Test for changes of bug 4044 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4044 */
|
||||
public void testThatNoSensorFixesAreRecordedAsWhenStartOfTrackingIsNull() throws InterruptedException {
|
||||
@@ -794,7 +803,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
|
||||
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/** Test for bug 4125 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4125 */
|
||||
public void testThatLoadingStateIsTriggeredWhenAddingMapping() throws InterruptedException {
|
||||
@@ -810,7 +819,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
fixLoaderAndTracker.stop(true, /* willBeRemoved */ false);
|
||||
statusTransitionListener.assertTransitions(TrackedRaceStatusEnum.PREPARED, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.LOADING, TrackedRaceStatusEnum.TRACKING, TrackedRaceStatusEnum.FINISHED);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/** Test for bug 4125 - https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=4125 */
|
||||
public void testThatLoadingStateIsTriggeredWhenStartOfTrackingIsSet() throws InterruptedException {
|
||||
|
||||
+21
-4
@@ -2,19 +2,24 @@ package com.sap.sailing.domain.racelogtracking.test.impl;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.Timeout;
|
||||
|
||||
import com.mongodb.MongoException;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEndOfTrackingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartOfTrackingEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
@@ -42,22 +47,34 @@ import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
public class TrackedRaceLoadsFixesTest extends AbstractGPSFixStoreTest {
|
||||
private static final Logger logger = Logger.getLogger(TrackedRaceLoadsFixesTest.class.getName());
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
|
||||
private final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
|
||||
private final Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
private final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null,
|
||||
null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null,
|
||||
null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
|
||||
private final Course course = new CourseImpl("course", Arrays.asList(new WaypointImpl(mark), new WaypointImpl(mark2)));
|
||||
private final RaceDefinition raceDefinition = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(comp, comp2));
|
||||
|
||||
private RaceDefinition raceDefinition;
|
||||
|
||||
@Before
|
||||
public void setUp() throws UnknownHostException, MongoException {
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
this.raceDefinition = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
}
|
||||
|
||||
@Rule
|
||||
public Timeout TrackedRaceLoadsFixesTestTimeout = new Timeout(3 * 60 * 1000);
|
||||
|
||||
@Test
|
||||
public void doesRaceLoadOnlyBetweenStartAndEndOfTracking() throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||
|
||||
DeviceIdentifier markDevice = new SmartphoneImeiIdentifier("imei2");
|
||||
defineMarksOnRegattaLog(mark, mark2);
|
||||
|
||||
map(comp, device, 0, 10000);
|
||||
map(mark, markDevice, 0, 10000);
|
||||
|
||||
|
||||
+43
-20
@@ -8,6 +8,8 @@ import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -18,6 +20,7 @@ import com.sap.sailing.domain.abstractlog.race.impl.RaceLogRaceStatusEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartOfTrackingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogStartTimeEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDefineMarkEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
@@ -59,18 +62,22 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
||||
@Test
|
||||
public void testStartTimeInferencePrecedenceOrder() throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
|
||||
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
||||
new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp, comp2 }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
|
||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||
null, /* endDate */null, null, null, "a", null));
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||
/* useMarkPassingCalculator */ false,
|
||||
@@ -132,17 +139,21 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
||||
@Test
|
||||
public void testStartTimeChangeNotificationForFirstUpdateThroughRaceLog() throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
|
||||
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
||||
new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp, comp2 }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||
null, /* endDate */null, null, null, "a", null));
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||
/* useMarkPassingCalculator */ false,
|
||||
@@ -170,17 +181,21 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
||||
@Test
|
||||
public void testStartTimeChangeNotificationForFirstUpdateThroughStartMarkPassing() throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
|
||||
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
||||
new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp, comp2 }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||
null, /* endDate */null, null, null, "a", null));
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||
/* useMarkPassingCalculator */ false,
|
||||
@@ -211,17 +226,21 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
||||
@Test
|
||||
public void testStartAndEndTrackingTimeInferencePrecedenceOrderTriggersListener() throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
|
||||
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
||||
new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp, comp2 }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||
null, /* endDate */null, null, null, "a", null));
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
|
||||
assertTrue(regatta.getRegatta().useStartTimeInference());
|
||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||
@@ -321,17 +340,21 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
|
||||
@Test
|
||||
public void testStartAndEndOfTrackingTimeChangeNotificationForFirstUpdateThroughRaceLog() throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException, InterruptedException {
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", null, null, null, null, null,
|
||||
Competitor comp2 = DomainFactory.INSTANCE.getOrCreateCompetitor("comp2", "comp2", "c2", null, null, null, null,
|
||||
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
Boat boat2 = DomainFactory.INSTANCE.getOrCreateBoat("boat2", "boat2", boatClass, "USA 123", null);
|
||||
Map<Competitor, Boat> competitorsAndBoats = new HashMap<>();
|
||||
competitorsAndBoats.put(comp, boat);
|
||||
competitorsAndBoats.put(comp2, boat2);
|
||||
Mark mark2 = DomainFactory.INSTANCE.getOrCreateMark("mark2");
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(1), author, new MillisecondsTimePoint(1), 0, mark));
|
||||
regattaLog.add(new RegattaLogDefineMarkEventImpl(new MillisecondsTimePoint(2), author, new MillisecondsTimePoint(1), 0, mark2));
|
||||
Course course = new CourseImpl("course", Arrays.asList(new Waypoint[] { new WaypointImpl(mark),
|
||||
new WaypointImpl(mark2) }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, Arrays.asList(new Competitor[] { comp, comp2 }));
|
||||
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
|
||||
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* startDate */
|
||||
null, /* endDate */null, null, null, "a", null));
|
||||
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
|
||||
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null, null, null, "a", null));
|
||||
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
|
||||
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
|
||||
/* useMarkPassingCalculator */ false,
|
||||
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.racelogtracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceBoatBravoMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoMappingEventImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
@@ -31,6 +32,7 @@ public class BravoDataFixMapper implements SensorFixMapper<BravoFix, DynamicSens
|
||||
|
||||
@Override
|
||||
public boolean isResponsibleFor(Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
|
||||
return RegattaLogDeviceCompetitorBravoMappingEventImpl.class.isAssignableFrom(eventType);
|
||||
return RegattaLogDeviceCompetitorBravoMappingEventImpl.class.isAssignableFrom(eventType)
|
||||
|| RegattaLogDeviceBoatBravoMappingEventImpl.class.isAssignableFrom(eventType);
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.racelogtracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceBoatBravoExtendedMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorBravoExtendedMappingEventImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.tracking.BravoExtendedFix;
|
||||
@@ -32,6 +33,7 @@ public class BravoExtendedDataFixMapper implements SensorFixMapper<BravoFix, Dyn
|
||||
|
||||
@Override
|
||||
public boolean isResponsibleFor(Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
|
||||
return RegattaLogDeviceCompetitorBravoExtendedMappingEventImpl.class.isAssignableFrom(eventType);
|
||||
return RegattaLogDeviceCompetitorBravoExtendedMappingEventImpl.class.isAssignableFrom(eventType)
|
||||
|| RegattaLogDeviceBoatBravoExtendedMappingEventImpl.class.isAssignableFrom(eventType);
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.domain.racelogtracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceBoatExpeditionExtendedMappingEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.tracking.BravoExtendedFix;
|
||||
@@ -36,6 +37,7 @@ public class ExpeditionExtendedDataFixMapper implements SensorFixMapper<BravoFix
|
||||
|
||||
@Override
|
||||
public boolean isResponsibleFor(Class<? extends RegattaLogDeviceMappingEvent<?>> eventType) {
|
||||
return RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.class.isAssignableFrom(eventType);
|
||||
return RegattaLogDeviceCompetitorExpeditionExtendedMappingEventImpl.class.isAssignableFrom(eventType)
|
||||
|| RegattaLogDeviceBoatExpeditionExtendedMappingEventImpl.class.isAssignableFrom(eventType);
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -19,6 +19,7 @@ import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.DoesNotHaveRegattaLogException;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.RaceNotCreatedException;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
|
||||
import com.sap.sailing.domain.regattalike.HasRegattaLike;
|
||||
import com.sap.sailing.domain.tracking.DynamicTrackedRegatta;
|
||||
import com.sap.sailing.domain.tracking.RaceTracker;
|
||||
@@ -64,13 +65,13 @@ public class RaceLogConnectivityParams extends AbstractRaceTrackingConnectivityP
|
||||
|
||||
@Override
|
||||
public RaceTracker createRaceTracker(TrackedRegattaRegistry trackedRegattaRegistry, WindStore windStore,
|
||||
RaceLogResolver raceLogResolver, long timeoutInMilliseconds) {
|
||||
return createRaceTracker(regatta, trackedRegattaRegistry, windStore, raceLogResolver, timeoutInMilliseconds);
|
||||
RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) {
|
||||
return createRaceTracker(regatta, trackedRegattaRegistry, windStore, raceLogResolver, leaderboardGroupResolver, timeoutInMilliseconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceTracker createRaceTracker(Regatta regatta, TrackedRegattaRegistry trackedRegattaRegistry,
|
||||
WindStore windStore, RaceLogResolver raceLogResolver, long timeoutInMilliseconds) {
|
||||
WindStore windStore, RaceLogResolver raceLogResolver, LeaderboardGroupResolver leaderboardGroupResolver, long timeoutInMilliseconds) {
|
||||
if (regatta == null) {
|
||||
BoatClass boatClass = new RaceInformationFinder(getRaceLog()).analyze().getBoatClass();
|
||||
regatta = service.getOrCreateDefaultRegatta(
|
||||
|
||||
+3
-2
@@ -36,6 +36,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.impl.BaseRegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.ControlPoint;
|
||||
@@ -296,9 +297,9 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
|
||||
}
|
||||
throw new RaceNotCreatedException(String.format("Race for racelog (%s) has already been created", raceLog));
|
||||
}
|
||||
Iterable<Competitor> competitors = raceColumn.getAllCompetitors(params.getFleet());
|
||||
Map<Competitor, Boat> competitorsAndTheirBoats = raceColumn.getAllCompetitorsAndTheirBoats(params.getFleet());
|
||||
Serializable raceId = denoteEvent.getRaceId();
|
||||
final RaceDefinition raceDef = new RaceDefinitionImpl(raceName, course, boatClass, competitors, raceId);
|
||||
final RaceDefinition raceDef = new RaceDefinitionImpl(raceName, course, boatClass, competitorsAndTheirBoats, raceId);
|
||||
Iterable<Sideline> sidelines = Collections.<Sideline> emptyList();
|
||||
// set race definition, so race is linked to leaderboard automatically
|
||||
trackedRegatta.getRegatta().addRace(raceDef);
|
||||
|
||||
+13
-11
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
@@ -27,6 +28,7 @@ import com.sap.sailing.domain.abstractlog.race.tracking.impl.RaceLogStartTrackin
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceMarkMappingEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseBase;
|
||||
@@ -138,13 +140,13 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
RegattaLeaderboard rLeaderboard = (RegattaLeaderboard) leaderboard;
|
||||
boatClass = rLeaderboard.getRegatta().getBoatClass();
|
||||
} else {
|
||||
if (!Util.isEmpty(raceColumn.getAllCompetitors(fleet))) {
|
||||
boatClass = findDominatingBoatClass(raceColumn.getAllCompetitors(fleet));
|
||||
} else if (!Util.isEmpty(raceColumn.getAllCompetitors())) {
|
||||
boatClass = findDominatingBoatClass(raceColumn.getAllCompetitors());
|
||||
if (!Util.isEmpty(raceColumn.getAllCompetitorsAndTheirBoats(fleet).values())) {
|
||||
boatClass = findDominatingBoatClass(raceColumn.getAllCompetitorsAndTheirBoats(fleet).values());
|
||||
} else if (!Util.isEmpty(raceColumn.getAllCompetitorsAndTheirBoats().values())) {
|
||||
boatClass = findDominatingBoatClass(raceColumn.getAllCompetitorsAndTheirBoats().values());
|
||||
} else if (!Util.isEmpty(leaderboard.getAllCompetitors())) {
|
||||
boatClass = findDominatingBoatClass(leaderboard.getAllCompetitors());
|
||||
} else {
|
||||
boatClass = leaderboard.getBoatClass();
|
||||
} else {
|
||||
throw new NotDenotableForRaceLogTrackingException("Couldn't infer boat class, no competitors on race and leaderboard");
|
||||
}
|
||||
}
|
||||
@@ -167,8 +169,8 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
return result;
|
||||
}
|
||||
|
||||
private BoatClass findDominatingBoatClass(Iterable<Competitor> allCompetitors) {
|
||||
return Util.getDominantObject(()->StreamSupport.stream(allCompetitors.spliterator(), /* parallel */ false).map(c->c.getBoat().getBoatClass()).iterator());
|
||||
private BoatClass findDominatingBoatClass(Iterable<Boat> allBoats) {
|
||||
return Util.getDominantObject(()->StreamSupport.stream(allBoats.spliterator(), /* parallel */ false).map(b->b.getBoatClass()).iterator());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,16 +230,16 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter {
|
||||
|
||||
@Override
|
||||
public void copyCompetitors(final RaceColumn fromRaceColumn, final Fleet fromFleet, final Iterable<Pair<RaceColumn, Fleet>> toRaces) {
|
||||
Iterable<Competitor> competitorsToCopy = fromRaceColumn.getAllCompetitors(fromFleet);
|
||||
Map<Competitor, Boat> competitorsAndBoatsToCopy = fromRaceColumn.getAllCompetitorsAndTheirBoats(fromFleet);
|
||||
for (Pair<RaceColumn, Fleet> toRace : toRaces) {
|
||||
final RaceColumn toRaceColumn = toRace.getA();
|
||||
final Fleet toFleet = toRace.getB();
|
||||
try {
|
||||
if (toRaceColumn.isCompetitorRegistrationInRacelogEnabled(toFleet)) {
|
||||
toRaceColumn.registerCompetitors(competitorsToCopy, toFleet);
|
||||
toRaceColumn.registerCompetitors(competitorsAndBoatsToCopy, toFleet);
|
||||
} else {
|
||||
toRaceColumn.enableCompetitorRegistrationOnRaceLog(toFleet);
|
||||
toRaceColumn.registerCompetitors(competitorsToCopy, toFleet);
|
||||
toRaceColumn.registerCompetitors(competitorsAndBoatsToCopy, toFleet);
|
||||
}
|
||||
} catch (CompetitorRegistrationOnRaceLogDisabledException e1) {
|
||||
// cannot happen as we explicitly checked successfully before, or enabled it when the check failed; still produce a log documenting this strangeness:
|
||||
|
||||
+173
-85
@@ -16,10 +16,13 @@ import java.util.logging.Logger;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
@@ -170,102 +173,139 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
public void fixReceived(DeviceIdentifier device, Timed fix) {
|
||||
if (!preemptiveStopRequested.get() && trackedRace.getStartOfTracking() != null) {
|
||||
final TimePoint timePoint = fix.getTimePoint();
|
||||
deviceMappings.forEachMappingOfDeviceIncludingTimePoint(device, fix.getTimePoint(), (mapping) -> {
|
||||
mapping.getRegattaLogEvent().accept(new MappingEventVisitor() {
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
if (preemptiveStopRequested.get()) {
|
||||
return;
|
||||
deviceMappings.forEachMappingOfDeviceIncludingTimePoint(device, fix.getTimePoint(), new Consumer<DeviceMappingWithRegattaLogEvent<WithID>>() {
|
||||
@Override
|
||||
public void accept(DeviceMappingWithRegattaLogEvent<WithID> mapping) {
|
||||
mapping.getRegattaLogEvent().accept(new MappingEventVisitor() {
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
recordSensorFixForCompetitor(event.getMappedTo(), event);
|
||||
}
|
||||
SensorFixMapper<SensorFix, DynamicSensorFixTrack<Competitor, SensorFix>, Competitor> mapper = sensorFixMapperFactory
|
||||
.createCompetitorMapper(event.getClass());
|
||||
DynamicSensorFixTrack<Competitor, SensorFix> track = mapper.getTrack(trackedRace,
|
||||
event.getMappedTo());
|
||||
if (track != null && trackedRace.isWithinStartAndEndOfTracking(fix.getTimePoint())) {
|
||||
mapper.addFix(track, (DoubleVectorFix) fix);
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
final Boat boat = event.getMappedTo();
|
||||
final Competitor competitor = trackedRace.getCompetitorOfBoat(boat);
|
||||
if (competitor != null) {
|
||||
recordSensorFixForCompetitor(competitor, event);
|
||||
} else {
|
||||
logger.log(Level.WARNING,
|
||||
"Could not record fix for boat because no competitor could be determined. Boat: "
|
||||
+ boat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||
if (preemptiveStopRequested.get()) {
|
||||
return;
|
||||
|
||||
private void recordSensorFixForCompetitor(Competitor competitor, RegattaLogDeviceMappingEvent<?> event) {
|
||||
if (preemptiveStopRequested.get()) {
|
||||
return;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
SensorFixMapper<SensorFix, DynamicSensorFixTrack<Competitor, SensorFix>, Competitor> mapper = sensorFixMapperFactory
|
||||
.createCompetitorMapper((Class<? extends RegattaLogDeviceMappingEvent<?>>) event.getClass());
|
||||
DynamicSensorFixTrack<Competitor, SensorFix> track = mapper.getTrack(trackedRace,
|
||||
competitor);
|
||||
if (track != null && trackedRace.isWithinStartAndEndOfTracking(fix.getTimePoint())) {
|
||||
mapper.addFix(track, (DoubleVectorFix) fix);
|
||||
}
|
||||
}
|
||||
Competitor comp = event.getMappedTo();
|
||||
if (fix instanceof GPSFixMoving) {
|
||||
trackedRace.recordFix(comp, (GPSFixMoving) fix);
|
||||
} else {
|
||||
logger.log(Level.WARNING,
|
||||
String.format(
|
||||
"Could not add fix for competitor (%s) in race (%s), as it"
|
||||
+ " is no GPSFixMoving, meaning it is missing COG/SOG values",
|
||||
comp, trackedRace.getRace().getName()));
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||
recordForCompetitor(event.getMappedTo());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
||||
if (preemptiveStopRequested.get()) {
|
||||
return;
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
final Boat boat = event.getMappedTo();
|
||||
final Competitor comp = trackedRace.getCompetitorOfBoat(boat);
|
||||
if (comp != null) {
|
||||
recordForCompetitor(comp);
|
||||
} else {
|
||||
logger.log(Level.WARNING,
|
||||
"Could not record fix for boat because no competitor could be determined. Boat: "
|
||||
+ boat);
|
||||
}
|
||||
}
|
||||
Mark mark = event.getMappedTo();
|
||||
final DynamicGPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
|
||||
final GPSFix firstFixAtOrAfter;
|
||||
final boolean forceFix;
|
||||
if (trackedRace.isWithinStartAndEndOfTracking(fix.getTimePoint())) {
|
||||
forceFix = false;
|
||||
} else {
|
||||
markTrack.lockForRead();
|
||||
try {
|
||||
if (Util.isEmpty(markTrack.getRawFixes())
|
||||
|| (firstFixAtOrAfter = markTrack.getFirstFixAtOrAfter(timePoint)) != null
|
||||
&& firstFixAtOrAfter.getTimePoint().equals(timePoint)) {
|
||||
// either the first fix or overwriting an existing one
|
||||
forceFix = true;
|
||||
} else {
|
||||
// checking if the given fix is "better" than an existing one
|
||||
TimePoint startOfTracking = trackedRace.getStartOfTracking();
|
||||
TimePoint endOfTracking = trackedRace.getStartOfTracking();
|
||||
if (startOfTracking != null) {
|
||||
GPSFix fixAfterStartOfTracking = markTrack
|
||||
.getFirstFixAtOrAfter(startOfTracking);
|
||||
if (fixAfterStartOfTracking == null
|
||||
|| !trackedRace.isWithinStartAndEndOfTracking(
|
||||
fixAfterStartOfTracking.getTimePoint())) {
|
||||
// There is no fix in the tracking interval, so this fix could be "better"
|
||||
// than ones already available in the track
|
||||
// Better means closer before/after the beginning/end of the tracking
|
||||
// interval
|
||||
if (timePoint.before(startOfTracking)) {
|
||||
// check if it is closer to the beginning of the tracking interval
|
||||
GPSFix fixBeforeStartOfTracking = markTrack
|
||||
.getLastFixAtOrBefore(startOfTracking);
|
||||
forceFix = (fixBeforeStartOfTracking == null
|
||||
|| fixBeforeStartOfTracking.getTimePoint().before(timePoint));
|
||||
} else if (endOfTracking != null && timePoint.after(endOfTracking)) {
|
||||
// check if it is closer to the end of the tracking interval
|
||||
GPSFix fixAfterEndOfTracking = markTrack
|
||||
.getFirstFixAtOrAfter(endOfTracking);
|
||||
forceFix = (fixAfterEndOfTracking == null
|
||||
|| fixAfterEndOfTracking.getTimePoint().after(timePoint));
|
||||
|
||||
public void recordForCompetitor(Competitor comp) {
|
||||
if (preemptiveStopRequested.get()) {
|
||||
return;
|
||||
}
|
||||
if (fix instanceof GPSFixMoving) {
|
||||
trackedRace.recordFix(comp, (GPSFixMoving) fix);
|
||||
} else {
|
||||
logger.log(Level.WARNING,
|
||||
String.format(
|
||||
"Could not add fix for competitor (%s) in race (%s), as it"
|
||||
+ " is no GPSFixMoving, meaning it is missing COG/SOG values",
|
||||
comp, trackedRace.getRace().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
||||
if (preemptiveStopRequested.get()) {
|
||||
return;
|
||||
}
|
||||
Mark mark = event.getMappedTo();
|
||||
final DynamicGPSFixTrack<Mark, GPSFix> markTrack = trackedRace.getOrCreateTrack(mark);
|
||||
final GPSFix firstFixAtOrAfter;
|
||||
final boolean forceFix;
|
||||
if (trackedRace.isWithinStartAndEndOfTracking(fix.getTimePoint())) {
|
||||
forceFix = false;
|
||||
} else {
|
||||
markTrack.lockForRead();
|
||||
try {
|
||||
if (Util.isEmpty(markTrack.getRawFixes())
|
||||
|| (firstFixAtOrAfter = markTrack.getFirstFixAtOrAfter(timePoint)) != null
|
||||
&& firstFixAtOrAfter.getTimePoint().equals(timePoint)) {
|
||||
// either the first fix or overwriting an existing one
|
||||
forceFix = true;
|
||||
} else {
|
||||
// checking if the given fix is "better" than an existing one
|
||||
TimePoint startOfTracking = trackedRace.getStartOfTracking();
|
||||
TimePoint endOfTracking = trackedRace.getStartOfTracking();
|
||||
if (startOfTracking != null) {
|
||||
GPSFix fixAfterStartOfTracking = markTrack
|
||||
.getFirstFixAtOrAfter(startOfTracking);
|
||||
if (fixAfterStartOfTracking == null
|
||||
|| !trackedRace.isWithinStartAndEndOfTracking(
|
||||
fixAfterStartOfTracking.getTimePoint())) {
|
||||
// There is no fix in the tracking interval, so this fix could be "better"
|
||||
// than ones already available in the track
|
||||
// Better means closer before/after the beginning/end of the tracking
|
||||
// interval
|
||||
if (timePoint.before(startOfTracking)) {
|
||||
// check if it is closer to the beginning of the tracking interval
|
||||
GPSFix fixBeforeStartOfTracking = markTrack
|
||||
.getLastFixAtOrBefore(startOfTracking);
|
||||
forceFix = (fixBeforeStartOfTracking == null
|
||||
|| fixBeforeStartOfTracking.getTimePoint().before(timePoint));
|
||||
} else if (endOfTracking != null && timePoint.after(endOfTracking)) {
|
||||
// check if it is closer to the end of the tracking interval
|
||||
GPSFix fixAfterEndOfTracking = markTrack
|
||||
.getFirstFixAtOrAfter(endOfTracking);
|
||||
forceFix = (fixAfterEndOfTracking == null
|
||||
|| fixAfterEndOfTracking.getTimePoint().after(timePoint));
|
||||
} else {
|
||||
forceFix = false;
|
||||
}
|
||||
} else {
|
||||
// there is already a fix in the tracking interval
|
||||
forceFix = false;
|
||||
}
|
||||
} else {
|
||||
// there is already a fix in the tracking interval
|
||||
forceFix = false;
|
||||
}
|
||||
} else {
|
||||
forceFix = false;
|
||||
}
|
||||
} finally {
|
||||
markTrack.unlockAfterRead();
|
||||
}
|
||||
} finally {
|
||||
markTrack.unlockAfterRead();
|
||||
}
|
||||
trackedRace.recordFix(mark, (GPSFix) fix, /* only when in tracking interval */ !forceFix);
|
||||
}
|
||||
trackedRace.recordFix(mark, (GPSFix) fix, /* only when in tracking interval */ !forceFix);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -378,9 +418,30 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
mappingEvent.accept(new MappingEventVisitor() {
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
final Competitor competitor = event.getMappedTo();
|
||||
loadSensorFixesForCompetitor(timeRangeToLoad, progressConsumer, stopCallback, event, competitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
final Boat boat = event.getMappedTo();
|
||||
final Competitor competitor = trackedRace.getCompetitorOfBoat(boat);
|
||||
if (competitor != null) {
|
||||
loadSensorFixesForCompetitor(timeRangeToLoad, progressConsumer, stopCallback, event, competitor);
|
||||
} else {
|
||||
logger.log(Level.WARNING,
|
||||
"Could not load fixes for boat because no competitor could be determined. Boat: "
|
||||
+ boat);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSensorFixesForCompetitor(TimeRange timeRangeToLoad, final Consumer<Double> progressConsumer,
|
||||
final BooleanSupplier stopCallback, RegattaLogDeviceMappingEvent<?> event,
|
||||
final Competitor competitor) {
|
||||
@SuppressWarnings("unchecked")
|
||||
SensorFixMapper<Timed, DynamicTrack<Timed>, Competitor> mapper = sensorFixMapperFactory
|
||||
.createCompetitorMapper(event.getClass());
|
||||
DynamicTrack<Timed> track = mapper.getTrack(trackedRace, event.getMappedTo());
|
||||
.createCompetitorMapper((Class<? extends RegattaLogDeviceMappingEvent<?>>) event.getClass());
|
||||
DynamicTrack<Timed> track = mapper.getTrack(trackedRace, competitor);
|
||||
if (track != null) {
|
||||
// for split-fleet racing, device mappings coming from the regatta log may not be relevant
|
||||
// for the trackedRace because the competitors may not compete in it; in this case, the
|
||||
@@ -398,7 +459,24 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = trackedRace.getTrack(event.getMappedTo());
|
||||
loadForCompetitor(event.getMappedTo(), event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
final Boat boat = event.getMappedTo();
|
||||
final Competitor comp = trackedRace.getCompetitorOfBoat(boat);
|
||||
if (comp != null) {
|
||||
loadForCompetitor(comp, event);
|
||||
} else {
|
||||
logger.log(Level.WARNING,
|
||||
"Could not load fixes for boat because no competitor could be determined. Boat: "
|
||||
+ boat);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadForCompetitor(Competitor competitor, RegattaLogDeviceMappingEvent<?> event) {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> track = trackedRace.getTrack(competitor);
|
||||
if (track != null) {
|
||||
// for split-fleet racing, device mappings coming from the regatta log may not be relevant
|
||||
// for the trackedRace because the competitors may not compete in it; in this case, the
|
||||
@@ -408,7 +486,7 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
timeRangeToLoad.from(), timeRangeToLoad.to(), /* toIsInclusive */ false,
|
||||
stopCallback, progressConsumer);
|
||||
} catch (TransformationException | NoCorrespondingServiceRegisteredException e) {
|
||||
logger.log(Level.WARNING, "Could not load competitor track " + event.getMappedTo() + "; device "
|
||||
logger.log(Level.WARNING, "Could not load competitor track " + competitor + "; device "
|
||||
+ event.getDevice());
|
||||
}
|
||||
}
|
||||
@@ -441,11 +519,21 @@ public class FixLoaderAndTracker implements TrackingDataLoader {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceMarkMappingEvent event) {
|
||||
DynamicGPSFixTrack<Mark, GPSFix> track = trackedRace.getOrCreateTrack(event.getMappedTo());
|
||||
|
||||
+14
-1
@@ -15,6 +15,8 @@ import java.util.logging.Logger;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
@@ -70,7 +72,12 @@ public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
|
||||
private final RegattaLogEventVisitor regattaLogEventVisitor = new BaseRegattaLogEventVisitor() {
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
logger.log(Level.FINE, "New mapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||
logger.log(Level.FINE, "New CompetitorSensorDataMapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||
updateMappings();
|
||||
}
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
logger.log(Level.FINE, "New BoatSensorDataMapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||
updateMappings();
|
||||
}
|
||||
|
||||
@@ -87,6 +94,12 @@ public abstract class RegattaLogDeviceMappings<ItemT extends WithID> {
|
||||
"New DeviceCompetitorMapping for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||
updateMappings();
|
||||
}
|
||||
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
logger.log(Level.FINE,
|
||||
"New DeviceBoatMappingEvent for: " + event.getMappedTo() + "; device: " + event.getDevice());
|
||||
updateMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||
|
||||
+5
-5
@@ -65,7 +65,7 @@ public class CurrentRaceFilterImplTest {
|
||||
_505RaceRows.add(_505RaceRow);
|
||||
_505Series.add(new SeriesWithRowsImpl("Default", /* isMedal */ false, /* isFleetsCanRunInParallel */ false, _505RaceRows));
|
||||
final RaceGroup _505 = new RaceGroupImpl("505", /* displayName */ null,
|
||||
new BoatClassImpl(BoatClassMasterdata._5O5.getDisplayName(), BoatClassMasterdata._5O5),
|
||||
new BoatClassImpl(BoatClassMasterdata._5O5.getDisplayName(), BoatClassMasterdata._5O5), /* canBoatsOfCompetitorsChangePerRace */ false,
|
||||
/* courseArea */ null, _505Series, /* regattaConfiguration */ null);
|
||||
return _505;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class CurrentRaceFilterImplTest {
|
||||
final List<RaceRow> yesRaceRows = Arrays.asList(createRaceRow(1, 9, "R", "Yellow"), createRaceRow(1, 9, "R", "Blue"));
|
||||
yesSeries.add(new SeriesWithRowsImpl("Default", /* isMedal */ false, /* isFleetsCanRunInParallel */ true, yesRaceRows));
|
||||
final RaceGroup yes = new RaceGroupImpl("YES", /* displayName */ null,
|
||||
new BoatClassImpl(BoatClassMasterdata._470.getDisplayName(), BoatClassMasterdata._470),
|
||||
new BoatClassImpl(BoatClassMasterdata._470.getDisplayName(), BoatClassMasterdata._470), /* canBoatsOfCompetitorsChangePerRace */ false,
|
||||
/* courseArea */ null, yesSeries, /* regattaConfiguration */ null);
|
||||
return yes;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public class CurrentRaceFilterImplTest {
|
||||
final List<RaceRow> isafMedalRaceRows = Arrays.asList(createRaceRow(1, 1, "M", "Medal"));
|
||||
isafSeries.add(new SeriesWithRowsImpl("Medal", /* isMedal */ true, /* isFleetsCanRunInParallel */ true, isafMedalRaceRows));
|
||||
final RaceGroup isaf = new RaceGroupImpl("ISAF", /* displayName */ null,
|
||||
new BoatClassImpl(BoatClassMasterdata._470.getDisplayName(), BoatClassMasterdata._470),
|
||||
new BoatClassImpl(BoatClassMasterdata._470.getDisplayName(), BoatClassMasterdata._470), /* canBoatsOfCompetitorsChangePerRace */ false,
|
||||
/* courseArea */ null, isafSeries, /* regattaConfiguration */ null);
|
||||
return isaf;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public class CurrentRaceFilterImplTest {
|
||||
final List<RaceRow> essDay4RaceRows = Arrays.asList(createRaceRow(16, 5, "R", "Default"));
|
||||
essSeries.add(new SeriesWithRowsImpl("Day 4", /* isMedal */ false, /* isFleetsCanRunInParallel */ true, essDay4RaceRows));
|
||||
final RaceGroup ess = new RaceGroupImpl("ESS", /* displayName */ null,
|
||||
new BoatClassImpl(BoatClassMasterdata.EXTREME_40.getDisplayName(), BoatClassMasterdata.EXTREME_40),
|
||||
new BoatClassImpl(BoatClassMasterdata.EXTREME_40.getDisplayName(), BoatClassMasterdata.EXTREME_40), /* canBoatsOfCompetitorsChangePerRace */ false,
|
||||
/* courseArea */ null, essSeries, /* regattaConfiguration */ null);
|
||||
return ess;
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class CurrentRaceFilterImplTest {
|
||||
final List<RaceRow> leagueRaceRows = Arrays.asList(createRaceRow(1, 15, "F", "Red"), createRaceRow(1, 15, "F", "Green"), createRaceRow(1, 15, "F", "Blue"));
|
||||
leagueSeries.add(new SeriesWithRowsImpl("Default", /* isMedal */ false, /* isFleetsCanRunInParallel */ false, leagueRaceRows));
|
||||
final RaceGroup league = new RaceGroupImpl("League", /* displayName */ null,
|
||||
new BoatClassImpl(BoatClassMasterdata.J70.getDisplayName(), BoatClassMasterdata.J70),
|
||||
new BoatClassImpl(BoatClassMasterdata.J70.getDisplayName(), BoatClassMasterdata.J70), /* canBoatsOfCompetitorsChangePerRace */ false,
|
||||
/* courseArea */ null, leagueSeries, /* regattaConfiguration */ null);
|
||||
return league;
|
||||
}
|
||||
|
||||
+11
-3
@@ -14,13 +14,21 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorDeregistrator;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorsInLogAnalyzer;
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorImpl;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sailing.domain.base.impl.BoatClassImpl;
|
||||
import com.sap.sailing.domain.base.impl.BoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.CompetitorWithBoatImpl;
|
||||
import com.sap.sailing.domain.base.impl.DynamicBoat;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class CompetitorDeregistrationTest extends AbstractRegattaLogTrackingTest {
|
||||
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final static BoatClass boatClass = new BoatClassImpl("505", /* typicallyStartsUpwind */ true);
|
||||
private final static DynamicBoat boat1 = new BoatImpl("id12345", "boat1", boatClass, /* sailID */ null);
|
||||
private final static DynamicBoat boat2 = new BoatImpl("id12345", "boat1", boatClass, /* sailID */ null);
|
||||
private final CompetitorWithBoat competitor = new CompetitorWithBoatImpl("comp", "Comp", "KYC", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, boat1);
|
||||
private final CompetitorWithBoat competitor2 = new CompetitorWithBoatImpl("comp2", "Comp2", "KYC", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, boat2);
|
||||
|
||||
@Test
|
||||
public void testCompetitorDeregistration() {
|
||||
|
||||
+2
-2
@@ -27,8 +27,8 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import junit.framework.Assert;
|
||||
|
||||
public class DeviceMappingFinderTest extends AbstractRegattaLogTrackingTest {
|
||||
private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final Competitor competitor = new CompetitorImpl("comp", "Comp", "KYC", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", "KYC", null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
private final DeviceIdentifier device = new SmartphoneImeiIdentifier("imei");
|
||||
|
||||
private int time = 0;
|
||||
|
||||
+1
-1
@@ -23,5 +23,5 @@ public interface RaceLogEventData extends Serializable {
|
||||
* A {@link RaceLogEventData} might be associated with a list of competitors, which are somehow relevant for this
|
||||
* kind of event. An example is a list of competitors who are marked for an individual recall.
|
||||
*/
|
||||
List<Competitor> getInvolvedBoats();
|
||||
List<Competitor> getInvolvedCompetitors();
|
||||
}
|
||||
+1
-1
@@ -37,7 +37,7 @@ public interface RaceLogEventVisitor {
|
||||
public void visit(RaceLogDenoteForTrackingEvent event);
|
||||
|
||||
public void visit(RaceLogStartTrackingEvent event);
|
||||
|
||||
|
||||
public void visit(RaceLogRegisterCompetitorEvent event);
|
||||
|
||||
public void visit(RaceLogAdditionalScoringInformationEvent additionalScoringInformation);
|
||||
|
||||
+2
-2
@@ -23,11 +23,11 @@ public class MarkPassingDataFinder extends RaceLogAnalyzer<Set<Triple<Competitor
|
||||
for (RaceLogEvent event : getLog().getUnrevokedEvents()) {
|
||||
if (event instanceof RaceLogFixedMarkPassingEvent) {
|
||||
RaceLogFixedMarkPassingEvent castedEvent = (RaceLogFixedMarkPassingEvent) event;
|
||||
result.add(new Triple<Competitor, Integer, TimePoint>(castedEvent.getInvolvedBoats().get(0), castedEvent
|
||||
result.add(new Triple<Competitor, Integer, TimePoint>(castedEvent.getInvolvedCompetitors().get(0), castedEvent
|
||||
.getZeroBasedIndexOfPassedWaypoint(), castedEvent.getTimePointOfFixedPassing()));
|
||||
} else if (event instanceof RaceLogSuppressedMarkPassingsEvent){
|
||||
RaceLogSuppressedMarkPassingsEvent castedEvent = (RaceLogSuppressedMarkPassingsEvent) event;
|
||||
result.add(new Triple<Competitor, Integer, TimePoint>(castedEvent.getInvolvedBoats().get(0), castedEvent.getZeroBasedIndexOfFirstSuppressedWaypoint(), null));
|
||||
result.add(new Triple<Competitor, Integer, TimePoint>(castedEvent.getInvolvedCompetitors().get(0), castedEvent.getZeroBasedIndexOfFirstSuppressedWaypoint(), null));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.sap.sailing.domain.abstractlog.race.analyzing.impl;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl.RaceLogUsesOwnCompetitorsAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorsAndBoatsInLogAnalyzer;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
public class RaceLogRegisteredCompetitorsAndBoatsAnalyzer extends RaceLogAnalyzer<Map<Competitor, Boat>> {
|
||||
|
||||
public RaceLogRegisteredCompetitorsAndBoatsAnalyzer(RaceLog raceLog) {
|
||||
super(raceLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Competitor, Boat> performAnalysis() {
|
||||
final Map<Competitor, Boat> result;
|
||||
if (new RaceLogUsesOwnCompetitorsAnalyzer(getLog()).analyze()){
|
||||
// get Events from RaceLog
|
||||
result = new CompetitorsAndBoatsInLogAnalyzer<>(getLog()).analyze();
|
||||
} else {
|
||||
// as we're explicitly only trying to find those registrations in the RaceLog, we won't
|
||||
// return anything from the regatta log.
|
||||
result = Collections.emptyMap();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -103,7 +103,7 @@ public abstract class AbstractRaceLogChangedVisitor implements RaceLogEventVisit
|
||||
public void visit(RaceLogRegisterCompetitorEvent event) {
|
||||
notifyListenerAboutEventAdded(event);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogAdditionalScoringInformationEvent additionalScoringInformation) {
|
||||
notifyListenerAboutEventAdded(additionalScoringInformation);
|
||||
|
||||
+2
-1
@@ -109,7 +109,7 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor {
|
||||
public void visit(RaceLogRegisterCompetitorEvent event) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(RaceLogAdditionalScoringInformationEvent event) {
|
||||
|
||||
@@ -144,4 +144,5 @@ public abstract class BaseRaceLogEventVisitor implements RaceLogEventVisitor {
|
||||
public void visit(RaceLogUseCompetitorsFromRaceLogEvent event) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -21,7 +21,7 @@ public class RaceLogEventDataImpl implements RaceLogEventData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Competitor> getInvolvedBoats() {
|
||||
public List<Competitor> getInvolvedCompetitors() {
|
||||
return involvedBoats;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,6 @@ public class RaceLogEventDataImpl implements RaceLogEventData {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + ", involvedBoats: " + getInvolvedBoats() + ", passId: " + getPassId();
|
||||
return super.toString() + ", involvedBoats: " + getInvolvedCompetitors() + ", passId: " + getPassId();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -36,8 +36,8 @@ public abstract class RaceLogEventImpl extends AbstractLogEventImpl<RaceLogEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Competitor> getInvolvedBoats() {
|
||||
return raceLogEventData.getInvolvedBoats();
|
||||
public List<Competitor> getInvolvedCompetitors() {
|
||||
return raceLogEventData.getInvolvedCompetitors();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -49,8 +49,8 @@ public class RaceLogFixedMarkPassingEventImpl extends RaceLogEventImpl implement
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return (getInvolvedBoats() == null || getInvolvedBoats().get(0) == null ? "Unknown" :
|
||||
getInvolvedBoats().get(0).getName()) + " at mark " + getZeroBasedIndexOfPassedWaypoint() + " at "
|
||||
return (getInvolvedCompetitors() == null || getInvolvedCompetitors().get(0) == null ? "Unknown" :
|
||||
getInvolvedCompetitors().get(0).getName()) + " at mark " + getZeroBasedIndexOfPassedWaypoint() + " at "
|
||||
+ getTimePointOfFixedPassing();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -35,8 +35,8 @@ public class RaceLogRevokeEventImpl extends RevokeEventImpl<RaceLogEventVisitor>
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Competitor> getInvolvedBoats() {
|
||||
return raceLogEventData.getInvolvedBoats();
|
||||
public List<Competitor> getInvolvedCompetitors() {
|
||||
return raceLogEventData.getInvolvedCompetitors();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -42,6 +42,6 @@ public class RaceLogSuppressedMarkPassingsEventImpl extends RaceLogEventImpl imp
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return getInvolvedBoats().get(0).getName() + " at mark " + getZeroBasedIndexOfFirstSuppressedWaypoint();
|
||||
return getInvolvedCompetitors().get(0).getName() + " at mark " + getZeroBasedIndexOfFirstSuppressedWaypoint();
|
||||
}
|
||||
}
|
||||
+11
-3
@@ -3,8 +3,16 @@ package com.sap.sailing.domain.abstractlog.race.tracking;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.shared.events.RegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
|
||||
public interface RaceLogRegisterCompetitorEvent extends RaceLogEvent,
|
||||
RegisterCompetitorEvent<RaceLogEventVisitor> {
|
||||
|
||||
/**
|
||||
* The event registers a {@link CompetitorWithBoat} or a pair of {@link Competitor} and {@link Boat} on a race.
|
||||
* The competitor type is determined by the {@link Regatta} attribute 'canBoatsOfCompetitorsChangePerRace'
|
||||
* If 'canBoatsOfCompetitorsChangePerRace' is true the type must be {@link Competitor}
|
||||
* If 'canBoatsOfCompetitorsChangePerRace' is false the type must be {@link CompetitorWithBoat}
|
||||
*/
|
||||
public interface RaceLogRegisterCompetitorEvent extends RaceLogEvent, RegisterCompetitorEvent<RaceLogEventVisitor> {
|
||||
Boat getBoat();
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.sap.sailing.domain.abstractlog.race.tracking.analyzing.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.RaceLogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorsAndBoatsInLogAnalyzer;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
|
||||
/**
|
||||
* Used to find competitors (including their boats) of a race based on {@link RaceLog} and {@link RegattaLog} contents. Checks whether the
|
||||
* competitors for the given race are registered on the RaceLog via {@link RaceLogUsesOwnCompetitorsAnalyzer} or on the
|
||||
* RegattaLog and fetches the competitors appropriately.
|
||||
*
|
||||
* Should not be used by clients directly. Instead, get the competitor set from the {@code RaceColumn}, using either one
|
||||
* of {@code getAllCompetitorsAndTheirBoats()} and {@code getAllCompetitorsAndTheirBoats(Fleet)}. Those methods automatically check whether a
|
||||
* tracked race is present, which takes precedence over the Race/RegattaLog.
|
||||
*
|
||||
* @author Jan Bross (D056848)
|
||||
*
|
||||
*/
|
||||
public class RegisteredCompetitorsAndBoatsAnalyzer extends RaceLogAnalyzer<Map<Competitor, Boat>> {
|
||||
private RegattaLog regattaLog;
|
||||
|
||||
public RegisteredCompetitorsAndBoatsAnalyzer(RaceLog raceLog, RegattaLog regattaLog) {
|
||||
super(raceLog);
|
||||
this.regattaLog = regattaLog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Competitor, Boat> performAnalysis() {
|
||||
final Map<Competitor, Boat> result;
|
||||
if (new RaceLogUsesOwnCompetitorsAnalyzer(getLog()).analyze()) {
|
||||
// get Events from RaceLog
|
||||
result = new CompetitorsAndBoatsInLogAnalyzer<>(getLog()).analyze();
|
||||
} else {
|
||||
// get Events from RegattaLog
|
||||
result = new CompetitorsAndBoatsInLogAnalyzer<>(regattaLog).analyze();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+61
-5
@@ -10,43 +10,83 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.race.impl.RaceLogEventDataImpl;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.shared.events.impl.BaseRegisterCompetitorEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* Links a competitor to the boat it sails with in the race. The {@link #boat} field refers to the
|
||||
* {@link CompetitorWithBoat#getBoat() competitor's boat} if the competitor has a fixed boat attached.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class RaceLogRegisterCompetitorEventImpl extends BaseRegisterCompetitorEventImpl<RaceLogEventVisitor> implements
|
||||
RaceLogRegisterCompetitorEvent {
|
||||
private static final long serialVersionUID = -5114645637316367845L;
|
||||
private final RaceLogEventData raceLogEventData;
|
||||
|
||||
/**
|
||||
* The boat the competitor sails with in the race to which the race log containing this event belongs.
|
||||
* Never {@code null}.
|
||||
*/
|
||||
private final Boat boat;
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code competitor} is null
|
||||
*/
|
||||
public RaceLogRegisterCompetitorEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable id, int passId, Competitor competitor)
|
||||
AbstractLogEventAuthor author, Serializable id, int passId, CompetitorWithBoat competitor)
|
||||
throws IllegalArgumentException {
|
||||
super(createdAt, logicalTimePoint, author, id, competitor);
|
||||
this.raceLogEventData = new RaceLogEventDataImpl(null, passId);
|
||||
checkBoat(competitor.getBoat());
|
||||
this.boat = competitor.getBoat();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code competitor} is null
|
||||
* if {@code competitor} is null or if {@code boat} is null
|
||||
*/
|
||||
public RaceLogRegisterCompetitorEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable id, int passId, Competitor competitor, Boat boat)
|
||||
throws IllegalArgumentException {
|
||||
super(createdAt, logicalTimePoint, author, id, competitor);
|
||||
this.raceLogEventData = new RaceLogEventDataImpl(null, passId);
|
||||
checkBoat(boat);
|
||||
this.boat = boat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code competitor} is null or if {@code competitor.getBoat()} is null
|
||||
*/
|
||||
public RaceLogRegisterCompetitorEventImpl(TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, int passId, Competitor competitor)
|
||||
AbstractLogEventAuthor author, int passId, CompetitorWithBoat competitor)
|
||||
throws IllegalArgumentException {
|
||||
this(now(), logicalTimePoint, author, randId(), passId, competitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code competitor} is null or if {@code boat} is null
|
||||
*/
|
||||
public RaceLogRegisterCompetitorEventImpl(TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, int passId, Competitor competitor, Boat boat)
|
||||
throws IllegalArgumentException {
|
||||
this(now(), logicalTimePoint, author, randId(), passId, competitor, boat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPassId() {
|
||||
return raceLogEventData.getPassId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Competitor> getInvolvedBoats() {
|
||||
return Collections.singletonList(getCompetitor());
|
||||
public List<Competitor> getInvolvedCompetitors() {
|
||||
return Collections.singletonList((Competitor) getCompetitor());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,4 +98,20 @@ public class RaceLogRegisterCompetitorEventImpl extends BaseRegisterCompetitorEv
|
||||
public void accept(RaceLogEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boat getBoat() {
|
||||
return boat;
|
||||
}
|
||||
|
||||
private static void checkBoat(Boat boat) throws IllegalArgumentException {
|
||||
if (boat == null) {
|
||||
throw new IllegalArgumentException("Boat must not be null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return "competitor: " + getCompetitor().toString() + " with boat " + getBoat().toString();
|
||||
}
|
||||
}
|
||||
+6
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEvent;
|
||||
@@ -13,7 +15,11 @@ public interface MappingEventVisitor {
|
||||
void visit(RegattaLogDeviceMarkMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceCompetitorMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceBoatMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceBoatSensorDataMappingEvent event);
|
||||
|
||||
}
|
||||
+10
-1
@@ -2,9 +2,12 @@ package com.sap.sailing.domain.abstractlog.regatta;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
||||
@@ -16,13 +19,19 @@ public interface RegattaLogEventVisitor {
|
||||
void visit(RegattaLogDeviceMarkMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceCompetitorMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceBoatMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event);
|
||||
|
||||
void visit(RegattaLogDeviceBoatSensorDataMappingEvent event);
|
||||
|
||||
void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event);
|
||||
|
||||
void visit(RegattaLogRegisterBoatEvent event);
|
||||
|
||||
void visit(RegattaLogRegisterCompetitorEvent event);
|
||||
|
||||
|
||||
void visit(RegattaLogSetCompetitorTimeOnTimeFactorEvent event);
|
||||
|
||||
void visit(RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent event);
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
|
||||
public interface RegattaLogDeviceBoatMappingEvent extends RegattaLogDeviceMappingEvent<Boat> {
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events;
|
||||
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
|
||||
public interface RegattaLogDeviceBoatSensorDataMappingEvent extends RegattaLogDeviceMappingEvent<Boat> {
|
||||
|
||||
}
|
||||
+6
@@ -13,6 +13,12 @@ public abstract class RegattaLogDeviceMappingEventImpl<ItemType extends WithID>
|
||||
RegattaLogDeviceMappingEvent<ItemType> {
|
||||
private static final long serialVersionUID = -8439653251231710356L;
|
||||
|
||||
public interface Factory<ItemType extends WithID, T extends RegattaLogDeviceMappingEvent<ItemType>> {
|
||||
T create(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, ItemType mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to);
|
||||
}
|
||||
|
||||
private final ItemType mappedTo;
|
||||
private final DeviceIdentifier device;
|
||||
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.Revokable;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
|
||||
/**
|
||||
* The event registers a standalone {@link Boat} on a regatta.
|
||||
*/
|
||||
public interface RegattaLogRegisterBoatEvent extends RegattaLogEvent, Revokable {
|
||||
Boat getBoat();
|
||||
}
|
||||
+10
-2
@@ -3,8 +3,16 @@ package com.sap.sailing.domain.abstractlog.regatta.events;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.shared.events.RegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
|
||||
public interface RegattaLogRegisterCompetitorEvent extends RegattaLogEvent,
|
||||
RegisterCompetitorEvent<RegattaLogEventVisitor> {
|
||||
/**
|
||||
* The event registers a {@link Competitor} or {@link CompetitorWithBoat} on a regatta.
|
||||
* The competitor type is determined by the {@link Regatta} attribute 'canBoatsOfCompetitorsChangePerRace'
|
||||
* If 'canBoatsOfCompetitorsChangePerRace' is true the type must be {@link Competitor}
|
||||
* If 'canBoatsOfCompetitorsChangePerRace' is false the type must be {@link CompetitorWithBoat}
|
||||
*/
|
||||
public interface RegattaLogRegisterCompetitorEvent
|
||||
extends RegattaLogEvent, RegisterCompetitorEvent<RegattaLogEventVisitor> {
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* Base type for mapping event for devices mapped for specific Bravo type fixes.
|
||||
*/
|
||||
public abstract class AbstractRegattaLogDeviceBoatSensorDataMappingEventImpl extends RegattaLogDeviceMappingEventImpl<Boat>
|
||||
implements RegattaLogDeviceBoatSensorDataMappingEvent {
|
||||
private static final long serialVersionUID = -1494030544804758753L;
|
||||
|
||||
public AbstractRegattaLogDeviceBoatSensorDataMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Boat mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
|
||||
}
|
||||
|
||||
public AbstractRegattaLogDeviceBoatSensorDataMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||
Boat mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
|
||||
super(logicalTimePoint, author, mappedTo, device, from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(RegattaLogEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MappingEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
-6
@@ -18,12 +18,6 @@ public abstract class AbstractRegattaLogDeviceCompetitorSensorDataMappingEventIm
|
||||
implements RegattaLogDeviceCompetitorSensorDataMappingEvent {
|
||||
private static final long serialVersionUID = -1494030544804758753L;
|
||||
|
||||
public interface Factory<T extends RegattaLogDeviceCompetitorSensorDataMappingEvent> {
|
||||
T create(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to);
|
||||
}
|
||||
|
||||
public AbstractRegattaLogDeviceCompetitorSensorDataMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* Mapping event for devices mapped for Bravo extended type fixes.
|
||||
*/
|
||||
public class RegattaLogDeviceBoatBravoExtendedMappingEventImpl extends AbstractRegattaLogDeviceBoatSensorDataMappingEventImpl {
|
||||
private static final long serialVersionUID = -1494030544804758753L;
|
||||
|
||||
|
||||
public RegattaLogDeviceBoatBravoExtendedMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Boat mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
|
||||
}
|
||||
|
||||
public RegattaLogDeviceBoatBravoExtendedMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||
Boat mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
|
||||
super(logicalTimePoint, author, mappedTo, device, from, to);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* Mapping event for devices mapped for Bravo type fixes.
|
||||
*/
|
||||
public class RegattaLogDeviceBoatBravoMappingEventImpl extends AbstractRegattaLogDeviceBoatSensorDataMappingEventImpl {
|
||||
private static final long serialVersionUID = -1494030544804758753L;
|
||||
|
||||
public RegattaLogDeviceBoatBravoMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Boat mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
|
||||
}
|
||||
|
||||
public RegattaLogDeviceBoatBravoMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||
Boat mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
|
||||
super(logicalTimePoint, author, mappedTo, device, from, to);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* Mapping event for devices mapped for "Expedition" extended type fixes, coming from the
|
||||
* "Expedition" software that was originally used in the context of this solution only for
|
||||
* handling wind data but now is also used to forward sensor data into competitor tracks.
|
||||
*/
|
||||
public class RegattaLogDeviceBoatExpeditionExtendedMappingEventImpl extends AbstractRegattaLogDeviceBoatSensorDataMappingEventImpl {
|
||||
private static final long serialVersionUID = -7865925670153838864L;
|
||||
|
||||
public RegattaLogDeviceBoatExpeditionExtendedMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Boat mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, to);
|
||||
}
|
||||
|
||||
public RegattaLogDeviceBoatExpeditionExtendedMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||
Boat mappedTo, DeviceIdentifier device, TimePoint from, TimePoint to) {
|
||||
super(logicalTimePoint, author, mappedTo, device, from, to);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.MappingEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class RegattaLogDeviceBoatMappingEventImpl extends RegattaLogDeviceMappingEventImpl<Boat>
|
||||
implements RegattaLogDeviceBoatMappingEvent {
|
||||
public RegattaLogDeviceBoatMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Boat mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint toInclusive) {
|
||||
super(createdAt, logicalTimePoint, author, pId, mappedTo, device, from, toInclusive);
|
||||
}
|
||||
|
||||
public RegattaLogDeviceBoatMappingEventImpl(TimePoint logicalTimePoint, AbstractLogEventAuthor author,
|
||||
Boat mappedTo, DeviceIdentifier device, TimePoint from, TimePoint toInclusive) {
|
||||
super(logicalTimePoint, author, mappedTo, device, from, toInclusive);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -1494030544804758753L;
|
||||
|
||||
@Override
|
||||
public void accept(RegattaLogEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(MappingEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
||||
-1
@@ -13,7 +13,6 @@ import com.sap.sse.common.TimePoint;
|
||||
public class RegattaLogDeviceCompetitorBravoMappingEventImpl extends AbstractRegattaLogDeviceCompetitorSensorDataMappingEventImpl {
|
||||
private static final long serialVersionUID = -1494030544804758753L;
|
||||
|
||||
|
||||
public RegattaLogDeviceCompetitorBravoMappingEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable pId, Competitor mappedTo, DeviceIdentifier device,
|
||||
TimePoint from, TimePoint to) {
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.events.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.impl.AbstractLogEventImpl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class RegattaLogRegisterBoatEventImpl extends AbstractLogEventImpl<RegattaLogEventVisitor>
|
||||
implements RegattaLogRegisterBoatEvent {
|
||||
private static final long serialVersionUID = -4531928509653259811L;
|
||||
private final Boat boat;
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code boat} is null
|
||||
*/
|
||||
public RegattaLogRegisterBoatEventImpl(TimePoint createdAt, TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Serializable id, Boat boat) throws IllegalArgumentException {
|
||||
super(createdAt, logicalTimePoint, author, id);
|
||||
checkBoat(boat);
|
||||
this.boat = boat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code boat} is null
|
||||
*/
|
||||
public RegattaLogRegisterBoatEventImpl(TimePoint logicalTimePoint,
|
||||
AbstractLogEventAuthor author, Boat boat) throws IllegalArgumentException {
|
||||
this(now(), logicalTimePoint, author, randId(), boat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(RegattaLogEventVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
private static void checkBoat(Boat boat) throws IllegalArgumentException {
|
||||
if (boat == null) {
|
||||
throw new IllegalArgumentException("Boat may not be null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boat getBoat() {
|
||||
return boat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShortInfo() {
|
||||
return "boat: " + getBoat().toString();
|
||||
}
|
||||
}
|
||||
+8
@@ -7,8 +7,16 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.shared.events.impl.BaseRegisterCompetitorEventImpl;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
* This event can be used for 2 kinds of competitor registrations.
|
||||
* If 'canBoatsOfCompetitorsChangePerRace' is true for a regatta the event registers a standalone {@link Competitor} without a boat.
|
||||
* If 'canBoatsOfCompetitorsChangePerRace' is false the event registers a {@link CompetitorWithBoat}.
|
||||
* @author Frank Mittag
|
||||
*
|
||||
*/
|
||||
public class RegattaLogRegisterCompetitorEventImpl extends BaseRegisterCompetitorEventImpl<RegattaLogEventVisitor>
|
||||
implements RegattaLogRegisterCompetitorEvent {
|
||||
private static final long serialVersionUID = -5114645637316367845L;
|
||||
|
||||
+15
@@ -3,9 +3,12 @@ package com.sap.sailing.domain.abstractlog.regatta.impl;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
||||
@@ -24,15 +27,27 @@ public class BaseRegattaLogEventVisitor implements RegattaLogEventVisitor {
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterBoatEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterCompetitorEvent event) {
|
||||
}
|
||||
|
||||
+18
@@ -4,9 +4,12 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogCloseOpenEndedDeviceMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDefineMarkEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceBoatSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorSensorDataMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMarkMappingEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRevokeEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogSetCompetitorTimeOnDistanceAllowancePerNauticalMileEvent;
|
||||
@@ -29,12 +32,22 @@ public abstract class RegattaLogEventListener implements RegattaLogEventVisitor
|
||||
public void visit(RegattaLogDeviceCompetitorMappingEvent event) {
|
||||
eventAdded(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatMappingEvent event) {
|
||||
eventAdded(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogCloseOpenEndedDeviceMappingEvent event) {
|
||||
eventAdded(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterBoatEvent event) {
|
||||
eventAdded(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogRegisterCompetitorEvent event) {
|
||||
eventAdded(event);
|
||||
@@ -59,4 +72,9 @@ public abstract class RegattaLogEventListener implements RegattaLogEventVisitor
|
||||
public void visit(RegattaLogDeviceCompetitorSensorDataMappingEvent event) {
|
||||
eventAdded(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(RegattaLogDeviceBoatSensorDataMappingEvent event) {
|
||||
eventAdded(event);
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLog;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEventAuthor;
|
||||
import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* Finds the boat registration events for a given set of {@link Boat boats} that must be
|
||||
* {@link AbstractLog#revokeEvent(AbstractLogEventAuthor, AbstractLogEvent) revoked} in order to deregister the
|
||||
* boats. Note that the de-registration cannot be performed during analysis because
|
||||
* {@link BaseLogAnalyzer#analyze()} obtains a read lock on the log whereas
|
||||
* {@link AbstractLog#revokeEvent(AbstractLogEventAuthor, AbstractLogEvent)} requires a write lock, and upgrading from a
|
||||
* read to a write lock is not possible.<p>
|
||||
*
|
||||
* Clients must call {@link #deregister} with the result of {@link #analyze()} in order to actually perform the
|
||||
* deregistration.
|
||||
*
|
||||
* @author Frank Mittag
|
||||
*
|
||||
*/
|
||||
public class RegattaLogBoatDeregistrator<LogT extends AbstractLog<EventT, VisitorT>, EventT extends AbstractLogEvent<VisitorT>, VisitorT>
|
||||
extends BaseLogAnalyzer<LogT, EventT, VisitorT, Set<EventT>> {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RegattaLogBoatDeregistrator.class.getName());
|
||||
protected final Iterable<Boat> boatsToDeregister;
|
||||
private AbstractLogEventAuthor eventAuthor;
|
||||
|
||||
public RegattaLogBoatDeregistrator(LogT log, Iterable<Boat> boatsToDeregister, AbstractLogEventAuthor eventAuthor) {
|
||||
super(log);
|
||||
this.boatsToDeregister = boatsToDeregister;
|
||||
this.eventAuthor = eventAuthor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<EventT> performAnalysis() {
|
||||
final Set<EventT> result = new HashSet<>();
|
||||
final HashSet<Boat> boatSet = new HashSet<Boat>();
|
||||
Util.addAll(boatsToDeregister, boatSet);
|
||||
for (EventT event : log.getUnrevokedEventsDescending()) {
|
||||
if (event instanceof RegattaLogRegisterBoatEvent) {
|
||||
RegattaLogRegisterBoatEvent registerEvent = (RegattaLogRegisterBoatEvent) event;
|
||||
if (boatSet.contains(registerEvent.getBoat())) {
|
||||
result.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void deregister(final Set<EventT> boatRegistrationEvents) {
|
||||
for (final EventT event : boatRegistrationEvents) {
|
||||
try {
|
||||
log.revokeEvent(eventAuthor, event,
|
||||
"unregistering boat because no longer selected for registration");
|
||||
} catch (NotRevokableException e) {
|
||||
logger.log(Level.WARNING, "could not unregister boat by adding RevokeEvent", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package com.sap.sailing.domain.abstractlog.regatta.tracking.analyzing.impl;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLog;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterBoatEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
|
||||
/**
|
||||
* This class searches for RegisterBoat events in the given log.
|
||||
*
|
||||
* Boats alone in a regatta log are not enough to be used in a real race.
|
||||
* Instead a competitor and a boat together must be registered through a {@link RegisterCompetitorEvent} event.
|
||||
*
|
||||
*/
|
||||
public class RegattaLogBoatsInLogAnalyzer<LogT extends AbstractLog<EventT, VisitorT>, EventT extends AbstractLogEvent<VisitorT>, VisitorT>
|
||||
extends BaseLogAnalyzer<LogT, EventT, VisitorT, Set<Boat>> {
|
||||
|
||||
public RegattaLogBoatsInLogAnalyzer(LogT log) {
|
||||
super(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Boat> performAnalysis() {
|
||||
Set<Boat> result = new HashSet<Boat>();
|
||||
for (EventT event : getLog().getUnrevokedEvents()) {
|
||||
if (event instanceof RegattaLogRegisterBoatEvent) {
|
||||
result.add(((RegattaLogRegisterBoatEvent) event).getBoat());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.sap.sailing.domain.abstractlog.shared.analyzing;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLog;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.BaseLogAnalyzer;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogRegisterCompetitorEvent;
|
||||
import com.sap.sailing.domain.base.Boat;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CompetitorWithBoat;
|
||||
|
||||
/**
|
||||
* This class searches for {@link RaceLogRegisterCompetitorEvent}s or {@link RegattaLogRegisterCompetitorEvent}s in the given log
|
||||
* in order to determine the competitor/boat mappings for both kind of events
|
||||
*
|
||||
*/
|
||||
public class CompetitorsAndBoatsInLogAnalyzer<LogT extends AbstractLog<EventT, VisitorT>, EventT extends AbstractLogEvent<VisitorT>, VisitorT>
|
||||
extends BaseLogAnalyzer<LogT, EventT, VisitorT, Map<Competitor, Boat>> {
|
||||
|
||||
public CompetitorsAndBoatsInLogAnalyzer(LogT log) {
|
||||
super(log);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Competitor, Boat> performAnalysis() {
|
||||
Map<Competitor, Boat> result = new HashMap<>();
|
||||
LogT log = getLog();
|
||||
|
||||
if (log instanceof RegattaLog) {
|
||||
for (EventT event : getLog().getUnrevokedEvents()) {
|
||||
if (event instanceof RegattaLogRegisterCompetitorEvent) {
|
||||
RegattaLogRegisterCompetitorEvent regattaLogCompetitorEvent = (RegattaLogRegisterCompetitorEvent) event;
|
||||
if (regattaLogCompetitorEvent.getCompetitor().hasBoat()) {
|
||||
CompetitorWithBoat competitorWithBoat = (CompetitorWithBoat) regattaLogCompetitorEvent.getCompetitor();
|
||||
result.put(competitorWithBoat, competitorWithBoat.getBoat());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (log instanceof RaceLog) {
|
||||
for (EventT event : getLog().getUnrevokedEvents()) {
|
||||
if (event instanceof RaceLogRegisterCompetitorEvent) {
|
||||
RaceLogRegisterCompetitorEvent raceLogCompetitorEvent = (RaceLogRegisterCompetitorEvent) event;
|
||||
result.put(raceLogCompetitorEvent.getCompetitor(), raceLogCompetitorEvent.getBoat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -35,7 +35,7 @@ public class CompetitorsInLogAnalyzer<LogT extends AbstractLog<EventT, VisitorT>
|
||||
|
||||
@Override
|
||||
protected Set<Competitor> performAnalysis() {
|
||||
Set<Competitor> result = new HashSet<Competitor>();
|
||||
Set<Competitor> result = new HashSet<>();
|
||||
|
||||
for (EventT event : getLog().getUnrevokedEvents()) {
|
||||
if (event instanceof RegisterCompetitorEvent) {
|
||||
|
||||
+2
-1
@@ -3,11 +3,12 @@ package com.sap.sailing.domain.abstractlog.shared.events;
|
||||
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
|
||||
import com.sap.sailing.domain.abstractlog.Revokable;
|
||||
import com.sap.sailing.domain.abstractlog.race.RaceLog;
|
||||
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
|
||||
/**
|
||||
* Register a competitor for that race using the {@link RaceLog} in racelog-tracked races.
|
||||
* Register a competitor for {@link RaceLog} and {@link RegattaLog} tracked races and regattas.
|
||||
*
|
||||
* A dummy {@link Competitor} implementation with only an {@link Competitor#getId() id} may be used,
|
||||
* if the competitor is known to already exist on the server, as it is
|
||||
|
||||
+22
-3
@@ -1,14 +1,33 @@
|
||||
package com.sap.sailing.domain.base;
|
||||
|
||||
import com.sap.sse.common.Color;
|
||||
import com.sap.sse.common.Named;
|
||||
import com.sap.sse.common.IsManagedByCache;
|
||||
import com.sap.sse.common.NamedWithID;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
|
||||
public interface Boat extends Named {
|
||||
BoatClass getBoatClass();
|
||||
/**
|
||||
* The boat being sailed by a competitor.
|
||||
*
|
||||
*/
|
||||
public interface Boat extends NamedWithID, IsManagedByCache<SharedDomainFactory> {
|
||||
BoatClass getBoatClass();
|
||||
|
||||
@Dimension(messageKey="SailID")
|
||||
String getSailID();
|
||||
|
||||
Color getColor();
|
||||
|
||||
/**
|
||||
* Adds a listener to this boat.
|
||||
* Adding a listener that is already part of this boat's listeners set remains without effect.
|
||||
*/
|
||||
void addBoatChangeListener(BoatChangeListener listener);
|
||||
|
||||
/**
|
||||
* Removes a listener from this boat.
|
||||
* Trying to remove a listener that is not currently in the set of this boats's listener remains
|
||||
* without effect.
|
||||
*/
|
||||
void removeBoatChangeListener(BoatChangeListener listener);
|
||||
|
||||
}
|
||||
Loaded 100 of 840 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user