diff --git a/.gitignore b/.gitignore
index 00de9eb7a46..fa2035fc9ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,6 @@ sailing_debug0*
/java/com.sap.sailing.server.gateway.serialization.test/.settings/*.prefs
.DS_Store
java/com.sap.sailing.simulator/bin/com/sap/sailing/simulator/Simulator.gwt.xml
+/mobile/google-play-services_lib/bin/*
+
+/mobile/com.sap.sailing.racecommittee.app/res/values/keys.xml
diff --git a/configuration/buildAndUpdateProduct.sh b/configuration/buildAndUpdateProduct.sh
index ac1cc21b32f..438b327b63e 100755
--- a/configuration/buildAndUpdateProduct.sh
+++ b/configuration/buildAndUpdateProduct.sh
@@ -379,7 +379,7 @@ if [[ "$@" == "install" ]] || [[ "$@" == "all" ]]; then
# make sure to save the information from env.sh
. $ACDIR/env.sh
- echo "$VERSION_INFO-$MONGDB_PORT-$MEMORY-$REPLICATION_CHANNEL" > $ACDIR/configuration/jetty/version.txt
+ echo "$VERSION_INFO-$MONGODB_PORT-$MEMORY-$REPLICATION_CHANNEL" > $ACDIR/configuration/jetty/version.txt
sed -i "s/mongo.port=.*$/mongo.port=$MONGODB_PORT/g" $ACDIR/configuration/config.ini
sed -i "s/expedition.udp.port=.*$/expedition.udp.port=$EXPEDITION_PORT/g" $ACDIR/configuration/config.ini
diff --git a/java/com.sap.sailing.domain.common/META-INF/MANIFEST.MF b/java/com.sap.sailing.domain.common/META-INF/MANIFEST.MF
index 37de5a111b9..f2de8aac085 100755
--- a/java/com.sap.sailing.domain.common/META-INF/MANIFEST.MF
+++ b/java/com.sap.sailing.domain.common/META-INF/MANIFEST.MF
@@ -13,4 +13,5 @@ Export-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.common.quadtree,
com.sap.sailing.domain.common.quadtree.impl;x-friends:="com.sap.sailing.domain.test",
com.sap.sailing.domain.common.racelog,
+ com.sap.sailing.domain.common.racelog.utils,
com.sap.sailing.domain.common.dto
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MarkType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MarkType.java
index 11e361cd195..aef826d30e3 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MarkType.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MarkType.java
@@ -1,3 +1,3 @@
package com.sap.sailing.domain.common;
-public enum MarkType { BUOY, CAMERABOAT, STARTBOAT, UMPIREBOAT, LANDMARK }
\ No newline at end of file
+public enum MarkType { BUOY, CAMERABOAT, STARTBOAT, UMPIREBOAT, LANDMARK, FINISHBOAT }
\ No newline at end of file
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RaceLogRaceStatus.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RaceLogRaceStatus.java
index 84dbfc45378..c0ba3da7a37 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RaceLogRaceStatus.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/RaceLogRaceStatus.java
@@ -2,8 +2,17 @@ package com.sap.sailing.domain.common.racelog;
/**
* @author D053502
- *
+ *
*/
public enum RaceLogRaceStatus {
- UNKNOWN, UNSCHEDULED, SCHEDULED, STARTPHASE, RUNNING, FINISHING, FINISHED
+ UNKNOWN, UNSCHEDULED, SCHEDULED, STARTPHASE, RUNNING, FINISHING, FINISHED;
+
+ public static boolean isActive(RaceLogRaceStatus status) {
+ if (status == null) {
+ return false;
+ }
+
+ return status.equals(SCHEDULED) || status.equals(STARTPHASE) || status.equals(RUNNING)
+ || status.equals(FINISHING);
+ }
}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/StartProcedureType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/StartProcedureType.java
index b39fbb39d43..0bd82f959ba 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/StartProcedureType.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/StartProcedureType.java
@@ -1,18 +1,18 @@
package com.sap.sailing.domain.common.racelog;
public enum StartProcedureType {
- //RRS26("Fix Line Start (RRS26)"),
+ RRS26("Fix Line Start (RRS26)"),
GateStart("Gate Start"),
ESS("\"Extreme Sailing Series\"-Start");
private String displayName;
- private StartProcedureType(String displayName){
+ private StartProcedureType(String displayName) {
this.displayName = displayName;
}
@Override
- public String toString(){
+ public String toString() {
return displayName;
}
}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/utils/FlagAlphabetInterpretationTemplate.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/utils/FlagAlphabetInterpretationTemplate.java
new file mode 100644
index 00000000000..ed86ebb1309
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/utils/FlagAlphabetInterpretationTemplate.java
@@ -0,0 +1,74 @@
+package com.sap.sailing.domain.common.racelog.utils;
+
+import com.sap.sailing.domain.common.racelog.Flags;
+import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
+
+public abstract class FlagAlphabetInterpretationTemplate {
+
+ public String getMeaningOfRaceStateAndFlags(RaceLogRaceStatus status, Flags upperFlag, Flags lowerFlag, boolean isDisplayed) {
+ String statusText = "";
+ if (status.equals(RaceLogRaceStatus.RUNNING) && upperFlag.equals(Flags.XRAY) && isDisplayed) {
+ statusText = getTextForRunningRaceWithEarlyStarter();
+ } else if (status.equals(RaceLogRaceStatus.RUNNING) && upperFlag.equals(Flags.XRAY) && !isDisplayed) {
+ statusText = getTextForRunningRace();
+ } else if (status.equals(RaceLogRaceStatus.RUNNING)) {
+ statusText = getTextForRunningRace();
+ } else if (status.equals(RaceLogRaceStatus.FINISHING)) {
+ statusText = getTextForFinishingRace();
+ } else if (status.equals(RaceLogRaceStatus.FINISHED)) {
+ statusText = getTextForFinishedRace();
+ } else if (status.equals(RaceLogRaceStatus.SCHEDULED)) {
+ statusText = getTextForScheduledRace();
+ } else if (status.equals(RaceLogRaceStatus.STARTPHASE)) {
+ statusText = getTextForRaceInStartphase();
+ } else if (status.equals(RaceLogRaceStatus.UNSCHEDULED)) {
+ statusText = getTextForUnscheduledRace();
+ if (upperFlag != null) {
+ if (upperFlag.equals(Flags.FIRSTSUBSTITUTE)) {
+ statusText = getTextForFirstSubstituteFlag();
+ } else if (upperFlag.equals(Flags.AP) && lowerFlag.equals(Flags.ALPHA) && isDisplayed) {
+ statusText = getTextForAnsweringPennantWithAlphaFlags();
+ } else if (upperFlag.equals(Flags.AP) && lowerFlag.equals(Flags.HOTEL) && isDisplayed) {
+ statusText = getTextForAnsweringPennantWithHotelFlags();
+ } else if (upperFlag.equals(Flags.AP) && isDisplayed) {
+ statusText = getTextForAnsweringPennantFlag();
+ } else if (upperFlag.equals(Flags.NOVEMBER) && lowerFlag.equals(Flags.ALPHA) && isDisplayed) {
+ statusText = getTextForNovemberWithAlphaFlags();
+ } else if (upperFlag.equals(Flags.NOVEMBER) && lowerFlag.equals(Flags.HOTEL) && isDisplayed) {
+ statusText = getTextForNovemberWithHotelFlags();
+ } else if (upperFlag.equals(Flags.NOVEMBER) && isDisplayed) {
+ statusText = getTextForNovemberFlag();
+ }
+ }
+ }
+ return statusText;
+ }
+
+ protected abstract String getTextForRunningRace();
+
+ protected abstract String getTextForRunningRaceWithEarlyStarter();
+
+ protected abstract String getTextForFinishingRace();
+
+ protected abstract String getTextForFinishedRace();
+
+ protected abstract String getTextForScheduledRace();
+
+ protected abstract String getTextForRaceInStartphase();
+
+ protected abstract String getTextForUnscheduledRace();
+
+ protected abstract String getTextForFirstSubstituteFlag();
+
+ protected abstract String getTextForAnsweringPennantFlag();
+
+ protected abstract String getTextForAnsweringPennantWithAlphaFlags();
+
+ protected abstract String getTextForAnsweringPennantWithHotelFlags();
+
+ protected abstract String getTextForNovemberFlag();
+
+ protected abstract String getTextForNovemberWithAlphaFlags();
+
+ protected abstract String getTextForNovemberWithHotelFlags();
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/utils/RaceStateOfSameDayHelper.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/utils/RaceStateOfSameDayHelper.java
new file mode 100644
index 00000000000..4e3c37a8d41
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/utils/RaceStateOfSameDayHelper.java
@@ -0,0 +1,47 @@
+package com.sap.sailing.domain.common.racelog.utils;
+
+import java.util.Calendar;
+import java.util.Date;
+
+import com.sap.sailing.domain.common.TimePoint;
+
+public class RaceStateOfSameDayHelper {
+
+ public static boolean isRaceStateOfSameDay(TimePoint raceStartTimePoint, TimePoint raceFinishedTimePoint, Calendar now) {
+ Date raceStartTime = null;
+ Date raceFinishedTime = null;
+
+ if (raceStartTimePoint != null) {
+ raceStartTime = raceStartTimePoint.asDate();
+ }
+ if (raceFinishedTimePoint != null) {
+ raceFinishedTime = raceFinishedTimePoint.asDate();
+ }
+
+ return isRaceStateOfSameDay(raceStartTime, raceFinishedTime, now);
+ }
+
+ public static boolean isRaceStateOfSameDay(Date raceStartTime, Date raceFinishedTime, Calendar now) {
+ boolean result = false;
+ if (raceFinishedTime != null) {
+ Calendar finishedTimeCal = Calendar.getInstance();
+ finishedTimeCal.setTime(raceFinishedTime);
+ if(isSameDay(now, finishedTimeCal)) {
+ result = true;
+ }
+ } else if (raceStartTime != null) {
+ Calendar startTimeCal = Calendar.getInstance();
+ startTimeCal.setTime(raceStartTime);
+ if(isSameDay(now, startTimeCal)) {
+ result = true;
+ }
+ }
+ return result;
+ }
+
+ private static boolean isSameDay(Calendar cal1, Calendar cal2) {
+ return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
+ cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
index d9089de27d0..931fd011d15 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
@@ -38,7 +38,6 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.SpeedWithBearing;
import com.sap.sailing.domain.base.Venue;
import com.sap.sailing.domain.base.Waypoint;
-import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.CourseDataImpl;
import com.sap.sailing.domain.base.impl.EventImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
@@ -83,8 +82,8 @@ import com.sap.sailing.domain.leaderboard.ThresholdBasedResultDiscardingRule;
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
-import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.impl.ScoreCorrectionImpl;
+import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
import com.sap.sailing.domain.leaderboard.meta.LeaderboardGroupMetaLeaderboard;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
import com.sap.sailing.domain.persistence.MongoRaceLogStoreFactory;
@@ -100,10 +99,12 @@ import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogStore;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
import com.sap.sailing.domain.tracking.TrackedRegattaRegistry;
import com.sap.sailing.domain.tracking.Wind;
@@ -333,26 +334,6 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return result;
}
- private CourseArea loadCourseAreaFromEvents(DBObject dbObject) {
- Serializable courseAreaId = (Serializable) dbObject.get(FieldNames.COURSE_AREA_ID.name());
- CourseArea result;
- if (courseAreaId == null) {
- result = null;
- } else {
- UUID courseAreaUuid = UUID.fromString(courseAreaId.toString());
- Iterable allEvents = loadAllEvents();
- result = null;
- for (Event event : allEvents) {
- for (CourseArea courseArea : event.getVenue().getCourseAreas()) {
- if (courseArea.getId().equals(courseAreaUuid)) {
- result = courseArea;
- }
- }
- }
- }
- return result;
- }
-
/**
* @return null if the regatta cannot be resolved; otherwise the leaderboard for the regatta specified
*/
@@ -382,7 +363,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
final ScoringScheme scoringScheme = loadScoringScheme(dbLeaderboard);
RaceLogStore raceLogStore = MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(
new MongoObjectFactoryImpl(database), this);
- CourseArea courseArea = loadCourseAreaFromEvents(dbLeaderboard);
+
+ Serializable courseAreaId = (Serializable) dbLeaderboard.get(FieldNames.COURSE_AREA_ID.name());
+ CourseArea courseArea = null;
+ if (courseAreaId != null) {
+ UUID courseAreaUuid = UUID.fromString(courseAreaId.toString());
+ courseArea = DomainFactory.INSTANCE.getExistingCourseAreaById(courseAreaUuid);
+ }
+
result = new FlexibleLeaderboardImpl(raceLogStore, (String) dbLeaderboard.get(FieldNames.LEADERBOARD_NAME
.name()), scoreCorrection, resultDiscardingRule, scoringScheme, courseArea);
// For a FlexibleLeaderboard, fleets are owned by the leaderboard's RaceColumn objects. We need to manage
@@ -839,7 +827,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
private CourseArea loadCourseArea(DBObject courseAreaDBObject) {
String name = (String) courseAreaDBObject.get(FieldNames.COURSE_AREA_NAME.name());
Serializable id = (Serializable) courseAreaDBObject.get(FieldNames.COURSE_AREA_ID.name());
- return new CourseAreaImpl(name, id);
+ return DomainFactory.INSTANCE.getOrCreateCourseArea(id, name);
}
@Override
@@ -881,7 +869,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
RaceLogStore raceLogStore = MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(
new MongoObjectFactoryImpl(database),
this);
- CourseArea courseArea = loadCourseAreaFromEvents(dbRegatta);
+
+ Serializable courseAreaId = (Serializable) dbRegatta.get(FieldNames.COURSE_AREA_ID.name());
+ CourseArea courseArea = null;
+ if (courseAreaId != null) {
+ UUID courseAreaUuid = UUID.fromString(courseAreaId.toString());
+ courseArea = DomainFactory.INSTANCE.getExistingCourseAreaById(courseAreaUuid);
+ }
+
result = new RegattaImpl(raceLogStore, baseName, boatClass, series, /* persistent */ true, loadScoringScheme(dbRegatta), id, courseArea);
}
return result;
@@ -1058,11 +1053,27 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return loadRaceLogGateLineOpeningTimeEvent(createdAt, timePoint, id, passId, competitors, dbObject);
} else if (eventClass.equals(RaceLogStartProcedureChangedEvent.class.getSimpleName())) {
return loadRaceLogStartProcedureChangedEvent(createdAt, timePoint, id, passId, competitors, dbObject);
+ } else if (eventClass.equals(RaceLogProtestStartTimeEvent.class.getSimpleName())) {
+ return loadRaceLogRaceLogProtestStartTimeEvent(createdAt, timePoint, id, passId, competitors, dbObject);
+ } else if (eventClass.equals(RaceLogWindFixEvent.class.getSimpleName())) {
+ return loadRaceLogRaceLogWindFixEvent(createdAt, timePoint, id, passId, competitors, dbObject);
}
throw new IllegalStateException(String.format("Unknown RaceLogEvent type %s", eventClass));
}
+ private RaceLogEvent loadRaceLogRaceLogWindFixEvent(TimePoint createdAt, TimePoint timePoint, Serializable id,
+ Integer passId, List competitors, DBObject dbObject) {
+ Wind wind = loadWind((DBObject) dbObject.get(FieldNames.WIND.name()));
+ return raceLogEventFactory.createWindFixEvent(createdAt, timePoint, id, competitors, passId, wind);
+ }
+
+ private RaceLogEvent loadRaceLogRaceLogProtestStartTimeEvent(TimePoint createdAt, TimePoint timePoint,
+ Serializable id, Integer passId, List competitors, DBObject dbObject) {
+ TimePoint protestStartTime = loadTimePoint(dbObject, FieldNames.RACE_LOG_PROTEST_START_TIME);
+ return raceLogEventFactory.createProtestStartTimeEvent(createdAt, timePoint, id, competitors, passId, protestStartTime);
+ }
+
private RaceLogEvent loadRaceLogStartProcedureChangedEvent(TimePoint createdAt, TimePoint timePoint,
Serializable id, Integer passId, List competitors, DBObject dbObject) {
StartProcedureType type = StartProcedureType.valueOf(dbObject.get(FieldNames.RACE_LOG_START_PROCEDURE_TYPE.name()).toString());
@@ -1084,7 +1095,15 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
private RaceLogEvent loadRaceLogFinishPositioningConfirmedEvent(TimePoint createdAt, TimePoint timePoint,
Serializable id, Integer passId, List competitors, DBObject dbObject) {
- return raceLogEventFactory.createFinishPositioningConfirmedEvent(createdAt, timePoint, id, competitors, passId);
+ BasicDBList dbPositionedCompetitorList = (BasicDBList) dbObject.get(FieldNames.RACE_LOG_POSITIONED_COMPETITORS.name());
+ List> positionedCompetitors = null;
+ //When a confirmation event is loaded that does not contain the positioned competitors (this is the case for the ESS events in
+ //Singapore and Quingdao) then null should be set for the positionedCompetitors, which is evaluated later on.
+ if (dbPositionedCompetitorList != null) {
+ positionedCompetitors = loadPositionedCompetitors(dbPositionedCompetitorList);
+ }
+
+ return raceLogEventFactory.createFinishPositioningConfirmedEvent(createdAt, timePoint, id, competitors, passId, positionedCompetitors);
}
private RaceLogEvent loadRaceLogFinishPositioningListChangedEvent(TimePoint createdAt, TimePoint timePoint,
@@ -1101,7 +1120,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
}
private RaceLogCourseDesignChangedEvent loadRaceLogCourseDesignChangedEvent(TimePoint createdAt, TimePoint timePoint, Serializable id, Integer passId, List competitors, DBObject dbObject) {
- CourseBase courseData = loadCourseData((BasicDBList) dbObject.get(FieldNames.RACE_LOG_COURSE_DESIGN.name()));
+ String courseName = (String) dbObject.get(FieldNames.RACE_LOG_COURSE_DESIGN_NAME.name());
+ CourseBase courseData = loadCourseData((BasicDBList) dbObject.get(FieldNames.RACE_LOG_COURSE_DESIGN.name()), courseName);
return raceLogEventFactory.createCourseDesignChangedEvent(createdAt, timePoint, id, competitors, passId, courseData);
}
@@ -1168,8 +1188,11 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
return raceLogEventFactory.createRaceStatusEvent(createdAt, timePoint, id, competitors, passId, nextStatus);
}
- private CourseBase loadCourseData(BasicDBList dbCourseList) {
- CourseBase courseData = new CourseDataImpl("TemplateCourse");
+ private CourseBase loadCourseData(BasicDBList dbCourseList, String courseName) {
+ if (courseName == null) {
+ courseName = "Course template";
+ }
+ CourseBase courseData = new CourseDataImpl(courseName);
int i = 0;
for (Object object : dbCourseList) {
DBObject dbObject = (DBObject) object;
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java
index 5b9853889f6..1ccaf2b5a3d 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/FieldNames.java
@@ -72,5 +72,6 @@ public enum FieldNames {
RACE_LOG_EVENT, RACE_LOG_EVENT_PASS_ID, RACE_LOG_EVENT_ID, RACE_LOG_EVENT_CREATED_AT, RACE_LOG_EVENT_INVOLVED_BOATS, RACE_LOG_EVENT_FLAG_UPPER, RACE_LOG_EVENT_FLAG_LOWER,
RACE_LOG_EVENT_FLAG_DISPLAYED, RACE_LOG_EVENT_START_TIME, RACE_LOG_EVENT_CLASS, RACE_LOG_EVENT_NEXT_STATUS, RACE_LOG_COURSE_DESIGN, WAYPOINT_ID,
WAYPOINT_NAME, WAYPOINT_PASSINGSIDE, CONTROLPOINT, CONTROLPOINT_CLASS, MARK_ID, MARK_COLOR, MARK_NAME, MARK_PATTERN, MARK_SHAPE, MARK_TYPE,
- CONTROLPOINT_VALUE, GATE_ID, GATE_NAME, GATE_LEFT, GATE_RIGHT, RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME, RACE_LOG_START_PROCEDURE_TYPE;
+ CONTROLPOINT_VALUE, GATE_ID, GATE_NAME, GATE_LEFT, GATE_RIGHT, RACE_LOG_POSITIONED_COMPETITORS, RACE_LOG_PATHFINDER_ID, RACE_LOG_GATE_LINE_OPENING_TIME,
+ RACE_LOG_START_PROCEDURE_TYPE, RACE_LOG_PROTEST_START_TIME, RACE_LOG_COURSE_DESIGN_NAME;
}
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
index f175862a823..f38d50af98b 100755
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
@@ -55,9 +55,11 @@ import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.tracking.Positioned;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.TrackedRegatta;
@@ -605,8 +607,6 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogGateLineOpeningTimeEvent(gateLineOpeningTimeEvent));
return result;
}
-
-
public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogStartProcedureChangedEvent event) {
DBObject result = new BasicDBObject();
@@ -614,7 +614,39 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogStartProcedureChangedEvent(event));
return result;
}
+
+ public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogProtestStartTimeEvent event) {
+ DBObject result = new BasicDBObject();
+ result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
+ result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogProtestStartTimeEvent(event));
+ return result;
+ }
+ public DBObject storeRaceLogEntry(RaceLogIdentifier raceLogIdentifier, RaceLogWindFixEvent event) {
+ DBObject result = new BasicDBObject();
+ result.put(FieldNames.RACE_LOG_IDENTIFIER.name(), MongoUtils.escapeDollarAndDot(raceLogIdentifier.getIdentifier().toString()));
+ result.put(FieldNames.RACE_LOG_EVENT.name(), storeRaceLogWindFix(event));
+ return result;
+ }
+
+ private Object storeRaceLogWindFix(RaceLogWindFixEvent event) {
+ DBObject result = new BasicDBObject();
+ storeRaceLogEventProperties(event, result);
+
+ result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogWindFixEvent.class.getSimpleName());
+ result.put(FieldNames.WIND.name(), storeWind(event.getWindFix()));
+ return result;
+ }
+
+ private Object storeRaceLogProtestStartTimeEvent(RaceLogProtestStartTimeEvent event) {
+ DBObject result = new BasicDBObject();
+ storeRaceLogEventProperties(event, result);
+
+ result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogProtestStartTimeEvent.class.getSimpleName());
+ storeTimePoint(event.getProtestStartTime(), result, FieldNames.RACE_LOG_PROTEST_START_TIME);
+ return result;
+ }
+
private Object storeRaceLogStartProcedureChangedEvent(RaceLogStartProcedureChangedEvent event) {
DBObject result = new BasicDBObject();
storeRaceLogEventProperties(event, result);
@@ -656,7 +688,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
result.put(FieldNames.RACE_LOG_EVENT_FLAG_DISPLAYED.name(), String.valueOf(flagEvent.isDisplayed()));
return result;
}
-
+
private void storeRaceLogEventProperties(RaceLogEvent event, DBObject result) {
storeTimed(event, result);
storeTimePoint(event.getCreatedAt(), result, FieldNames.RACE_LOG_EVENT_CREATED_AT);
@@ -707,7 +739,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
storeRaceLogEventProperties(courseDesignChangedEvent, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogCourseDesignChangedEvent.class.getSimpleName());
-
+
+ result.put(FieldNames.RACE_LOG_COURSE_DESIGN_NAME.name(), courseDesignChangedEvent.getCourseDesign().getName());
result.put(FieldNames.RACE_LOG_COURSE_DESIGN.name(), storeCourseBase(courseDesignChangedEvent.getCourseDesign()));
return result;
}
@@ -728,6 +761,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
storeRaceLogEventProperties(finishPositioningConfirmedEvent, result);
result.put(FieldNames.RACE_LOG_EVENT_CLASS.name(), RaceLogFinishPositioningConfirmedEvent.class.getSimpleName());
+
+ result.put(FieldNames.RACE_LOG_POSITIONED_COMPETITORS.name(), storePositionedCompetitors(finishPositioningConfirmedEvent.getPositionedCompetitors()));
return result;
}
@@ -745,10 +780,12 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
private BasicDBList storePositionedCompetitors(List> positionedCompetitors) {
BasicDBList dbList = new BasicDBList();
- for (Triple competitorPair : positionedCompetitors) {
- dbList.add(storePositionedCompetitor(competitorPair));
+ if (positionedCompetitors != null) {
+ for (Triple competitorPair : positionedCompetitors) {
+ dbList.add(storePositionedCompetitor(competitorPair));
+ }
}
-
+
return dbList;
}
@@ -817,4 +854,5 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
}
return passing;
}
+
}
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogListener.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogListener.java
index c91a5c5ec4c..55493b47612 100644
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogListener.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoRaceLogListener.java
@@ -14,9 +14,11 @@ import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
public class MongoRaceLogListener implements RaceLogEventVisitor {
@@ -79,20 +81,20 @@ public class MongoRaceLogListener implements RaceLogEventVisitor {
@Override
public void visit(RaceLogFinishPositioningConfirmedEvent event) {
- DBObject finishPositioningConfirmedEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
- storeEventInCollection(finishPositioningConfirmedEventTrackEntry);
+ DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
+ storeEventInCollection(object);
}
@Override
public void visit(RaceLogPathfinderEvent event) {
- DBObject pathfinderEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
- storeEventInCollection(pathfinderEventTrackEntry);
+ DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
+ storeEventInCollection(object);
}
@Override
public void visit(RaceLogGateLineOpeningTimeEvent event) {
- DBObject gateLineOpeningTimeEventTrackEntry = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
- storeEventInCollection(gateLineOpeningTimeEventTrackEntry);
+ DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
+ storeEventInCollection(object);
}
@Override
@@ -101,4 +103,16 @@ public class MongoRaceLogListener implements RaceLogEventVisitor {
storeEventInCollection(object);
}
+ @Override
+ public void visit(RaceLogProtestStartTimeEvent event) {
+ DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
+ storeEventInCollection(object);
+ }
+
+ @Override
+ public void visit(RaceLogWindFixEvent event) {
+ DBObject object = mongoObjectFactory.storeRaceLogEntry(raceLogIdentifier, event);
+ storeEventInCollection(object);
+ }
+
}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/AbortingFlagFinderTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/AbortingFlagFinderTest.java
new file mode 100644
index 00000000000..7128fd9300b
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/AbortingFlagFinderTest.java
@@ -0,0 +1,122 @@
+package com.sap.sailing.domain.racelog.analyzing.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.when;
+
+import java.util.UUID;
+
+import org.junit.Test;
+
+import com.sap.sailing.domain.common.racelog.Flags;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
+import com.sap.sailing.domain.racelog.analyzing.impl.AbortingFlagFinder;
+
+public class AbortingFlagFinderTest extends RaceLogAnalyzerTest {
+
+ @Override
+ protected AbortingFlagFinder createAnalyzer(RaceLog raceLog) {
+ return new AbortingFlagFinder(raceLog);
+ }
+
+ @Test
+ public void testNullOnEmpty() {
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testNullOnNoPreviousPass() {
+ int passId = 0;
+ RaceLogFlagEvent event1 = createAbortingEvent(passId);
+
+ raceLog.add(event1);
+
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testNullOnPreviousPassNotAborted() {
+ int passId = 0;
+ RaceLogFlagEvent event1 = createNonAbortingEvent(passId);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 1, passId + 1, UUID.randomUUID());
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testNullOnPassBeforePreviousAborted() {
+ int passId = 0;
+ RaceLogFlagEvent event1 = createAbortingEvent(passId);
+ RaceLogFlagEvent event2 = createNonAbortingEvent(passId + 1);
+ RaceLogFlagEvent event3 = createEvent(RaceLogFlagEvent.class, 1, passId + 2, UUID.randomUUID());
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testPreviousPassAborted() {
+ int passId = 0;
+ RaceLogFlagEvent event1 = createAbortingEvent(passId);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 1, passId + 1, UUID.randomUUID());
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+
+ assertEquals(event1, analyzer.analyze());
+ }
+
+ @Test
+ public void testPreviousPassAbortedReturnsMostRecentAbortEvent() {
+ int passId = 0;
+ RaceLogFlagEvent event1 = createAbortingEvent(passId, 1);
+ RaceLogFlagEvent event2 = createAbortingEvent(passId, 2);
+ RaceLogFlagEvent event3 = createEvent(RaceLogFlagEvent.class, 1, passId + 1, UUID.randomUUID());
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ assertEquals(event2, analyzer.analyze());
+ }
+
+ @Test
+ public void testPreviousPassAndPassBeforePreviousAborted() {
+ int passId = 0;
+ RaceLogFlagEvent event1 = createAbortingEvent(passId);
+ RaceLogFlagEvent event2 = createAbortingEvent(passId + 1);
+ RaceLogFlagEvent event3 = createEvent(RaceLogFlagEvent.class, 1, passId + 2, UUID.randomUUID());
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ assertEquals(event2, analyzer.analyze());
+ }
+
+ private static RaceLogFlagEvent createAbortingEvent(int passId) {
+ return createAbortingEvent(passId, 1);
+ }
+
+ private static RaceLogFlagEvent createAbortingEvent(int passId, int time) {
+ RaceLogFlagEvent event = createEvent(RaceLogFlagEvent.class, time, passId, UUID.randomUUID());
+ when(event.getUpperFlag()).thenReturn(Flags.AP);
+ when(event.isDisplayed()).thenReturn(true);
+ return event;
+ }
+
+ private static RaceLogFlagEvent createNonAbortingEvent(int passId) {
+ RaceLogFlagEvent event = createEvent(RaceLogFlagEvent.class, 1, passId, UUID.randomUUID());
+ when(event.getUpperFlag()).thenReturn(Flags.AP);
+ when(event.isDisplayed()).thenReturn(false);
+ return event;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/LastFlagsFinderTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/LastFlagsFinderTest.java
new file mode 100644
index 00000000000..c5f84c32151
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/LastFlagsFinderTest.java
@@ -0,0 +1,172 @@
+package com.sap.sailing.domain.racelog.analyzing.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
+import com.sap.sailing.domain.racelog.analyzing.impl.LastFlagsFinder;
+
+public class LastFlagsFinderTest extends RaceLogAnalyzerTest {
+
+ @Override
+ protected LastFlagsFinder createAnalyzer(RaceLog raceLog) {
+ return new LastFlagsFinder(raceLog);
+ }
+
+ @Test
+ public void testNullForNoFlag() {
+ RaceLogEvent event1 = createEvent(RaceLogEvent.class, 1);
+ raceLog.add(event1);
+
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testSingleLast() {
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 2);
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+
+ List result = analyzer.analyze();
+ assertEquals(1, result.size());
+ assertEquals(event2, result.get(0));
+ }
+
+ @Test
+ public void testSingleInBetween() {
+ RaceLogEvent event1 = createEvent(RaceLogEvent.class, 1);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 2);
+ RaceLogEvent event3 = createEvent(RaceLogEvent.class, 3);
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ List result = analyzer.analyze();
+ assertEquals(1, result.size());
+ assertEquals(event2, result.get(0));
+ }
+
+ @Test
+ public void testTwoLast() {
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 2, "a");
+ RaceLogFlagEvent event3 = createEvent(RaceLogFlagEvent.class, 2, "b");
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ List result = analyzer.analyze();
+ assertEquals(2, result.size());
+ assertEquals(event3, result.get(0));
+ assertEquals(event2, result.get(1));
+ }
+
+ @Test
+ public void testTwoLastWithInBetween() {
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 2, "a");
+ RaceLogEvent event3 = createEvent(RaceLogEvent.class, 2, "b");
+ RaceLogFlagEvent event4 = createEvent(RaceLogFlagEvent.class, 2, "c");
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+ raceLog.add(event4);
+
+ List result = analyzer.analyze();
+ assertEquals(2, result.size());
+ assertEquals(event4, result.get(0));
+ assertEquals(event2, result.get(1));
+ }
+
+ @Test
+ public void testMoreThanTwoLast() {
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 2, "a");
+ RaceLogFlagEvent event3 = createEvent(RaceLogFlagEvent.class, 2, "b");
+ RaceLogFlagEvent event4 = createEvent(RaceLogFlagEvent.class, 2, "c");
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+ raceLog.add(event4);
+
+ List result = analyzer.analyze();
+ assertEquals(3, result.size());
+ assertEquals(event4, result.get(0));
+ assertEquals(event3, result.get(1));
+ assertEquals(event2, result.get(2));
+ }
+
+ @Test
+ public void testGetMostRecentDisplayedNullOnNull() {
+ assertNull(LastFlagsFinder.getMostRecent(null));
+ }
+
+ @Test
+ public void testGetMostRecentDisplayedNullOnEmpty() {
+ assertNull(LastFlagsFinder.getMostRecent(new ArrayList()));
+ }
+
+ @Test
+ public void testGetMostRecentDisplayedDisplayedOverRemoved() {
+ List events = new ArrayList();
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1);
+ when(event1.isDisplayed()).thenReturn(false);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 1);
+ when(event2.isDisplayed()).thenReturn(true);
+
+ events.add(event1);
+ events.add(event2);
+
+ assertEquals(event2, LastFlagsFinder.getMostRecent(events));
+
+ // order independent?
+ Collections.reverse(events);
+ assertEquals(event2, LastFlagsFinder.getMostRecent(events));
+ }
+
+ @Test
+ public void testGetMostRecentDisplayedMultipleDisplayedOverRemoved() {
+ List events = new ArrayList();
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1);
+ when(event1.isDisplayed()).thenReturn(false);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 1, "a");
+ when(event2.isDisplayed()).thenReturn(true);
+ RaceLogFlagEvent event3 = createEvent(RaceLogFlagEvent.class, 1, "b");
+ when(event3.isDisplayed()).thenReturn(true);
+
+ events.add(event1);
+ events.add(event2);
+ events.add(event3);
+
+ assertEquals(event3, LastFlagsFinder.getMostRecent(events));
+ }
+
+ @Test
+ public void testGetMostRecentDisplayedMultipleRemoved() {
+ List events = new ArrayList();
+ RaceLogFlagEvent event1 = createEvent(RaceLogFlagEvent.class, 1, "a");
+ when(event1.isDisplayed()).thenReturn(false);
+ RaceLogFlagEvent event2 = createEvent(RaceLogFlagEvent.class, 1, "b");
+ when(event2.isDisplayed()).thenReturn(false);
+
+ events.add(event1);
+ events.add(event2);
+
+ assertEquals(event2, LastFlagsFinder.getMostRecent(events));
+ }
+}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/LastWindFixFinderTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/LastWindFixFinderTest.java
new file mode 100644
index 00000000000..7a3296b986c
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/LastWindFixFinderTest.java
@@ -0,0 +1,42 @@
+package com.sap.sailing.domain.racelog.analyzing.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
+import com.sap.sailing.domain.racelog.analyzing.impl.LastWindFixFinder;
+import com.sap.sailing.domain.tracking.Wind;
+
+public class LastWindFixFinderTest extends RaceLogAnalyzerTest {
+
+ @Override
+ protected LastWindFixFinder createAnalyzer(RaceLog raceLog) {
+ return new LastWindFixFinder(raceLog);
+ }
+
+ @Test
+ public void testNullForNone() {
+ RaceLogEvent event1 = createEvent(RaceLogEvent.class, 1);
+ raceLog.add(event1);
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testMostRecent() {
+ RaceLogWindFixEvent event1 = createEvent(RaceLogWindFixEvent.class, 1);
+ RaceLogWindFixEvent event2 = createEvent(RaceLogWindFixEvent.class, 2);
+ when(event2.getWindFix()).thenReturn(mock(Wind.class));
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+
+ raceLog.lockForRead();
+ assertEquals(event2.getWindFix(), analyzer.analyze());
+ }
+}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/ProtestStartTmeFinderTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/ProtestStartTmeFinderTest.java
new file mode 100644
index 00000000000..577620d82ca
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/ProtestStartTmeFinderTest.java
@@ -0,0 +1,42 @@
+package com.sap.sailing.domain.racelog.analyzing.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
+import com.sap.sailing.domain.racelog.analyzing.impl.ProtestStartTimeFinder;
+
+public class ProtestStartTmeFinderTest extends RaceLogAnalyzerTest {
+
+ @Override
+ protected ProtestStartTimeFinder createAnalyzer(RaceLog raceLog) {
+ return new ProtestStartTimeFinder(raceLog);
+ }
+
+ @Test
+ public void testNullForNone() {
+ RaceLogEvent event1 = createEvent(RaceLogEvent.class, 1);
+ raceLog.add(event1);
+ assertNull(analyzer.analyze());
+ }
+
+ @Test
+ public void testMostRecent() {
+ RaceLogProtestStartTimeEvent event1 = createEvent(RaceLogProtestStartTimeEvent.class, 1);
+ RaceLogProtestStartTimeEvent event2 = createEvent(RaceLogProtestStartTimeEvent.class, 2);
+ when(event2.getProtestStartTime()).thenReturn(mock(TimePoint.class));
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+
+ raceLog.lockForRead();
+ assertEquals(event2.getProtestStartTime(), analyzer.analyze());
+ }
+}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java
new file mode 100644
index 00000000000..2b1a0ea7265
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/analyzing/test/RaceLogAnalyzerTest.java
@@ -0,0 +1,44 @@
+package com.sap.sailing.domain.racelog.analyzing.test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.Serializable;
+
+import org.junit.Before;
+
+import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
+
+public abstract class RaceLogAnalyzerTest {
+
+ protected AnalyzerType analyzer;
+ protected RaceLog raceLog;
+
+ @Before
+ public void setUpBase() {
+ raceLog = new RaceLogImpl("RaceLogTest", "test-identifier");
+ analyzer = createAnalyzer(raceLog);
+ }
+
+ protected abstract AnalyzerType createAnalyzer(RaceLog raceLog);
+
+ protected static T createEvent(Class type, long milliseconds) {
+ return createEvent(type, milliseconds, 0, "");
+ }
+
+ protected static T createEvent(Class type, long milliseconds, Serializable id) {
+ return createEvent(type, milliseconds, 0, id);
+ }
+
+ protected static T createEvent(Class type, long milliseconds, int passId, Serializable id) {
+ T event = mock(type);
+ when(event.getPassId()).thenReturn(passId);
+ when(event.getTimePoint()).thenReturn(new MillisecondsTimePoint(milliseconds));
+ when(event.getId()).thenReturn(id);
+ return event;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogAnalyzerTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogAnalyzerTest.java
deleted file mode 100644
index 4aa979513bb..00000000000
--- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogAnalyzerTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.sap.sailing.domain.racelog.test;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
-import com.sap.sailing.domain.common.TimePoint;
-import com.sap.sailing.domain.common.racelog.Flags;
-import com.sap.sailing.domain.racelog.RaceLog;
-import com.sap.sailing.domain.racelog.RaceLogEventFactory;
-import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
-import com.sap.sailing.domain.racelog.analyzing.impl.LastFlagFinder;
-import com.sap.sailing.domain.racelog.impl.RaceLogImpl;
-
-public class RaceLogAnalyzerTest {
-
- @Test
- public void testLastFlagFinder() {
- RaceLog raceLog = new RaceLogImpl("RaceLogTest", "test-identifier");
- TimePoint t1 = MillisecondsTimePoint.now();
- int passId = 0;
- boolean isDisplayed = true;
- RaceLogFlagEvent rcEvent = RaceLogEventFactory.INSTANCE.createFlagEvent(t1, passId, Flags.XRAY, Flags.NONE,
- isDisplayed);
- raceLog.add(rcEvent);
- rcEvent = RaceLogEventFactory.INSTANCE.createFlagEvent(t1.plus(1), passId, Flags.PAPA, Flags.NONE,
- isDisplayed);
- raceLog.add(rcEvent);
-
- raceLog.lockForRead();
- try {
- LastFlagFinder lff = new LastFlagFinder(raceLog);
- assertEquals(rcEvent, lff.getLastFlagEvent());
-
- } finally {
- raceLog.unlockAfterRead();
- }
- }
-
-}
diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogTest.java
index 0ceea5a6e87..447ceb59b99 100644
--- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogTest.java
+++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/racelog/test/RaceLogTest.java
@@ -146,6 +146,50 @@ public class RaceLogTest {
verify(listener, never()).visit(event);
}
+ @Test
+ public void testRawFixesDescending() {
+ RaceLogEvent event1 = mock(RaceLogEvent.class);
+ RaceLogEvent event2 = mock(RaceLogEvent.class);
+ RaceLogEvent event3 = mock(RaceLogEvent.class);
+
+ when(event1.getTimePoint()).thenReturn(new MillisecondsTimePoint(1));
+ when(event2.getTimePoint()).thenReturn(new MillisecondsTimePoint(2));
+ when(event3.getTimePoint()).thenReturn(new MillisecondsTimePoint(3));
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ raceLog.lockForRead();
+ assertEquals(event3, Util.get(raceLog.getRawFixesDescending(), 0));
+ assertEquals(event2, Util.get(raceLog.getRawFixesDescending(), 1));
+ assertEquals(event1, Util.get(raceLog.getRawFixesDescending(), 2));
+ raceLog.unlockAfterRead();
+ }
+
+ @Test
+ public void testFixesDescending() {
+ RaceLogEvent event1 = mock(RaceLogEvent.class);
+ RaceLogEvent event2 = mock(RaceLogEvent.class);
+ RaceLogEvent event3 = mock(RaceLogEvent.class);
+
+ when(event1.getPassId()).thenReturn(1);
+ when(event1.getTimePoint()).thenReturn(new MillisecondsTimePoint(1));
+ when(event2.getPassId()).thenReturn(1);
+ when(event2.getTimePoint()).thenReturn(new MillisecondsTimePoint(2));
+ when(event3.getPassId()).thenReturn(0);
+ when(event3.getTimePoint()).thenReturn(new MillisecondsTimePoint(3));
+
+ raceLog.add(event1);
+ raceLog.add(event2);
+ raceLog.add(event3);
+
+ raceLog.lockForRead();
+ assertEquals(event2, Util.get(raceLog.getFixesDescending(), 0));
+ assertEquals(event1, Util.get(raceLog.getFixesDescending(), 1));
+ raceLog.unlockAfterRead();
+ }
+
private class VisitFlagEventAnswer implements Answer
*/
public interface RaceLog extends Track, WithID {
+
+ public static final int DefaultPassId = 0;
+
/**
* Gets the current pass id.
*
@@ -47,4 +50,8 @@ public interface RaceLog extends Track, WithID {
* Checks if the race log is empty.
*/
boolean isEmpty();
+
+ Iterable getRawFixesDescending();
+
+ Iterable getFixesDescending();
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventFactory.java
index 33f5e3c5a11..a0b8c3860b3 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventFactory.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventFactory.java
@@ -12,59 +12,82 @@ import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.StartProcedureType;
import com.sap.sailing.domain.racelog.impl.RaceLogEventFactoryImpl;
+import com.sap.sailing.domain.tracking.Wind;
public interface RaceLogEventFactory {
RaceLogEventFactory INSTANCE = new RaceLogEventFactoryImpl();
RaceLogFlagEvent createFlagEvent(TimePoint timePoint, Serializable id, List involvedBoats, int passId,
Flags upperFlag, Flags lowerFlag, boolean isDisplayed);
+
RaceLogFlagEvent createFlagEvent(TimePoint timePoint, int passId, Flags upperFlag, Flags lowerFlag,
boolean isDisplayed);
RaceLogStartTimeEvent createStartTimeEvent(TimePoint timePoint, Serializable id, List involvedBoats,
int passId, TimePoint startTime);
+
RaceLogStartTimeEvent createStartTimeEvent(TimePoint timePoint, int passId, TimePoint startTime);
RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, Serializable id, List competitors,
int passId, RaceLogRaceStatus nextStatus);
+
RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, int passId, RaceLogRaceStatus nextStatus);
RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, Serializable id, List competitors,
int passId);
+
RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, int passId);
RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, Serializable courseAreaId);
+
RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, int passId,
Serializable courseAreaId);
RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, CourseBase courseData);
+
RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, int passId,
CourseBase courseData);
RaceLogFinishPositioningListChangedEvent createFinishPositioningListChangedEvent(TimePoint timePoint,
Serializable id, List competitors, int passId,
List> positionedCompetitors);
+
RaceLogFinishPositioningListChangedEvent createFinishPositioningListChangedEvent(TimePoint timePoint, int passId,
List> positionedCompetitors);
RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, Serializable id,
- List competitors, int passId);
- RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId);
+ List competitors, int passId, List> positionedCompetitors);
+
+ RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId,
+ List> positionedCompetitors);
RaceLogPathfinderEvent createPathfinderEvent(TimePoint timePoint, Serializable id, List competitors,
int passId, String pathfinderId);
+
RaceLogPathfinderEvent createPathfinderEvent(TimePoint timePoint, int passId, String pathfinderId);
RaceLogGateLineOpeningTimeEvent createGateLineOpeningTimeEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, Long gateLineOpeningTimeInMillis);
+
RaceLogGateLineOpeningTimeEvent createGateLineOpeningTimeEvent(TimePoint timePoint, int passId,
Long gateLineOpeningTimeInMillis);
RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, StartProcedureType type);
+
RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint timePoint, int passId,
StartProcedureType type);
+ RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint timePoint, Serializable id,
+ List competitors, int passId, TimePoint protestStartTime);
+
+ RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint timePoint, int passId, TimePoint protestStartTime);
+
+ RaceLogWindFixEvent createWindFixEvent(TimePoint eventTime, int currentPassId, Wind wind);
+
+ RaceLogWindFixEvent createWindFixEvent(TimePoint timePoint, Serializable id,
+ List competitors, int passId, Wind wind);
+
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventRestoreFactory.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventRestoreFactory.java
index 7639e9a7b72..9094f945cf1 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventRestoreFactory.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventRestoreFactory.java
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.StartProcedureType;
import com.sap.sailing.domain.racelog.impl.RaceLogEventRestoreFactoryImpl;
+import com.sap.sailing.domain.tracking.Wind;
public interface RaceLogEventRestoreFactory extends RaceLogEventFactory {
RaceLogEventRestoreFactory INSTANCE = new RaceLogEventRestoreFactoryImpl();
@@ -39,7 +40,8 @@ public interface RaceLogEventRestoreFactory extends RaceLogEventFactory {
List> positionedCompetitors);
RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint createdAt,
- TimePoint logicalTimePoint, Serializable id, List competitors, int passId);
+ TimePoint logicalTimePoint, Serializable id, List competitors, int passId,
+ List> positionedCompetitors);
RaceLogPathfinderEvent createPathfinderEvent(TimePoint createdAt, TimePoint logicalTimePoint, Serializable id,
List competitors, int passId, String pathfinderId);
@@ -49,4 +51,10 @@ public interface RaceLogEventRestoreFactory extends RaceLogEventFactory {
RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint createdAt, TimePoint timePoint,
Serializable id, List competitors, int passId, StartProcedureType type);
+
+ RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint createdAt, TimePoint timePoint,
+ Serializable id, List competitors, int passId, TimePoint protestStartTime);
+
+ RaceLogWindFixEvent createWindFixEvent(TimePoint createdAt, TimePoint timePoint, Serializable id,
+ List competitors, Integer passId, Wind wind);
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventVisitor.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventVisitor.java
index bcecedd3d47..45f58b5f642 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventVisitor.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogEventVisitor.java
@@ -1,5 +1,6 @@
package com.sap.sailing.domain.racelog;
+
public interface RaceLogEventVisitor {
public void visit(RaceLogFlagEvent event);
@@ -22,4 +23,8 @@ public interface RaceLogEventVisitor {
public void visit(RaceLogGateLineOpeningTimeEvent event);
public void visit(RaceLogStartProcedureChangedEvent event);
+
+ public void visit(RaceLogProtestStartTimeEvent event);
+
+ public void visit(RaceLogWindFixEvent event);
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningConfirmedEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningConfirmedEvent.java
index aff470f3651..69f35dd2244 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningConfirmedEvent.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningConfirmedEvent.java
@@ -1,5 +1,12 @@
package com.sap.sailing.domain.racelog;
-public interface RaceLogFinishPositioningConfirmedEvent extends RaceLogEvent {
+/**
+ * This RaceLog evet type confirms the entered positioning list. Since we do not guarantee the order of incoming events from the app (due to possible
+ * connectivity issues), this event type contains the the confirmed positioning list again. Although this racelog event type contains the same information
+ * such as {@link RaceLogFinishPositioningListChangedEvent} we keep it for backwards compatibility reasons.
+ *
+ */
+public interface RaceLogFinishPositioningConfirmedEvent extends RaceLogFinishPositioningEvent {
+
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningEvent.java
new file mode 100644
index 00000000000..5c92d3e9a9b
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningEvent.java
@@ -0,0 +1,12 @@
+package com.sap.sailing.domain.racelog;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.sap.sailing.domain.common.MaxPointsReason;
+import com.sap.sailing.domain.common.impl.Util.Triple;
+
+public abstract interface RaceLogFinishPositioningEvent extends RaceLogEvent {
+
+ List> getPositionedCompetitors();
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningListChangedEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningListChangedEvent.java
index ea5c8513178..7eeb1265a60 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningListChangedEvent.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogFinishPositioningListChangedEvent.java
@@ -1,12 +1,6 @@
package com.sap.sailing.domain.racelog;
-import java.io.Serializable;
-import java.util.List;
-import com.sap.sailing.domain.common.MaxPointsReason;
-import com.sap.sailing.domain.common.impl.Util.Triple;
-
-public interface RaceLogFinishPositioningListChangedEvent extends RaceLogEvent {
+public interface RaceLogFinishPositioningListChangedEvent extends RaceLogFinishPositioningEvent {
- List> getPositionedCompetitors();
-}
+}
\ No newline at end of file
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogProtestStartTimeEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogProtestStartTimeEvent.java
new file mode 100644
index 00000000000..bce44018dda
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogProtestStartTimeEvent.java
@@ -0,0 +1,15 @@
+package com.sap.sailing.domain.racelog;
+
+import com.sap.sailing.domain.common.TimePoint;
+
+/**
+ * Indicates that the protest start time for the related race has changed.
+ *
+ */
+public interface RaceLogProtestStartTimeEvent extends RaceLogEvent {
+
+ /**
+ * Returns the start time of the race's protest time.
+ */
+ TimePoint getProtestStartTime();
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogWindFixEvent.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogWindFixEvent.java
new file mode 100644
index 00000000000..b4815a71177
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/RaceLogWindFixEvent.java
@@ -0,0 +1,15 @@
+package com.sap.sailing.domain.racelog;
+
+import com.sap.sailing.domain.tracking.Wind;
+
+/**
+ * Contains a wind fix that the race officers documented in the Race Committee App ashore
+ *
+ */
+public interface RaceLogWindFixEvent extends RaceLogEvent {
+
+ /**
+ * Returns the wind fix entered by the race committee
+ */
+ Wind getWindFix();
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/AbortingFlagFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/AbortingFlagFinder.java
index d61cecfcba6..c3e606f939f 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/AbortingFlagFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/AbortingFlagFinder.java
@@ -5,47 +5,32 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
-public class AbortingFlagFinder extends RaceLogAnalyzer {
+public class AbortingFlagFinder extends RaceLogAnalyzer {
public AbortingFlagFinder(RaceLog raceLog) {
super(raceLog);
}
- public RaceLogFlagEvent getAbortingFlagEvent() {
-
- RaceLogFlagEvent newFlagEvent = null;
-
- this.raceLog.lockForRead();
- try {
- newFlagEvent = searchForAbortingFlagEvent();
- } finally {
- this.raceLog.unlockAfterRead();
+ @Override
+ protected RaceLogFlagEvent performAnalyzation() {
+ if (raceLog.getCurrentPassId() <= RaceLog.DefaultPassId) {
+ return null;
}
-
- return newFlagEvent;
- }
- private RaceLogFlagEvent searchForAbortingFlagEvent() {
- RaceLogFlagEvent newFlagEvent = null;
-
- if (raceLog.getCurrentPassId() > 0) {
- int relevantPassId = raceLog.getCurrentPassId() - 1;
- for (RaceLogEvent event : getAllEvents()) {
- if (event.getPassId() == relevantPassId) {
- if (event instanceof RaceLogFlagEvent) {
- RaceLogFlagEvent flagEvent = (RaceLogFlagEvent) event;
- if (isAbortingFlag(flagEvent)) {
- newFlagEvent = flagEvent;
- }
- }
+ int lastButOnePass = raceLog.getCurrentPassId() - 1;
+ for (RaceLogEvent event : getAllEventsDescending()) {
+ if (event.getPassId() == lastButOnePass && event instanceof RaceLogFlagEvent) {
+ RaceLogFlagEvent flagEvent = (RaceLogFlagEvent) event;
+ if (isDisplayedAbortingFlag(flagEvent)) {
+ return flagEvent;
}
}
}
-
- return newFlagEvent;
+
+ return null;
}
-
- private boolean isAbortingFlag(RaceLogFlagEvent flagEvent) {
+
+ private static boolean isDisplayedAbortingFlag(RaceLogFlagEvent flagEvent) {
return (flagEvent.getUpperFlag().equals(Flags.AP) && flagEvent.isDisplayed())
|| (flagEvent.getUpperFlag().equals(Flags.NOVEMBER) && flagEvent.isDisplayed())
|| (flagEvent.getUpperFlag().equals(Flags.FIRSTSUBSTITUTE) && flagEvent.isDisplayed());
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/ConfirmedFinishPositioningListFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/ConfirmedFinishPositioningListFinder.java
new file mode 100644
index 00000000000..bceb0a085b4
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/ConfirmedFinishPositioningListFinder.java
@@ -0,0 +1,31 @@
+package com.sap.sailing.domain.racelog.analyzing.impl;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.sap.sailing.domain.common.MaxPointsReason;
+import com.sap.sailing.domain.common.impl.Util.Triple;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogFinishPositioningConfirmedEvent;
+
+public class ConfirmedFinishPositioningListFinder extends RaceLogAnalyzer>> {
+
+ public ConfirmedFinishPositioningListFinder(RaceLog raceLog) {
+ super(raceLog);
+ }
+
+ @Override
+ protected List> performAnalyzation() {
+ List> lastFinishPositioningList = null;
+
+ for (RaceLogEvent event : getPassEvents()) {
+ if (event instanceof RaceLogFinishPositioningConfirmedEvent) {
+ RaceLogFinishPositioningConfirmedEvent finishPositioningEvent = (RaceLogFinishPositioningConfirmedEvent) event;
+ lastFinishPositioningList = finishPositioningEvent.getPositionedCompetitors();
+ }
+ }
+
+ return lastFinishPositioningList;
+ }
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishPositioningListFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishPositioningListFinder.java
index 97cf66bf0ff..e7ec923ff7b 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishPositioningListFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishPositioningListFinder.java
@@ -9,26 +9,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningListChangedEvent;
-public class FinishPositioningListFinder extends RaceLogAnalyzer {
+public class FinishPositioningListFinder extends RaceLogAnalyzer>> {
public FinishPositioningListFinder(RaceLog raceLog) {
super(raceLog);
}
-
- public List> getFinishPositioningList() {
- List> lastFinishPositioningList = null;
- this.raceLog.lockForRead();
- try {
- lastFinishPositioningList = searchForLastFinishPositioningList();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return lastFinishPositioningList;
- }
-
- private List> searchForLastFinishPositioningList() {
+ @Override
+ protected List> performAnalyzation() {
List> lastFinishPositioningList = null;
for (RaceLogEvent event : getPassEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishedTimeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishedTimeFinder.java
index 2664356eed2..eacb45ac001 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishedTimeFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishedTimeFinder.java
@@ -6,26 +6,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
-public class FinishedTimeFinder extends RaceLogAnalyzer {
+public class FinishedTimeFinder extends RaceLogAnalyzer {
public FinishedTimeFinder(RaceLog raceLog) {
super(raceLog);
}
- public TimePoint getFinishedTime() {
- TimePoint finishedTime = null;
-
- this.raceLog.lockForRead();
- try {
- finishedTime = searchForFinishedTime();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return finishedTime;
- }
-
- private TimePoint searchForFinishedTime() {
+ @Override
+ protected TimePoint performAnalyzation() {
TimePoint finishedTime = null;
for (RaceLogEvent event : getPassEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishingTimeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishingTimeFinder.java
index b74c1dede26..2071cd9e2d6 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishingTimeFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/FinishingTimeFinder.java
@@ -6,26 +6,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
-public class FinishingTimeFinder extends RaceLogAnalyzer {
+public class FinishingTimeFinder extends RaceLogAnalyzer {
public FinishingTimeFinder(RaceLog raceLog) {
super(raceLog);
}
- public TimePoint getFinishingTime() {
- TimePoint finishingTime = null;
-
- this.raceLog.lockForRead();
- try {
- finishingTime = searchForFinishingTime();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return finishingTime;
- }
-
- private TimePoint searchForFinishingTime() {
+ @Override
+ protected TimePoint performAnalyzation() {
TimePoint finishingTime = null;
for (RaceLogEvent event : getPassEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/GateLineOpeningTimeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/GateLineOpeningTimeFinder.java
index f2033952b22..06355605087 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/GateLineOpeningTimeFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/GateLineOpeningTimeFinder.java
@@ -4,25 +4,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
-public class GateLineOpeningTimeFinder extends RaceLogAnalyzer {
+public class GateLineOpeningTimeFinder extends RaceLogAnalyzer {
public GateLineOpeningTimeFinder(RaceLog raceLog) {
super(raceLog);
}
- public Long getGateLineOpeningTime() {
- Long gateLineOpeningTime;
- this.raceLog.lockForRead();
- try {
- gateLineOpeningTime = searchForGateLineOpeningTime();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return gateLineOpeningTime;
- }
-
- private Long searchForGateLineOpeningTime() {
+ @Override
+ protected Long performAnalyzation() {
Long gateLineOpeningTime = null;
for (RaceLogEvent event : getPassEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallDisplayedFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallDisplayedFinder.java
new file mode 100644
index 00000000000..de3ed99ca6d
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallDisplayedFinder.java
@@ -0,0 +1,17 @@
+package com.sap.sailing.domain.racelog.analyzing.impl;
+
+import com.sap.sailing.domain.common.racelog.Flags;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
+
+public class IndividualRecallDisplayedFinder extends IndividualRecallFinder {
+
+ public IndividualRecallDisplayedFinder(RaceLog raceLog) {
+ super(raceLog);
+ }
+
+ protected boolean isRelevant(RaceLogFlagEvent flagEvent) {
+ return flagEvent.getUpperFlag().equals(Flags.XRAY) && flagEvent.isDisplayed();
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallFinder.java
index 7bc24f0825f..5994b6e43a7 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallFinder.java
@@ -1,50 +1,26 @@
package com.sap.sailing.domain.racelog.analyzing.impl;
import com.sap.sailing.domain.common.TimePoint;
-import com.sap.sailing.domain.common.racelog.Flags;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
-public class IndividualRecallFinder extends RaceLogAnalyzer {
+public abstract class IndividualRecallFinder extends RaceLogAnalyzer {
public IndividualRecallFinder(RaceLog raceLog) {
super(raceLog);
}
-
- public TimePoint getIndividualRecallDisplayedTime() {
- TimePoint displayedTime = null;
-
- this.raceLog.lockForRead();
- try {
- displayedTime = searchForIndividualRecallDisplayedTime();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return displayedTime;
- }
- public TimePoint getIndividualRecallDisplayedRemovalTime() {
- TimePoint removalTime = null;
-
- this.raceLog.lockForRead();
- try {
- removalTime = searchForIndividualRecallRemovalTime();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return removalTime;
- }
-
- private TimePoint searchForIndividualRecallDisplayedTime() {
+ protected abstract boolean isRelevant(RaceLogFlagEvent flagEvent);
+
+ @Override
+ protected TimePoint performAnalyzation() {
TimePoint displayedTime = null;
for (RaceLogEvent event : getPassEvents()) {
if (event instanceof RaceLogFlagEvent) {
RaceLogFlagEvent flagEvent = (RaceLogFlagEvent) event;
- if (flagEvent.getUpperFlag().equals(Flags.XRAY) && flagEvent.isDisplayed()) {
+ if (isRelevant(flagEvent)) {
displayedTime = flagEvent.getTimePoint();
}
}
@@ -52,21 +28,5 @@ public class IndividualRecallFinder extends RaceLogAnalyzer {
return displayedTime;
}
-
- private TimePoint searchForIndividualRecallRemovalTime() {
- TimePoint removalTime = null;
-
- for (RaceLogEvent event : getPassEvents()) {
- if (event instanceof RaceLogFlagEvent) {
- RaceLogFlagEvent flagEvent = (RaceLogFlagEvent) event;
- if (flagEvent.getUpperFlag().equals(Flags.XRAY) && !flagEvent.isDisplayed()) {
- removalTime = flagEvent.getTimePoint();
- }
- }
- }
-
- return removalTime;
- }
-
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallRemovedFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallRemovedFinder.java
new file mode 100644
index 00000000000..76ce775ea48
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/IndividualRecallRemovedFinder.java
@@ -0,0 +1,17 @@
+package com.sap.sailing.domain.racelog.analyzing.impl;
+
+import com.sap.sailing.domain.common.racelog.Flags;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
+
+public class IndividualRecallRemovedFinder extends IndividualRecallFinder {
+
+ public IndividualRecallRemovedFinder(RaceLog raceLog) {
+ super(raceLog);
+ }
+
+ protected boolean isRelevant(RaceLogFlagEvent flagEvent) {
+ return flagEvent.getUpperFlag().equals(Flags.XRAY) && !flagEvent.isDisplayed();
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastFlagFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastFlagFinder.java
deleted file mode 100644
index 598067f1aa3..00000000000
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastFlagFinder.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.sap.sailing.domain.racelog.analyzing.impl;
-
-import com.sap.sailing.domain.racelog.RaceLog;
-import com.sap.sailing.domain.racelog.RaceLogEvent;
-import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
-
-public class LastFlagFinder extends RaceLogAnalyzer {
-
- public LastFlagFinder(RaceLog raceLog) {
- super(raceLog);
- }
-
- public RaceLogFlagEvent getLastFlagEvent() {
- RaceLogFlagEvent lastFlagEvent = null;
-
- this.raceLog.lockForRead();
- try {
- lastFlagEvent = searchForLastFlagEvent();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return lastFlagEvent;
- }
-
- private RaceLogFlagEvent searchForLastFlagEvent() {
- RaceLogFlagEvent lastFlagEvent = null;
-
- for (RaceLogEvent event : getPassEvents()) {
- if (event instanceof RaceLogFlagEvent) {
- lastFlagEvent = (RaceLogFlagEvent) event;
- }
- }
-
- return lastFlagEvent;
- }
-
-}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastFlagsFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastFlagsFinder.java
new file mode 100644
index 00000000000..30748e187a1
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastFlagsFinder.java
@@ -0,0 +1,99 @@
+package com.sap.sailing.domain.racelog.analyzing.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
+
+/**
+ * Analyzation returns the most recent {@link RaceLogFlagEvent}s.
+ *
+ * If there is no {@link RaceLogFlagEvent} in the current pass, null is returned. Otherwise a {@link List}
+ * of {@link RaceLogFlagEvent} is returned containing all {@link RaceLogEvent}s with the most recent {@link TimePoint}.
+ *
+ */
+public class LastFlagsFinder extends RaceLogAnalyzer> {
+
+ public LastFlagsFinder(RaceLog raceLog) {
+ super(raceLog);
+ }
+
+ @Override
+ protected List performAnalyzation() {
+
+ Iterator iterator = getPassEventsDescending().iterator();
+ RaceLogFlagEvent flagEvent = getNextFlagEvent(iterator);
+ if (flagEvent != null) {
+ return collectAllWithSameTimePoint(iterator, flagEvent);
+ }
+ return null;
+ }
+
+ private List collectAllWithSameTimePoint(Iterator iterator,
+ RaceLogFlagEvent flagEvent) {
+ List result = new ArrayList();
+ TimePoint lastFlagsTime = flagEvent.getTimePoint();
+
+ while (flagEvent.getTimePoint().equals(lastFlagsTime)) {
+ result.add(flagEvent);
+ flagEvent = getNextFlagEvent(iterator);
+ if (flagEvent == null) {
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ private RaceLogFlagEvent getNextFlagEvent(Iterator iterator) {
+ while (iterator.hasNext()) {
+ RaceLogEvent event = iterator.next();
+ if (event instanceof RaceLogFlagEvent) {
+ return (RaceLogFlagEvent) event;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Use this method the obtain the most "interesting" {@link RaceLogFlagEvent} of the {@link LastFlagsFinder}'s
+ * analyzation result.
+ *
+ * If an empty list or null is passed, this method returns null. Otherwise the (most
+ * recent) {@link RaceLogFlagEvent} with the highest ID is returned favoring events with
+ * {@link RaceLogFlagEvent#isDisplayed()} returning true.
+ *
+ * @param events
+ * result of {@link LastFlagsFinder#analyze()}.
+ * @return {@link RaceLogFlagEvent} or null.
+ */
+ public static RaceLogFlagEvent getMostRecent(List events) {
+ if (events == null || events.isEmpty()) {
+ return null;
+ }
+
+ List sortedEvents = new ArrayList(events);
+ Collections.sort(sortedEvents, new Comparator() {
+ @Override
+ public int compare(RaceLogFlagEvent left, RaceLogFlagEvent right) {
+ int result = right.getTimePoint().compareTo(left.getTimePoint());
+ if (result == 0) {
+ result = Boolean.valueOf(right.isDisplayed()).compareTo(left.isDisplayed());
+ if (result == 0) {
+ result = right.getId().toString().compareTo(left.getId().toString());
+ }
+ }
+ return result;
+ }
+ });
+
+ return sortedEvents.get(0);
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastPublishedCourseDesignFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastPublishedCourseDesignFinder.java
index 06fa8fc1e20..b242fee2862 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastPublishedCourseDesignFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastPublishedCourseDesignFinder.java
@@ -6,26 +6,14 @@ import com.sap.sailing.domain.racelog.RaceLogCourseDesignChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.analyzing.impl.RaceLogAnalyzer;
-public class LastPublishedCourseDesignFinder extends RaceLogAnalyzer {
+public class LastPublishedCourseDesignFinder extends RaceLogAnalyzer {
public LastPublishedCourseDesignFinder(RaceLog raceLog) {
super(raceLog);
}
- public CourseBase getLastCourseDesign() {
- CourseBase lastCourseData = null;
-
- this.raceLog.lockForRead();
- try {
- lastCourseData = searchForLastCourseData();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return lastCourseData;
- }
-
- private CourseBase searchForLastCourseData() {
+ @Override
+ protected CourseBase performAnalyzation() {
CourseBase lastCourseData = null;
for (RaceLogEvent event : getAllEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastWindFixFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastWindFixFinder.java
new file mode 100644
index 00000000000..37d97a9c808
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/LastWindFixFinder.java
@@ -0,0 +1,28 @@
+package com.sap.sailing.domain.racelog.analyzing.impl;
+
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
+import com.sap.sailing.domain.tracking.Wind;
+
+public class LastWindFixFinder extends RaceLogAnalyzer {
+
+ public LastWindFixFinder(RaceLog raceLog) {
+ super(raceLog);
+ }
+
+ @Override
+ protected Wind performAnalyzation() {
+ Wind lastWind = null;
+
+ for (RaceLogEvent event : getAllEvents()) {
+ if (event instanceof RaceLogWindFixEvent) {
+ RaceLogWindFixEvent windFixEvent = (RaceLogWindFixEvent) event;
+ lastWind = windFixEvent.getWindFix();
+ }
+ }
+
+ return lastWind;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/PathfinderFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/PathfinderFinder.java
index 1516f27ba12..b7ed1ac5946 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/PathfinderFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/PathfinderFinder.java
@@ -4,24 +4,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
-public class PathfinderFinder extends RaceLogAnalyzer {
+public class PathfinderFinder extends RaceLogAnalyzer {
public PathfinderFinder(RaceLog raceLog) {
super(raceLog);
}
- public String getPathfinderId() {
- String pathfinderId;
- this.raceLog.lockForRead();
- try {
- pathfinderId = searchForPathfinderId();
- } finally {
- this.raceLog.unlockAfterRead();
- }
- return pathfinderId;
- }
-
- private String searchForPathfinderId() {
+ @Override
+ protected String performAnalyzation() {
String pathfinderId = null;
for (RaceLogEvent event : getPassEvents()) {
if (event instanceof RaceLogPathfinderEvent) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/ProtestStartTimeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/ProtestStartTimeFinder.java
new file mode 100644
index 00000000000..38a3aa48248
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/ProtestStartTimeFinder.java
@@ -0,0 +1,24 @@
+package com.sap.sailing.domain.racelog.analyzing.impl;
+
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.racelog.RaceLog;
+import com.sap.sailing.domain.racelog.RaceLogEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
+
+public class ProtestStartTimeFinder extends RaceLogAnalyzer {
+
+ public ProtestStartTimeFinder(RaceLog raceLog) {
+ super(raceLog);
+ }
+
+ @Override
+ protected TimePoint performAnalyzation() {
+ for (RaceLogEvent event : getPassEventsDescending()) {
+ if (event instanceof RaceLogProtestStartTimeEvent) {
+ return ((RaceLogProtestStartTimeEvent) event).getProtestStartTime();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceLogAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceLogAnalyzer.java
index 3b21248fe0e..96bab9fd0e7 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceLogAnalyzer.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceLogAnalyzer.java
@@ -3,7 +3,13 @@ package com.sap.sailing.domain.racelog.analyzing.impl;
import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
-public abstract class RaceLogAnalyzer {
+/**
+ * Analyzer to perform a query over a given {@link RaceLog}. Each subclass defines its ResultType.
+ *
+ * @param
+ * type of analyzation's result.
+ */
+public abstract class RaceLogAnalyzer {
protected RaceLog raceLog;
@@ -11,6 +17,17 @@ public abstract class RaceLogAnalyzer {
this.raceLog = raceLog;
}
+ public ResultType analyze() {
+ raceLog.lockForRead();
+ try {
+ return performAnalyzation();
+ } finally {
+ raceLog.unlockAfterRead();
+ }
+ }
+
+ protected abstract ResultType performAnalyzation();
+
protected Iterable getPassEvents() {
return raceLog.getFixes();
}
@@ -18,4 +35,12 @@ public abstract class RaceLogAnalyzer {
protected Iterable getAllEvents() {
return raceLog.getRawFixes();
}
+
+ protected Iterable getPassEventsDescending() {
+ return raceLog.getFixesDescending();
+ }
+
+ protected Iterable getAllEventsDescending() {
+ return raceLog.getRawFixesDescending();
+ }
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceStatusAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceStatusAnalyzer.java
index a9857a00635..2baf3b1e683 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceStatusAnalyzer.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/RaceStatusAnalyzer.java
@@ -5,27 +5,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
-public class RaceStatusAnalyzer extends RaceLogAnalyzer {
+public class RaceStatusAnalyzer extends RaceLogAnalyzer {
public RaceStatusAnalyzer(RaceLog raceLog) {
super(raceLog);
}
- public RaceLogRaceStatus getStatus() {
-
- RaceLogRaceStatus newStatus = RaceLogRaceStatus.UNSCHEDULED;
-
- this.raceLog.lockForRead();
- try {
- newStatus = searchForRaceStatus();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return newStatus;
- }
-
- private RaceLogRaceStatus searchForRaceStatus() {
+ @Override
+ protected RaceLogRaceStatus performAnalyzation() {
RaceLogRaceStatus newStatus = RaceLogRaceStatus.UNSCHEDULED;
for (RaceLogEvent event : getPassEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartProcedureTypeAnalyzer.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartProcedureTypeAnalyzer.java
index f5d3047b514..a7ce9a802da 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartProcedureTypeAnalyzer.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartProcedureTypeAnalyzer.java
@@ -5,24 +5,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
-public class StartProcedureTypeAnalyzer extends RaceLogAnalyzer {
+public class StartProcedureTypeAnalyzer extends RaceLogAnalyzer {
public StartProcedureTypeAnalyzer(RaceLog raceLog) {
super(raceLog);
}
-
- public StartProcedureType getActiveStartProcedureType() {
- StartProcedureType result = null;
- raceLog.lockForRead();
- try {
- result = searchLog();
- } finally {
- raceLog.unlockAfterRead();
- }
- return result;
- }
- private StartProcedureType searchLog() {
+ @Override
+ protected StartProcedureType performAnalyzation() {
StartProcedureType result = null;
for (RaceLogEvent event : getAllEvents()) {
if (event instanceof RaceLogStartProcedureChangedEvent) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartTimeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartTimeFinder.java
index 6905f598e7f..fc24491c803 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartTimeFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/analyzing/impl/StartTimeFinder.java
@@ -5,26 +5,14 @@ import com.sap.sailing.domain.racelog.RaceLog;
import com.sap.sailing.domain.racelog.RaceLogEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
-public class StartTimeFinder extends RaceLogAnalyzer {
+public class StartTimeFinder extends RaceLogAnalyzer {
public StartTimeFinder(RaceLog raceLog) {
super(raceLog);
}
- public TimePoint getStartTime() {
- TimePoint startTime = null;
-
- this.raceLog.lockForRead();
- try {
- startTime = searchForStartTime();
- } finally {
- this.raceLog.unlockAfterRead();
- }
-
- return startTime;
- }
-
- private TimePoint searchForStartTime() {
+ @Override
+ protected TimePoint performAnalyzation() {
TimePoint startTime = null;
for (RaceLogEvent event : getPassEvents()) {
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventFactoryImpl.java
index 5e0f21b51fa..3bb354693e4 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventFactoryImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventFactoryImpl.java
@@ -22,28 +22,34 @@ import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
+import com.sap.sailing.domain.tracking.Wind;
public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
@Override
- public RaceLogFlagEvent createFlagEvent(TimePoint timePoint, Serializable id, List involvedBoats, int passId,
- Flags upperFlag, Flags lowerFlag, boolean isDisplayed) {
- return new RaceLogFlagEventImpl(MillisecondsTimePoint.now(), timePoint, id, involvedBoats, passId, upperFlag, lowerFlag, isDisplayed);
- }
-
- @Override
- public RaceLogFlagEvent createFlagEvent(TimePoint timePoint,
+ public RaceLogFlagEvent createFlagEvent(TimePoint timePoint, Serializable id, List involvedBoats,
int passId, Flags upperFlag, Flags lowerFlag, boolean isDisplayed) {
- return createFlagEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, upperFlag, lowerFlag, isDisplayed);
+ return new RaceLogFlagEventImpl(MillisecondsTimePoint.now(), timePoint, id, involvedBoats, passId, upperFlag,
+ lowerFlag, isDisplayed);
}
@Override
- public RaceLogStartTimeEvent createStartTimeEvent(TimePoint timePoint, Serializable id, List involvedBoats, int passId,
- TimePoint startTime) {
- return new RaceLogStartTimeEventImpl(MillisecondsTimePoint.now(), timePoint, id, involvedBoats, passId, startTime);
+ public RaceLogFlagEvent createFlagEvent(TimePoint timePoint, int passId, Flags upperFlag, Flags lowerFlag,
+ boolean isDisplayed) {
+ return createFlagEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, upperFlag, lowerFlag,
+ isDisplayed);
+ }
+
+ @Override
+ public RaceLogStartTimeEvent createStartTimeEvent(TimePoint timePoint, Serializable id,
+ List involvedBoats, int passId, TimePoint startTime) {
+ return new RaceLogStartTimeEventImpl(MillisecondsTimePoint.now(), timePoint, id, involvedBoats, passId,
+ startTime);
}
@Override
@@ -52,20 +58,20 @@ public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
}
@Override
- public RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint,Serializable id, List competitors, int passId,
- RaceLogRaceStatus nextStatus) {
- return new RaceLogRaceStatusEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, nextStatus);
+ public RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, Serializable id,
+ List competitors, int passId, RaceLogRaceStatus nextStatus) {
+ return new RaceLogRaceStatusEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId,
+ nextStatus);
}
@Override
- public RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint,
- int passId, RaceLogRaceStatus nextStatus) {
+ public RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, int passId, RaceLogRaceStatus nextStatus) {
return createRaceStatusEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, nextStatus);
}
@Override
- public RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, Serializable id, List competitors,
- int passId) {
+ public RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, Serializable id,
+ List competitors, int passId) {
return new RaceLogPassChangeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId);
}
@@ -75,55 +81,66 @@ public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
}
@Override
- public RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, Serializable id, List competitors,
- int passId, Serializable courseAreaId) {
- return new RaceLogCourseAreaChangeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, courseAreaId);
+ public RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, Serializable id,
+ List competitors, int passId, Serializable courseAreaId) {
+ return new RaceLogCourseAreaChangeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId,
+ courseAreaId);
}
@Override
- public RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(
- TimePoint timePoint, int passId, Serializable courseAreaId) {
- return createCourseAreaChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, courseAreaId);
+ public RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, int passId,
+ Serializable courseAreaId) {
+ return createCourseAreaChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId,
+ courseAreaId);
}
@Override
public RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, CourseBase courseData) {
- return new RaceLogCourseDesignChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, courseData);
+ return new RaceLogCourseDesignChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId,
+ courseData);
}
@Override
- public RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, int passId, CourseBase courseData) {
- return createCourseDesignChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, courseData);
+ public RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, int passId,
+ CourseBase courseData) {
+ return createCourseDesignChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId,
+ courseData);
}
@Override
- public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(
- TimePoint timePoint, Serializable id, List competitors, int passId, List> positionedCompetitors) {
- return new RaceLogFinishPositioningListChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, positionedCompetitors);
+ public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(TimePoint timePoint,
+ Serializable id, List competitors, int passId,
+ List> positionedCompetitors) {
+ return new RaceLogFinishPositioningListChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id,
+ competitors, passId, positionedCompetitors);
}
@Override
- public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(
- TimePoint timePoint, int passId, List> positionedCompetitors) {
- return createFinishPositioningListChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, positionedCompetitors);
+ public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(TimePoint timePoint,
+ int passId, List> positionedCompetitors) {
+ return createFinishPositioningListChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(),
+ passId, positionedCompetitors);
}
@Override
public RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint,
- Serializable id, List competitors, int passId) {
- return new RaceLogFinishPositioningConfirmedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId);
+ Serializable id, List competitors, int passId, List> positionedCompetitors) {
+ return new RaceLogFinishPositioningConfirmedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors,
+ passId, positionedCompetitors);
}
@Override
- public RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId) {
- return createFinishPositioningConfirmedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId);
+ public RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId,
+ List> positionedCompetitors) {
+ return createFinishPositioningConfirmedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, positionedCompetitors);
}
@Override
public RaceLogPathfinderEvent createPathfinderEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, String pathfinderId) {
- return new RaceLogPathfinderEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, pathfinderId);
+ return new RaceLogPathfinderEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId,
+ pathfinderId);
}
@Override
@@ -134,19 +151,22 @@ public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
@Override
public RaceLogGateLineOpeningTimeEvent createGateLineOpeningTimeEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, Long gateLineOpeningTimeInMillis) {
- return new RaceLogGateLineOpeningTimeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, gateLineOpeningTimeInMillis);
+ return new RaceLogGateLineOpeningTimeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId,
+ gateLineOpeningTimeInMillis);
}
@Override
public RaceLogGateLineOpeningTimeEvent createGateLineOpeningTimeEvent(TimePoint timePoint, int passId,
Long gateLineOpeningTimeInMillis) {
- return createGateLineOpeningTimeEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, gateLineOpeningTimeInMillis);
+ return createGateLineOpeningTimeEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId,
+ gateLineOpeningTimeInMillis);
}
@Override
public RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint timePoint, Serializable id,
List competitors, int passId, StartProcedureType type) {
- return new RaceLogStartProcedureChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, type);
+ return new RaceLogStartProcedureChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors,
+ passId, type);
}
@Override
@@ -155,4 +175,29 @@ public class RaceLogEventFactoryImpl implements RaceLogEventFactory {
return createStartProcedureChangedEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, type);
}
+ @Override
+ public RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint timePoint, Serializable id,
+ List competitors, int passId, TimePoint protestStartTime) {
+ return new RaceLogProtestStartTimeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors,
+ passId, protestStartTime);
+ }
+
+ @Override
+ public RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint timePoint, int passId,
+ TimePoint protestStartTime) {
+ return createProtestStartTimeEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId,
+ protestStartTime);
+ }
+
+ @Override
+ public RaceLogWindFixEvent createWindFixEvent(TimePoint timePoint, int passId, Wind wind) {
+ return createWindFixEvent(timePoint, UUID.randomUUID(), new ArrayList(), passId, wind);
+ }
+
+ @Override
+ public RaceLogWindFixEvent createWindFixEvent(TimePoint timePoint, Serializable id, List competitors,
+ int passId, Wind wind) {
+ return new RaceLogWindFixEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, wind);
+ }
+
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventImpl.java
index 2e0283688aa..9af8367e157 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventImpl.java
@@ -51,12 +51,4 @@ public abstract class RaceLogEventImpl implements RaceLogEvent {
return passId;
}
- @Override
- public boolean equals(Object object) {
- return object instanceof RaceLogEvent && logicalTimePoint.equals(((RaceLogEvent) object).getTimePoint())
- && id.equals(((RaceLogEvent) object).getId())
- && involvedBoats.equals(((RaceLogEvent) object).getInvolvedBoats())
- && passId == ((RaceLogEvent) object).getPassId();
- }
-
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventRestoreFactoryImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventRestoreFactoryImpl.java
index a7f92e13e22..3f793d6037d 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventRestoreFactoryImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogEventRestoreFactoryImpl.java
@@ -20,9 +20,12 @@ import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
+import com.sap.sailing.domain.tracking.Wind;
public class RaceLogEventRestoreFactoryImpl extends RaceLogEventFactoryImpl implements RaceLogEventRestoreFactory {
@@ -70,8 +73,8 @@ public class RaceLogEventRestoreFactoryImpl extends RaceLogEventFactoryImpl impl
@Override
public RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint createdAt,
- TimePoint logicalTimePoint, Serializable id, List competitors, int passId) {
- return new RaceLogFinishPositioningConfirmedEventImpl(createdAt, logicalTimePoint, id, competitors, passId);
+ TimePoint logicalTimePoint, Serializable id, List competitors, int passId, List> positionedCompetitors) {
+ return new RaceLogFinishPositioningConfirmedEventImpl(createdAt, logicalTimePoint, id, competitors, passId, positionedCompetitors);
}
@Override
@@ -92,5 +95,17 @@ public class RaceLogEventRestoreFactoryImpl extends RaceLogEventFactoryImpl impl
return new RaceLogStartProcedureChangedEventImpl(createdAt, timePoint, id, competitors, passId, type);
}
+ @Override
+ public RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint createdAt, TimePoint timePoint,
+ Serializable id, List competitors, int passId, TimePoint protestStartTime) {
+ return new RaceLogProtestStartTimeEventImpl(createdAt, timePoint, id, competitors, passId, protestStartTime);
+ }
+
+ @Override
+ public RaceLogWindFixEvent createWindFixEvent(TimePoint createdAt, TimePoint timePoint, Serializable id,
+ List competitors, Integer passId, Wind wind) {
+ return new RaceLogWindFixEventImpl(createdAt, timePoint, id, competitors, passId, wind);
+ }
+
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningConfirmedEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningConfirmedEventImpl.java
index e0e5ff4a5e7..b57b8a28e23 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningConfirmedEventImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningConfirmedEventImpl.java
@@ -4,22 +4,23 @@ import java.io.Serializable;
import java.util.List;
import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningConfirmedEvent;
-public class RaceLogFinishPositioningConfirmedEventImpl extends RaceLogEventImpl implements RaceLogFinishPositioningConfirmedEvent {
+public class RaceLogFinishPositioningConfirmedEventImpl extends RaceLogFinishPositioningEventImpl implements RaceLogFinishPositioningConfirmedEvent {
private static final long serialVersionUID = 5028181339200048499L;
-
+
public RaceLogFinishPositioningConfirmedEventImpl(TimePoint createdAt,
- TimePoint pTimePoint, Serializable pId, List pCompetitors, int pPassId) {
- super(createdAt, pTimePoint, pId, pCompetitors, pPassId);
+ TimePoint pTimePoint, Serializable pId, List pCompetitors, int pPassId, List> positionedCompetitors) {
+ super(createdAt, pTimePoint, pId, pCompetitors, pPassId, positionedCompetitors);
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
-
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningEventImpl.java
new file mode 100644
index 00000000000..cb7e21d9453
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningEventImpl.java
@@ -0,0 +1,29 @@
+package com.sap.sailing.domain.racelog.impl;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.common.MaxPointsReason;
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.common.impl.Util.Triple;
+import com.sap.sailing.domain.racelog.RaceLogFinishPositioningEvent;
+
+public abstract class RaceLogFinishPositioningEventImpl extends RaceLogEventImpl implements RaceLogFinishPositioningEvent {
+
+ private static final long serialVersionUID = -8168584588697908309L;
+
+ protected List> positionedCompetitors;
+
+ public RaceLogFinishPositioningEventImpl(TimePoint createdAt, TimePoint pTimePoint, Serializable pId,
+ List pInvolvedBoats, int pPassId, List> positionedCompetitors) {
+ super(createdAt, pTimePoint, pId, pInvolvedBoats, pPassId);
+ this.positionedCompetitors = positionedCompetitors;
+ }
+
+ @Override
+ public List> getPositionedCompetitors() {
+ return positionedCompetitors;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningListChangedEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningListChangedEventImpl.java
index a5c502a54d2..266a3d72e9f 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningListChangedEventImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFinishPositioningListChangedEventImpl.java
@@ -10,26 +10,17 @@ import com.sap.sailing.domain.common.impl.Util.Triple;
import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
import com.sap.sailing.domain.racelog.RaceLogFinishPositioningListChangedEvent;
-public class RaceLogFinishPositioningListChangedEventImpl extends RaceLogEventImpl implements RaceLogFinishPositioningListChangedEvent {
+public class RaceLogFinishPositioningListChangedEventImpl extends RaceLogFinishPositioningEventImpl implements RaceLogFinishPositioningListChangedEvent {
private static final long serialVersionUID = -8167472925561954739L;
- private List> positionedCompetitors;
-
public RaceLogFinishPositioningListChangedEventImpl(TimePoint createdAt,
TimePoint pTimePoint, Serializable pId, List competitors, int pPassId, List> positionedCompetitors) {
- super(createdAt, pTimePoint, pId, competitors, pPassId);
- this.positionedCompetitors = positionedCompetitors;
+ super(createdAt, pTimePoint, pId, competitors, pPassId, positionedCompetitors);
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
-
- @Override
- public List> getPositionedCompetitors() {
- return positionedCompetitors;
- }
-
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFlagEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFlagEventImpl.java
index 51668f54513..d43cc2eb86c 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFlagEventImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogFlagEventImpl.java
@@ -43,13 +43,4 @@ public class RaceLogFlagEventImpl extends RaceLogEventImpl implements RaceLogFla
visitor.visit(this);
}
- @Override
- public boolean equals(Object object) {
- return super.equals(object)
- && object instanceof RaceLogFlagEvent
- && upperFlag.equals(((RaceLogFlagEvent) object).getUpperFlag())
- && lowerFlag.equals(((RaceLogFlagEvent) object).getLowerFlag())
- && isDisplayed == ((RaceLogFlagEvent) object).isDisplayed();
- }
-
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogImpl.java
index 59741fdaebf..3343ed59d7b 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogImpl.java
@@ -29,8 +29,6 @@ public class RaceLogImpl extends TrackImpl implements RaceLog {
private transient Set listeners;
private int currentPassId;
- public static final int DefaultPassId = 0;
-
/**
* Initializes a new {@link RaceLogImpl} with the default lock name.
*/
@@ -141,4 +139,14 @@ public class RaceLogImpl extends TrackImpl implements RaceLog {
listeners = new HashSet();
}
+ @Override
+ public Iterable getRawFixesDescending() {
+ return getRawFixes().descendingSet();
+ }
+
+ @Override
+ public Iterable getFixesDescending() {
+ return getFixes().descendingSet();
+ }
+
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogProtestStartTimeEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogProtestStartTimeEventImpl.java
new file mode 100644
index 00000000000..775fe9bfd91
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogProtestStartTimeEventImpl.java
@@ -0,0 +1,32 @@
+package com.sap.sailing.domain.racelog.impl;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
+
+public class RaceLogProtestStartTimeEventImpl extends RaceLogEventImpl implements RaceLogProtestStartTimeEvent {
+ private static final long serialVersionUID = -1800827552916395996L;
+
+ private TimePoint protestStartTime;
+
+ public RaceLogProtestStartTimeEventImpl(TimePoint createdAt, TimePoint pTimePoint, Serializable pId,
+ List pInvolvedBoats, int pPassId, TimePoint protestStartTime) {
+ super(createdAt, pTimePoint, pId, pInvolvedBoats, pPassId);
+ this.protestStartTime = protestStartTime;
+ }
+
+ @Override
+ public void accept(RaceLogEventVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public TimePoint getProtestStartTime() {
+ return protestStartTime;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogStartTimeEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogStartTimeEventImpl.java
index 510d22a9520..ae69e2e4d0d 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogStartTimeEventImpl.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogStartTimeEventImpl.java
@@ -30,11 +30,4 @@ public class RaceLogStartTimeEventImpl extends RaceLogRaceStatusEventImpl implem
visitor.visit(this);
}
- @Override
- public boolean equals(Object object) {
- // / TODO: please check the implementation of this method... why is this needed?
- return super.equals(object) && object instanceof RaceLogStartTimeEvent
- && startTime.equals(((RaceLogStartTimeEvent) object).getStartTime());
- }
-
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogWindFixEventImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogWindFixEventImpl.java
new file mode 100644
index 00000000000..44defb957d9
--- /dev/null
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/racelog/impl/RaceLogWindFixEventImpl.java
@@ -0,0 +1,33 @@
+package com.sap.sailing.domain.racelog.impl;
+
+import java.io.Serializable;
+import java.util.List;
+
+import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.common.TimePoint;
+import com.sap.sailing.domain.racelog.RaceLogEventVisitor;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
+import com.sap.sailing.domain.tracking.Wind;
+
+public class RaceLogWindFixEventImpl extends RaceLogEventImpl implements RaceLogWindFixEvent {
+ private static final long serialVersionUID = 7879094280634905183L;
+
+ private final Wind windFix;
+
+ public RaceLogWindFixEventImpl(TimePoint createdAt, TimePoint pTimePoint, Serializable pId,
+ List pInvolvedBoats, int pPassId, Wind windFix) {
+ super(createdAt, pTimePoint, pId, pInvolvedBoats, pPassId);
+ this.windFix = windFix;
+ }
+
+ @Override
+ public void accept(RaceLogEventVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public Wind getWindFix() {
+ return windFix;
+ }
+
+}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Positioned.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/Positioned.java
similarity index 100%
rename from java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Positioned.java
rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/Positioned.java
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Wind.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/Wind.java
similarity index 100%
rename from java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/Wind.java
rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/Wind.java
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/WindImpl.java
similarity index 100%
rename from java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindImpl.java
rename to java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/WindImpl.java
diff --git a/java/com.sap.sailing.domain.test/SailingDomainTest (No Proxy).launch b/java/com.sap.sailing.domain.test/SailingDomainTest (No Proxy).launch
index 3b3dbe049f1..4929fbc0fde 100755
--- a/java/com.sap.sailing.domain.test/SailingDomainTest (No Proxy).launch
+++ b/java/com.sap.sailing.domain.test/SailingDomainTest (No Proxy).launch
@@ -7,6 +7,7 @@
+
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogEventTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogEventTest.java
deleted file mode 100644
index 920444fb7a9..00000000000
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/RaceLogEventTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.sap.sailing.domain.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotSame;
-
-import java.util.ArrayList;
-import java.util.UUID;
-
-import org.junit.Test;
-
-import com.sap.sailing.domain.base.Competitor;
-import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
-import com.sap.sailing.domain.common.TimePoint;
-import com.sap.sailing.domain.common.racelog.Flags;
-import com.sap.sailing.domain.racelog.RaceLogEventFactory;
-import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
-
-public class RaceLogEventTest {
-
- @Test
- public void testEqualityOfTwoNotSameEvents() {
- TimePoint t1 = MillisecondsTimePoint.now();
- int passId = 0;
- UUID randomUUID = UUID.randomUUID();
- RaceLogFlagEvent rcEvent1 = RaceLogEventFactory.INSTANCE.createFlagEvent(t1, randomUUID, new ArrayList(), passId, Flags.CLASS, Flags.NONE, false);
- RaceLogFlagEvent rcEvent2 = RaceLogEventFactory.INSTANCE.createFlagEvent(t1, randomUUID, new ArrayList(), passId, Flags.CLASS, Flags.NONE, false);
- assertNotSame(rcEvent1, rcEvent2);
- assertEquals(rcEvent1, rcEvent2);
- }
-
-}
diff --git a/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs b/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs
index 5dfd5763bfd..a75e8e21989 100755
--- a/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs
+++ b/java/com.sap.sailing.domain/.settings/org.eclipse.core.resources.prefs
@@ -1,3 +1,2 @@
eclipse.preferences.version=1
-encoding//src/com/sap/sailing/domain/base/impl/AbstractSpeedWithAbstractBearingImpl.java=UTF-8
encoding//src/com/sap/sailing/domain/tracking/impl/CompactGPSFixMovingImpl.java=UTF-8
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java
index 25ebfecb5c7..8947625b32f 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/DomainFactoryImpl.java
@@ -22,6 +22,7 @@ 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;
+import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Gate;
@@ -88,6 +89,8 @@ public class DomainFactoryImpl implements DomainFactory {
private final Map competitorCache;
+ private final Map courseAreaCache;
+
/**
* Weakly references the waypoints. If a waypoint is no longer strongly referenced, the corresponding reference contained
* as value will have its referred object be null. In this case, the methods reading from this cache will purge
@@ -134,6 +137,7 @@ public class DomainFactoryImpl implements DomainFactory {
competitorCache = new HashMap();
waypointCache = new ConcurrentHashMap();
mayStartWithNoUpwindLeg = new HashSet(Arrays.asList(new String[] { "extreme40", "ess", "ess40" }));
+ courseAreaCache = new HashMap<>();
}
@Override
@@ -452,4 +456,19 @@ public class DomainFactoryImpl implements DomainFactory {
return result;
}
+ @Override
+ public CourseArea getOrCreateCourseArea(Serializable courseAreaId, String name) {
+ CourseArea result = getExistingCourseAreaById(courseAreaId);
+ if (result == null) {
+ result = new CourseAreaImpl(name, courseAreaId);
+ courseAreaCache.put(courseAreaId, result);
+ }
+ return result;
+ }
+
+ @Override
+ public CourseArea getExistingCourseAreaById(Serializable courseAreaId) {
+ return courseAreaCache.get(courseAreaId);
+ }
+
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java
index 675e440456b..2f343bdf068 100644
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RaceColumnRaceLogReplicator.java
@@ -14,9 +14,11 @@ import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogIdentifier;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Serializable {
private static final long serialVersionUID = 4752330236765192592L;
@@ -90,4 +92,14 @@ public class RaceColumnRaceLogReplicator implements RaceLogEventVisitor, Seriali
public void visit(RaceLogStartProcedureChangedEvent event) {
notifyOnAdd(event);
}
+
+ @Override
+ public void visit(RaceLogProtestStartTimeEvent event) {
+ notifyOnAdd(event);
+ }
+
+ @Override
+ public void visit(RaceLogWindFixEvent event) {
+ notifyOnAdd(event);
+ }
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java
index 39fd82a7aeb..a2598aea6b1 100644
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceLogListener.java
@@ -11,9 +11,11 @@ import com.sap.sailing.domain.racelog.RaceLogFlagEvent;
import com.sap.sailing.domain.racelog.RaceLogGateLineOpeningTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogPassChangeEvent;
import com.sap.sailing.domain.racelog.RaceLogPathfinderEvent;
+import com.sap.sailing.domain.racelog.RaceLogProtestStartTimeEvent;
import com.sap.sailing.domain.racelog.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.racelog.RaceLogStartProcedureChangedEvent;
import com.sap.sailing.domain.racelog.RaceLogStartTimeEvent;
+import com.sap.sailing.domain.racelog.RaceLogWindFixEvent;
import com.sap.sailing.domain.racelog.analyzing.impl.LastPublishedCourseDesignFinder;
import com.sap.sailing.domain.racelog.analyzing.impl.RaceStatusAnalyzer;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
@@ -58,13 +60,13 @@ public class DynamicTrackedRaceLogListener implements RaceLogEventVisitor {
}
private void analyzeStatus() {
- /* RaceLogRaceStatus newStatus = */statusAnalyzer.getStatus();
+ /* RaceLogRaceStatus newStatus = */statusAnalyzer.analyze();
// TODO: What can we do with the status? Should we use DynamicTrackedRace.setStatus?
}
private void analyzeCourseDesign() {
- CourseBase courseDesign = courseDesignFinder.getLastCourseDesign();
+ CourseBase courseDesign = courseDesignFinder.analyze();
// On the initial analyze step after attaching the RaceLog there might be no course design.
if (courseDesign != null) {
@@ -129,4 +131,15 @@ public class DynamicTrackedRaceLogListener implements RaceLogEventVisitor {
}
+ @Override
+ public void visit(RaceLogProtestStartTimeEvent event) {
+
+ }
+
+ @Override
+ public void visit(RaceLogWindFixEvent event) {
+ // TODO handle a new wind fix entered by the race committee
+ // add the wind fix to the race committee WindTrack
+ }
+
}
diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
index f1051db69e5..edf3978e336 100755
--- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
+++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java
@@ -479,7 +479,7 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
public TimePoint getStartOfRace() {
if (startTime == null) {
for (RaceLog raceLog : attachedRaceLogs.values()) {
- startTime = new StartTimeFinder(raceLog).getStartTime();
+ startTime = new StartTimeFinder(raceLog).analyze();
if (startTime != null) {
break;
}
diff --git a/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/down.png b/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/down.png
index ad7d485a7e0..ebf713b5c6f 100644
Binary files a/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/down.png and b/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/down.png differ
diff --git a/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/up.png b/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/up.png
index 800755d59cc..a7a5e25ef6a 100644
Binary files a/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/up.png and b/java/com.sap.sailing.gwt.ui/images/flags/flagsRacecommittee/up.png differ
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/EventConfigImagesBarCell.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/EventConfigImagesBarCell.java
index d739bf01100..e64241fb1f1 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/EventConfigImagesBarCell.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/EventConfigImagesBarCell.java
@@ -25,7 +25,9 @@ public class EventConfigImagesBarCell extends ImagesBarCell {
@Override
protected Iterable getImageSpecs() {
- return Arrays.asList(new ImageSpec(ACTION_EDIT, stringMessages.actionEdit(), makeImagePrototype(resources.editIcon())),
- new ImageSpec(ACTION_REMOVE, stringMessages.actionRemove(), makeImagePrototype(resources.removeIcon())));
+ return Arrays.asList(
+ new ImageSpec(ACTION_EDIT, stringMessages.actionEdit(), makeImagePrototype(resources.editIcon())),
+ new ImageSpec(ACTION_REMOVE, stringMessages.actionRemove(), makeImagePrototype(resources.removeIcon()))
+ );
}
}
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/AnchorCell.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/AnchorCell.java
new file mode 100644
index 00000000000..1afc4648b98
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/AnchorCell.java
@@ -0,0 +1,26 @@
+package com.sap.sailing.gwt.ui.client;
+
+import com.google.gwt.cell.client.AbstractCell;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import com.google.gwt.user.client.ui.Anchor;
+
+/**
+ * A GWT cell rendering a simple anchor.
+ * @author C5163874
+ *
+ */
+public class AnchorCell extends AbstractCell {
+ @Override
+ public void render(com.google.gwt.cell.client.Cell.Context context, Anchor a, SafeHtmlBuilder sb) {
+ if (a.getHref() != null && a.getHref().trim().length() > 0 && a.isEnabled()) {
+ sb.append(SafeHtmlUtils.fromTrustedString(""));
+ sb.append(SafeHtmlUtils.fromTrustedString(a.getText()));
+ sb.append(SafeHtmlUtils.fromTrustedString(""));
+ } else {
+ sb.append(SafeHtmlUtils.fromTrustedString(a.getText()));
+ }
+ }
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/EntryPointLinkFactory.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/EntryPointLinkFactory.java
new file mode 100644
index 00000000000..0aefc686e46
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/EntryPointLinkFactory.java
@@ -0,0 +1,32 @@
+package com.sap.sailing.gwt.ui.client;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.google.gwt.user.client.Window;
+
+public class EntryPointLinkFactory {
+ public static String createRaceBoardLink(Map parameters) {
+ return createEntryPointLink("/gwt/RaceBoard.html", parameters);
+ }
+
+ public static String createLeaderboardLink(Map parameters) {
+ return createEntryPointLink("/gwt/Leaderboard.html", parameters);
+ }
+
+ private static String createEntryPointLink(String baseLink, Map parameters) {
+ String debugParam = Window.Location.getParameter("gwt.codesvr");
+ String link = baseLink;
+ int i = 1;
+ for(Entry entry: parameters.entrySet()) {
+ link += i == 1 ? "?" : "&";
+ link += entry.getKey() + "=" + entry.getValue();
+ i++;
+ }
+ if (debugParam != null && !debugParam.isEmpty()) {
+ link += i == 1 ? "?" : "&";
+ link += "gwt.codesvr=" + debugParam;
+ }
+ return URLEncoder.encode(link);
+ }
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java
index 894c26a01a6..8b3e4d5a30e 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java
@@ -38,6 +38,7 @@ import com.sap.sailing.gwt.ui.shared.GPSFixDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.ManeuverDTO;
import com.sap.sailing.gwt.ui.shared.RaceCourseDTO;
+import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
@@ -300,9 +301,12 @@ public interface SailingService extends RemoteService {
CourseAreaDTO createCourseArea(String eventIdAsString, String courseAreaName);
- List getRegattaOverviewEntriesForEvent(String eventIdAsString);
-
EventDTO getEventByIdAsString(String eventIdAsString);
+ List getRegattaStructureForEvent(String eventIdAsString);
+
+ List getRaceStateEntriesForRaceGroup(String eventIdAsString, List visibleCourseAreas,
+ List visibleRegattas, boolean showOnlyCurrentlyRunningRaces, boolean showOnlyRacesOfSameDay);
+
String getBuildVersion();
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java
index 431ff2b5707..4cde9a5ab70 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java
@@ -38,6 +38,7 @@ import com.sap.sailing.gwt.ui.shared.GPSFixDTO;
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
import com.sap.sailing.gwt.ui.shared.ManeuverDTO;
import com.sap.sailing.gwt.ui.shared.RaceCourseDTO;
+import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
import com.sap.sailing.gwt.ui.shared.RegattaDTO;
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
@@ -417,13 +418,17 @@ public interface SailingServiceAsync {
void getPolarSheetData(String polarSheetId, int angle, int windSpeedLevel, AsyncCallback wrapperCallback);
- void getRegattaOverviewEntriesForEvent(String eventIdAsString, AsyncCallback> asyncCallback);
-
void getEventByIdAsString(String eventIdAsString, AsyncCallback asyncCallback);
void updateRegatta(RegattaIdentifier regattaIdentifier, String defaultCourseAreaId, AsyncCallback callback);
void getBuildVersion(AsyncCallback callback);
+ void getRegattaStructureForEvent(String eventIdAsString, AsyncCallback> asyncCallback);
+
+ void getRaceStateEntriesForRaceGroup(String eventIdAsString, List visibleCourseAreas,
+ List visibleRegattas, boolean showOnlyCurrentlyRunningRaces, boolean showOnlyRacesOfSameDay,
+ AsyncCallback> markedAsyncCallback);
+
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
index b4ffdeede8b..dff732ad46a 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
@@ -654,5 +654,20 @@ public interface StringMessages extends Messages {
String addSeries();
String regattaDefinesResultDiscardingRules();
String startsWithZeroScore();
+ String regattaOverviewConfiguration();
String firstRaceIsNonDiscardableCarryForward();
+ String asLink();
+ String raceIsRunning();
+ String raceIsRunningWithEarlyStarters();
+ String raceIsFinishing();
+ String raceIsFinished();
+ String raceIsScheduled();
+ String raceIsInStartphase();
+ String generalRecall();
+ String startPostponed();
+ String startPostponedNoMoreRacingToday();
+ String startPostponedFurtherSignalsAshore();
+ String raceAbandoned();
+ String raceAbandonedNoMoreRacingToday();
+ String raceAbandonedFurtherSignalsAshore();
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
index c22daf76e08..f8e93c1beca 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
@@ -646,5 +646,20 @@ showOnlyCurrentlyRunningRaces=Show currently running races
seriesDefinesResultDiscardingRule=Series defines result discarding rules
addSeries=Add series
regattaDefinesResultDiscardingRules=Regatta defines result discarding rules
-startsWithZeroScore=Series starts with zero score
-firstRaceIsNonDiscardableCarryForward=Starts with non-discardable carry-forward
\ No newline at end of file
+startsWithZeroScore=Series starts with zero score
+regattaOverviewConfiguration=Regatta Overview Configuration
+firstRaceIsNonDiscardableCarryForward=Starts with non-discardable carry-forward
+asLink=As link
+raceIsRunning=Race is running
+raceIsRunningWithEarlyStarters=Race is running (had early starters)
+raceIsFinishing=Race is finishing
+raceIsFinished=Race is finished
+raceIsScheduled=Race is scheduled
+raceIsInStartphase=Race in start phase
+generalRecall=General recall
+startPostponed=Start postponed
+startPostponedNoMoreRacingToday=Start postponed - No more racing today
+startPostponedFurtherSignalsAshore=Start postponed - Further signals ashore
+raceAbandoned=Race abandoned
+raceAbandonedNoMoreRacingToday=Race abandoned - No more racing today
+raceAbandonedFurtherSignalsAshore=Race abandoned - Further signals ashore
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
index fcadc0c299b..e4c5c040825 100755
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
@@ -585,7 +585,7 @@ disableRaceFilter=Deaktiviere Filter
enableRaceFilter=Aktiviere Filter
raceStatusColumn=Renn-Status
loading=Lade...
-showHiddenRaces=Rennen im Status HIDDEN anzeigen
+showHiddenRaces=Rennen im Status HIDDEN anzeigen
selectedCompetitors=Ausgewählte Teilnehmer
filterNothing=Nichts filtern
topNCompetitorsByRaceRank=Wettfahrt Top {0}
@@ -645,4 +645,19 @@ seriesDefinesResultDiscardingRule=Serie legt Streichregel fest
addSeries=Serie hinzufügen
regattaDefinesResultDiscardingRules=Streichergebnisse werden von der Regatta festgelegt
startsWithZeroScore=Serie beginnt mit auf 0 gesetzten Ergebnissen
-firstRaceIsNonDiscardableCarryForward=Beginnt mit nicht streichbarem Übertrag
\ No newline at end of file
+regattaOverviewConfiguration=Regattaübersicht-Konfiguration
+firstRaceIsNonDiscardableCarryForward=Beginnt mit nicht streichbarem Übertrag
+asLink=Als Link
+raceIsRunning=Rennen läuft
+raceIsRunningWithEarlyStarters=Rennen läuft (es gab Frühstarter)
+raceIsFinishing=Rennen am beenden
+raceIsFinished=Rennen beendet
+raceIsScheduled=Startzeit angesetzt
+raceIsInStartphase=Rennen in der Startphase
+generalRecall=Gesamtrückruf
+startPostponed=Startverschiebung
+startPostponedNoMoreRacingToday=Startverschiebung - heute keine Rennen mehr
+startPostponedFurtherSignalsAshore=Startverschiebung - weitere Signale an Land
+raceAbandoned=Rennabbruch
+raceAbandonedNoMoreRacingToday=Rennabbruch - heute keine Rennen mehr
+raceAbandonedFurtherSignalsAshore=Rennabbruch - weitere Signale an Land
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/EventAndRaceGroupAvailabilityListener.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/EventAndRaceGroupAvailabilityListener.java
new file mode 100644
index 00000000000..e17b08375f7
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/EventAndRaceGroupAvailabilityListener.java
@@ -0,0 +1,11 @@
+package com.sap.sailing.gwt.ui.regattaoverview;
+
+import java.util.List;
+
+import com.sap.sailing.gwt.ui.shared.EventDTO;
+import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
+
+public interface EventAndRaceGroupAvailabilityListener {
+ void onEventUpdated(EventDTO event);
+ void onRaceGroupsUpdated(List raceGroups);
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/EventProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/EventProvider.java
deleted file mode 100644
index 9c8b5ab5230..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/EventProvider.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.sap.sailing.gwt.ui.regattaoverview;
-
-import com.sap.sailing.gwt.ui.shared.EventDTO;
-
-public interface EventProvider {
-
- EventDTO getEvent();
-
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagAlphabetInterpreter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagAlphabetInterpreter.java
new file mode 100644
index 00000000000..d8be735a6c3
--- /dev/null
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagAlphabetInterpreter.java
@@ -0,0 +1,84 @@
+package com.sap.sailing.gwt.ui.regattaoverview;
+
+import com.sap.sailing.domain.common.racelog.utils.FlagAlphabetInterpretationTemplate;
+import com.sap.sailing.gwt.ui.client.StringMessages;
+
+public class FlagAlphabetInterpreter extends FlagAlphabetInterpretationTemplate {
+
+ private StringMessages stringMessages;
+
+ public FlagAlphabetInterpreter(StringMessages stringMessages) {
+ this.stringMessages = stringMessages;
+ }
+
+ @Override
+ protected String getTextForRunningRace() {
+ return stringMessages.raceIsRunning();
+ }
+
+ @Override
+ protected String getTextForRunningRaceWithEarlyStarter() {
+ return stringMessages.raceIsRunningWithEarlyStarters();
+ }
+
+ @Override
+ protected String getTextForFinishingRace() {
+ return stringMessages.raceIsFinishing();
+ }
+
+ @Override
+ protected String getTextForFinishedRace() {
+ return stringMessages.raceIsFinished();
+ }
+
+ @Override
+ protected String getTextForScheduledRace() {
+ return stringMessages.raceIsScheduled();
+ }
+
+ @Override
+ protected String getTextForRaceInStartphase() {
+ return stringMessages.raceIsInStartphase();
+ }
+
+ @Override
+ protected String getTextForUnscheduledRace() {
+ return stringMessages.noStarttimeAnnouncedYet();
+ }
+
+ @Override
+ protected String getTextForFirstSubstituteFlag() {
+ return stringMessages.generalRecall();
+ }
+
+ @Override
+ protected String getTextForAnsweringPennantFlag() {
+ return stringMessages.startPostponed();
+ }
+
+ @Override
+ protected String getTextForAnsweringPennantWithAlphaFlags() {
+ return stringMessages.startPostponedNoMoreRacingToday();
+ }
+
+ @Override
+ protected String getTextForAnsweringPennantWithHotelFlags() {
+ return stringMessages.startPostponedFurtherSignalsAshore();
+ }
+
+ @Override
+ protected String getTextForNovemberFlag() {
+ return stringMessages.raceAbandoned();
+ }
+
+ @Override
+ protected String getTextForNovemberWithAlphaFlags() {
+ return stringMessages.raceAbandonedNoMoreRacingToday();
+ }
+
+ @Override
+ protected String getTextForNovemberWithHotelFlags() {
+ return stringMessages.raceAbandonedFurtherSignalsAshore();
+ }
+
+}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageCell.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageCell.java
index b8ea1eb4a9c..25b4eb2fb56 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageCell.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageCell.java
@@ -10,7 +10,7 @@ import com.sap.sailing.gwt.ui.client.shared.components.ImagesBarCell;
public class FlagImageCell extends ImagesBarCell {
static final String ACTION_EDIT = "ACTION_EDIT";
private final StringMessages stringMessages;
- private static RegattaOverviewResources resources = GWT.create(RegattaOverviewResources.class);
+ private static RegattaRaceStatesFlagsResources resources = GWT.create(RegattaRaceStatesFlagsResources.class);
public FlagImageCell(StringMessages stringConstants) {
super();
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageResolver.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageResolver.java
index e1d6ceae760..c6c7435217a 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageResolver.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/FlagImageResolver.java
@@ -11,7 +11,7 @@ public class FlagImageResolver {
private Map flagImageMap;
- private static RegattaOverviewResources resources = GWT.create(RegattaOverviewResources.class);
+ private static RegattaRaceStatesFlagsResources resources = GWT.create(RegattaRaceStatesFlagsResources.class);
public FlagImageResolver() {
this.flagImageMap = new HashMap();
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RaceCourseComposite.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RaceCourseComposite.java
deleted file mode 100644
index b801c2fac20..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RaceCourseComposite.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.sap.sailing.gwt.ui.regattaoverview;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.user.cellview.client.CellTable;
-import com.google.gwt.user.cellview.client.TextColumn;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.SimplePanel;
-import com.google.gwt.user.client.ui.VerticalPanel;
-import com.google.gwt.view.client.ListDataProvider;
-import com.sap.sailing.domain.common.NauticalSide;
-import com.sap.sailing.gwt.ui.client.ErrorReporter;
-import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
-import com.sap.sailing.gwt.ui.client.StringMessages;
-import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
-import com.sap.sailing.gwt.ui.shared.WaypointDTO;
-
-public class RaceCourseComposite extends Composite {
-
- private final CellTable waypointTable;
- private ListDataProvider waypointDataProvider;
- private final SimplePanel mainPanel;
-
- @SuppressWarnings("unused")
- private final SailingServiceAsync sailingService;
- private final StringMessages stringMessages;
-
- private RegattaOverviewEntryDTO race;
-
- private static RegattaRaceStatesTableResources tableRes = GWT.create(RegattaRaceStatesTableResources.class);
-
- private static final String STYLE_NAME_PREFIX = "RegattaOverview-";
- private static final String STYLE_WORD_WRAP = STYLE_NAME_PREFIX + "wordWrap";
-
- public RaceCourseComposite(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
- final StringMessages stringMessages) {
- this.sailingService = sailingService;
- this.stringMessages = stringMessages;
-
- this.race = null;
-
- mainPanel = new SimplePanel();
- VerticalPanel panel = new VerticalPanel();
- mainPanel.setWidget(panel);
- panel.setWidth("100%");
-
- waypointDataProvider = new ListDataProvider();
- waypointTable = createCourseDesignTable();
-
- panel.add(waypointTable);
-
- initWidget(mainPanel);
-
- }
-
- private CellTable createCourseDesignTable() {
- CellTable table = new CellTable(/* pageSize */10000, tableRes);
- waypointDataProvider.addDataDisplay(table);
- table.setWidth("100%");
-
- TextColumn waypointNameColumn = new TextColumn() {
- @Override
- public String getValue(WaypointDTO waypointDTO) {
- String result = waypointDTO.getName();
- result += (waypointDTO.passingSide == null) ? "" : ", to " + getNauticalSideAsText(waypointDTO.passingSide);
- return result;
- }
- };
-
- table.addColumn(waypointNameColumn, stringMessages.waypoints());
- waypointNameColumn.setCellStyleNames(STYLE_WORD_WRAP);
-
- return table;
- }
-
- public void setRace(RegattaOverviewEntryDTO regattaOverviewEntryDTO) {
- this.race = regattaOverviewEntryDTO;
- updateCourseDetails();
- }
-
- private void updateCourseDetails() {
- if (this.race != null && this.race.raceInfo.lastCourseDesign != null) {
- waypointDataProvider.getList().clear();
- waypointDataProvider.getList().addAll(this.race.raceInfo.lastCourseDesign.waypoints);
- }
- }
-
- private String getNauticalSideAsText(NauticalSide passingSide) {
- switch (passingSide) {
- case PORT:
- return stringMessages.portSide();
- case STARBOARD:
- return stringMessages.starboardSide();
- default:
- return "";
- }
- }
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewEntryPoint.java
index e5d61d9cf04..57c5c7fe26d 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewEntryPoint.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewEntryPoint.java
@@ -1,13 +1,23 @@
package com.sap.sailing.gwt.ui.regattaoverview;
+import java.util.ArrayList;
+import java.util.List;
+
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.sap.sailing.gwt.ui.client.AbstractEntryPoint;
import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel;
+import com.sap.sailing.gwt.ui.client.URLEncoder;
public class RegattaOverviewEntryPoint extends AbstractEntryPoint {
-
+
+ private final static String PARAM_EVENT = "event";
+ private final static String PARAM_ONLY_RUNNING_RACES = "onlyrunningraces";
+ private final static String PARAM_ONLY_RACES_OF_SAME_DAY = "onlyracesofsameday";
+ private final static String PARAM_REGATTA = "regatta";
+ private final static String PARAM_COURSE_AREA = "coursearea";
+
@Override
public void doOnModuleLoad() {
super.doOnModuleLoad();
@@ -23,10 +33,66 @@ public class RegattaOverviewEntryPoint extends AbstractEntryPoint {
RootPanel.getBodyElement().getStyle().setPadding(0, Unit.PX);
RootPanel.getBodyElement().getStyle().setPaddingTop(20, Unit.PX);
}
- String eventIdAsString = Window.Location.getParameter("event");
- RegattaOverviewPanel regattaOverviewPanel = new RegattaOverviewPanel(sailingService, this, stringMessages, eventIdAsString);
+ String eventIdAsString = Window.Location.getParameter(PARAM_EVENT);
+
+ RegattaRaceStatesSettings settings = createRegattaRaceStatesSettingsFromURL();
+
+ RegattaOverviewPanel regattaOverviewPanel = new RegattaOverviewPanel(sailingService, this, stringMessages, eventIdAsString, settings);
rootPanel.add(regattaOverviewPanel);
}
-
-}
+
+ public static RegattaRaceStatesSettings createRegattaRaceStatesSettingsFromURL() {
+ List visibleCourseAreas = new ArrayList();
+ List visibleRegattas = new ArrayList();
+
+ boolean showOnlyCurrentlyRunningRaces = Window.Location.getParameter(PARAM_ONLY_RUNNING_RACES) == null
+ || !Window.Location.getParameter(PARAM_ONLY_RUNNING_RACES).equalsIgnoreCase("false");
+
+ boolean showOnlyRacesOfSameDay = Window.Location.getParameter(PARAM_ONLY_RACES_OF_SAME_DAY) != null
+ && Window.Location.getParameter(PARAM_ONLY_RACES_OF_SAME_DAY).equalsIgnoreCase("true");
+
+ if (Window.Location.getParameterMap().containsKey(PARAM_COURSE_AREA)) {
+ visibleCourseAreas.addAll(Window.Location.getParameterMap().get(PARAM_COURSE_AREA));
+ }
+
+ if (Window.Location.getParameterMap().containsKey(PARAM_REGATTA)) {
+ visibleRegattas.addAll(Window.Location.getParameterMap().get(PARAM_REGATTA));
+ }
+
+ return new RegattaRaceStatesSettings(visibleCourseAreas, visibleRegattas, showOnlyRacesOfSameDay, showOnlyCurrentlyRunningRaces);
+ }
+
+ public static String getUrl(String eventIdAsString, RegattaRaceStatesSettings settings,
+ boolean isSetVisibleCourseAreasInUrl, boolean isSetVisibleRegattasInUrl) {
+ String debugParam = Window.Location.getParameter("gwt.codesvr");
+ String showOnlyCurrentlyRunningRaces = "&" + PARAM_ONLY_RUNNING_RACES + "=" + (settings.isShowOnlyCurrentlyRunningRaces() ? "true" : "false");
+ String showOnlyRacesOfSameDay = "&" + PARAM_ONLY_RACES_OF_SAME_DAY + "=" + (settings.isShowOnlyRacesOfSameDay() ? "true" : "false");
+
+ StringBuilder visibleCourseAreas = new StringBuilder();
+ if (isSetVisibleCourseAreasInUrl) {
+ for (String visibleCourseArea : settings.getVisibleCourseAreas()) {
+ visibleCourseAreas.append('&');
+ visibleCourseAreas.append(PARAM_COURSE_AREA);
+ visibleCourseAreas.append('=');
+ visibleCourseAreas.append(visibleCourseArea);
+ }
+ }
+ StringBuilder visibleRegattas = new StringBuilder();
+ if (isSetVisibleRegattasInUrl) {
+ for (String visibleRegatta : settings.getVisibleRegattas()) {
+ visibleRegattas.append('&');
+ visibleRegattas.append(PARAM_REGATTA);
+ visibleRegattas.append('=');
+ visibleRegattas.append(visibleRegatta);
+ }
+ }
+ String link = URLEncoder.encode("/gwt/RegattaOverview.html?" + PARAM_EVENT+ "=" + eventIdAsString
+ + visibleCourseAreas.toString()
+ + visibleRegattas.toString()
+ + showOnlyCurrentlyRunningRaces
+ + showOnlyRacesOfSameDay
+ + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
+ return link;
+ }
+}
\ No newline at end of file
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewPanel.java
index 21742edc7f3..965a153e962 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewPanel.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewPanel.java
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.regattaoverview;
+import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -25,9 +26,9 @@ import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
import com.sap.sailing.gwt.ui.client.Timer.PlayStates;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
import com.sap.sailing.gwt.ui.shared.EventDTO;
-import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
+import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
-public class RegattaOverviewPanel extends SimplePanel implements RegattaOverviewRaceSelectionChangeListener, EventProvider {
+public class RegattaOverviewPanel extends SimplePanel {
private final long serverUpdateRateInMs = 10000;
private final long uiUpdateRateInMs = 1000;
@@ -37,14 +38,14 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
private final SailingServiceAsync sailingService;
protected final StringMessages stringMessages;
+ protected final ErrorReporter errorReporter;
private final String eventIdAsString;
private EventDTO eventDTO;
-
- private RegattaOverviewRaceSelectionModel raceSelectionProvider;
+ private List raceGroupDTOs;
+ private List eventRaceGroupListeners;
private RegattaRaceStatesComponent regattaRaceStatesComponent;
- private RaceCourseComposite raceCourseComposite;
private final Label eventNameLabel;
private final Label venueNameLabel;
@@ -64,47 +65,27 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
private static final String STYLE_VENUE_LABEL = STYLE_NAME_PREFIX + "VenueLabel";
private static final String STYLE_CLOCK_LABEL = STYLE_NAME_PREFIX + "ClockLabel";
- public RegattaOverviewPanel(SailingServiceAsync sailingService, final ErrorReporter errorReporter, final StringMessages stringMessages, String eventIdAsString) {
+ public RegattaOverviewPanel(SailingServiceAsync sailingService, final ErrorReporter errorReporter, final StringMessages stringMessages,
+ String eventIdAsString, RegattaRaceStatesSettings settings) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
+ this.errorReporter = errorReporter;
this.eventIdAsString = eventIdAsString;
this.eventDTO = null;
+ this.raceGroupDTOs = new ArrayList();
+ this.eventRaceGroupListeners = new ArrayList();
retrieveEvent();
+ retrieveRegattaStructure();
VerticalPanel mainPanel = new VerticalPanel();
setWidget(mainPanel);
mainPanel.setWidth("100%");
mainPanel.addStyleName(STYLE_CONTENT_WRAPPER);
- Grid grid = new Grid(2, 2);
- grid.setWidth("100%");
-
- Label raceOverviewLabel = new Label(stringMessages.courseAreaOverview());
- raceOverviewLabel.addStyleName(STYLE_TITLE_LABEL);
-
- Label courseDesignOverviewLabel = new Label(stringMessages.courseDesignOverview());
- courseDesignOverviewLabel.addStyleName(STYLE_TITLE_LABEL);
-
- grid.setWidget(0, 0, raceOverviewLabel);
- grid.setWidget(0, 1, courseDesignOverviewLabel);
-
- raceSelectionProvider = new RegattaOverviewRaceSelectionModel(false);
- raceSelectionProvider.addRegattaOverviewRaceSelectionChangeListener(this);
-
- regattaRaceStatesComponent = new RegattaRaceStatesComponent(sailingService, errorReporter, stringMessages, eventIdAsString,
- raceSelectionProvider, this);
- grid.setWidget(1, 0, regattaRaceStatesComponent);
-
- raceCourseComposite = new RaceCourseComposite(sailingService, errorReporter, stringMessages);
- grid.setWidget(1, 1, raceCourseComposite);
-
- grid.getRowFormatter().setVerticalAlign(0, HasVerticalAlignment.ALIGN_TOP);
- grid.getRowFormatter().setVerticalAlign(1, HasVerticalAlignment.ALIGN_TOP);
- grid.getColumnFormatter().setWidth(0, "80%");
- grid.getColumnFormatter().setWidth(1, "20%");
- grid.getColumnFormatter().getElement(1).getStyle().setPaddingTop(2.0, Unit.EM);
- grid.getColumnFormatter().getElement(1).getStyle().setPaddingLeft(20.0, Unit.PX);
+ regattaRaceStatesComponent = new RegattaRaceStatesComponent(sailingService, errorReporter, stringMessages, eventIdAsString, settings);
+ this.eventRaceGroupListeners.add(regattaRaceStatesComponent);
+ regattaRaceStatesComponent.setWidth("100%");
refreshNowButton = new Button(stringMessages.refreshNow());
refreshNowButton.addClickHandler(new ClickHandler() {
@@ -194,7 +175,7 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
flexTable.setWidget(0, 1, refreshStartStopClockPanel);
mainPanel.add(flexTable);
- mainPanel.add(grid);
+ mainPanel.add(regattaRaceStatesComponent);
onUpdateUI(new Date());
}
@@ -215,32 +196,15 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
public void onUpdateUI(Date time) {
timeLabel.setText(timeFormatter.format(time));
}
-
- @Override
- public void onRegattaOverviewEntrySelectionChange(List selectedRegattaOverviewEntries) {
- final RegattaOverviewEntryDTO selectedRegattaOverviewEntry;
- if (selectedRegattaOverviewEntries.iterator().hasNext()) {
- selectedRegattaOverviewEntry = selectedRegattaOverviewEntries.iterator().next();
- if (selectedRegattaOverviewEntry != null && regattaRaceStatesComponent.getAllRaces() != null) {
- for(RegattaOverviewEntryDTO regattaOverviewEntryDTO: regattaRaceStatesComponent.getAllRaces()) {
- if(regattaOverviewEntryDTO.equals(selectedRegattaOverviewEntry)) {
- raceCourseComposite.setRace(regattaOverviewEntryDTO);
- break;
- }
- }
- }
- } else {
- raceCourseComposite.setRace(null);
- }
- }
private void retrieveEvent() {
sailingService.getEventByIdAsString(eventIdAsString, new MarkedAsyncCallback() {
@Override
protected void handleFailure(Throwable cause) {
- //Show a (friendly) error message
settingsButton.setEnabled(false);
+ errorReporter.reportError("Error trying to load event with id " + eventIdAsString + " : "
+ + cause.getMessage());
}
@Override
@@ -257,11 +221,6 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
venueNameLabel.setText(eventDTO.venue.getName());
}
- @Override
- public EventDTO getEvent() {
- return eventDTO;
- }
-
protected void setEvent(EventDTO event) {
eventDTO = event;
onEventUpdated();
@@ -269,9 +228,50 @@ public class RegattaOverviewPanel extends SimplePanel implements RegattaOverview
private void onEventUpdated() {
fillEventAndVenueName();
- settingsButton.setEnabled(true);
+
+ for (EventAndRaceGroupAvailabilityListener listener : this.eventRaceGroupListeners) {
+ listener.onEventUpdated(eventDTO);
+ }
+
+ checkToEnableSettingsButton();
}
-
+ private void retrieveRegattaStructure() {
+ sailingService.getRegattaStructureForEvent(eventIdAsString, new MarkedAsyncCallback>() {
+
+ @Override
+ protected void handleFailure(Throwable cause) {
+ errorReporter.reportError("Error trying to load regattas for event with id " + eventIdAsString + " : "
+ + cause.getMessage());
+ }
+
+ @Override
+ protected void handleSuccess(List result) {
+ if (result != null) {
+ setRaceGroups(result);
+ }
+ }
+
+ });
+ }
+
+ protected void setRaceGroups(List result) {
+ raceGroupDTOs.clear();
+ raceGroupDTOs.addAll(result);
+ onRaceGroupsUpdated();
+ }
+
+ private void onRaceGroupsUpdated() {
+ for (EventAndRaceGroupAvailabilityListener listener : this.eventRaceGroupListeners) {
+ listener.onRaceGroupsUpdated(raceGroupDTOs);
+ }
+ checkToEnableSettingsButton();
+ }
+
+ private void checkToEnableSettingsButton() {
+ if (eventDTO != null && raceGroupDTOs.size() > 0) {
+ settingsButton.setEnabled(true);
+ }
+ }
}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionChangeListener.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionChangeListener.java
deleted file mode 100644
index 116cbf029f4..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionChangeListener.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.sap.sailing.gwt.ui.regattaoverview;
-
-import java.util.List;
-
-import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
-
-public interface RegattaOverviewRaceSelectionChangeListener {
- /**
- * The first element is the first one selected
- *
- * @param selectedRegattaOverviewEntries a non-null list which is empty if nothing is selected
- */
- void onRegattaOverviewEntrySelectionChange(List selectedRegattaOverviewEntries);
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionModel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionModel.java
deleted file mode 100644
index 36274cb3789..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionModel.java
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.sap.sailing.gwt.ui.regattaoverview;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
-
-public class RegattaOverviewRaceSelectionModel implements RegattaOverviewRaceSelectionProvider {
-
- private final List selection;
-
- private final List allRegattaOverviewRaces;
-
- private final Set listeners;
-
- private final boolean hasMultiSelection;
-
- public RegattaOverviewRaceSelectionModel(boolean hasMultiSelection) {
- this.hasMultiSelection = hasMultiSelection;
- this.selection = new ArrayList();
- this.allRegattaOverviewRaces = new ArrayList();
- listeners = new HashSet();
- }
-
- @Override
- public List getSelectedEntries() {
- return Collections.unmodifiableList(selection);
- }
-
- @Override
- public void addRegattaOverviewRaceSelectionChangeListener(RegattaOverviewRaceSelectionChangeListener listener) {
- listeners.add(listener);
- }
-
- @Override
- public void removeRegattaOverviewRaceSelectionChangeListener(RegattaOverviewRaceSelectionChangeListener listener) {
- listeners.remove(listener);
- }
-
- @Override
- public void setSelection(List newSelection, RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify) {
- boolean notify = !selection.equals(newSelection);
- selection.clear();
- selection.addAll(newSelection);
- if (notify) {
- notifyListeners(listenersNotToNotify);
- }
- }
-
- private void notifyListeners(RegattaOverviewRaceSelectionChangeListener[] listenersNotToNotify) {
- List selectedRegattaOverviewEntries = getSelectedEntries();
- for (RegattaOverviewRaceSelectionChangeListener listener : listeners) {
- if (listenersNotToNotify == null || !Arrays.asList(listenersNotToNotify).contains(listener)) {
- listener.onRegattaOverviewEntrySelectionChange(selectedRegattaOverviewEntries);
- }
- }
- }
-
- @Override
- public boolean hasMultiSelection() {
- return hasMultiSelection;
- }
-
- @Override
- public List getAllRegattaOverviewEntries() {
- return Collections.unmodifiableList(allRegattaOverviewRaces);
- }
-
- @Override
- public void setAllRegattaOverviewEntries(List newAllRegattaOverviewEntries,
- RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify) {
- allRegattaOverviewRaces.clear();
- for (RegattaOverviewEntryDTO r : newAllRegattaOverviewEntries) {
- allRegattaOverviewRaces.add(r);
- }
- for (Iterator i=selection.iterator(); i.hasNext(); ) {
- RegattaOverviewEntryDTO selectedRegattaOverviewEntry = i.next();
- if (!allRegattaOverviewRaces.contains(selectedRegattaOverviewEntry)) {
- i.remove();
- }
- }
- // when setting all regatta overview entries, the actual RegattaOverviewEntryDTOs will usually have changed their identity and maybe also their state;
- // so notifying the selection listeners is necessary anyhow
- notifyListeners(listenersNotToNotify);
- }
-
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionProvider.java
deleted file mode 100644
index 709a9fee027..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaOverviewRaceSelectionProvider.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.sap.sailing.gwt.ui.regattaoverview;
-
-import java.util.List;
-
-import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
-
-public interface RegattaOverviewRaceSelectionProvider {
- /**
- * @return a non-null list which may be empty
- */
- List getSelectedEntries();
-
- void addRegattaOverviewRaceSelectionChangeListener(RegattaOverviewRaceSelectionChangeListener listener);
-
- void removeRegattaOverviewRaceSelectionChangeListener(RegattaOverviewRaceSelectionChangeListener listener);
-
- void setSelection(List newSelection, RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify);
-
- boolean hasMultiSelection();
-
- /**
- * @return a non-null list which may be empty
- */
- List getAllRegattaOverviewEntries();
-
- void setAllRegattaOverviewEntries(List newAllRegattaOverviewEntries, RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify);
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComparator.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComparator.java
deleted file mode 100644
index 6d9fd0f2b55..00000000000
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComparator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.sap.sailing.gwt.ui.regattaoverview;
-
-import java.util.Comparator;
-
-import com.sap.sailing.domain.common.impl.NaturalComparator;
-import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
-
-public class RegattaRaceStatesComparator implements Comparator {
-
- @Override
- public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
- int result = left.courseAreaName.compareTo(right.courseAreaName);
- if (result == 0) {
- if (left.regattaName != null && right.regattaName != null) {
- result = new NaturalComparator().compare(left.regattaName, right.regattaName);
- }
- if (result == 0) {
- //TODO Caution: Series is missing!!!
- result = Integer.valueOf(left.raceInfo.fleetOrdering).compareTo(Integer.valueOf(right.raceInfo.fleetOrdering));
- if (result == 0) {
- result = (-1) * new NaturalComparator().compare(right.raceInfo.raceName, left.raceInfo.raceName);
- //the naturalComparator sorts the other way round R30 < R29 < R28 etc., therefore the (-1) multiplication
- }
- }
- }
- return result;
- }
-
-}
diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComponent.java
index b8e1b90054c..cf0c4f8616a 100644
--- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComponent.java
+++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/regattaoverview/RegattaRaceStatesComponent.java
@@ -4,46 +4,66 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import com.google.gwt.cell.client.ClickableTextCell;
+import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.ImageResourceCell;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
+import com.google.gwt.json.client.JSONObject;
+import com.google.gwt.json.client.JSONParser;
+import com.google.gwt.json.client.JSONValue;
import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.TextColumn;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.DialogBox;
+import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
+import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
-import com.google.gwt.view.client.SelectionChangeEvent;
-import com.google.gwt.view.client.SelectionModel;
-import com.google.gwt.view.client.SingleSelectionModel;
-import com.sap.sailing.domain.common.racelog.Flags;
-import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
+import com.sap.sailing.domain.common.LeaderboardNameConstants;
+import com.sap.sailing.domain.common.NauticalSide;
+import com.sap.sailing.domain.common.dto.FleetDTO;
+import com.sap.sailing.gwt.ui.client.AnchorCell;
+import com.sap.sailing.gwt.ui.client.EntryPointLinkFactory;
import com.sap.sailing.gwt.ui.client.ErrorReporter;
+import com.sap.sailing.gwt.ui.client.GwtJsonDeSerializer;
import com.sap.sailing.gwt.ui.client.MarkedAsyncCallback;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.components.Component;
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
+import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
+import com.sap.sailing.gwt.ui.shared.EventDTO;
+import com.sap.sailing.gwt.ui.shared.RaceGroupDTO;
+import com.sap.sailing.gwt.ui.shared.RaceGroupSeriesDTO;
import com.sap.sailing.gwt.ui.shared.RaceInfoDTO;
import com.sap.sailing.gwt.ui.shared.RegattaOverviewEntryDTO;
+import com.sap.sailing.gwt.ui.shared.WaypointDTO;
/**
* This component shows a table displaying the current state of races for a given event.
* Which races are shown depends on the setting {@link RegattaRaceStatesSettings}.
* Each entry shows what flags are currently displayed, what start time the race has and additional information, e.g. for Gate start.
*/
-public class RegattaRaceStatesComponent extends SimplePanel implements Component {
+public class RegattaRaceStatesComponent extends SimplePanel implements Component, EventAndRaceGroupAvailabilityListener {
private List allEntries;
- private final SelectionModel raceSelectionModel;
private final CellTable regattaOverviewTable;
private ListDataProvider regattaOverviewDataProvider;
private final VerticalPanel mainPanel;
@@ -52,61 +72,56 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
private final SailingServiceAsync sailingService;
private final StringMessages stringMessages;
private final String eventIdAsString;
- private final RegattaOverviewRaceSelectionProvider raceSelectionProvider;
- private final EventProvider eventProvider;
-
private final FlagImageResolver flagImageResolver;
- private RegattaRaceStatesSettings settings;
+ private EventDTO eventDTO;
+ private List raceGroupDTOs;
+ private TextColumn seriesNameColumn;
+ private TextColumn fleetNameColumn;
+
+ private final RegattaRaceStatesSettings settings;
+ private final FlagAlphabetInterpreter flagInterpreter;
+ private final String localStorageRegattaOverviewEventKey;
+
private static RegattaRaceStatesTableResources tableRes = GWT.create(RegattaRaceStatesTableResources.class);
+ private final static String LOCAL_STORAGE_REGATTA_OVERVIEW_KEY = "sailingAnalytics.regattaOverview.settings.";
+
public RegattaRaceStatesComponent(final SailingServiceAsync sailingService, ErrorReporter errorReporter,
- final StringMessages stringMessages, final String eventIdAsString, final RegattaOverviewRaceSelectionProvider raceSelectionProvider,
- final EventProvider eventProvider) {
+ final StringMessages stringMessages, final String eventIdAsString, RegattaRaceStatesSettings settings) {
this.sailingService = sailingService;
this.stringMessages = stringMessages;
this.eventIdAsString = eventIdAsString;
- this.raceSelectionProvider = raceSelectionProvider;
- this.eventProvider = eventProvider;
this.flagImageResolver = new FlagImageResolver();
+ this.allEntries = new ArrayList();
- settings = new RegattaRaceStatesSettings();//TODO initialize settings properly
+ this.eventDTO = null;
+ this.raceGroupDTOs = null;
+ this.localStorageRegattaOverviewEventKey = LOCAL_STORAGE_REGATTA_OVERVIEW_KEY + eventIdAsString;
+
+ this.flagInterpreter = new FlagAlphabetInterpreter(stringMessages);
+
+ this.settings = new RegattaRaceStatesSettings();
+ loadAndSetSettings(settings);
+
mainPanel = new VerticalPanel();
setWidth("100%");
regattaOverviewDataProvider = new ListDataProvider();
regattaOverviewTable = createRegattaTable();
- raceSelectionModel = new SingleSelectionModel();
- raceSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
-
- @Override
- public void onSelectionChange(SelectionChangeEvent event) {
- showSelectedRaces();
- }
-
- });
-
- regattaOverviewTable.setSelectionModel(raceSelectionModel);
-
mainPanel.add(regattaOverviewTable);
setWidget(mainPanel);
-
- loadAndUpdateEventLog();
}
- protected List getSelectedRaces() {
- List result = new ArrayList();
- if (regattaOverviewDataProvider != null) {
- for (RegattaOverviewEntryDTO race : regattaOverviewDataProvider.getList()) {
- if (raceSelectionModel.isSelected(race)) {
- result.add(race);
- }
- }
+ private void loadAndSetSettings(RegattaRaceStatesSettings settings) {
+ RegattaRaceStatesSettings loadedSettings = loadRegattaRaceStatesSettings();
+ if (loadedSettings != null) {
+ settings = loadedSettings;
}
- return result;
+ updateSettings(settings);
}
public void onUpdateServer(Date time) {
@@ -115,86 +130,31 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
private void updateTable(List newEntries) {
allEntries = newEntries;
- List filteredRegattaRaces = getFilteredRegattaRaces(allEntries);
- Collections.sort(filteredRegattaRaces, new RegattaRaceStatesComparator()); //sort entries after filtering
- List racesToBeShown = getRacesToBeShown(filteredRegattaRaces);
- //TODO group races by same day
+
regattaOverviewDataProvider.getList().clear();
- regattaOverviewDataProvider.getList().addAll(racesToBeShown);
+ regattaOverviewDataProvider.getList().addAll(allEntries);
// now sort again according to selected criterion
ColumnSortEvent.fire(regattaOverviewTable, regattaOverviewTable.getColumnSortList());
}
- private List getRacesToBeShown(List filteredEntries) {
- List racesToBeShown = new ArrayList(filteredEntries);
- if (settings.isShowOnlyCurrentlyRunningRaces()) {
- String currentRegattaName = "";
- String currentFleetName = "";
- int numberOfFinishedRacesOfCurrentRegattaFleet = 0;
- for (RegattaOverviewEntryDTO entry : filteredEntries) {
- if (!currentRegattaName.equals(entry.regattaName) || !currentFleetName.equals(entry.raceInfo.fleetName)) {
- currentRegattaName = entry.regattaName;
- currentFleetName = entry.raceInfo.fleetName;
- numberOfFinishedRacesOfCurrentRegattaFleet = 0;
- }
- if (!isRaceActive(entry.raceInfo.lastStatus)) {
- if (entry.raceInfo.lastStatus.equals(RaceLogRaceStatus.FINISHED)) {
- if (numberOfFinishedRacesOfCurrentRegattaFleet > 0) {
- racesToBeShown.remove(entry);
- }
- numberOfFinishedRacesOfCurrentRegattaFleet++;
- } else if (entry.raceInfo.lastStatus.equals(RaceLogRaceStatus.UNSCHEDULED)) {
- //don't filter when the race is unscheduled and aborted before
- if (!entry.raceInfo.isRaceAbortedInPassBefore) {
- racesToBeShown.remove(entry);
- }
-
- }
- }
- }
- }
- return racesToBeShown;
- }
-
- private List getFilteredRegattaRaces(List raceList) {
- List filteredEntries = new ArrayList(raceList);
-
- for (RegattaOverviewEntryDTO entry : raceList) {
- if (!settings.getVisibleCourseAreas().contains(entry.courseAreaIdAsString)) {
- filteredEntries.remove(entry);
- continue;
- }
- if (!settings.getVisibleRegattas().contains(entry.regattaName)) {
- filteredEntries.remove(entry);
- continue;
- }
- }
-
- return filteredEntries;
- }
-
- private boolean isRaceActive(RaceLogRaceStatus status) {
- return status.equals(RaceLogRaceStatus.SCHEDULED) || status.equals(RaceLogRaceStatus.STARTPHASE)
- || status.equals(RaceLogRaceStatus.RUNNING) || status.equals(RaceLogRaceStatus.FINISHING);
- }
-
protected void loadAndUpdateEventLog() {
- if (eventIdAsString == null) {
+ if (eventIdAsString == null || eventDTO == null || raceGroupDTOs == null) {
return;
}
- sailingService.getRegattaOverviewEntriesForEvent(eventIdAsString,
- new MarkedAsyncCallback>() {
+ sailingService.getRaceStateEntriesForRaceGroup(eventIdAsString, settings.getVisibleCourseAreas(), settings.getVisibleRegattas(),
+ settings.isShowOnlyCurrentlyRunningRaces(), settings.isShowOnlyRacesOfSameDay(), new MarkedAsyncCallback>() {
- @Override
- protected void handleFailure(Throwable cause) {
+ @Override
+ protected void handleFailure(Throwable cause) {
- }
+ }
- @Override
- protected void handleSuccess(List result) {
- updateTable(result);
- }
- });
+ @Override
+ protected void handleSuccess(List result) {
+ updateTable(result);
+ }
+
+ });
}
private CellTable createRegattaTable() {
@@ -221,10 +181,17 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
});
- TextColumn regattaNameColumn = new TextColumn() {
+ AnchorCell leaderboardAnchorCell = new AnchorCell();
+ Column regattaNameColumn = new Column(leaderboardAnchorCell) {
@Override
- public String getValue(RegattaOverviewEntryDTO entryDTO) {
- return entryDTO.regattaName;
+ public Anchor getValue(RegattaOverviewEntryDTO entryDTO) {
+ Map leaderboardLinkParameters = new HashMap();
+ leaderboardLinkParameters.put("name", entryDTO.regattaName);
+ leaderboardLinkParameters.put("showRaceDetails", String.valueOf(true));
+ leaderboardLinkParameters.put("displayName", entryDTO.regattaDisplayName);
+ String leaderboardLink = EntryPointLinkFactory.createLeaderboardLink(leaderboardLinkParameters);
+ Anchor result = new Anchor(entryDTO.regattaDisplayName, leaderboardLink);
+ return result;
}
};
regattaNameColumn.setSortable(true);
@@ -232,44 +199,47 @@ public class RegattaRaceStatesComponent extends SimplePanel implements Component
@Override
public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
- return left.regattaName.compareTo(right.regattaName);
+ return left.regattaDisplayName.compareTo(right.regattaDisplayName);
}
});
- TextColumn fleetNameColumn = new TextColumn() {
+ seriesNameColumn = new TextColumn() {
@Override
public String getValue(RegattaOverviewEntryDTO entryDTO) {
- //TODO Fleet column shall be not shown when the races of this event have no fleets
- return entryDTO.raceInfo.fleetName.equals("Default") ? "-" : entryDTO.raceInfo.fleetName;
+ return entryDTO.raceInfo.seriesName.equals(LeaderboardNameConstants.DEFAULT_SERIES_NAME) ? "-" : entryDTO.raceInfo.seriesName;
+ }
+ };
+ seriesNameColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
+
+ fleetNameColumn = new TextColumn() {
+ @Override
+ public String getValue(RegattaOverviewEntryDTO entryDTO) {
+ return entryDTO.raceInfo.fleetName.equals(LeaderboardNameConstants.DEFAULT_FLEET_NAME) ? "-" : entryDTO.raceInfo.fleetName;
}
};
fleetNameColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
- fleetNameColumn.setSortable(true);
- regattaOverviewListHandler.setComparator(fleetNameColumn, new Comparator() {
+ AnchorCell raceCell = new AnchorCell();
+ Column raceNameColumn = new Column(raceCell) {
@Override
- public int compare(RegattaOverviewEntryDTO left, RegattaOverviewEntryDTO right) {
- return left.raceInfo.fleetName.compareTo(right.raceInfo.fleetName);
- }
-
- });
-
- TextColumn raceNameColumn = new TextColumn() {
- @Override
- public String getValue(RegattaOverviewEntryDTO entryDTO) {
- return entryDTO.raceInfo.raceName;
+ public Anchor getValue(RegattaOverviewEntryDTO entryDTO) {
+ Anchor result = null;
+ if (entryDTO.raceInfo.raceIdentifier != null && entryDTO.raceInfo.isTracked) {
+ Map