Merge branch 'master' into live1

This commit is contained in:
Simon Pamies committed 2013-06-20 13:34:34 +02:00
commit ca5e7fe685
392 files changed
+11652 -4577

No files matched your search

+3
View File
@@ -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
+1 -1
View File
@@ -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
@@ -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
@@ -1,3 +1,3 @@
package com.sap.sailing.domain.common;
public enum MarkType { BUOY, CAMERABOAT, STARTBOAT, UMPIREBOAT, LANDMARK }
public enum MarkType { BUOY, CAMERABOAT, STARTBOAT, UMPIREBOAT, LANDMARK, FINISHBOAT }
@@ -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);
}
}
@@ -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;
}
}
@@ -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();
}
@@ -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);
}
}
@@ -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<Event> allEvents = loadAllEvents();
result = null;
for (Event event : allEvents) {
for (CourseArea courseArea : event.getVenue().getCourseAreas()) {
if (courseArea.getId().equals(courseAreaUuid)) {
result = courseArea;
}
}
}
}
return result;
}
/**
* @return <code>null</code> 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<Competitor> 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<Competitor> 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<Competitor> 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<Competitor> competitors, DBObject dbObject) {
return raceLogEventFactory.createFinishPositioningConfirmedEvent(createdAt, timePoint, id, competitors, passId);
BasicDBList dbPositionedCompetitorList = (BasicDBList) dbObject.get(FieldNames.RACE_LOG_POSITIONED_COMPETITORS.name());
List<Triple<Serializable, String, MaxPointsReason>> 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<Competitor> 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;
@@ -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;
}
@@ -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<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
BasicDBList dbList = new BasicDBList();
for (Triple<Serializable, String, MaxPointsReason> competitorPair : positionedCompetitors) {
dbList.add(storePositionedCompetitor(competitorPair));
if (positionedCompetitors != null) {
for (Triple<Serializable, String, MaxPointsReason> competitorPair : positionedCompetitors) {
dbList.add(storePositionedCompetitor(competitorPair));
}
}
return dbList;
}
@@ -817,4 +854,5 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
}
return passing;
}
}
@@ -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);
}
}
@@ -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<AbortingFlagFinder> {
@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;
}
}
@@ -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<LastFlagsFinder> {
@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<RaceLogFlagEvent> 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<RaceLogFlagEvent> 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<RaceLogFlagEvent> 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<RaceLogFlagEvent> 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<RaceLogFlagEvent> 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<RaceLogFlagEvent>()));
}
@Test
public void testGetMostRecentDisplayedDisplayedOverRemoved() {
List<RaceLogFlagEvent> events = new ArrayList<RaceLogFlagEvent>();
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<RaceLogFlagEvent> events = new ArrayList<RaceLogFlagEvent>();
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<RaceLogFlagEvent> events = new ArrayList<RaceLogFlagEvent>();
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));
}
}
@@ -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<LastWindFixFinder> {
@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());
}
}
@@ -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<ProtestStartTimeFinder> {
@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());
}
}
@@ -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<AnalyzerType> {
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 extends RaceLogEvent> T createEvent(Class<T> type, long milliseconds) {
return createEvent(type, milliseconds, 0, "");
}
protected static <T extends RaceLogEvent> T createEvent(Class<T> type, long milliseconds, Serializable id) {
return createEvent(type, milliseconds, 0, id);
}
protected static <T extends RaceLogEvent> T createEvent(Class<T> 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;
}
}
@@ -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();
}
}
}
@@ -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<Object> {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
@@ -10,6 +10,6 @@ import com.sap.sailing.domain.common.WithID;
* @author Axel Uhl (D043530)
*
*/
public interface CourseArea extends Named, WithID {
public interface CourseArea extends Named, WithID, IsManagedBySharedDomainFactory {
}
@@ -77,6 +77,10 @@ public interface SharedDomainFactory {
Competitor createCompetitor(Serializable id, String name, Team team, Boat boat);
Competitor getOrCreateCompetitor(Serializable competitorId, String name, Team team, Boat boat);
CourseArea getOrCreateCourseArea(Serializable courseAreaId, String name);
CourseArea getExistingCourseAreaById(Serializable courseAreaId);
}
@@ -3,6 +3,8 @@ package com.sap.sailing.domain.base.impl;
import java.io.Serializable;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.IsManagedBySharedDomainFactory;
import com.sap.sailing.domain.base.SharedDomainFactory;
import com.sap.sailing.domain.common.impl.NamedImpl;
public class CourseAreaImpl extends NamedImpl implements CourseArea {
@@ -21,14 +23,7 @@ public class CourseAreaImpl extends NamedImpl implements CourseArea {
}
@Override
public boolean equals(Object obj) {
if (obj instanceof CourseArea) {
CourseArea courseArea = (CourseArea) obj;
if (this.id.equals(courseArea.getId())) {
return true;
}
return false;
}
return super.equals(obj);
public IsManagedBySharedDomainFactory resolve(SharedDomainFactory domainFactory) {
return domainFactory.getOrCreateCourseArea(id, getName());
}
}
@@ -7,5 +7,9 @@ import com.sap.sailing.domain.base.SeriesBase;
* between Leaderboards and Regattas for any app since Leaderboards do not have any series, but Regattas.
*/
public interface SeriesWithRows extends SeriesBase {
/**
* All {@link RaceRow}s of this series.
*/
public Iterable<RaceRow> getRaceRows();
}
@@ -17,6 +17,9 @@ import com.sap.sailing.domain.tracking.Track;
* </p>
*/
public interface RaceLog extends Track<RaceLogEvent>, WithID {
public static final int DefaultPassId = 0;
/**
* Gets the current pass id.
*
@@ -47,4 +50,8 @@ public interface RaceLog extends Track<RaceLogEvent>, WithID {
* Checks if the race log is empty.
*/
boolean isEmpty();
Iterable<RaceLogEvent> getRawFixesDescending();
Iterable<RaceLogEvent> getFixesDescending();
}
@@ -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<Competitor> 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<Competitor> involvedBoats,
int passId, TimePoint startTime);
RaceLogStartTimeEvent createStartTimeEvent(TimePoint timePoint, int passId, TimePoint startTime);
RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, Serializable id, List<Competitor> competitors,
int passId, RaceLogRaceStatus nextStatus);
RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, int passId, RaceLogRaceStatus nextStatus);
RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, Serializable id, List<Competitor> competitors,
int passId);
RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, int passId);
RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, Serializable id,
List<Competitor> competitors, int passId, Serializable courseAreaId);
RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, int passId,
Serializable courseAreaId);
RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, Serializable id,
List<Competitor> competitors, int passId, CourseBase courseData);
RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, int passId,
CourseBase courseData);
RaceLogFinishPositioningListChangedEvent createFinishPositioningListChangedEvent(TimePoint timePoint,
Serializable id, List<Competitor> competitors, int passId,
List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors);
RaceLogFinishPositioningListChangedEvent createFinishPositioningListChangedEvent(TimePoint timePoint, int passId,
List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors);
RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, Serializable id,
List<Competitor> competitors, int passId);
RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId);
List<Competitor> competitors, int passId, List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors);
RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId,
List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors);
RaceLogPathfinderEvent createPathfinderEvent(TimePoint timePoint, Serializable id, List<Competitor> competitors,
int passId, String pathfinderId);
RaceLogPathfinderEvent createPathfinderEvent(TimePoint timePoint, int passId, String pathfinderId);
RaceLogGateLineOpeningTimeEvent createGateLineOpeningTimeEvent(TimePoint timePoint, Serializable id,
List<Competitor> competitors, int passId, Long gateLineOpeningTimeInMillis);
RaceLogGateLineOpeningTimeEvent createGateLineOpeningTimeEvent(TimePoint timePoint, int passId,
Long gateLineOpeningTimeInMillis);
RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint timePoint, Serializable id,
List<Competitor> competitors, int passId, StartProcedureType type);
RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint timePoint, int passId,
StartProcedureType type);
RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor> competitors, int passId, Wind wind);
}
@@ -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<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors);
RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint createdAt,
TimePoint logicalTimePoint, Serializable id, List<Competitor> competitors, int passId);
TimePoint logicalTimePoint, Serializable id, List<Competitor> competitors, int passId,
List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors);
RaceLogPathfinderEvent createPathfinderEvent(TimePoint createdAt, TimePoint logicalTimePoint, Serializable id,
List<Competitor> competitors, int passId, String pathfinderId);
@@ -49,4 +51,10 @@ public interface RaceLogEventRestoreFactory extends RaceLogEventFactory {
RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint createdAt, TimePoint timePoint,
Serializable id, List<Competitor> competitors, int passId, StartProcedureType type);
RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint createdAt, TimePoint timePoint,
Serializable id, List<Competitor> competitors, int passId, TimePoint protestStartTime);
RaceLogWindFixEvent createWindFixEvent(TimePoint createdAt, TimePoint timePoint, Serializable id,
List<Competitor> competitors, Integer passId, Wind wind);
}
@@ -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);
}
@@ -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 {
}
@@ -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<Triple<Serializable, String, MaxPointsReason>> getPositionedCompetitors();
}
@@ -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<Triple<Serializable, String, MaxPointsReason>> getPositionedCompetitors();
}
}
@@ -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();
}
@@ -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();
}
@@ -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<RaceLogFlagEvent> {
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());
@@ -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<List<Triple<Serializable, String, MaxPointsReason>>> {
public ConfirmedFinishPositioningListFinder(RaceLog raceLog) {
super(raceLog);
}
@Override
protected List<Triple<Serializable, String, MaxPointsReason>> performAnalyzation() {
List<Triple<Serializable, String, MaxPointsReason>> lastFinishPositioningList = null;
for (RaceLogEvent event : getPassEvents()) {
if (event instanceof RaceLogFinishPositioningConfirmedEvent) {
RaceLogFinishPositioningConfirmedEvent finishPositioningEvent = (RaceLogFinishPositioningConfirmedEvent) event;
lastFinishPositioningList = finishPositioningEvent.getPositionedCompetitors();
}
}
return lastFinishPositioningList;
}
}
@@ -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<List<Triple<Serializable, String, MaxPointsReason>>> {
public FinishPositioningListFinder(RaceLog raceLog) {
super(raceLog);
}
public List<Triple<Serializable, String, MaxPointsReason>> getFinishPositioningList() {
List<Triple<Serializable, String, MaxPointsReason>> lastFinishPositioningList = null;
this.raceLog.lockForRead();
try {
lastFinishPositioningList = searchForLastFinishPositioningList();
} finally {
this.raceLog.unlockAfterRead();
}
return lastFinishPositioningList;
}
private List<Triple<Serializable, String, MaxPointsReason>> searchForLastFinishPositioningList() {
@Override
protected List<Triple<Serializable, String, MaxPointsReason>> performAnalyzation() {
List<Triple<Serializable, String, MaxPointsReason>> lastFinishPositioningList = null;
for (RaceLogEvent event : getPassEvents()) {
@@ -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<TimePoint> {
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()) {
@@ -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<TimePoint> {
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()) {
@@ -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<Long> {
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()) {
@@ -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();
}
}
@@ -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<TimePoint> {
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;
}
}
@@ -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();
}
}
@@ -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;
}
}
@@ -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, <code>null</code> 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<List<RaceLogFlagEvent>> {
public LastFlagsFinder(RaceLog raceLog) {
super(raceLog);
}
@Override
protected List<RaceLogFlagEvent> performAnalyzation() {
Iterator<RaceLogEvent> iterator = getPassEventsDescending().iterator();
RaceLogFlagEvent flagEvent = getNextFlagEvent(iterator);
if (flagEvent != null) {
return collectAllWithSameTimePoint(iterator, flagEvent);
}
return null;
}
private List<RaceLogFlagEvent> collectAllWithSameTimePoint(Iterator<RaceLogEvent> iterator,
RaceLogFlagEvent flagEvent) {
List<RaceLogFlagEvent> result = new ArrayList<RaceLogFlagEvent>();
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<RaceLogEvent> 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 <code>null</code> is passed, this method returns <code>null</code>. Otherwise the (most
* recent) {@link RaceLogFlagEvent} with the highest ID is returned favoring events with
* {@link RaceLogFlagEvent#isDisplayed()} returning <code>true</code>.
*
* @param events
* result of {@link LastFlagsFinder#analyze()}.
* @return {@link RaceLogFlagEvent} or <code>null</code>.
*/
public static RaceLogFlagEvent getMostRecent(List<RaceLogFlagEvent> events) {
if (events == null || events.isEmpty()) {
return null;
}
List<RaceLogFlagEvent> sortedEvents = new ArrayList<RaceLogFlagEvent>(events);
Collections.sort(sortedEvents, new Comparator<RaceLogFlagEvent>() {
@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);
}
}
@@ -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<CourseBase> {
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()) {
@@ -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<Wind> {
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;
}
}
@@ -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<String> {
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) {
@@ -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<TimePoint> {
public ProtestStartTimeFinder(RaceLog raceLog) {
super(raceLog);
}
@Override
protected TimePoint performAnalyzation() {
for (RaceLogEvent event : getPassEventsDescending()) {
if (event instanceof RaceLogProtestStartTimeEvent) {
return ((RaceLogProtestStartTimeEvent) event).getProtestStartTime();
}
}
return null;
}
}
@@ -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 <code>ResultType</code>.
*
* @param <ResultType>
* type of analyzation's result.
*/
public abstract class RaceLogAnalyzer<ResultType> {
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<RaceLogEvent> getPassEvents() {
return raceLog.getFixes();
}
@@ -18,4 +35,12 @@ public abstract class RaceLogAnalyzer {
protected Iterable<RaceLogEvent> getAllEvents() {
return raceLog.getRawFixes();
}
protected Iterable<RaceLogEvent> getPassEventsDescending() {
return raceLog.getFixesDescending();
}
protected Iterable<RaceLogEvent> getAllEventsDescending() {
return raceLog.getRawFixesDescending();
}
}
@@ -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<RaceLogRaceStatus> {
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()) {
@@ -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<StartProcedureType> {
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) {
@@ -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<TimePoint> {
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()) {
@@ -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<Competitor> 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<Competitor> involvedBoats,
int passId, Flags upperFlag, Flags lowerFlag, boolean isDisplayed) {
return createFlagEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), 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<Competitor> 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<Competitor>(), passId, upperFlag, lowerFlag,
isDisplayed);
}
@Override
public RaceLogStartTimeEvent createStartTimeEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor> competitors, int passId,
RaceLogRaceStatus nextStatus) {
return new RaceLogRaceStatusEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, nextStatus);
public RaceLogRaceStatusEvent createRaceStatusEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor>(), passId, nextStatus);
}
@Override
public RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, Serializable id, List<Competitor> competitors,
int passId) {
public RaceLogPassChangeEvent createPassChangeEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor> competitors,
int passId, Serializable courseAreaId) {
return new RaceLogCourseAreaChangeEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, courseAreaId);
public RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor>(), passId, courseAreaId);
public RaceLogCourseAreaChangedEvent createCourseAreaChangedEvent(TimePoint timePoint, int passId,
Serializable courseAreaId) {
return createCourseAreaChangedEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), passId,
courseAreaId);
}
@Override
public RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor>(), passId, courseData);
public RaceLogCourseDesignChangedEvent createCourseDesignChangedEvent(TimePoint timePoint, int passId,
CourseBase courseData) {
return createCourseDesignChangedEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), passId,
courseData);
}
@Override
public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(
TimePoint timePoint, Serializable id, List<Competitor> competitors, int passId, List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
return new RaceLogFinishPositioningListChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, positionedCompetitors);
public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(TimePoint timePoint,
Serializable id, List<Competitor> competitors, int passId,
List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
return new RaceLogFinishPositioningListChangedEventImpl(MillisecondsTimePoint.now(), timePoint, id,
competitors, passId, positionedCompetitors);
}
@Override
public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(
TimePoint timePoint, int passId, List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
return createFinishPositioningListChangedEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), passId, positionedCompetitors);
public RaceLogFinishPositioningListChangedEventImpl createFinishPositioningListChangedEvent(TimePoint timePoint,
int passId, List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
return createFinishPositioningListChangedEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(),
passId, positionedCompetitors);
}
@Override
public RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint,
Serializable id, List<Competitor> competitors, int passId) {
return new RaceLogFinishPositioningConfirmedEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId);
Serializable id, List<Competitor> competitors, int passId, List<Triple<Serializable, String, MaxPointsReason>> 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<Competitor>(), passId);
public RaceLogFinishPositioningConfirmedEvent createFinishPositioningConfirmedEvent(TimePoint timePoint, int passId,
List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
return createFinishPositioningConfirmedEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), passId, positionedCompetitors);
}
@Override
public RaceLogPathfinderEvent createPathfinderEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor> 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<Competitor>(), passId, gateLineOpeningTimeInMillis);
return createGateLineOpeningTimeEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), passId,
gateLineOpeningTimeInMillis);
}
@Override
public RaceLogStartProcedureChangedEvent createStartProcedureChangedEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor>(), passId, type);
}
@Override
public RaceLogProtestStartTimeEvent createProtestStartTimeEvent(TimePoint timePoint, Serializable id,
List<Competitor> 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<Competitor>(), passId,
protestStartTime);
}
@Override
public RaceLogWindFixEvent createWindFixEvent(TimePoint timePoint, int passId, Wind wind) {
return createWindFixEvent(timePoint, UUID.randomUUID(), new ArrayList<Competitor>(), passId, wind);
}
@Override
public RaceLogWindFixEvent createWindFixEvent(TimePoint timePoint, Serializable id, List<Competitor> competitors,
int passId, Wind wind) {
return new RaceLogWindFixEventImpl(MillisecondsTimePoint.now(), timePoint, id, competitors, passId, wind);
}
}
@@ -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();
}
}
@@ -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<Competitor> competitors, int passId) {
return new RaceLogFinishPositioningConfirmedEventImpl(createdAt, logicalTimePoint, id, competitors, passId);
TimePoint logicalTimePoint, Serializable id, List<Competitor> competitors, int passId, List<Triple<Serializable, String, MaxPointsReason>> 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<Competitor> 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<Competitor> competitors, Integer passId, Wind wind) {
return new RaceLogWindFixEventImpl(createdAt, timePoint, id, competitors, passId, wind);
}
}
@@ -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<Competitor> pCompetitors, int pPassId) {
super(createdAt, pTimePoint, pId, pCompetitors, pPassId);
TimePoint pTimePoint, Serializable pId, List<Competitor> pCompetitors, int pPassId, List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
super(createdAt, pTimePoint, pId, pCompetitors, pPassId, positionedCompetitors);
}
@Override
public void accept(RaceLogEventVisitor visitor) {
visitor.visit(this);
}
}
@@ -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<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors;
public RaceLogFinishPositioningEventImpl(TimePoint createdAt, TimePoint pTimePoint, Serializable pId,
List<Competitor> pInvolvedBoats, int pPassId, List<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors) {
super(createdAt, pTimePoint, pId, pInvolvedBoats, pPassId);
this.positionedCompetitors = positionedCompetitors;
}
@Override
public List<Triple<Serializable, String, MaxPointsReason>> getPositionedCompetitors() {
return positionedCompetitors;
}
}
@@ -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<Triple<Serializable, String, MaxPointsReason>> positionedCompetitors;
public RaceLogFinishPositioningListChangedEventImpl(TimePoint createdAt,
TimePoint pTimePoint, Serializable pId, List<Competitor> competitors, int pPassId, List<Triple<Serializable, String, MaxPointsReason>> 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<Triple<Serializable, String, MaxPointsReason>> getPositionedCompetitors() {
return positionedCompetitors;
}
}
@@ -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();
}
}
@@ -29,8 +29,6 @@ public class RaceLogImpl extends TrackImpl<RaceLogEvent> implements RaceLog {
private transient Set<RaceLogEventVisitor> 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<RaceLogEvent> implements RaceLog {
listeners = new HashSet<RaceLogEventVisitor>();
}
@Override
public Iterable<RaceLogEvent> getRawFixesDescending() {
return getRawFixes().descendingSet();
}
@Override
public Iterable<RaceLogEvent> getFixesDescending() {
return getFixes().descendingSet();
}
}
@@ -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<Competitor> 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;
}
}
@@ -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());
}
}
@@ -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<Competitor> 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;
}
}
@@ -7,6 +7,7 @@
<listEntry value="2"/>
</listAttribute>
<mapAttribute key="org.eclipse.debug.core.preferred_launchers">
<mapEntry key="[debug]" value="org.eclipse.jdt.junit.launchconfig"/>
<mapEntry key="[run]" value="org.eclipse.jdt.junit.launchconfig"/>
</mapAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
@@ -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<Competitor>(), passId, Flags.CLASS, Flags.NONE, false);
RaceLogFlagEvent rcEvent2 = RaceLogEventFactory.INSTANCE.createFlagEvent(t1, randomUUID, new ArrayList<Competitor>(), passId, Flags.CLASS, Flags.NONE, false);
assertNotSame(rcEvent1, rcEvent2);
assertEquals(rcEvent1, rcEvent2);
}
}
@@ -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
@@ -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<Serializable, Competitor> competitorCache;
private final Map<Serializable, CourseArea> 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 <code>null</code>. In this case, the methods reading from this cache will purge
@@ -134,6 +137,7 @@ public class DomainFactoryImpl implements DomainFactory {
competitorCache = new HashMap<Serializable, Competitor>();
waypointCache = new ConcurrentHashMap<Serializable, WeakWaypointReference>();
mayStartWithNoUpwindLeg = new HashSet<String>(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);
}
}
@@ -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);
}
}
@@ -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
}
}
@@ -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;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 299 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 298 B

@@ -25,7 +25,9 @@ public class EventConfigImagesBarCell extends ImagesBarCell {
@Override
protected Iterable<ImageSpec> 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()))
);
}
}
@@ -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<Anchor> {
@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("<a target=\"_blank\" href=\""));
sb.append(SafeHtmlUtils.fromTrustedString(a.getHref()));
sb.append(SafeHtmlUtils.fromTrustedString("\">"));
sb.append(SafeHtmlUtils.fromTrustedString(a.getText()));
sb.append(SafeHtmlUtils.fromTrustedString("</a>"));
} else {
sb.append(SafeHtmlUtils.fromTrustedString(a.getText()));
}
}
}
@@ -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<String, String> parameters) {
return createEntryPointLink("/gwt/RaceBoard.html", parameters);
}
public static String createLeaderboardLink(Map<String, String> parameters) {
return createEntryPointLink("/gwt/Leaderboard.html", parameters);
}
private static String createEntryPointLink(String baseLink, Map<String, String> parameters) {
String debugParam = Window.Location.getParameter("gwt.codesvr");
String link = baseLink;
int i = 1;
for(Entry<String, String> 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);
}
}
@@ -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<RegattaOverviewEntryDTO> getRegattaOverviewEntriesForEvent(String eventIdAsString);
EventDTO getEventByIdAsString(String eventIdAsString);
List<RaceGroupDTO> getRegattaStructureForEvent(String eventIdAsString);
List<RegattaOverviewEntryDTO> getRaceStateEntriesForRaceGroup(String eventIdAsString, List<String> visibleCourseAreas,
List<String> visibleRegattas, boolean showOnlyCurrentlyRunningRaces, boolean showOnlyRacesOfSameDay);
String getBuildVersion();
}
@@ -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<PolarSheetsHistogramData> wrapperCallback);
void getRegattaOverviewEntriesForEvent(String eventIdAsString, AsyncCallback<List<RegattaOverviewEntryDTO>> asyncCallback);
void getEventByIdAsString(String eventIdAsString, AsyncCallback<EventDTO> asyncCallback);
void updateRegatta(RegattaIdentifier regattaIdentifier, String defaultCourseAreaId, AsyncCallback<Void> callback);
void getBuildVersion(AsyncCallback<String> callback);
void getRegattaStructureForEvent(String eventIdAsString, AsyncCallback<List<RaceGroupDTO>> asyncCallback);
void getRaceStateEntriesForRaceGroup(String eventIdAsString, List<String> visibleCourseAreas,
List<String> visibleRegattas, boolean showOnlyCurrentlyRunningRaces, boolean showOnlyRacesOfSameDay,
AsyncCallback<List<RegattaOverviewEntryDTO>> markedAsyncCallback);
}
@@ -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();
}
@@ -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
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
@@ -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
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
@@ -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<RaceGroupDTO> raceGroups);
}
@@ -1,9 +0,0 @@
package com.sap.sailing.gwt.ui.regattaoverview;
import com.sap.sailing.gwt.ui.shared.EventDTO;
public interface EventProvider {
EventDTO getEvent();
}
@@ -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();
}
}
@@ -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();
@@ -11,7 +11,7 @@ public class FlagImageResolver {
private Map<Flags, ImageResource> flagImageMap;
private static RegattaOverviewResources resources = GWT.create(RegattaOverviewResources.class);
private static RegattaRaceStatesFlagsResources resources = GWT.create(RegattaRaceStatesFlagsResources.class);
public FlagImageResolver() {
this.flagImageMap = new HashMap<Flags, ImageResource>();
@@ -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<WaypointDTO> waypointTable;
private ListDataProvider<WaypointDTO> 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<WaypointDTO>();
waypointTable = createCourseDesignTable();
panel.add(waypointTable);
initWidget(mainPanel);
}
private CellTable<WaypointDTO> createCourseDesignTable() {
CellTable<WaypointDTO> table = new CellTable<WaypointDTO>(/* pageSize */10000, tableRes);
waypointDataProvider.addDataDisplay(table);
table.setWidth("100%");
TextColumn<WaypointDTO> waypointNameColumn = new TextColumn<WaypointDTO>() {
@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 "";
}
}
}
@@ -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<String> visibleCourseAreas = new ArrayList<String>();
List<String> visibleRegattas = new ArrayList<String>();
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;
}
}
@@ -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<RaceGroupDTO> raceGroupDTOs;
private List<EventAndRaceGroupAvailabilityListener> 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<RaceGroupDTO>();
this.eventRaceGroupListeners = new ArrayList<EventAndRaceGroupAvailabilityListener>();
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<RegattaOverviewEntryDTO> 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<EventDTO>() {
@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<List<RaceGroupDTO>>() {
@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<RaceGroupDTO> result) {
if (result != null) {
setRaceGroups(result);
}
}
});
}
protected void setRaceGroups(List<RaceGroupDTO> 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);
}
}
}
@@ -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-<code>null</code> list which is empty if nothing is selected
*/
void onRegattaOverviewEntrySelectionChange(List<RegattaOverviewEntryDTO> selectedRegattaOverviewEntries);
}
@@ -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<RegattaOverviewEntryDTO> selection;
private final List<RegattaOverviewEntryDTO> allRegattaOverviewRaces;
private final Set<RegattaOverviewRaceSelectionChangeListener> listeners;
private final boolean hasMultiSelection;
public RegattaOverviewRaceSelectionModel(boolean hasMultiSelection) {
this.hasMultiSelection = hasMultiSelection;
this.selection = new ArrayList<RegattaOverviewEntryDTO>();
this.allRegattaOverviewRaces = new ArrayList<RegattaOverviewEntryDTO>();
listeners = new HashSet<RegattaOverviewRaceSelectionChangeListener>();
}
@Override
public List<RegattaOverviewEntryDTO> 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<RegattaOverviewEntryDTO> newSelection, RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify) {
boolean notify = !selection.equals(newSelection);
selection.clear();
selection.addAll(newSelection);
if (notify) {
notifyListeners(listenersNotToNotify);
}
}
private void notifyListeners(RegattaOverviewRaceSelectionChangeListener[] listenersNotToNotify) {
List<RegattaOverviewEntryDTO> 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<RegattaOverviewEntryDTO> getAllRegattaOverviewEntries() {
return Collections.unmodifiableList(allRegattaOverviewRaces);
}
@Override
public void setAllRegattaOverviewEntries(List<RegattaOverviewEntryDTO> newAllRegattaOverviewEntries,
RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify) {
allRegattaOverviewRaces.clear();
for (RegattaOverviewEntryDTO r : newAllRegattaOverviewEntries) {
allRegattaOverviewRaces.add(r);
}
for (Iterator<RegattaOverviewEntryDTO> 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);
}
}
@@ -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-<code>null</code> list which may be empty
*/
List<RegattaOverviewEntryDTO> getSelectedEntries();
void addRegattaOverviewRaceSelectionChangeListener(RegattaOverviewRaceSelectionChangeListener listener);
void removeRegattaOverviewRaceSelectionChangeListener(RegattaOverviewRaceSelectionChangeListener listener);
void setSelection(List<RegattaOverviewEntryDTO> newSelection, RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify);
boolean hasMultiSelection();
/**
* @return a non-<code>null</code> list which may be empty
*/
List<RegattaOverviewEntryDTO> getAllRegattaOverviewEntries();
void setAllRegattaOverviewEntries(List<RegattaOverviewEntryDTO> newAllRegattaOverviewEntries, RegattaOverviewRaceSelectionChangeListener... listenersNotToNotify);
}
@@ -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<RegattaOverviewEntryDTO> {
@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;
}
}
Loaded 100 of 392 files, more files were not shown because too many files have changed in this diff. Show more