Merge branch 'bug4709' into bug4709_pv

Conflicts:
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/Regatta.java
	java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/SlicingTest.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CreateRegattaCallback.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java
	java/com.sap.sailing.server.gateway.test/src/com/sap/sailing/server/gateway/test/jaxrs/AbstractJaxRsApiTest.java
	java/com.sap.sailing.server.gateway.test/src/com/sap/sailing/server/gateway/test/jaxrs/RegattasResourceTest.java
	java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/EventsResource.java
	java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java
This commit is contained in:
Thomas Wiese
2018-10-24 15:20:27 +02:00
89 changed files with 1166 additions and 306 deletions
@@ -0,0 +1,112 @@
package com.sap.sailing.domain.common;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.sap.sailing.domain.common.i18n.CommonStringMessages;
/**
* Types of registration of competitors to a regatta. Regattas can be <b>closed</b>, so only invited competitors are
* allowed or <b>open</b>, which means competitors can register themselves.
*
* @author Thomas Wiese
*
*/
public enum CompetitorRegistrationType {
/** Competitors are registered and invited by regatta owner. */
CLOSED(false, false),
/** Competitors are registering themselve, but the regatta owner has to confirm the registration. */
OPEN_MODERATED(true, true),
/** Competitors are registering themselves without the need of confirmation. */
OPEN_UNMODERATED(true, false);
private static final Logger logger = Logger.getLogger(CompetitorRegistrationType.class.getName());
private boolean open;
private boolean moderated;
private CompetitorRegistrationType(boolean open, boolean moderated) {
this.open = open;
this.moderated = moderated;
}
/**
* Is registration open to self register of competitors?
*
* @return true for self registration
*/
public boolean isOpen() {
return this.open;
}
/**
* Is registration moderated?
*
* @return true if moderated
*/
public boolean isModerated() {
return this.moderated;
}
/**
* Get ComptetitorRegistrationType for given name. If the name is unknown or null it returns {@link #CLOSED} as
* default value.
*
* @param name
* enum name
* @param failForUnknown
* if set and name is not konwn competitor type than this method throws IllegalArgumentException
* @return CompetitorRegistrationType
*/
public static CompetitorRegistrationType valueOfOrDefault(String name, boolean failForUnknown) {
if (name == null) {
return CLOSED;
} else {
try {
return valueOf(name);
} catch (IllegalArgumentException iae) {
if (failForUnknown) {
throw iae;
} else {
logger.log(Level.WARNING, "Unknown CompetitorRegistrationType " + name
+ " for regatta. Interpreting it to default CLOSED.");
return CLOSED;
}
}
}
}
/**
* et ComptetitorRegistrationType for given name. If the name is unknown or null it returns {{@link #CLOSED} as
* default value.
*
* @param name
* enum name
* @return CompetitorRegistrationType
*/
public static CompetitorRegistrationType valueOfOrDefault(String name) {
return valueOfOrDefault(name, false);
}
/**
* Get i18n label.
*
* @return message string
*/
public String getLabel(CommonStringMessages stringMessages) {
switch (this) {
case CLOSED:
return stringMessages.competitorRegistrationTypeClosed();
case OPEN_UNMODERATED:
return stringMessages.competitorRegistrationTypeOpenUnmoderated();
case OPEN_MODERATED:
return stringMessages.competitorRegistrationTypeOpenModerated();
default:
return this.name();
}
}
}
@@ -14,5 +14,8 @@ public interface CommonStringMessages {
String importWindTracks();
String importSensorFixes();
String updateEventLeaderboardGroupLinks();
String competitorRegistrationTypeClosed();
String competitorRegistrationTypeOpenModerated();
String competitorRegistrationTypeOpenUnmoderated();
}
@@ -171,6 +171,7 @@ import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.VenueImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.MarkType;
@@ -1281,10 +1282,13 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
canBoatsOfCompetitorsChangePerRace = false;
createMigratableRegatta = true;
}
CompetitorRegistrationType competitorRegistrationType = CompetitorRegistrationType
.valueOfOrDefault((String) dbRegatta.get(FieldNames.REGATTA_COMPETITOR_REGISTRATION_TYPE.name()));
final RankingMetricConstructor rankingMetricConstructor = loadRankingMetricConstructor(dbRegatta);
if (createMigratableRegatta) {
result = new MigratableRegattaImpl(getRaceLogStore(), getRegattaLogStore(), name, boatClass,
canBoatsOfCompetitorsChangePerRace, startDate, endDate, series, /* persistent */true,
canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, startDate, endDate, series, /* persistent */true,
loadScoringScheme(dbRegatta), id, courseArea,
buoyZoneRadiusInHullLengths == null ? Regatta.DEFAULT_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS
: buoyZoneRadiusInHullLengths,
@@ -1293,7 +1297,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
rankingMetricConstructor, new MongoObjectFactoryImpl(database));
} else {
result = new RegattaImpl(getRaceLogStore(), getRegattaLogStore(), name, boatClass,
canBoatsOfCompetitorsChangePerRace, startDate, endDate, series, /* persistent */true,
canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, startDate, endDate, series, /* persistent */true,
loadScoringScheme(dbRegatta), id, courseArea,
buoyZoneRadiusInHullLengths == null ? Regatta.DEFAULT_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS
: buoyZoneRadiusInHullLengths,
@@ -1302,6 +1306,8 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
rankingMetricConstructor);
}
result.setRegattaConfiguration(configuration);
String registrationLinkSecret = (String) dbRegatta.get(FieldNames.REGATTA_REGISTRATION_LINK_SECRET.name());
result.setRegistrationLinkSecret(registrationLinkSecret);
}
return result;
}
@@ -39,6 +39,8 @@ public enum FieldNames {
REGATTA_USE_START_TIME_INFERENCE,
REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES,
REGATTA_CAN_BOATS_OF_COMPETITORS_CHANGE_PER_RACE,
REGATTA_COMPETITOR_REGISTRATION_TYPE,
REGATTA_REGISTRATION_LINK_SECRET,
SERIES_NAME,
SERIES_IS_MEDAL,
SERIES_IS_FLEETS_CAN_RUN_IN_PARALLEL,
@@ -9,6 +9,7 @@ import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.MigratableRegatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.persistence.MongoObjectFactory;
import com.sap.sailing.domain.racelog.RaceLogStore;
@@ -27,11 +28,12 @@ public class MigratableRegattaImpl extends RegattaImpl implements MigratableRega
private transient final MongoObjectFactory mongoObjectFactory;
public <S extends Series> MigratableRegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, String name,
BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate,
BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType,
TimePoint startDate, TimePoint endDate,
Iterable<S> series, boolean persistent, ScoringScheme scoringScheme, Serializable id, CourseArea courseArea,
Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor, MongoObjectFactory mongoObjectFactory) {
super(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, startDate, endDate, series,
super(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, startDate, endDate, series,
persistent, scoringScheme, id, courseArea, buoyZoneRadiusInHullLengths, useStartTimeInference,
controlTrackingFromStartAndFinishTimes, rankingMetricConstructor);
this.mongoObjectFactory = mongoObjectFactory;
@@ -717,6 +717,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
dbRegatta.put(FieldNames.REGATTA_USE_START_TIME_INFERENCE.name(), regatta.useStartTimeInference());
dbRegatta.put(FieldNames.REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES.name(), regatta.isControlTrackingFromStartAndFinishTimes());
dbRegatta.put(FieldNames.REGATTA_CAN_BOATS_OF_COMPETITORS_CHANGE_PER_RACE.name(), regatta.canBoatsOfCompetitorsChangePerRace());
dbRegatta.put(FieldNames.REGATTA_COMPETITOR_REGISTRATION_TYPE.name(), regatta.getCompetitorRegistrationType().name());
dbRegatta.put(FieldNames.REGATTA_REGISTRATION_LINK_SECRET.name(), regatta.getRegistrationLinkSecret());
dbRegatta.put(FieldNames.REGATTA_RANKING_METRIC.name(), storeRankingMetric(regatta));
boolean success = false;
final int MAX_TRIES = 3;
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
@@ -124,7 +125,7 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
protected DynamicTrackedRaceImpl createDynamicTrackedRace(BoatClass boatClass, RaceDefinition raceDefinition) {
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /* startDate */ null, /* endDate */null, null, null, "a", null));
return new DynamicTrackedRaceImpl(regatta, raceDefinition, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogResolver.class));
@@ -44,6 +44,7 @@ import com.sap.sailing.domain.base.impl.DynamicBoat;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
@@ -97,9 +98,11 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
Series series = new SeriesImpl("series", /* isMedal */ false, /* isFleetsCanRunInParallel */ true, Collections.singletonList(fleet), Collections.emptySet(),
service);
regatta = service.createRegatta(RegattaImpl.getDefaultName("regatta", "Laser"), "Laser",
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
UUID.randomUUID(), Collections.<Series> singletonList(series), /* persistent */ true,
new HighPoint(), UUID.randomUUID(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, UUID.randomUUID(),
Collections.<Series> singletonList(series), /* persistent */ true, new HighPoint(), UUID.randomUUID(),
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
series.addRaceColumn(columnName, /* trackedRegattaRegistry */null);
leaderboard = service.addRegattaLeaderboard(regatta.getRegattaIdentifier(), "RegattaLeaderboard", new int[] {});
adapter = RaceLogTrackingAdapterFactory.INSTANCE.getAdapter(DomainFactory.INSTANCE);
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
@@ -101,7 +102,8 @@ public class RaceLogFixTrackerManagerTest {
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogResolver.class));
@@ -57,6 +57,7 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.SpeedWithBearing;
@@ -167,7 +168,8 @@ public class SensorFixStoreAndLoadTest {
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
DynamicTrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
trackedRace = new DynamicTrackedRaceImpl(regatta, race, Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, 0, 0, 0, /* useMarkPassingCalculator */ false, OneDesignRankingMetric::new,
mock(RaceLogResolver.class));
@@ -33,6 +33,7 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.racelog.RaceLogRaceStatus;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
@@ -77,7 +78,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
@@ -153,7 +155,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
@@ -195,7 +198,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
@@ -240,7 +244,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
assertTrue(regatta.getRegatta().useStartTimeInference());
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
@@ -354,7 +359,8 @@ public class TrackedRaceStartTimeInferenceTest extends AbstractGPSFixStoreTest {
RaceDefinition race = new RaceDefinitionImpl("race", course, boatClass, competitorsAndBoats);
TrackedRegatta regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */null, /* endDate */null, null, null, "a", null));
final DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(regatta, race,
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, 0, 0, 0,
/* useMarkPassingCalculator */ false,
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
@@ -109,7 +110,7 @@ public class SimpleDomainFactoryTest {
public void testCourseConfigForMark() throws PatchFailedException {
DomainFactory domainFactory = DomainFactory.INSTANCE;
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, "TestEvent",
/* boatClass */ null, /* canBoatsOfCompetitorsChangePerRace */ true,
/* boatClass */ null, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, new RacingEventServiceImpl(),
com.sap.sailing.domain.base.DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", null);
Race race = new RaceImpl("1234", "R1", "Race 1234");
@@ -136,7 +137,7 @@ public class SimpleDomainFactoryTest {
public void testCourseConfigForGate() throws PatchFailedException {
DomainFactory domainFactory = DomainFactory.INSTANCE;
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
"TestEvent", /* boatClass */ null, /* canBoatsOfCompetitorsChangePerRace */ true,
"TestEvent", /* boatClass */ null, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, new RacingEventServiceImpl(),
com.sap.sailing.domain.base.DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", null);
Race race = new RaceImpl("1234", "R1", "Race 1234");
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.MarkType;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -118,7 +119,8 @@ public class DomainFactoryImpl implements DomainFactory {
Calendar calendar = Calendar.getInstance();
result = new RegattaImpl(raceLogStore, regattaLogStore, RegattaImpl.getDefaultName(
"ST Regatta " + calendar.get(Calendar.YEAR) + " for race " + raceID, regattaBoatClass.getName()),
regattaBoatClass, /* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
regattaBoatClass, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null,
trackedRegattaRegistry, getBaseDomainFactory().createScoringScheme(
ScoringSchemeType.LOW_POINT), raceID, null);
logger.info("Created regatta "+result.getName()+" ("+result.hashCode()+")");
@@ -33,6 +33,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.WindSourceType;
@@ -97,7 +98,8 @@ public class TestFarthestAheadWithSkippedMarkPassing {
BoatClassImpl boatClass = new BoatClassImpl("Some Handicap Boat Class", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* courseArea */ null, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
TrackedRegatta trackedRegatta = new DynamicTrackedRegattaImpl(regatta);
List<Waypoint> waypoints = new ArrayList<Waypoint>();
@@ -33,6 +33,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.WindSourceType;
@@ -79,7 +80,7 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
BoatClassImpl boatClass = new BoatClassImpl("Some Handicap Boat Class", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* courseArea */ null, /* controlTrackingFromStartAndFinishTimes */ false, TimeOnTimeAndDistanceRankingMetric::new);
TrackedRegatta trackedRegatta = new DynamicTrackedRegattaImpl(regatta);
List<Waypoint> waypoints = new ArrayList<Waypoint>();
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.abstractlog.NotRevokableException;
import com.sap.sailing.domain.leaderboard.impl.CompetitorProviderFromRaceColumnsAndRegattaLike;
@@ -78,7 +79,7 @@ public class CompetitorProviderCacheInvalidationTest extends AbstractLeaderboard
competitorProviderFlexibleLeaderboard = new CompetitorProviderFromRaceColumnsAndRegattaLike(flexibleLeaderboard);
regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, "Test Regatta", new BoatClassImpl("49er", BoatClassMasterdata._49ER),
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /* startDate */ null, /* endDate */null,
/* trackedRegattaRegistry */null, new LowPoint(), UUID.randomUUID(),
courseArea);
regattaLeaderboard = new RegattaLeaderboardImpl(regatta, new ThresholdBasedResultDiscardingRuleImpl(new int[0]));
@@ -36,6 +36,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
@@ -308,7 +309,7 @@ public class CourseTest {
final Map<Competitor,Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(hasso, hasso.getBoat());
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(/* trackedRegatta */new DynamicTrackedRegattaImpl(
new RegattaImpl("test", null, true, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
new RaceDefinitionImpl("Test Race", course, boatClass, competitorsAndBoats),
Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE, /* delayToLiveInMillis */3000,
/* millisecondsOverWhichToAverageWind */30000,
@@ -342,7 +343,7 @@ public class CourseTest {
final Map<Competitor,Boat> competitorsAndBoats = new HashMap<>();
competitorsAndBoats.put(hasso, hasso.getBoat());
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(/* trackedRegatta */ new DynamicTrackedRegattaImpl(
new RegattaImpl("test", null, true, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new)),
new RaceDefinitionImpl("Test Race", course, boatClass, competitorsAndBoats), Collections.<Sideline> emptyList(),
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 3000,
/* millisecondsOverWhichToAverageWind */ 30000,
@@ -36,6 +36,7 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
@@ -77,7 +78,8 @@ public class CourseUpdateDuringNonAtomicSerializationTest implements Serializabl
course = new CourseImpl("Test Course", waypoints);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, "Test Regatta",
new BoatClassImpl("505", BoatClassMasterdata._5O5),
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
new LowPoint(), UUID.randomUUID(), new CourseAreaImpl("Alpha", UUID.randomUUID()));
TrackedRegatta trackedRegatta = new TrackedRegattaImpl(regatta);
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, regatta.getBoatClass(), Collections.<Competitor,Boat>emptyMap());
@@ -43,6 +43,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.leaderboard.Leaderboard;
@@ -91,7 +92,7 @@ public class LeaderboardCourseChangeTest {
RaceColumn raceColumn = series.addRaceColumn(raceColumnName, trackedRegattaRegistry);
ScoringScheme scoringScheme = new LowPoint();
Regatta mockedRegatta = new RegattaImpl(RegattaImpl.getDefaultName("TestRegatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, seriesSet, false, scoringScheme,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null, seriesSet, false, scoringScheme,
UUID.randomUUID(), mock(CourseArea.class), OneDesignRankingMetric::new);
ControlPoint start = new MarkImpl("Start");
ControlPoint m1 = new MarkImpl("M1");
@@ -48,6 +48,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -1714,7 +1715,8 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
TrackedRegattaRegistry trackedRegattaRegistry = mock(TrackedRegattaRegistry.class);
Regatta dummyRegatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, "Dummy",
new BoatClassImpl("Extreme40", false),
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, trackedRegattaRegistry,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, trackedRegattaRegistry,
new HighPointFirstGets10Or8AndLastBreaksTie(), "578876345345",
new CourseAreaImpl("Humba", UUID.randomUUID()));
trackedRegattaRegistry.getOrCreateTrackedRegatta(dummyRegatta);
@@ -2326,7 +2328,7 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
}
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("Extreme40", /* typicallyStartsUpwind */ false);
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null,
series, /* persistent */false, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.HIGH_POINT_FIRST_GETS_TEN), "123", /* course area */null, OneDesignRankingMetric::new);
List<Competitor> competitors = createCompetitors(12);
final int firstYellowCompetitorIndex = 3;
@@ -2445,7 +2447,7 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
}
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null,
series, /* persistent */false, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* course area */null, OneDesignRankingMetric::new);
List<Competitor> competitors = createCompetitors(12);
final int firstYellowCompetitorIndex = 3;
@@ -2558,7 +2560,7 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
}
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null,
series, /* persistent */false, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* course area */null, OneDesignRankingMetric::new);
List<Competitor> competitors = createCompetitors(12);
final int firstYellowCompetitorIndex = 3;
@@ -2647,7 +2649,7 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
}
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null,
series, /* persistent */false, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", /* course area */null, OneDesignRankingMetric::new);
final int TOTAL_NUMBER_OF_COMPETITORS = 100;
List<Competitor> competitors = createCompetitors(TOTAL_NUMBER_OF_COMPETITORS);
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
@@ -126,7 +127,7 @@ public class LeaderboardScoringAndRankingTestBase extends AbstractLeaderboardTes
series.add(defaultSeries);
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName(regattaName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null, series,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /* startDate */null, /* endDate */null, series,
/* persistent */false, scoringScheme, "123", null, OneDesignRankingMetric::new);
return regatta;
}
@@ -182,7 +183,7 @@ public class LeaderboardScoringAndRankingTestBase extends AbstractLeaderboardTes
}
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, series,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null, series,
/* persistent */ false, scoringScheme, "123", null, OneDesignRankingMetric::new);
return regatta;
}
@@ -228,7 +229,7 @@ public class LeaderboardScoringAndRankingTestBase extends AbstractLeaderboardTes
}
}
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, series,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /*startDate*/ null, /*endDate*/ null, series,
/* persistent */ false, scoringScheme, /* ID */ "123", /* course area */ null, OneDesignRankingMetric::new);
return regatta;
}
@@ -17,6 +17,7 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.leaderboard.Leaderboard;
@@ -65,7 +66,7 @@ public class LeaderboardScoringAndRankingTestForLowPoints extends LeaderboardSco
private Regatta setupRegatta(boolean useFirstTwoWins) {
final BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("470", /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
false, /* startDate */ null, /* endDate */ null, series, /* persistent */false,
false, CompetitorRegistrationType.CLOSED, /* startDate */ null, /* endDate */ null, series, /* persistent */false,
DomainFactory.INSTANCE
.createScoringScheme(useFirstTwoWins ? ScoringSchemeType.LOW_POINT_FIRST_TO_WIN_TWO_RACES
: ScoringSchemeType.LOW_POINT),
@@ -26,6 +26,7 @@ import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.TrackedRaces;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.TimingConstants;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.impl.DegreePosition;
@@ -229,7 +230,7 @@ public class RaceExecutionOrderProvdiderAttachDetachTest extends TrackBasedTest
raceColumnInSeries = series.addRaceColumn(RACECOLUMN_SERIES, null);
ScoringScheme scoringScheme = new LowPoint();
regatta = new RegattaImpl(RegattaImpl.getDefaultName(REGATTA, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /* startDate */null, /* endDate */null,
seriesSet, false, scoringScheme, UUID.randomUUID(), null, OneDesignRankingMetric::new);
}
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
@@ -94,7 +95,8 @@ public class ReachingLegTest extends TrackBasedTest {
BoatClassImpl boatClass = new BoatClassImpl(boatClassName, /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName(regattaName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", null);
TrackedRegatta trackedRegatta = new DynamicTrackedRegattaImpl(regatta);
List<Waypoint> waypoints = new ArrayList<Waypoint>();
@@ -26,6 +26,7 @@ import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RaceColumnListenerWithDefaultAction;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
@@ -115,7 +116,7 @@ public class RegattaLogEventNotificationForwardingTest extends AbstractSerializa
@Test
public void testRegattaLeaderboardRegattaLogEventForwarding() {
Regatta regatta = new RegattaImpl("test", null, true, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new);
Regatta regatta = new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new);
final RegattaLogEvent[] receivedRegattaLogEvent = new RegattaLogEvent[1];
regatta.addRaceColumnListener(new RaceColumnListenerWithDefaultAction() {
private static final long serialVersionUID = -3835439531940986851L;
@@ -136,7 +137,7 @@ public class RegattaLogEventNotificationForwardingTest extends AbstractSerializa
@Test
public void testRegattaLeaderboardRegattaLogEventForwardingAfterRegattaDeserialization() throws ClassNotFoundException, IOException {
Regatta regatta = new RegattaImpl("test", null, true, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new);
Regatta regatta = new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null, "test", null, OneDesignRankingMetric::new);
Regatta deserializedRegatta = cloneBySerialization(regatta, DomainFactory.INSTANCE);
final RegattaLogEvent[] receivedRegattaLogEvent = new RegattaLogEvent[1];
deserializedRegatta.addRaceColumnListener(new RaceColumnListenerWithDefaultAction() {
@@ -181,7 +182,7 @@ public class RegattaLogEventNotificationForwardingTest extends AbstractSerializa
Series series = new SeriesImpl("Test Series", /* isMedal */ false, /* isFleetsCanRunInParallel */ true,
/* fleets */ Collections.singleton(new FleetImpl("Default")),
Collections.singleton("R1"), /* trackedRegattaRegistry */ null);
Regatta regatta = new RegattaImpl("test", null, true, null, null, Collections.singleton(series), false,
Regatta regatta = new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, Collections.singleton(series), false,
new LowPoint(), "test", null, OneDesignRankingMetric::new);
return regatta;
}
@@ -18,6 +18,7 @@ import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.ranking.RankingMetric;
@@ -34,7 +35,8 @@ public class SerializeRankingMetricTest extends AbstractSerializationTest {
final BoatClass _49er = DomainFactory.INSTANCE.getOrCreateBoatClass("49er");
final TrackedRace trackedRace = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(
new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, "Regatta", /* boatClass */ _49er,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */ null,
/* trackedRegattaRegistry */ null, new LowPoint(), UUID.randomUUID(), /* courseArea */ null)),
new RaceDefinitionImpl("Race", new CourseImpl("Course", Collections.<Waypoint>emptyList()) ,
/* boatClass */ _49er, Collections.<Competitor,Boat>emptyMap()),
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
@@ -50,7 +51,8 @@ public class TestDeadlockInRegattaListener {
final String regattaName = "Test Regatta";
final RegattaImpl regatta = new RegattaImpl(
/* raceLogStore */ null, EmptyRegattaLogStore.INSTANCE, regattaName,
new BoatClassImpl("49er", true), /* can boats change */ false, /* startDate */ null, /* endDate */ null,
new BoatClassImpl("49er", true), /* can boats change */ false, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */ null,
/* trackedRegattaRegistry */ null, new LowPoint(), UUID.randomUUID(),
/* courseArea */ null, /* controlTrackingFromStartAndFinishTimes */ true,
OneDesignRankingMetric::new);
@@ -47,6 +47,7 @@ import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.WindSourceType;
@@ -161,7 +162,8 @@ public abstract class TrackBasedTest {
BoatClassImpl boatClass = new BoatClassImpl(boatClassName, /* typicallyStartsUpwind */ true);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName(regattaName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */ null,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", null);
TrackedRegatta trackedRegatta = new DynamicTrackedRegattaImpl(regatta);
List<Waypoint> waypoints = new ArrayList<Waypoint>();
@@ -211,7 +213,7 @@ public abstract class TrackBasedTest {
TrackedRegattaRegistry trackedRegattaRegistry = mock(TrackedRegattaRegistry.class);
Series series = new SeriesImpl("series name", isMedal, /* isFleetsCanRunInParallel */ true, regattaFleets, raceColumnNames, trackedRegattaRegistry);
Iterable<? extends Series> regattaSeries = Collections.singleton(series);
return new RegattaImpl(regattaName, boatClass, /* canBoatsOfCompetitorsChangePerRace */ true,
return new RegattaImpl(regattaName, boatClass, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
startDate, endDate, regattaSeries, persistent, scoringScheme, regatteId , courseArea, OneDesignRankingMetric::new);
}
@@ -22,6 +22,7 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sailing.domain.tracking.MarkPassing;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
@@ -44,7 +45,7 @@ public class UpdateMarkPassingTest {
when(race.getBoatClass()).thenReturn(new BoatClassImpl("49er", /* typicallyStartsUpwind */ true));
when(race.getCompetitors()).thenReturn(Collections.singleton(competitor));
DynamicTrackedRaceImpl trackedRace = new DynamicTrackedRaceImpl(
/* trackedRegatta */new DynamicTrackedRegattaImpl(new RegattaImpl("test", null, true, null, null, new HashSet<Series>(), false, null,
/* trackedRegatta */new DynamicTrackedRegattaImpl(new RegattaImpl("test", null, true, CompetitorRegistrationType.CLOSED, null, null, new HashSet<Series>(), false, null,
"test", null, OneDesignRankingMetric::new)),
race, Collections.<Sideline> emptyList(), EmptyWindStore.INSTANCE,
/* delayToLiveInMillis */1000, /* millisecondsOverWhichToAverageWind */30000,
@@ -36,6 +36,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.common.SpeedWithBearing;
@@ -304,7 +305,8 @@ public class WindTest {
DynamicTrackedRace trackedRace = new DynamicTrackedRaceImpl(new DynamicTrackedRegattaImpl(
new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName("Test Regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null,
/* trackedRegattaRegistry */ null, domainFactory.createScoringScheme(ScoringSchemeType.LOW_POINT), "123", null)),
new RaceDefinitionImpl("Test Race",
new CourseImpl("Test Course", Arrays.asList(new Waypoint[] { w1, w2, w3 })),
@@ -31,6 +31,7 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.impl.DegreePosition;
@@ -72,7 +73,8 @@ public class AbstractMockedRaceMarkPassingTest {
Waypoint w4 = new WaypointImpl(m, PassingInstruction.Starboard);
Waypoint w5 = new WaypointImpl(cp, PassingInstruction.Line);
waypoints = Arrays.asList(w1, w2, w3, w4, w5);
Regatta r = new RegattaImpl(RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, /* canBoatsOfCompetitorsChangePerRace */ true,
Regatta r = new RegattaImpl(RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, Arrays.asList(new SeriesImpl("Series", true, /* isFleetsCanRunInParallel */ true, Arrays.asList(new FleetImpl("fleet")),
new ArrayList<String>(), null)), true, new HighPoint(), "ID", new CourseAreaImpl("area", new UUID(5, 5)), OneDesignRankingMetric::new);
Course course = new CourseImpl("course", waypoints);
@@ -30,6 +30,7 @@ import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.SpeedWithConfidence;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
@@ -344,6 +345,11 @@ public class MockedTrackedRace implements DynamicTrackedRace {
return false;
}
@Override
public CompetitorRegistrationType getCompetitorRegistrationType() {
return CompetitorRegistrationType.CLOSED;
}
@Override
public void addRace(RaceDefinition race) {
}
@@ -590,6 +596,15 @@ public class MockedTrackedRace implements DynamicTrackedRace {
@Override
public void setFleetsCanRunInParallelToTrue() {
}
@Override
public String getRegistrationLinkSecret() {
return null;
}
@Override
public void setRegistrationLinkSecret(String registrationLinkSecret) {
}
};
}
@@ -26,6 +26,7 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
@@ -48,7 +49,8 @@ public class TrackedRegattaTest {
public void setUp() {
regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ false, /* startDate */ null, /* endDate */null, null, null, "a", null));
/* canBoatsOfCompetitorsChangePerRace */ false, CompetitorRegistrationType.CLOSED,
/* startDate */ null, /* endDate */null, null, null, "a", null));
}
@Test(expected = TimeoutException.class)
@@ -51,6 +51,7 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SidelineImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -456,7 +457,8 @@ public class DomainFactoryImpl implements DomainFactory {
if (result == null) {
result = new RegattaImpl(raceLogStore, regattaLogStore, RegattaImpl.getDefaultName(
defaultRegattaNameAndBoatClass.getA(), boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ false, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ false, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null,
trackedRegattaRegistry,
// use the low-point system as the default scoring scheme
getBaseDomainFactory().createScoringScheme(ScoringSchemeType.LOW_POINT), race.getId(), null);
@@ -250,4 +250,17 @@ public interface Regatta
default HasPermissions getType() {
return SecuredDomainType.REGATTA;
}
/**
* get secret for registration link of open regattas.
* @return secret to append on regisration URL
*/
String getRegistrationLinkSecret();
/**
* set secret for registration link of open regattas to be appended to the URL.
* @param registrationLinkSecret secret string
*/
void setRegistrationLinkSecret(String registrationLinkSecret);
}
@@ -45,6 +45,7 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.RegattaListener;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaIdentifier;
@@ -124,6 +125,8 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
private CourseArea defaultCourseArea;
private RegattaConfiguration configuration;
private RaceExecutionOrderCache raceExecutionOrderCache;
private String registrationLinkSecret;
/**
* Regattas may be constructed as implicit default regattas in which case they won't need to be stored durably and
@@ -152,6 +155,8 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
private boolean canBoatsOfCompetitorsChangePerRace;
private CompetitorRegistrationType competitorRegistrationType;
/**
* Defaults to <code>true</code>. See {@link Regatta#useStartTimeInference()}.
*/
@@ -166,10 +171,12 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
* Constructs a regatta with an empty {@link RaceLogStore} and with
* {@link Regatta#isControlTrackingFromStartAndFinishTimes()} set to {@code false}.
*/
public RegattaImpl(String name, BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate,
public RegattaImpl(String name, BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType,
TimePoint startDate, TimePoint endDate,
Iterable<? extends Series> series, boolean persistent, ScoringScheme scoringScheme, Serializable id,
CourseArea courseArea, RankingMetricConstructor rankingMetricConstructor) {
this(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, name, boatClass, canBoatsOfCompetitorsChangePerRace, startDate, endDate, series,
this(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, name, boatClass, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType,
startDate, endDate, series,
persistent, scoringScheme, id, courseArea, 0.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false,
rankingMetricConstructor);
}
@@ -187,9 +194,11 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
* carried out.
*/
public RegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, String name, BoatClass boatClass,
boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, TrackedRegattaRegistry trackedRegattaRegistry,
boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType,
TimePoint startDate, TimePoint endDate, TrackedRegattaRegistry trackedRegattaRegistry,
ScoringScheme scoringScheme, Serializable id, CourseArea courseArea) {
this(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, startDate, endDate, trackedRegattaRegistry, scoringScheme,
this(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType,
startDate, endDate, trackedRegattaRegistry, scoringScheme,
id, courseArea, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
}
@@ -204,11 +213,12 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
* carried out.
*/
public RegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, String name, BoatClass boatClass,
boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, TrackedRegattaRegistry trackedRegattaRegistry,
boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType,
TimePoint startDate, TimePoint endDate, TrackedRegattaRegistry trackedRegattaRegistry,
ScoringScheme scoringScheme, Serializable id, CourseArea courseArea,
boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor) {
this(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, startDate, endDate, Collections
.singletonList(new SeriesImpl(LeaderboardNameConstants.DEFAULT_SERIES_NAME,
this(raceLogStore, regattaLogStore, name, boatClass, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType,
startDate, endDate, Collections.singletonList(new SeriesImpl(LeaderboardNameConstants.DEFAULT_SERIES_NAME,
/* isMedal */false, /* isFleetsCanRunInParallel */ true, Collections
.singletonList(new FleetImpl(LeaderboardNameConstants.DEFAULT_FLEET_NAME)),
/* race column names */new ArrayList<String>(), trackedRegattaRegistry)), /* persistent */false,
@@ -222,7 +232,8 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
* this new regatta.
*/
public <S extends Series> RegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, String name,
BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, Iterable<S> series, boolean persistent,
BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType,
TimePoint startDate, TimePoint endDate, Iterable<S> series, boolean persistent,
ScoringScheme scoringScheme, Serializable id, CourseArea courseArea, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor) {
super(name);
@@ -273,6 +284,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
};
this.regattaLikeHelper.addListener(new RegattaLogEventAdditionForwarder(raceColumnListeners));
this.raceExecutionOrderCache = new RaceExecutionOrderCache();
this.competitorRegistrationType = competitorRegistrationType;
}
@Override
@@ -758,6 +770,11 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
this.canBoatsOfCompetitorsChangePerRace = canBoatsOfCompetitorsChangePerRace;
}
@Override
public CompetitorRegistrationType getCompetitorRegistrationType() {
return this.competitorRegistrationType == null ? CompetitorRegistrationType.CLOSED : this.competitorRegistrationType;
}
@Override
public RegattaLog getRegattaLog() {
return regattaLikeHelper.getRegattaLog();
@@ -949,5 +966,15 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
RegattaLogBoatDeregistrator<RegattaLog, RegattaLogEvent, RegattaLogEventVisitor> deregisterer = new RegattaLogBoatDeregistrator<>(regattaLog, boats, regattaLogEventAuthorForRegatta);
deregisterer.deregister(deregisterer.analyze());
}
@Override
public String getRegistrationLinkSecret() {
return registrationLinkSecret;
}
@Override
public void setRegistrationLinkSecret(String registrationLinkSecret) {
this.registrationLinkSecret = registrationLinkSecret;
}
}
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.base.RaceColumnListener;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.impl.AbstractRaceExecutionOrderProvider;
import com.sap.sailing.domain.base.impl.RegattaLogEventAdditionForwarder;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.LeaderboardType;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.FlexibleRaceColumn;
@@ -377,6 +378,12 @@ public class FlexibleLeaderboardImpl extends AbstractLeaderboardImpl implements
return false;
}
@Override
public CompetitorRegistrationType getCompetitorRegistrationType() {
return CompetitorRegistrationType.CLOSED;
}
/**
* In addition to invoking the superclass implementation, a flexible leaderboard also
* detaches all race logs from any tracked race currently linked to any of the race columns
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.abstractlog.regatta.impl.CompetitorTimeOnDistanceA
import com.sap.sailing.domain.abstractlog.regatta.impl.CompetitorTimeOnTimeFactorFinder;
import com.sap.sailing.domain.abstractlog.regatta.impl.RegattaLogEventListener;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.regattalog.RegattaLogStore;
import com.sap.sse.common.Duration;
@@ -66,6 +67,11 @@ public abstract class BaseRegattaLikeImpl implements IsRegattaLike {
return false;
}
@Override
public CompetitorRegistrationType getCompetitorRegistrationType() {
return CompetitorRegistrationType.CLOSED;
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject();
listeners = new HashSet<>();
@@ -6,6 +6,7 @@ import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sse.common.Duration;
@@ -31,7 +32,13 @@ public interface IsRegattaLike extends Serializable {
* @return true when the competitors change their boats, false otherwise
*/
boolean canBoatsOfCompetitorsChangePerRace();
/**
* Get type of comeptitor registration.
* @return type of competitor registration
*/
CompetitorRegistrationType getCompetitorRegistrationType();
RaceColumn getRaceColumnByName(String raceColumnName);
RegattaLikeIdentifier getRegattaLikeIdentifier();
@@ -12,6 +12,7 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.impl.DegreePosition;
@@ -40,7 +41,7 @@ public class PingMarkViaRegattaLogTest {
Series series = new SeriesImpl("series", false, /* isFleetsCanRunInParallel */ true, Collections.singletonList(fleet),
Collections.singletonList(columnName), service);
Regatta regatta = service.createRegatta(RegattaImpl.getDefaultName("regatta", "Laser"), "Laser",
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /* registrationLinkSecret */ null, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), Collections.<Series>singletonList(series),
false, new HighPoint(), UUID.randomUUID(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, RankingMetricsFactory.getRankingMetricConstructor(RankingMetrics.ONE_DESIGN));
@@ -18,6 +18,7 @@ import org.mockito.Mockito;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.domain.common.CompetitorDescriptor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
@@ -95,10 +96,9 @@ public class SlicingTest {
new SeriesCreationParametersDTO(fleets, false, false, true, false, new int[0], false, 0));
final RegattaCreationParametersDTO regattaCreationParameters = new RegattaCreationParametersDTO(
seriesCreationParameters);
final RegattaDTO regatta = sailingService.createRegatta("default", regattaName, boatClassName, false, null,
null,
regattaCreationParameters, false, ScoringSchemeType.HIGH_POINT, null, 3.0, false, false,
RankingMetrics.ONE_DESIGN);
final RegattaDTO regatta = sailingService.createRegatta("default", regattaName, boatClassName, false,
CompetitorRegistrationType.CLOSED, null, null, null, regattaCreationParameters, false,
ScoringSchemeType.HIGH_POINT, null, 3.0, false, false, RankingMetrics.ONE_DESIGN);
final List<Pair<String, Integer>> columnNames = new ArrayList<>();
columnNames.add(new Pair<>(columnNameOriginalRace, 0));
sailingService.addRaceColumnsToSeries(regatta.getRegattaIdentifier(), seriesName, columnNames);
@@ -1,5 +1,6 @@
package com.sap.sailing.gwt.ui.adminconsole;
import java.util.EnumSet;
import java.util.List;
import java.util.UUID;
@@ -8,6 +9,9 @@ import com.google.gwt.dom.client.OptionElement;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.Grid;
@@ -15,11 +19,13 @@ import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.gwt.ui.client.DataEntryDialogWithDateTimeBox;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
import com.sap.sailing.gwt.ui.common.client.RandomString;
import com.sap.sailing.gwt.ui.leaderboard.RankingMetricTypeFormatter;
import com.sap.sailing.gwt.ui.leaderboard.ScoringSchemeTypeFormatter;
import com.sap.sailing.gwt.ui.shared.CourseAreaDTO;
@@ -55,9 +61,12 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
protected final DoubleBox buoyZoneRadiusInHullLengthsDoubleBox;
protected final ListEditorComposite<SeriesDTO> seriesEditor;
private final ListBox rankingMetricListBox;
protected final ListBox competitorRegistrationTypeListBox;
protected final Button registrationLinkWithQRCodeOpenButton;
protected final List<EventDTO> existingEvents;
private EventDTO defaultEvent;
private RegistrationLinkWithQRCode registrationLinkWithQRCode;
public AbstractRegattaWithSeriesAndFleetsDialog(RegattaDTO regatta, Iterable<SeriesDTO> series, List<EventDTO> existingEvents, EventDTO correspondingEvent,
String title, String okButton, StringMessages stringMessages, Validator<T> validator, DialogCallback<T> callback) {
@@ -103,6 +112,42 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
courseAreaListBox.setEnabled(false);
this.seriesEditor = createSeriesEditor(series);
setupEventAndCourseAreaListBoxes(stringMessages);
competitorRegistrationTypeListBox = createListBox(false);
EnumSet.allOf(CompetitorRegistrationType.class).forEach(t->competitorRegistrationTypeListBox.addItem(t.getLabel(stringMessages), t.name()));
competitorRegistrationTypeListBox.setSelectedIndex(regatta.competitorRegistrationType.ordinal());
competitorRegistrationTypeListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
if (CompetitorRegistrationType.valueOf(competitorRegistrationTypeListBox.getSelectedValue()).isOpen()) {
registrationLinkWithQRCodeOpenButton.setEnabled(true);
registrationLinkWithQRCode.setSecret(RandomString.createRandomSecret(20));
} else {
registrationLinkWithQRCodeOpenButton.setEnabled(false);
registrationLinkWithQRCode.setSecret(null);
}
}
});
registrationLinkWithQRCode = new RegistrationLinkWithQRCode();
registrationLinkWithQRCode.setSecret(regatta.registrationLinkSecret);
registrationLinkWithQRCodeOpenButton = new Button(stringMessages.registrationLinkConfig(), new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
new RegistrationLinkWithQRCodeDialog(stringMessages, registrationLinkWithQRCode,
new DialogCallback<RegistrationLinkWithQRCode>() {
@Override
public void ok(RegistrationLinkWithQRCode result) {
registrationLinkWithQRCode = result;
}
@Override
public void cancel() {
}
}).show();
}
});
}
/**
@@ -146,7 +191,7 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
if (additionalWidget != null) {
panel.add(additionalWidget);
}
Grid formGrid = new Grid(9, 2);
Grid formGrid = new Grid(11, 2);
panel.add(formGrid);
formGrid.setWidget(0, 0, new Label(stringMessages.timeZone() + ":"));
@@ -167,6 +212,10 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
formGrid.setWidget(7, 1, controlTrackingFromStartAndFinishTimesCheckBox);
formGrid.setWidget(8, 0, new Label(stringMessages.buoyZoneRadiusInHullLengths() + ":"));
formGrid.setWidget(8, 1, buoyZoneRadiusInHullLengthsDoubleBox);
formGrid.setWidget(9, 0, new Label(stringMessages.competitorRegistrationType() + ":"));
formGrid.setWidget(9, 1, competitorRegistrationTypeListBox);
formGrid.setWidget(10, 0, new Label(stringMessages.registrationLink() + ":"));
formGrid.setWidget(10, 1, registrationLinkWithQRCodeOpenButton);
setupAdditionalWidgetsOnPanel(panel, formGrid);
return panel;
}
@@ -294,6 +343,12 @@ public abstract class AbstractRegattaWithSeriesAndFleetsDialog<T> extends DataEn
result.buoyZoneRadiusInHullLengths = buoyZoneRadiusInHullLengthsDoubleBox.getValue();
setCourseAreaInRegatta(result);
result.series = getSeriesEditor().getValue();
result.competitorRegistrationType = CompetitorRegistrationType.valueOf(competitorRegistrationTypeListBox.getSelectedValue());
if (result.competitorRegistrationType.isOpen() && registrationLinkWithQRCode != null) {
result.registrationLinkSecret = registrationLinkWithQRCode.getSecret();
} else {
result.registrationLinkSecret = null;
}
return result;
}
@@ -70,7 +70,8 @@ public class CreateRegattaCallback implements DialogCallback<RegattaDTO>{
}
sailingService.createRegatta(userService.getCurrentTenantName(), newRegatta.getName(),
newRegatta.boatClass == null ? null : newRegatta.boatClass.getName(),
newRegatta.canBoatsOfCompetitorsChangePerRace, newRegatta.startDate, newRegatta.endDate,
newRegatta.canBoatsOfCompetitorsChangePerRace, newRegatta.competitorRegistrationType,
newRegatta.registrationLinkSecret, newRegatta.startDate, newRegatta.endDate,
new RegattaCreationParametersDTO(seriesStructure), true,
newRegatta.scoringScheme, newRegatta.defaultCourseAreaUuid, newRegatta.buoyZoneRadiusInHullLengths, newRegatta.useStartTimeInference,
newRegatta.controlTrackingFromStartAndFinishTimes,
@@ -63,8 +63,10 @@ public class RegattaDetailsComposite extends Composite {
private final Label useStartTimeInference;
private final Label controlTrackingFromStartAndFinishTimes;
private final Label canBoatsOfCompetitorsChangePerRace;
private final Label competitorRegistrationType;
private final Label configuration;
private final Label buoyZoneRadiusInHullLengths;
private final Label openRegattaRegistrationLink;
private final SelectionModel<SeriesDTO> seriesSelectionModel;
private final CellTable<SeriesDTO> seriesTable;
@@ -83,7 +85,7 @@ public class RegattaDetailsComposite extends Composite {
VerticalPanel vPanel = new VerticalPanel();
mainPanel.add(vPanel);
int rows = 13;
int rows = 15;
Grid grid = new Grid(rows, 2);
vPanel.add(grid);
@@ -97,11 +99,13 @@ public class RegattaDetailsComposite extends Composite {
useStartTimeInference = createLabelAndValueWidget(grid, currentRow++, stringMessages.useStartTimeInference(), "UseStartTimeInferenceLabel");
controlTrackingFromStartAndFinishTimes = createLabelAndValueWidget(grid, currentRow++, stringMessages.controlTrackingFromStartAndFinishTimes(), "UseStartTimeInferenceLabel");
canBoatsOfCompetitorsChangePerRace = createLabelAndValueWidget(grid, currentRow++, stringMessages.canBoatsOfCompetitorsChangePerRace(), "CanBoatsOfCompetitorsChangePerRaceLabel");
competitorRegistrationType = createLabelAndValueWidget(grid, currentRow++, stringMessages.competitorRegistrationType(), "CompetitorRegistrationTypeLabel");
buoyZoneRadiusInHullLengths = createLabelAndValueWidget(grid, currentRow++, stringMessages.buoyZoneRadiusInHullLengths(), "BuoyZoneRadiusInHullLengthsLabel");
configuration = createLabelAndValueWidget(grid, currentRow++, stringMessages.racingProcedureConfiguration(), "RacingProcedureLabel");
scoringSystem = createLabelAndValueWidget(grid, currentRow++, stringMessages.scoringSystem(), "ScoringSystemLabel");
rankingMetric = createLabelAndValueWidget(grid, currentRow++, stringMessages.rankingMetric(), "RankingMetricLabel");
openRegattaRegistrationLink = createLabelAndValueWidget(grid, currentRow++, stringMessages.registrationLink(), "OpenRegattaRegistrationLinkLabel") ;
seriesTable = createRegattaSeriesTable();
seriesTable.ensureDebugId("SeriesCellTable");
seriesSelectionModel = new SingleSelectionModel<SeriesDTO>();
@@ -405,8 +409,12 @@ public class RegattaDetailsComposite extends Composite {
useStartTimeInference.setText(regatta.useStartTimeInference ? stringMessages.yes() : stringMessages.no());
controlTrackingFromStartAndFinishTimes.setText(regatta.controlTrackingFromStartAndFinishTimes ? stringMessages.yes() : stringMessages.no());
canBoatsOfCompetitorsChangePerRace.setText(regatta.canBoatsOfCompetitorsChangePerRace ? stringMessages.yes() : stringMessages.no());
buoyZoneRadiusInHullLengths.setText(String.valueOf(regatta.buoyZoneRadiusInHullLengths));
competitorRegistrationType.setText(regatta.competitorRegistrationType.getLabel(stringMessages));
openRegattaRegistrationLink.setText(regatta.competitorRegistrationType.isOpen()
? "http://www.sapsailing.com?secret=" + regatta.registrationLinkSecret //TODO: get correct URL for branch.io
: "-");
buoyZoneRadiusInHullLengths.setText(String.valueOf(regatta.buoyZoneRadiusInHullLengths));
if (regatta.configuration != null) {
configuration.setText(stringMessages.configured());
} else {
@@ -187,6 +187,15 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
regattaCanBoatsOfCompetitorsChangePerRaceColumn.setSortable(true);
columnSortHandler.setComparator(regattaCanBoatsOfCompetitorsChangePerRaceColumn,
(r1, r2)->Boolean.valueOf(r1.canBoatsOfCompetitorsChangePerRace).compareTo(Boolean.valueOf(r2.canBoatsOfCompetitorsChangePerRace)));
TextColumn<RegattaDTO> competitorRegistrationTypeColumn = new TextColumn<RegattaDTO>() {
@Override
public String getValue(RegattaDTO regatta) {
return regatta.competitorRegistrationType.getLabel(stringMessages);
}
};
competitorRegistrationTypeColumn.setSortable(true);
columnSortHandler.setComparator(competitorRegistrationTypeColumn, (r1, r2)->r1.competitorRegistrationType.ordinal() - r2.competitorRegistrationType.ordinal());
TextColumn<RegattaDTO> startEndDateColumn = new TextColumn<RegattaDTO>() {
@Override
@@ -265,6 +274,7 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
table.addColumn(regattaSelectionCheckboxColumn, regattaSelectionCheckboxColumn.getHeader());
table.addColumn(regattaNameColumn, stringMessages.regattaName());
table.addColumn(regattaCanBoatsOfCompetitorsChangePerRaceColumn, stringMessages.canBoatsChange());
table.addColumn(competitorRegistrationTypeColumn, stringMessages.competitorRegistrationTypeShort());
table.addColumn(startEndDateColumn, stringMessages.from() + "/" + stringMessages.to());
table.addColumn(regattaBoatClassColumn, stringMessages.boatClass());
table.addColumn(rankingMetricColumn, stringMessages.rankingMetric());
@@ -324,9 +334,9 @@ public class RegattaListComposite extends Composite implements RegattasDisplayer
private void commitEditedRegatta(final RegattaDTO editedRegatta) {
final RegattaIdentifier regattaName = new RegattaName(editedRegatta.getName());
sailingService.updateRegatta(regattaName, editedRegatta.startDate, editedRegatta.endDate, editedRegatta.defaultCourseAreaUuid,
editedRegatta.configuration, editedRegatta.buoyZoneRadiusInHullLengths, editedRegatta.useStartTimeInference, editedRegatta.controlTrackingFromStartAndFinishTimes,
editedRegatta.registrationLinkSecret,
new MarkedAsyncCallback<Void>(new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
@@ -22,7 +22,6 @@ public abstract class RegattaWithSeriesAndFleetsDialog extends AbstractRegattaWi
protected TextBox nameEntryField;
protected SuggestBox boatClassEntryField;
protected CheckBox canBoatsOfCompetitorsChangePerRaceCheckBox;
public RegattaWithSeriesAndFleetsDialog(RegattaDTO regatta, Iterable<SeriesDTO> series, List<EventDTO> existingEvents, EventDTO defaultEvent,
String title, String okButton, StringMessages stringMessages,
Validator<RegattaDTO> validator, DialogCallback<RegattaDTO> callback) {
@@ -44,6 +44,7 @@ public class RegattaWithSeriesAndFleetsEditDialog extends RegattaWithSeriesAndFl
scoringSchemeListBox.setEnabled(false);
sailingEventsListBox.setEnabled(true);
courseAreaListBox.setEnabled(true);
competitorRegistrationTypeListBox.setEnabled(false);
regattaConfigurationCheckbox = createCheckbox(stringMessages.setRacingProcedureConfiguration());
regattaConfigurationCheckbox.ensureDebugId("RacingProcedureConfigurationCheckBox");
@@ -0,0 +1,34 @@
package com.sap.sailing.gwt.ui.adminconsole;
/**
* Type to transfer data between {#link {@link RegistrationLinkWithQRCodeDialog) and caller.
*
* @author Thomas Wiese
*
*/
public class RegistrationLinkWithQRCode {
/* Secret for extending registration URL. */
private String secret;
public RegistrationLinkWithQRCode() {
super();
}
/**
* Get entered secrect.
* @return Secret or null, if not set
*/
public String getSecret() {
return secret;
}
/**
* Set secret.
* @param secret
*/
public void setSecret(String secret) {
this.secret = secret;
}
}
@@ -0,0 +1,67 @@
package com.sap.sailing.gwt.ui.adminconsole;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.common.client.RandomString;
import com.sap.sse.gwt.client.dialog.DataEntryDialog;
public class RegistrationLinkWithQRCodeDialog extends DataEntryDialog<RegistrationLinkWithQRCode> {
private StringMessages stringMessages;
private TextBox secretTextBox;
private Button generateSecretButton;
private RegistrationLinkWithQRCode registrationLinkWithQRCode;
public RegistrationLinkWithQRCodeDialog(final StringMessages stringMessages,
RegistrationLinkWithQRCode registrationLinkWithQRCode,
DialogCallback<RegistrationLinkWithQRCode> callback) {
super(stringMessages.registrationLinkDialog(), stringMessages.explainRegistrationLinkDialog(),
stringMessages.ok(), stringMessages.cancel(), null, true, callback);
this.stringMessages = stringMessages;
this.registrationLinkWithQRCode = registrationLinkWithQRCode == null ? new RegistrationLinkWithQRCode()
: registrationLinkWithQRCode;
secretTextBox = createTextBox(registrationLinkWithQRCode.getSecret(), 30);
generateSecretButton = new Button("generate", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
final String randomString = RandomString.createRandomSecret(20);
registrationLinkWithQRCode.setSecret(randomString);
secretTextBox.setText(randomString);
}
});
}
@Override
protected RegistrationLinkWithQRCode getResult() {
registrationLinkWithQRCode.setSecret(secretTextBox.getValue());
return registrationLinkWithQRCode;
}
@Override
protected Widget getAdditionalWidget() {
final VerticalPanel panel = new VerticalPanel();
Widget additionalWidget = super.getAdditionalWidget();
if (additionalWidget != null) {
panel.add(additionalWidget);
}
Grid formGrid = new Grid(1, 3);
panel.add(formGrid);
formGrid.setWidget(0, 0, new Label(stringMessages.registrationLinkSecret() + ":"));
formGrid.setWidget(0, 1, secretTextBox);
formGrid.setWidget(0, 2, generateSecretButton);
return panel;
}
}
@@ -751,7 +751,7 @@ public class SmartphoneTrackingEventManagementPanel extends AbstractLeaderboardC
final RegattaIdentifier regattaIdentifier = new RegattaName(regatta.getName());
sailingService.updateRegatta(regattaIdentifier, regatta.startDate, regatta.endDate,
regatta.defaultCourseAreaUuid, configuration, regatta.buoyZoneRadiusInHullLengths, regatta.useStartTimeInference,
regatta.controlTrackingFromStartAndFinishTimes,
regatta.controlTrackingFromStartAndFinishTimes, regatta.registrationLinkSecret,
new MarkedAsyncCallback<Void>(new AsyncCallback<Void>() {
@Override
public void onFailure(Throwable caught) {
@@ -16,6 +16,7 @@ import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState;
import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.CompetitorDescriptor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.LeaderboardType;
@@ -265,10 +266,11 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
void moveLeaderboardColumnDown(String leaderboardName, String columnName);
RegattaDTO createRegatta(String tenantOwnerName, String regattaName, String boatClassName,
boolean canBoatsOfCompetitorsChangePerRace, Date startDate, Date endDate,
RegattaCreationParametersDTO seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent,
ScoringSchemeType scoringSchemeType, UUID defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
RegattaDTO createRegatta(String tenantOwnerName, String regattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace,
CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret, Date startDate,
Date endDate, RegattaCreationParametersDTO seriesNamesWithFleetNamesAndFleetOrderingAndMedal,
boolean persistent, ScoringSchemeType scoringSchemeType, UUID defaultCourseAreaId,
Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetrics rankingMetricType);
void removeRegatta(RegattaIdentifier regattaIdentifier);
@@ -278,7 +280,8 @@ public interface SailingService extends RemoteService, FileStorageManagementGwtS
void removeRegattas(Collection<RegattaIdentifier> regattas);
void updateRegatta(RegattaIdentifier regattaIdentifier, Date startDate, Date endDate, UUID defaultCourseAreaUuid,
RegattaConfigurationDTO regattaConfiguration, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes);
RegattaConfigurationDTO regattaConfiguration, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
String registrationLinkSecret);
List<RaceColumnInSeriesDTO> addRaceColumnsToSeries(RegattaIdentifier regattaIdentifier, String seriesName,
List<Pair<String, Integer>> columnNames);
@@ -13,6 +13,7 @@ import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.common.CompetitorDescriptor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DetailType;
import com.sap.sailing.domain.common.LeaderboardType;
@@ -472,8 +473,8 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
void moveRaceColumnInSeriesDown(RegattaIdentifier regattaIdentifier, String seriesName, String columnName,
AsyncCallback<Void> callback);
void createRegatta(String tenantOwnerName, String regattaName, String boatClassName,
boolean canBoatsOfCompetitorsChangePerRace, Date startDate, Date endDate,
void createRegatta(String tenantOwnerName, String regattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace,
CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret, Date startDate, Date endDate,
RegattaCreationParametersDTO seriesNamesWithFleetNamesAndFleetOrderingAndMedal, boolean persistent,
ScoringSchemeType scoringSchemeType, UUID defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetrics rankingMetricType,
@@ -569,7 +570,7 @@ public interface SailingServiceAsync extends ServerInfoRetriever, FileStorageMan
void updateRegatta(RegattaIdentifier regattaIdentifier, Date startDate, Date endDate, UUID defaultCourseAreaUuid,
RegattaConfigurationDTO regattaConfiguration, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, AsyncCallback<Void> callback);
boolean controlTrackingFromStartAndFinishTimes, String registrationLinkSecret, AsyncCallback<Void> callback);
/**
* @param detailType
@@ -1191,9 +1191,16 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
String setTimeToNow();
String useStartTimeInference();
String controlTrackingFromStartAndFinishTimes();
String canBoatsOfCompetitorsChangePerRace();
String canBoatsOfCompetitorsChangePerRace();
String canBoatsChange();
String canNotRegisterBoats();
String competitorRegistrationType();
String competitorRegistrationTypeShort();
String registrationLink();
String registrationLinkConfig();
String registrationLinkDialog();
String registrationLinkSecret();
String explainRegistrationLinkDialog();
String numberOfQueueMessagesSent();
String totalSize();
String averageMessageSize();
@@ -1181,6 +1181,16 @@ controlTrackingFromStartAndFinishTimes=Control tracking from start and finish ti
canBoatsOfCompetitorsChangePerRace=Can boats of competitors change per race
canBoatsChange=Can boats change
canNotRegisterBoats=Boats can only be registered here when they can change per race, otherwise they are registered together with the competitor.
competitorRegistrationType=Competitor Registration Type
competitorRegistrationTypeShort=Registration
competitorRegistrationTypeClosed=closed
competitorRegistrationTypeOpenModerated=open moderated
competitorRegistrationTypeOpenUnmoderated=open unmoderated
registrationLink=Registration Link
registrationLinkConfig=configure
registrationLinkDialog=Link for open regatta registration
registrationLinkSecret=Secret
explainRegistrationLinkDialog=
numberOfQueueMessagesSent=Number of queue messages sent
totalSize=Total Size
averageMessageSize=Average size per message in bytes
@@ -1168,6 +1168,16 @@ controlTrackingFromStartAndFinishTimes=Tracking durch Start- und Ende-Zeiten aut
canBoatsOfCompetitorsChangePerRace=Das Boot des Teilnehmers kann sich pro Wettfahrt ändern
canBoatsChange=Boot kann sich ändern
canNotRegisterBoats=Boote können hier nur registriert werden, wenn sie sich pro Wettfahrt ändern, ansonsten werden sie zusammen mit dem Teilnehmer registriert.
competitorRegistrationType=Teilnehmerregistrierung
competitorRegistrationTypeShort=Registrierung
competitorRegistrationTypeClosed=Geschlossen
competitorRegistrationTypeOpenModerated=Öffentlich moderiert
competitorRegistrationTypeOpenUnmoderated=Öffentlich unmoderiert
registrationLink=Registrierungslink
registrationLinkConfig=konfigurieren
registrationLinkDialog=Registrierungslink für offene Regattas
registrationLinkSecret=Secret
explainRegistrationLinkDialog=
numberOfQueueMessagesSent=Anzahl verschickter Queue Nachrichten
totalSize=Gesamtgröße
averageMessageSize=Durchschnittsgrösse einer Nachricht
@@ -0,0 +1,22 @@
package com.sap.sailing.gwt.ui.common.client;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class RandomString {
/**
* Generate a random string containing uppercase letters and numbers.
*
* @param length
* length of the string to generate
* @return random string
*/
public static String createRandomSecret(int length) {
String randomString = Stream.generate(Math::random).map(r -> (int) (r * 100))
.filter(i -> (i > 47 && i < 58 || i > 64 && i < 90)).limit(length)
.map(i -> String.valueOf((char) i.intValue())).collect(Collectors.joining());
return randomString;
}
}
@@ -204,6 +204,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.SailingServerConfigurationImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorDescriptor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DataImportSubProgress;
@@ -1035,9 +1036,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
regattaDTO.useStartTimeInference = regatta.useStartTimeInference();
regattaDTO.controlTrackingFromStartAndFinishTimes = regatta.isControlTrackingFromStartAndFinishTimes();
regattaDTO.canBoatsOfCompetitorsChangePerRace = regatta.canBoatsOfCompetitorsChangePerRace();
regattaDTO.competitorRegistrationType = regatta.getCompetitorRegistrationType();
regattaDTO.configuration = convertToRegattaConfigurationDTO(regatta.getRegattaConfiguration());
regattaDTO.rankingMetricType = regatta.getRankingMetricType();
SecurityDTOUtil.addSecurityInformation(getSecurityService(), regattaDTO, regatta.getIdentifier());
regattaDTO.registrationLinkSecret = regatta.getRegistrationLinkSecret();
return regattaDTO;
}
@@ -4513,15 +4516,17 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public void updateRegatta(RegattaIdentifier regattaName, Date startDate, Date endDate, UUID defaultCourseAreaUuid,
RegattaConfigurationDTO configurationDTO, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes) {
RegattaConfigurationDTO configurationDTO, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
String registrationLinkSecret) {
Regatta regatta = getService().getRegatta(regattaName);
if (regatta != null) {
SecurityUtils.getSubject().checkPermission(SecuredDomainType.REGATTA.getStringPermissionForObjects(DefaultActions.UPDATE, regatta.getName()));
}
TimePoint startTimePoint = startDate != null ? new MillisecondsTimePoint(startDate) : null;
TimePoint endTimePoint = endDate != null ? new MillisecondsTimePoint(endDate) : null;
getService().apply(new UpdateSpecificRegatta(regattaName, startTimePoint, endTimePoint,
defaultCourseAreaUuid, convertToRegattaConfiguration(configurationDTO), buoyZoneRadiusInHullLengths, useStartTimeInference, controlTrackingFromStartAndFinishTimes));
getService().apply(new UpdateSpecificRegatta(regattaName, startTimePoint, endTimePoint, defaultCourseAreaUuid,
convertToRegattaConfiguration(configurationDTO), buoyZoneRadiusInHullLengths, useStartTimeInference,
controlTrackingFromStartAndFinishTimes, registrationLinkSecret));
}
@Override
@@ -4588,7 +4593,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public RegattaDTO createRegatta(String tenantOwnerName, String regattaName, String boatClassName,
boolean canBoatsOfCompetitorsChangePerRace, Date startDate, Date endDate,
boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret,
Date startDate, Date endDate,
RegattaCreationParametersDTO seriesNamesWithFleetNamesAndFleetOrderingAndMedal,
boolean persistent, ScoringSchemeType scoringSchemeType, UUID defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetrics rankingMetricType) {
@@ -4602,7 +4608,8 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
TimePoint startTimePoint = startDate != null ? new MillisecondsTimePoint(startDate) : null;
TimePoint endTimePoint = endDate != null ? new MillisecondsTimePoint(endDate) : null;
Regatta regatta = getService().apply(new AddSpecificRegatta(regattaName, boatClassName,
canBoatsOfCompetitorsChangePerRace, startTimePoint, endTimePoint, UUID.randomUUID(),
canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, registrationLinkSecret,
startTimePoint, endTimePoint, UUID.randomUUID(),
seriesNamesWithFleetNamesAndFleetOrderingAndMedal, persistent,
baseDomainFactory.createScoringScheme(scoringSchemeType), defaultCourseAreaId,
buoyZoneRadiusInHullLengths, useStartTimeInference,
@@ -4862,10 +4869,11 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
private void createRegattaFromRegattaDTO(String tenantOwnerName, RegattaDTO regatta) {
this.createRegatta(tenantOwnerName, regatta.getName(), regatta.boatClass.getName(),
regatta.canBoatsOfCompetitorsChangePerRace, regatta.startDate, regatta.endDate,
new RegattaCreationParametersDTO(getSeriesCreationParameters(regatta)),
true, regatta.scoringScheme, regatta.defaultCourseAreaUuid, regatta.buoyZoneRadiusInHullLengths, regatta.useStartTimeInference,
regatta.controlTrackingFromStartAndFinishTimes, regatta.rankingMetricType);
regatta.canBoatsOfCompetitorsChangePerRace, regatta.competitorRegistrationType, /* registrationLinkSecret */ null,
regatta.startDate, regatta.endDate,
new RegattaCreationParametersDTO(getSeriesCreationParameters(regatta)),
true, regatta.scoringScheme, regatta.defaultCourseAreaUuid, regatta.buoyZoneRadiusInHullLengths, regatta.useStartTimeInference,
regatta.controlTrackingFromStartAndFinishTimes, regatta.rankingMetricType);
}
private SeriesParameters getSeriesParameters(SeriesDTO seriesDTO) {
@@ -6,6 +6,7 @@ import java.util.List;
import java.util.UUID;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaIdentifier;
@@ -38,8 +39,10 @@ public class RegattaDTO extends NamedSecuredObjectDTO implements SecuredObject {
public boolean useStartTimeInference = true;
public boolean controlTrackingFromStartAndFinishTimes = false;
public boolean canBoatsOfCompetitorsChangePerRace = false;
public CompetitorRegistrationType competitorRegistrationType = CompetitorRegistrationType.CLOSED;
public RankingMetrics rankingMetricType;
public Double buoyZoneRadiusInHullLengths;
public String registrationLinkSecret;
public RegattaDTO() {}
@@ -71,7 +74,9 @@ public class RegattaDTO extends NamedSecuredObjectDTO implements SecuredObject {
this.useStartTimeInference = other.useStartTimeInference;
this.controlTrackingFromStartAndFinishTimes = other.controlTrackingFromStartAndFinishTimes;
this.canBoatsOfCompetitorsChangePerRace = other.canBoatsOfCompetitorsChangePerRace;
this.competitorRegistrationType = other.competitorRegistrationType;
this.buoyZoneRadiusInHullLengths = other.buoyZoneRadiusInHullLengths;
this.registrationLinkSecret = other.registrationLinkSecret;
}
public Pair<SeriesDTO, FleetDTO> getSeriesAndFleet(RegattaAndRaceIdentifier raceIdentifier) {
@@ -18,6 +18,7 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.leaderboard.ScoringScheme;
import com.sap.sailing.domain.persistence.DomainObjectFactory;
@@ -62,7 +63,8 @@ public abstract class AbstractTestStoringAndRetrievingRaceLogInRegatta extends R
List<Series> series = createSeriesForTestRegatta();
Regatta regatta = new RegattaImpl(getRaceLogStore(), getRegattaLogStore(), RegattaImpl.getDefaultName(regattaBaseName,
boatClass == null ? null : boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, series, persistent, scoringScheme, "123",
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, series, persistent, scoringScheme, "123",
courseArea, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
return regatta;
}
@@ -23,6 +23,7 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.racelog.tracking.NotDenotableForRaceLogTrackingException;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
@@ -49,9 +50,11 @@ public class RaceLogConnectivityParamsLoadAndStoreTest extends AbstractConnectiv
final SeriesImpl theSeries = new SeriesImpl("Default", /* isMedal */ false, /* isFleetsCanRunInParallel */ true,
Arrays.<Fleet>asList(fleet), Collections.emptyList(), racingEventService);
final Iterable<? extends Series> series = Arrays.<Series>asList(theSeries);
final Regatta regatta = racingEventService.createRegatta("My Regatta", "12mR", true, MillisecondsTimePoint.now(), MillisecondsTimePoint.now().plus(Duration.ONE_DAY),
UUID.randomUUID(), series, /* persistent */ true, new LowPoint(), new CourseAreaImpl("Default", UUID.randomUUID()),
/* buoyZoneRadiusInHullLengths */ 2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
final Regatta regatta = racingEventService.createRegatta("My Regatta", "12mR", true,
CompetitorRegistrationType.CLOSED, /* registrationLinkSecret */ null, MillisecondsTimePoint.now(),
MillisecondsTimePoint.now().plus(Duration.ONE_DAY), UUID.randomUUID(), series, /* persistent */ true,
new LowPoint(), new CourseAreaImpl("Default", UUID.randomUUID()), /* buoyZoneRadiusInHullLengths */ 2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
theSeries.addRaceColumn("R1", racingEventService);
theSeries.addRaceColumn("R2", racingEventService);
@@ -58,6 +58,7 @@ import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.VenueImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.MaxPointsReason;
import com.sap.sailing.domain.common.RaceIdentifier;
import com.sap.sailing.domain.common.RankingMetrics;
@@ -226,7 +227,8 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String regattaBaseName = "Kieler Woche";
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true);
Regatta regatta = createRegatta(RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, regattaStartDate, regattaEndDate, /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), courseArea, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.OPEN_MODERATED, regattaStartDate, regattaEndDate, /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), courseArea, OneDesignRankingMetric::new);
mof.storeRegatta(regatta);
DomainObjectFactory dof = PersistenceFactory.INSTANCE.getDomainObjectFactory(getMongoService(), DomainFactory.INSTANCE);
@@ -239,6 +241,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
assertEquals(loadedRegatta.getDefaultCourseArea().getName(), courseArea.getName());
assertEquals(loadedRegatta.getStartDate(), regattaStartDate);
assertEquals(loadedRegatta.getEndDate(), regattaEndDate);
assertTrue(loadedRegatta.getCompetitorRegistrationType() == CompetitorRegistrationType.OPEN_MODERATED);
}
@Test
@@ -418,12 +421,14 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String regattaBaseName = "Kieler Woche";
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true);
Regatta regattaProxy = createRegatta(RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ false, regattaStartDate, regattaEndDate, /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ false, CompetitorRegistrationType.CLOSED, regattaStartDate, regattaEndDate,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
final String regattaName = regattaProxy.getName();
Regatta regatta = res.createRegatta(regattaName, regattaProxy.getBoatClass().getName(),
/* canBoatsOfCompetitorsChangePerRace */ false, regattaStartDate, regattaEndDate,
"123", regattaProxy.getSeries(), regattaProxy.isPersistent(), DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT),
/* defaultCourseAreaId */ null, /*buoyZoneRadiusInHullLengths*/ 2.0, /* useStartTimeInference */ true,
/* canBoatsOfCompetitorsChangePerRace */ false, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, regattaStartDate, regattaEndDate, "123", regattaProxy.getSeries(),
regattaProxy.isPersistent(), DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT),
/* defaultCourseAreaId */ null, /* buoyZoneRadiusInHullLengths */ 2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
DynamicCompetitorWithBoat competitorWithBoat1 = AbstractLeaderboardTest.createCompetitorWithBoat("Humba1");
DynamicCompetitorWithBoat competitorWithBoat2 = AbstractLeaderboardTest.createCompetitorWithBoat("Humba2");
@@ -494,10 +499,15 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String regattaBaseName = "Kieler Woche";
Regatta regattaProxy = createRegatta(RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, regattaStartDate, regattaEndDate, /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
Regatta regatta = res.createRegatta(regattaProxy.getName(), regattaProxy.getBoatClass().getName(),
regattaProxy.canBoatsOfCompetitorsChangePerRace(), regattaProxy.getStartDate(), regattaProxy.getEndDate(),
"123", regattaProxy.getSeries(), regattaProxy.isPersistent(), DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.OPEN_UNMODERATED, regattaStartDate, regattaEndDate,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
Regatta regatta = res.createRegatta(regattaProxy.getName(), regattaProxy.getBoatClass().getName(),
regattaProxy.canBoatsOfCompetitorsChangePerRace(), regattaProxy.getCompetitorRegistrationType(),
/* registrationLinkSecret */ null, regattaProxy.getStartDate(), regattaProxy.getEndDate(), "123",
regattaProxy.getSeries(), regattaProxy.isPersistent(),
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
trackedRegatta[0] = new DynamicTrackedRegattaImpl(regatta);
addRaceColumns(numberOfQualifyingRaces, numberOfFinalRaces, regatta);
logColumnsInRegatta(regatta);
@@ -537,6 +547,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
.getName(), q2YellowTrackedRace.getRaceIdentifier()));
MaxPointsReason hassosLoadedMaxPointsReason = loadedLeaderboard.getScoreCorrection().getMaxPointsReason(hasso, loadedQ2, MillisecondsTimePoint.now());
assertEquals(MaxPointsReason.DNF, hassosLoadedMaxPointsReason);
assertEquals(regatta.getCompetitorRegistrationType(), loadedRegatta.getCompetitorRegistrationType());
}
private void logColumnsInRegattaLeaderboard(RegattaLeaderboard regattaLeaderboard) {
@@ -718,7 +729,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String regattaBaseName = "Kieler Woche";
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */true);
final String regattaName = RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName());
Regatta regatta = createRegatta(regattaName, boatClass, canBoatsOfCompetitorsChangePerRace,
Regatta regatta = createRegatta(regattaName, boatClass, canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType.CLOSED,
null, null, /* persistent */false,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
MongoObjectFactory mof = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService());
@@ -736,7 +747,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
final String regattaBaseName = "Kieler Woche";
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */true);
final String regattaName = RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName());
Regatta regatta = createRegatta(regattaName, boatClass, canBoatsOfCompetitorsChangePerRace,
Regatta regatta = createRegatta(regattaName, boatClass, canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType.CLOSED,
null, null, /* persistent */false,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
MongoObjectFactory mof = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService());
@@ -811,7 +822,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("29erXX", /* typicallyStartsUpwind */ true);
final String regattaName = RegattaImpl.getDefaultName(regattaBaseName, boatClass.getName());
Regatta regatta = createRegatta(regattaName, boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, regattaStartDate, regattaEndDate,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, regattaStartDate, regattaEndDate,
/* persistent */ false, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
MongoObjectFactory mof = PersistenceFactory.INSTANCE.getMongoObjectFactory(getMongoService());
mof.storeRegatta(regatta);
@@ -867,8 +878,8 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
private Regatta createRegattaAndAddRaceColumns(final int numberOfQualifyingRaces, final int numberOfFinalRaces,
final String regattaName, BoatClass boatClass, TimePoint startDate, TimePoint endDate, boolean persistent,
ScoringScheme scoringScheme, RankingMetricConstructor rankingMetricConstructor) {
Regatta regatta = createRegatta(regattaName, boatClass, /* canBoatsOfCompetitorsChangePerRace */ true,
startDate, endDate, persistent, scoringScheme, null, rankingMetricConstructor);
Regatta regatta = createRegatta(regattaName, boatClass, /* canBoatsOfCompetitorsChangePerRace */ true,
CompetitorRegistrationType.CLOSED, startDate, endDate, persistent, scoringScheme, null, rankingMetricConstructor);
addRaceColumns(numberOfQualifyingRaces, numberOfFinalRaces, regatta);
return regatta;
}
@@ -889,7 +900,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
addRaceColumnsToSeries(medalRaceColumnNames, regatta.getSeriesByName("Medal"));
}
private Regatta createRegatta(final String regattaName, BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate,
private Regatta createRegatta(final String regattaName, BoatClass boatClass, boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType, TimePoint startDate,
TimePoint endDate, boolean persistent, ScoringScheme scoringScheme, CourseArea courseArea,
RankingMetricConstructor rankingMetricConstructor) {
List<String> emptyRaceColumnNames = Collections.emptyList();
@@ -915,7 +926,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
medalFleets.add(new FleetImpl("Medal"));
Series medalSeries = new SeriesImpl("Medal", /* isMedal */ true, /* isFleetsCanRunInParallel */ true, medalFleets, emptyRaceColumnNames, /* trackedRegattaRegistry */ null);
series.add(medalSeries);
Regatta regatta = new RegattaImpl(regattaName, boatClass, canBoatsOfCompetitorsChangePerRace, startDate, endDate,
Regatta regatta = new RegattaImpl(regattaName, boatClass, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, startDate, endDate,
series, persistent, scoringScheme, "123", courseArea, rankingMetricConstructor);
return regatta;
}
@@ -930,7 +941,7 @@ public class TestStoringAndLoadingEventsAndRegattas extends AbstractMongoDBTest
public void testRegattaRaceAssociationStore() throws Exception {
BoatClass boatClass = DomainFactory.INSTANCE.getOrCreateBoatClass("112er", /* typicallyStartsUpwind */ true);
Regatta regatta = createRegatta(RegattaImpl.getDefaultName("Cologne Masters", boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, regattaStartDate, regattaEndDate, /* persistent */ true,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, regattaStartDate, regattaEndDate, /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, OneDesignRankingMetric::new);
Map<Competitor, Boat> competitorsAndBoats = new LinkedHashMap<>();
@@ -21,6 +21,7 @@ public class RegattaJsonSerializer implements JsonSerializer<Regatta> {
public static final String FIELD_TRACKED_RACES = "trackedRaces";
public static final String FIELD_COURSE_AREA_ID = "courseAreaId";
public static final String FIELD_CAN_BOATS_OF_COMPETITORS_CHANGE_PER_RACE = "canBoatsOfCompetitorsChangePerRace";
public static final String FIELD_COMPETITOR_REGISTRATION_TYPE = "competitorRegistrationType";
private final JsonSerializer<Series> seriesSerializer;
private final JsonSerializer<Competitor> competitorSerializer;
@@ -47,6 +48,7 @@ public class RegattaJsonSerializer implements JsonSerializer<Regatta> {
result.put(FIELD_COURSE_AREA_ID,
regatta.getDefaultCourseArea() != null ? regatta.getDefaultCourseArea().getId().toString() : null);
result.put(FIELD_CAN_BOATS_OF_COMPETITORS_CHANGE_PER_RACE, regatta.canBoatsOfCompetitorsChangePerRace());
result.put(FIELD_COMPETITOR_REGISTRATION_TYPE, regatta.getCompetitorRegistrationType().name());
if (seriesSerializer != null) {
JSONArray seriesJson = new JSONArray();
for (Series series : regatta.getSeries()) {
@@ -17,6 +17,8 @@ import javax.ws.rs.core.Response;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.SubjectThreadState;
import org.apache.shiro.util.ThreadState;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -38,6 +40,7 @@ import com.sap.sse.mongodb.MongoDBConfiguration;
import com.sap.sse.mongodb.MongoDBService;
import com.sap.sse.security.ActionWithResult;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.shared.User;
import com.sap.sse.security.shared.UserGroup;
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
import com.sap.sse.security.shared.impl.UserGroupImpl;
@@ -52,7 +55,7 @@ public abstract class AbstractJaxRsApiTest {
protected DummyLeaderboardsResource leaderboardsResource;
protected DummyBoatsResource boatsResource;
protected DummyCompetitorsResource competitorsResource;
protected static SimpleDateFormat TIMEPOINT_FORMATTER = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
@SuppressWarnings("unchecked")
@@ -114,11 +117,27 @@ public abstract class AbstractJaxRsApiTest {
.when(leaderboardsResource).getRaceLogTrackingAdapter();
}
public ThreadState setUser(User user) {
Subject subject = Mockito.mock(Subject.class);
if (user == null) {
Mockito.when(subject.isAuthenticated()).thenReturn(false);
Mockito.when(subject.getPrincipal()).thenReturn(null);
} else {
Mockito.when(subject.isAuthenticated()).thenReturn(true);
Mockito.when(subject.getPrincipal()).thenReturn(user.getName());
}
Mockito.when(securityService.getCurrentUser()).thenReturn(user);
ThreadState subjectThreadState = new SubjectThreadState(subject);
subjectThreadState.bind();
return subjectThreadState;
}
public SecurityService getSecurityService() {
return securityService;
}
private <T extends AbstractSailingServerResource> T spyResource(T resource) {
protected <T extends AbstractSailingServerResource> T spyResource(T resource) {
T spyResource = spy(resource);
doReturn(racingEventService).when(spyResource).getService();
return spyResource;
@@ -21,6 +21,7 @@ import org.json.simple.JSONValue;
import org.junit.Before;
import org.junit.Test;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NotFoundException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.impl.DegreePosition;
@@ -112,7 +113,7 @@ public class EventResourceTest extends AbstractJaxRsApiTest {
/* venueNameParam */ randomName, /* venueLat */ null, /* venueLng */ null, /* isPublicParam */ null,
/* officialWebsiteURLParam */ null, /* baseURLParam */ null, /* leaderboardGroupIdsListParam */ null,
/* createLeaderboardGroupParam */ "true", /* createRegattaParam */ "false",
/* boatClassNameParam */ null, /* numberOfRacesParam */ null, false);
/* boatClassNameParam */ null, /* numberOfRacesParam */ null, false, CompetitorRegistrationType.CLOSED.name());
}
private Response createEvent() throws ParseException, NotFoundException, NumberFormatException, IOException,
@@ -122,7 +123,7 @@ public class EventResourceTest extends AbstractJaxRsApiTest {
/* venueNameParam */ randomName, /* venueLat */ null, /* venueLng */ null, /* isPublicParam */ null,
/* officialWebsiteURLParam */ null, /* baseURLParam */ null, /* leaderboardGroupIdsListParam */ null,
/* createLeaderboardGroupParam */ "false", /* createRegattaParam */ "false",
/* boatClassNameParam */ null, /* numberOfRacesParam */ null, false);
/* boatClassNameParam */ null, /* numberOfRacesParam */ null, false, CompetitorRegistrationType.CLOSED.name());
}
private Response createEventAtLocation(Position location) throws ParseException, NotFoundException,
@@ -133,7 +134,7 @@ public class EventResourceTest extends AbstractJaxRsApiTest {
/* venueLng */ "" + location.getLngDeg(), /* isPublicParam */ null, /* officialWebsiteURLParam */ null,
/* baseURLParam */ null, /* leaderboardGroupIdsListParam */ null,
/* createLeaderboardGroupParam */ "false", /* createRegattaParam */ "false",
/* boatClassNameParam */ null, /* numberOfRacesParam */ null, false);
/* boatClassNameParam */ null, /* numberOfRacesParam */ null, false, CompetitorRegistrationType.CLOSED.name());
}
private Response createEventWithLeaderboardGroupAndRegatta() throws ParseException, NotFoundException,
@@ -143,7 +144,7 @@ public class EventResourceTest extends AbstractJaxRsApiTest {
/* venueNameParam */ randomName, /* venueLat */ null, /* venueLng */ null, /* isPublicParam */ null,
/* officialWebsiteURLParam */ null, /* baseURLParam */ null, /* leaderboardGroupIdsListParam */ null,
/* createLeaderboardGroupParam */ "true", /* createRegattaParam */ "true",
/* boatClassNameParam */ "A_CAT", /* numberOfRacesParam */ null, false);
/* boatClassNameParam */ "A_CAT", /* numberOfRacesParam */ null, false, CompetitorRegistrationType.CLOSED.name());
}
private Response getLeaderboard(String name) {
@@ -22,6 +22,7 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
@@ -49,9 +50,11 @@ public class LeaderboardGroupResourceTest extends AbstractJaxRsApiTest {
raceColumnNames, /* trackedRegattaRegistry */null);
series.add(testSeries);
regatta = racingEventService.createRegatta(RegattaImpl.getDefaultName(regattaName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, UUID.randomUUID(), series, /*persistent*/ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(), series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
testSeries.addRaceColumn("R1", /* trackedRegattaRegistry */ null);
testSeries.addRaceColumn("R2", /* trackedRegattaRegistry */ null);
List<Competitor> competitors = createCompetitors(4);
@@ -31,6 +31,7 @@ import com.sap.sailing.domain.base.impl.DynamicTeam;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.racelog.tracking.DeviceMappingConstants;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.leaderboard.impl.HighPoint;
@@ -55,8 +56,8 @@ public class LeaderboardsResourceCheckinAndOutTest extends AbstractJaxRsApiTest
competitor = racingEventService.getBaseDomainFactory().getOrCreateCompetitorWithBoat(c.getId(), c.getName(), c.getShortName(),
c.getColor(), c.getEmail(), c.getFlagImage(), (DynamicTeam) c.getTeam(),
/* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null, null, (DynamicBoat) boat);
Regatta regatta = new RegattaImpl("regatta", boatClass, /* canBoatsOfCompetitorsChangePerRace */ false, MillisecondsTimePoint.now(),
MillisecondsTimePoint.now(), Collections.singleton(new SeriesImpl("series", false, /* isFleetsCanRunInParallel */ true, Collections
Regatta regatta = new RegattaImpl("regatta", boatClass, /* canBoatsOfCompetitorsChangePerRace */ false, CompetitorRegistrationType.CLOSED,
MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), Collections.singleton(new SeriesImpl("series", false, /* isFleetsCanRunInParallel */ true, Collections
.singleton(new FleetImpl("fleet")), Arrays.asList("column"), racingEventService)), false,
new HighPoint(), 0, null, OneDesignRankingMetric::new);
racingEventService.addRegattaWithoutReplication(regatta);
@@ -21,6 +21,7 @@ import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.racelog.tracking.TransformationException;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
@@ -57,8 +58,8 @@ public class LeaderboardsResourcePingMarkTest extends AbstractJaxRsApiTest {
public void setUp() throws Exception {
super.setUp();
mark = racingEventService.getBaseDomainFactory().getOrCreateMark("id", "name");
Regatta regatta = new RegattaImpl("regatta", new BoatClassImpl("49er", false), /* canBoatsOfCompetitorsChangePerRace */ true, MillisecondsTimePoint.now(),
MillisecondsTimePoint.now(), Collections.singleton(new SeriesImpl("series", false, /* isFleetsCanRunInParallel */ true, Collections
Regatta regatta = new RegattaImpl("regatta", new BoatClassImpl("49er", false), /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
MillisecondsTimePoint.now(), MillisecondsTimePoint.now(), Collections.singleton(new SeriesImpl("series", false, /* isFleetsCanRunInParallel */ true, Collections
.singleton(new FleetImpl("fleet")), Arrays.asList("column"), racingEventService)), false,
new HighPoint(), 0, null, OneDesignRankingMetric::new);
racingEventService.addRegattaWithoutReplication(regatta);
@@ -26,6 +26,7 @@ import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
@@ -57,9 +58,11 @@ public class LeaderboardsResourceTest extends AbstractJaxRsApiTest {
raceColumnNames, /* trackedRegattaRegistry */null);
series.add(testSeries);
regatta = racingEventService.createRegatta(RegattaImpl.getDefaultName(regattaBaseName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, UUID.randomUUID(), series, /*persistent*/ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(), series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
testSeries.addRaceColumn("R1", /* trackedRegattaRegistry */ null);
testSeries.addRaceColumn("R2", /* trackedRegattaRegistry */ null);
List<Competitor> competitors = createCompetitors(4);
@@ -1,42 +1,63 @@
package com.sap.sailing.server.gateway.test.jaxrs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.DomainFactory;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.UserImpl;
import com.sap.sse.security.shared.Account;
import com.sap.sse.security.shared.User;
public class RegattasResourceTest extends AbstractJaxRsApiTest {
private String boatClassName = "49er";
private String regattaNamePart = "TestRegatta";
private String regattaName = RegattaImpl.getDefaultName(regattaNamePart, boatClassName);
private String closedRegattaNamePart = "TestRegatta";
private String openRegattaNamePart = "TestOpenRegatta";
private String closedRegattaName = RegattaImpl.getDefaultName(closedRegattaNamePart, boatClassName);
private String openRegattaName = RegattaImpl.getDefaultName(openRegattaNamePart, boatClassName);
private final String deviceUuid = "00000000-1111-2222-3333-444444444444";
private final String secret = "ABCDEF";
private final String competitorName1 = "Max Mustermann";
private final String competitorName2 = "Test Competitor";
@Before
public void setUp() throws Exception {
@@ -54,8 +75,13 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
Series testSeries = new SeriesImpl("TestSeries", /* isMedal */false, /* isFleetsCanRunInParallel */ true,
fleets, raceColumnNames, /* trackedRegattaRegistry */null);
series.add(testSeries);
racingEventService.createRegatta(regattaName, boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true,
startDate, endDate, UUID.randomUUID(), series, /* persistent */ true,
racingEventService.createRegatta(closedRegattaName, boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true,
CompetitorRegistrationType.CLOSED, /* registrationLinkSecret */ null, startDate, endDate, UUID.randomUUID(), series, /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
racingEventService.createRegatta(openRegattaName, boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true,
CompetitorRegistrationType.OPEN_MODERATED, secret, startDate, endDate, UUID.randomUUID(), series, /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
@@ -65,7 +91,7 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
Course course = new CourseImpl("emptyCourse", Collections.emptySet());
// get the same instance! of the boat class object, as else addRace will fail
BoatClass boatClass = racingEventService.getBaseDomainFactory().getOrCreateBoatClass(boatClassName);
racingEventService.addRace(new RegattaName(regattaName), new RaceDefinitionImpl("Race 1", course, boatClass));
racingEventService.addRace(new RegattaName(closedRegattaName), new RaceDefinitionImpl("Race 1", course, boatClass));
}
@Test
@@ -76,21 +102,126 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
Object obj = JSONValue.parse(jsonString);
JSONArray array = (JSONArray) obj;
assertTrue(array.size() == 1);
assertTrue(array.size() == 2);
JSONObject firstElement = (JSONObject) array.get(0);
String jsonName = (String) firstElement.get("name");
String jsonBoatClass = (String) firstElement.get("boatclass");
assertTrue(RegattaImpl.getDefaultName(regattaNamePart, boatClassName).equals(jsonName));
assertTrue(closedRegattaName.equals(jsonName)
|| openRegattaName.equals(jsonName));
assertTrue(boatClassName.equals(jsonBoatClass));
}
@Test
public void testNullCheckForTrackedRaceInGetManeuvers() throws Exception {
Response response = regattasResource.getManeuvers(regattaName, "Race 1", null, null);
Response response = regattasResource.getManeuvers(closedRegattaName, "Race 1", null, null);
// the current race is not tracked, expect an error
assertTrue(response.getStatus() != 200);
}
@Test
public void testGetRegatta() throws Exception {
Response regattaResponse = regattasResource.getRegatta(closedRegattaName);
String jsonString = (String) regattaResponse.getEntity();
assertNotNull(jsonString);
String readRegattaName = (String) ((JSONObject) JSONValue.parse(jsonString)).get("name");
assertEquals(closedRegattaName, readRegattaName);
}
@Test
public void testCompetitorRegistrationByAdmin() throws Exception {
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
doReturn(true).when(securityService).hasCurrentUserUpdatePermission(Mockito.any());
User user = new UserImpl("admin", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null);
setUser(user);
when(securityService.getCurrentUser()).thenReturn(user);
Response response = regattasResource.createAndAddCompetitor(closedRegattaName, boatClassName, null, "GER", null,
null, null, competitorName1, null, deviceUuid, null);
assertTrue(response.getStatus() + ": " + response.getEntity().toString(),
response.getStatus() == Status.OK.getStatusCode());
assertTrue(regattasResource.getService() == racingEventService);
response = regattasResource.createAndAddCompetitor(closedRegattaName, boatClassName, null, "GER", null, null,
null, competitorName2, null, deviceUuid, null);
assertTrue(response.getStatus() + ": " + response.getEntity().toString(),
response.getStatus() == Status.OK.getStatusCode());
Regatta regatta = racingEventService.getRegattaByName(closedRegattaName);
Iterator<Competitor> cit = regatta.getAllCompetitors().iterator();
Competitor readCompetitor = cit.next();
assertNotNull(readCompetitor);
assertTrue(
competitorName1.equals(readCompetitor.getName()) || competitorName2.equals(readCompetitor.getName()));
readCompetitor = cit.next();
assertNotNull(readCompetitor);
assertTrue(
competitorName1.equals(readCompetitor.getName()) || competitorName2.equals(readCompetitor.getName()));
}
@Test
public void testCompetitorRegistrationAnonymousOnOpenRegatta() throws Exception {
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
setUser(null);
Response response = regattasResource.createAndAddCompetitor(openRegattaName, boatClassName, null, "GER", null, null, null,
"Max Mustermann", null, deviceUuid, secret);
assertTrue(response.getStatus() + ": " + response.getEntity().toString(),
response.getStatus() == Status.OK.getStatusCode());
assertTrue(regattasResource.getService() == racingEventService);
Regatta regatta = racingEventService.getRegattaByName(openRegattaName);
testResponseOfOpenRegattaCompetitorRegistration(regatta);
}
@Test
public void testCompetitorRegistrationAnonymousOnOpenRegattaWrongSecret() throws Exception {
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
setUser(null);
Response response = regattasResource.createAndAddCompetitor(openRegattaName, boatClassName, null, "GER", null, null, null,
"Max Mustermann", null, deviceUuid, "WRONGSECRET");
assertTrue(response.getStatus() + ": " + response.getEntity().toString(),
response.getStatus() == Status.FORBIDDEN.getStatusCode());
}
@Test
public void testCompetitorRegistrationAuthenticatedOnOpenRegatta() throws Exception {
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
User user = new UserImpl("max", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null);
//when(securityService.getCurrentUser()).thenReturn(user);
setUser(user);
Regatta regatta = racingEventService.getRegattaByName(openRegattaName);
Response response = regattasResource.createAndAddCompetitor(openRegattaName, boatClassName, null, "GER", null, null, null,
"Max Mustermann", null, deviceUuid, secret);
assertTrue(response.getStatus() + ": " + response.getEntity().toString(),
response.getStatus() == Status.OK.getStatusCode());
assertTrue(regattasResource.getService() == racingEventService);
regatta = racingEventService.getRegattaByName(openRegattaName);
testResponseOfOpenRegattaCompetitorRegistration(regatta);
}
private void testResponseOfOpenRegattaCompetitorRegistration(final Regatta regatta) {
Iterator<Competitor> cit = regatta.getAllCompetitors().iterator();
Competitor readCompetitor = cit.next();
assertNotNull(readCompetitor);
// should have one device registration event of type RegattaLogDeviceCompetitorMappingEventImpl...
assertEquals(1, regatta.getRegattaLog().getUnrevokedEvents().stream()
.filter(e -> e instanceof RegattaLogDeviceCompetitorMappingEvent).count());
// ...with requested device id
assertEquals(deviceUuid,
((RegattaLogDeviceCompetitorMappingEvent) regatta.getRegattaLog().getUnrevokedEvents().stream()
.filter(e -> e instanceof RegattaLogDeviceCompetitorMappingEvent).findFirst().get()).getDevice()
.getStringRepresentation());
// Same deviceUuid for registration should fail
Response response = regattasResource.createAndAddCompetitor(regatta.getName(), boatClassName, null, "GER", null,
null, null, "Max Mustermann", null, deviceUuid, secret);
assertTrue("Reponse http status should be forbidden (403) but is " + response.getStatus(),
response.getStatus() == Status.FORBIDDEN.getStatusCode());
}
}
@@ -34,7 +34,7 @@ public abstract class AbstractSailingServerResource {
return resourceContext;
}
protected <T> T getService(Class<T> clazz) {
public <T> T getService(Class<T> clazz) {
BundleContext context = (BundleContext) servletContext
.getAttribute(RestServletContainer.OSGI_RFC66_WEBBUNDLE_BUNDLECONTEXT_NAME);
ServiceTracker<T, T> tracker = new ServiceTracker<T, T>(context, clazz, null);
@@ -38,6 +38,7 @@ import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
@@ -47,6 +48,7 @@ import com.sap.sailing.domain.base.Event;
import com.sap.sailing.domain.base.EventBase;
import com.sap.sailing.domain.base.RaceColumnInSeries;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.NotFoundException;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.RegattaName;
@@ -123,7 +125,8 @@ public class EventsResource extends AbstractSailingServerResource {
@FormParam("createregatta") String createRegattaParam,
@FormParam("boatclassname") String boatClassNameParam,
@FormParam("numberofraces") String numberOfRacesParam,
@FormParam("canBoatsOfCompetitorsChangePerRace") boolean canBoatsOfCompetitorsChangePerRace) throws ParseException, NotFoundException,
@FormParam("canBoatsOfCompetitorsChangePerRace") boolean canBoatsOfCompetitorsChangePerRace,
@FormParam("competitorRegistrationType") String competitorRegistrationType) throws ParseException, NotFoundException,
NumberFormatException, IOException, org.json.simple.parser.ParseException, InvalidDateException {
final Response response;
if (venueNameParam == null && (venueLat == null || venueLng == null)) {
@@ -133,7 +136,7 @@ public class EventsResource extends AbstractSailingServerResource {
startDateAsMillis, endDateParam, endDateAsMillis, venueNameParam,
/* venue latitude */ venueLat, /* venue longitude */ venueLng, isPublicParam, officialWebsiteURLParam,
baseURLParam, leaderboardGroupIdsListParam, createLeaderboardGroupParam, createRegattaParam,
boatClassNameParam, numberOfRacesParam, canBoatsOfCompetitorsChangePerRace);
boatClassNameParam, numberOfRacesParam, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType);
final JSONObject jsonResponse = new JSONObject();
jsonResponse.put("eventid", eventAndLeaderboardGroupAndLeaderboard.getA().getId().toString());
jsonResponse.put("eventname", eventAndLeaderboardGroupAndLeaderboard.getA().getName());
@@ -317,7 +320,7 @@ public class EventsResource extends AbstractSailingServerResource {
String scoringSchemeParam, UUID courseAreaId, String buoyZoneRadiusInHullLengthsParam,
String useStartTimeInterferenceParam, String controlTrackingFromStartAndFinishTimesParam,
String rankingMetricParam, List<Integer> leaderboardDiscardThresholdsParam, String numberOfRacesParam,
boolean canBoatsOfCompetitorsChangePerRace) throws ParseException, NotFoundException {
boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType) throws ParseException, NotFoundException {
boolean controlTrackingFromStartAndFinishTimes = controlTrackingFromStartAndFinishTimesParam == null ? false
: Boolean.parseBoolean(controlTrackingFromStartAndFinishTimesParam);
boolean useStartTimeInterference = useStartTimeInterferenceParam == null ? true
@@ -349,7 +352,7 @@ public class EventsResource extends AbstractSailingServerResource {
@Override
public Regatta run() throws Exception {
return getService().apply(new AddSpecificRegatta(regattaName, boatClassName,
canBoatsOfCompetitorsChangePerRace, null, null, regattaId, regattaCreationParametersDTO,
canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, null, null, null, regattaId, regattaCreationParametersDTO,
/* isPersistent */ true, scoringScheme, courseAreaId, buoyZoneRadiusInHullLengths,
useStartTimeInterference, controlTrackingFromStartAndFinishTimes, rankingMetric));
}
@@ -373,7 +376,8 @@ public class EventsResource extends AbstractSailingServerResource {
String venueNameParam, String venueLat, String venueLng, String isPublicParam,
String officialWebsiteURLParam, String baseURLParam, List<String> leaderboardGroupIdsListParam,
String createLeaderboardGroupParam, String createRegattaParam, String boatClassName,
String numberOfRacesParam, boolean canBoatsOfCompetitorsChangePerRace) throws ParseException, NotFoundException, NumberFormatException, IOException,
String numberOfRacesParam, boolean canBoatsOfCompetitorsChangePerRace,
String competitorRegistrationTypeString) throws ParseException, NotFoundException, NumberFormatException, IOException,
org.json.simple.parser.ParseException, InvalidDateException {
boolean isPublic = isPublicParam == null ? false : Boolean.parseBoolean(isPublicParam);
boolean createRegatta = createRegattaParam == null ? true : Boolean.parseBoolean(createRegattaParam);
@@ -415,13 +419,20 @@ public class EventsResource extends AbstractSailingServerResource {
} else {
leaderboardGroup = null;
}
final CompetitorRegistrationType competitorRegistrationType;
try {
competitorRegistrationType = CompetitorRegistrationType.valueOfOrDefault(competitorRegistrationTypeString, /* failForUnknown */ true);
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException(ExceptionManager.incorrectParameterValue(competitorRegistrationTypeString,
StringUtils.join(CompetitorRegistrationType.values(), ", ")));
}
final RegattaLeaderboard leaderboard;
if (createRegatta) {
leaderboard = validateAndCreateRegatta(event.getName(), boatClassName,
/* scoringSchemeParam */ null, courseArea.getId(), /* buoyZoneRadiusInHullLengthsParam */ null,
/* useStartTimeInterferenceParam */ null, /* controlTrackingFromStartAndFinishTimesParam */ null,
/* rankingMetricParam */ null, /* leaderboardDiscardThresholdsParam */ null,
numberOfRacesParam, canBoatsOfCompetitorsChangePerRace);
numberOfRacesParam, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType);
if (leaderboardGroup != null) {
getService().apply(new UpdateLeaderboardGroup(leaderboardGroup.getName(), leaderboardGroup.getName(),
leaderboardGroup.getDescription(), leaderboardGroup.getDisplayName(),
@@ -36,6 +36,11 @@ import org.json.simple.JSONValue;
import org.json.simple.parser.ParseException;
import com.sap.sailing.datamining.SailingPredefinedQueries;
import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl;
import com.sap.sailing.domain.abstractlog.regatta.RegattaLog;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceCompetitorMappingEvent;
import com.sap.sailing.domain.abstractlog.regatta.events.RegattaLogDeviceMappingEventImpl;
import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogDeviceCompetitorMappingEventImpl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CompetitorWithBoat;
import com.sap.sailing.domain.base.Course;
@@ -49,6 +54,7 @@ import com.sap.sailing.domain.base.impl.BoatImpl;
import com.sap.sailing.domain.base.impl.DynamicBoat;
import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.SpeedWithBearing;
@@ -61,6 +67,7 @@ import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.racelogtracking.impl.SmartphoneUUIDIdentifierImpl;
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
import com.sap.sailing.domain.tracking.DynamicTrackedRace;
import com.sap.sailing.domain.tracking.GPSFixTrack;
@@ -124,7 +131,6 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
import com.sap.sse.common.impl.RGBColor;
import com.sap.sse.common.util.RoundingUtil;
import com.sap.sse.datamining.shared.impl.PredefinedQueryIdentifier;
import com.sap.sse.security.SecurityService;
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
import com.sap.sse.security.shared.User;
@@ -146,6 +152,21 @@ public class RegattasResource extends AbstractSailingServerResource {
.type(MediaType.TEXT_PLAIN).build();
}
private Response getBadRegattaRegistrationTypeErrorResponse(String regattaName) {
return Response.status(Status.FORBIDDEN).entity("Self-registration to regatta '" + StringEscapeUtils.escapeHtml(regattaName) + "' is not allowed.")
.type(MediaType.TEXT_PLAIN).build();
}
private Response getBadRegattaRegistrationValidationErrorResponse(String errorText) {
return Response.status(Status.BAD_REQUEST).entity(StringEscapeUtils.escapeHtml(errorText) + ".")
.type(MediaType.TEXT_PLAIN).build();
}
private Response getAlreadyRegisteredDeviceErrorResponse(String regattaName, String deviceId) {
return Response.status(Status.FORBIDDEN).entity("Device is already registered to regatta '" + StringEscapeUtils.escapeHtml(regattaName) + "'.")
.type(MediaType.TEXT_PLAIN).build();
}
private Response getBadBoatClassResponse(String boatClassName) {
return Response.status(Status.NOT_FOUND).entity("Could not use a boat class with name '" + StringEscapeUtils.escapeHtml(boatClassName) + "'.")
.type(MediaType.TEXT_PLAIN).build();
@@ -328,44 +349,100 @@ public class RegattasResource extends AbstractSailingServerResource {
private Response createAndAddCompetitor(String regattaName,
String nationalityThreeLetterIOCCode, Double timeOnTimeFactor,
Long timeOnDistanceAllowancePerNauticalMileAsMillis, String searchTag, String competitorName,
String competitorEmail, Function<String, DynamicBoat> boatObtainer) {
String competitorEmail, Function<String, DynamicBoat> boatObtainer, String deviceUuid,
String registrationLinkSecret) {
final Subject subject = SecurityUtils.getSubject();
final User user = getSecurityService().getCurrentUser();
Response response;
Regatta regatta = findRegattaByName(regattaName);
if (regatta == null) {
response = getBadRegattaErrorResponse(regattaName);
} else {
getSecurityService().checkCurrentUserUpdatePermission(regatta);
final User user = getService(SecurityService.class).getCurrentUser();
final String shortName;
final String name;
if (competitorName != null) {
name = competitorName;
shortName = competitorName;
boolean registerCompetitor = false;
boolean checkInCompetitor = false;
final String eCompetitorName, eCompetitorShortName, eCompetitorEmail;
if (subject.isAuthenticated() && getSecurityService().hasCurrentUserUpdatePermission(regatta)) {
// case 1: admin or regatta owner is registering a competitor
// TODO: this could be also a selfregistration? perhaps decide about deviceUuid
registerCompetitor = true;
eCompetitorName = competitorName;
eCompetitorShortName = competitorName;
eCompetitorEmail = competitorEmail;
} else if (subject.isAuthenticated() && regatta.getCompetitorRegistrationType().isOpen()) {
// case 2: "unprivileged" authenticated user is registering
if (!regatta.getRegistrationLinkSecret().equals(registrationLinkSecret)) {
return getBadRegattaRegistrationTypeErrorResponse(regattaName);
}
registerCompetitor = true;
if (user == null) {
return getBadRegattaRegistrationValidationErrorResponse("invalid user (missing)");
}
eCompetitorName = competitorName != null ? competitorName : user.getFullName();
eCompetitorShortName = user.getName();
eCompetitorEmail = competitorEmail != null ? competitorEmail : user.getEmail();
// case 2.1: with device
checkInCompetitor = deviceUuid != null;
} else if (deviceUuid != null && regatta.getCompetitorRegistrationType().isOpen()) {
// case 3: unauthorized with device (check secret)
if (!regatta.getRegistrationLinkSecret().equals(registrationLinkSecret)) {
return getBadRegattaRegistrationTypeErrorResponse(regattaName);
}
registerCompetitor = true;
checkInCompetitor = true;
eCompetitorName = competitorName;
eCompetitorShortName = competitorName;
eCompetitorEmail = competitorEmail;
} else {
shortName = user.getName();
name = user.getFullName() == null ? shortName : user.getFullName();
return getBadRegattaRegistrationTypeErrorResponse(regattaName);
}
final String email;
if (competitorEmail != null) {
email = competitorEmail;
// Check regattalog if device has been registered to this regatta already
boolean duplicateDeviceId = false;
if (checkInCompetitor) {
RegattaLog regattaLog = regatta.getRegattaLog();
duplicateDeviceId = regattaLog.getUnrevokedEvents().stream().anyMatch(event -> {
if (event instanceof RegattaLogDeviceCompetitorMappingEvent) {
return deviceUuid.equals(
((RegattaLogDeviceCompetitorMappingEvent) event).getDevice().getStringRepresentation());
} else {
return false;
}
});
}
if (duplicateDeviceId) {
response = this.getAlreadyRegisteredDeviceErrorResponse(regattaName, deviceUuid);
} else if (eCompetitorName == null) {
return getBadRegattaRegistrationValidationErrorResponse("missing competitorName");
} else if (registerCompetitor) {
DynamicBoat boat = boatObtainer.apply(eCompetitorShortName);
final TeamImpl team = new TeamImpl(eCompetitorShortName,
Collections.singleton(new PersonImpl(eCompetitorName,
getService().getBaseDomainFactory()
.getOrCreateNationality(nationalityThreeLetterIOCCode),
/* dateOfBirth */ null, /* description */ null)),
/* coach */ null);
final CompetitorWithBoat competitor = getService().getCompetitorAndBoatStore()
.getOrCreateCompetitorWithBoat(UUID.randomUUID(), eCompetitorName, /* shortName */ eCompetitorShortName,
/* displayColor */ null, eCompetitorEmail, /* flagImageURI */ null, team, timeOnTimeFactor,
timeOnDistanceAllowancePerNauticalMileAsMillis == null ? null
: new MillisecondsDurationImpl(timeOnDistanceAllowancePerNauticalMileAsMillis),
searchTag, boat);
regatta.registerCompetitor(competitor);
response = Response.ok(CompetitorJsonSerializer.create().serialize(competitor).toJSONString())
.header("Content-Type", MediaType.APPLICATION_JSON + ";charset=UTF-8").build();
if (checkInCompetitor) {
final DeviceIdentifier device = new SmartphoneUUIDIdentifierImpl(UUID.fromString(deviceUuid));
final TimePoint now = MillisecondsTimePoint.now();
RegattaLogDeviceMappingEventImpl<Competitor> event = new RegattaLogDeviceCompetitorMappingEventImpl(
now, now, new LogEventAuthorImpl(eCompetitorName, 0), UUID.randomUUID(), competitor, device, now,
/* to */ null);
regatta.getRegattaLog().add(event);
}
} else {
email = user.getEmail();
response = getBadRegattaRegistrationTypeErrorResponse(regattaName);
}
DynamicBoat boat = boatObtainer.apply(shortName);
final TeamImpl team = new TeamImpl(shortName,
Collections.singleton(new PersonImpl(name,
getService().getBaseDomainFactory().getOrCreateNationality(nationalityThreeLetterIOCCode),
/* dateOfBirth */ null, /* description */ null)),
/* coach */ null);
final CompetitorWithBoat competitor = getService().getCompetitorAndBoatStore()
.getOrCreateCompetitorWithBoat(UUID.randomUUID(), name, /* shortName */ null,
/* displayColor */ null, email, /* flagImageURI */ null, team, timeOnTimeFactor,
timeOnDistanceAllowancePerNauticalMileAsMillis == null ? null
: new MillisecondsDurationImpl(timeOnDistanceAllowancePerNauticalMileAsMillis),
searchTag, boat);
regatta.registerCompetitor(competitor);
response = Response.ok(CompetitorJsonSerializer.create().serialize(competitor).toJSONString())
.header("Content-Type", MediaType.APPLICATION_JSON + ";charset=UTF-8").build();
}
return response;
}
@@ -379,7 +456,8 @@ public class RegattasResource extends AbstractSailingServerResource {
@QueryParam("timeontimefactor") Double timeOnTimeFactor,
@QueryParam("timeondistanceallowancepernauticalmileasmillis") Long timeOnDistanceAllowancePerNauticalMileAsMillis,
@QueryParam("searchtag") String searchTag, @QueryParam("competitorName") String competitorName,
@QueryParam("competitorEmail") String competitorEmail) {
@QueryParam("competitorEmail") String competitorEmail, @QueryParam("deviceUuid") String deviceUuid,
@QueryParam("secret") String registrationLinkSecret) {
Response response;
if (boatClassName == null) {
response = getBadBoatClassResponse(boatClassName);
@@ -387,7 +465,8 @@ public class RegattasResource extends AbstractSailingServerResource {
response = createAndAddCompetitor(regattaName, nationalityThreeLetterIOCCode, timeOnTimeFactor,
timeOnDistanceAllowancePerNauticalMileAsMillis, searchTag, competitorName, competitorEmail,
shortName -> new BoatImpl(UUID.randomUUID(), shortName, getService().getBaseDomainFactory()
.getOrCreateBoatClass(boatClassName, /* typicallyStartsUpwind */ true), sailId));
.getOrCreateBoatClass(boatClassName, /* typicallyStartsUpwind */ true), sailId), deviceUuid,
registrationLinkSecret);
}
return response;
}
@@ -401,7 +480,8 @@ public class RegattasResource extends AbstractSailingServerResource {
@QueryParam("timeontimefactor") Double timeOnTimeFactor,
@QueryParam("timeondistanceallowancepernauticalmileasmillis") Long timeOnDistanceAllowancePerNauticalMileAsMillis,
@QueryParam("searchtag") String searchTag, @QueryParam("competitorName") String competitorName,
@QueryParam("competitorEmail") String competitorEmail) {
@QueryParam("competitorEmail") String competitorEmail, @QueryParam("deviceUuid") String deviceUuid,
@QueryParam("secret") String registrationLinkSecret) {
Response response;
DynamicBoat boat = getService().getCompetitorAndBoatStore().getExistingBoatByIdAsString(boatId);
if (boat == null) {
@@ -409,7 +489,7 @@ public class RegattasResource extends AbstractSailingServerResource {
} else {
response = createAndAddCompetitor(regattaName, nationalityThreeLetterIOCCode, timeOnTimeFactor,
timeOnDistanceAllowancePerNauticalMileAsMillis, searchTag, competitorName, competitorEmail,
t -> boat);
t -> boat, deviceUuid, registrationLinkSecret);
}
return response;
}
@@ -40,6 +40,7 @@ import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.Placemark;
import com.sap.sailing.domain.common.Position;
@@ -625,10 +626,10 @@ public class ExpeditionAllInOneImporter {
/*hasSplitFleetContiguousScoring*/ false, /*maximumNumberOfDiscards*/ null));
final RegattaCreationParametersDTO regattaCreationParameters = new RegattaCreationParametersDTO(seriesCreationParameters);
regatta = service.apply(new AddSpecificRegatta(regattaNameAndleaderboardName, boatClassName,
/* can boats of competitors change */ false,
/* start date */ null, /* end date */ null, UUID.randomUUID(),
regattaCreationParameters, true, scoringScheme, courseAreaId, buoyZoneRadiusInHullLengths, true,
false, rankingMetric));
/* can boats of competitors change */ false, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* start date */ null, /* end date */ null, UUID.randomUUID(),
regattaCreationParameters, true, scoringScheme, courseAreaId, buoyZoneRadiusInHullLengths, true, false,
rankingMetric));
this.ensureBoatClassDetermination(regatta);
service.apply(new AddColumnToSeries(regattaIdentifier, seriesName, raceColumnName));
return regatta;
@@ -15,6 +15,7 @@ import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogRaceStatusEvent;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.dto.FleetDTO;
@@ -102,11 +103,13 @@ public abstract class AbstractLogReplicationTest<LogT extends AbstractLog<EventT
seriesCreationParameters.put(seriesName, creationParametersForDefaultSeries);
// 1. Install some race column on master...
RegattaCreationParametersDTO regattaCreationParams = new RegattaCreationParametersDTO(seriesCreationParameters);
AddSpecificRegatta addRegattaOperation = new AddSpecificRegatta(regattaName, boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* regatta ID */ UUID.randomUUID(), regattaCreationParams, /* persistent */ true,
new LowPoint(), /* default course area ID */ UUID.randomUUID(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, RankingMetrics.ONE_DESIGN);
AddSpecificRegatta addRegattaOperation = new AddSpecificRegatta(regattaName, boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null,
/* regatta ID */ UUID.randomUUID(), regattaCreationParams, /* persistent */ true, new LowPoint(),
/* default course area ID */ UUID.randomUUID(), /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
RankingMetrics.ONE_DESIGN);
return master.apply(addRegattaOperation);
}
@@ -31,6 +31,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -74,8 +75,10 @@ public class BoatReplicationTest extends AbstractServerReplicationTest {
Integer regattaId = 12345;
Iterable<Series> series = Collections.emptyList();
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, regattaId, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, regattaId, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Iterable<Waypoint> emptyWaypointList = Collections.emptyList();
final String boatName = "Kielboat Harry";
@@ -34,6 +34,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -82,8 +83,10 @@ public class CompetitorReplicationTest extends AbstractServerReplicationTest {
URI flagImageURI = new URI("http://www.sapsailing.com");
Iterable<Series> series = Collections.emptyList();
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, regattaId, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, regattaId, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Iterable<Waypoint> emptyWaypointList = Collections.emptyList();
final String competitorName = "Der mit dem Kiel zieht";
@@ -40,6 +40,7 @@ import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
@@ -125,9 +126,11 @@ public class InitialLoadReplicationObjectIdentityTest extends AbstractServerRepl
final String baseEventName = "Kiel Week 2012";
final String boatClassName = "49er";
final Iterable<Series> series = Collections.emptyList();
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, UUID.randomUUID(), series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true,
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName),
boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(), series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric.CONSTRUCTOR);
assertNotNull(master.getRegatta(masterRegatta.getRegattaIdentifier()));
assertTrue(master.getAllRegattas().iterator().hasNext());
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.base.configuration.impl.RegattaConfigurationImpl;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -44,11 +45,13 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
final String boatClassName = "49er";
final Iterable<Series> series = Collections.emptyList();
final UUID regattaId = UUID.randomUUID();
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, regattaId, series,
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName),
boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, regattaId, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Thread.sleep(1000);
Regatta replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
@@ -70,14 +73,18 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
final Iterable<Series> series = Collections.emptyList();
final UUID regattaId1 = UUID.randomUUID();
final UUID regattaId2 = UUID.randomUUID();
Regatta masterRegatta1 = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClass1Name), boatClass1Name,
canBoatsOfCompetitorsChangePerRaceRegatta1, /*startDate*/ null, /*endDate*/ null, regattaId1, series,
Regatta masterRegatta1 = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClass1Name),
boatClass1Name, canBoatsOfCompetitorsChangePerRaceRegatta1, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, regattaId1, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Regatta masterRegatta2 = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClass2Name), boatClass2Name,
canBoatsOfCompetitorsChangePerRaceRegatta2, /*startDate*/ null, /*endDate*/ null, regattaId2, series,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Regatta masterRegatta2 = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClass2Name),
boatClass2Name, canBoatsOfCompetitorsChangePerRaceRegatta2, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, regattaId2, series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Thread.sleep(1000);
@@ -104,14 +111,15 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
UUID currentCourseAreaId = null;
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName("Kiel Week 2012", "49er"), "49er",
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED, /* registrationLinkSecret */ null, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), Collections.<Series>emptyList(),
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), currentCourseAreaId,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
// Test for 'null'
master.apply(new UpdateSpecificRegatta(masterRegatta.getRegattaIdentifier(), /*startDate*/ null, /*endDate*/ null,
currentCourseAreaId, null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false));
currentCourseAreaId, null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
/* registrationLinkSecret*/ null));
Thread.sleep(1000);
replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -120,7 +128,8 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
// Test for 'alpha'
currentCourseAreaId = alphaCourseAreaId;
master.apply(new UpdateSpecificRegatta(masterRegatta.getRegattaIdentifier(), /*startDate*/ null, /*endDate*/ null,
currentCourseAreaId, null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false));
currentCourseAreaId, null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
/* registrationLinkSecret*/ null));
Thread.sleep(1000);
replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -129,7 +138,8 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
// Test for 'tv'
currentCourseAreaId = tvCourseAreaId;
master.apply(new UpdateSpecificRegatta(masterRegatta.getRegattaIdentifier(), /*startDate*/ null, /*endDate*/ null,
currentCourseAreaId, null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false));
currentCourseAreaId, null, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
/* registrationLinkSecret*/ null));
Thread.sleep(1000);
replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -138,7 +148,8 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
// Test back to 'null'
currentCourseAreaId = null;
master.apply(new UpdateSpecificRegatta(masterRegatta.getRegattaIdentifier(), /*startDate*/ null, /*endDate*/ null, currentCourseAreaId, null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false));
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
/* registrationLinkSecret*/ null));
Thread.sleep(1000);
replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -156,15 +167,18 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
master.addCourseAreas(event.getId(), new String[] {"Alpha"}, new UUID[] {alphaCourseAreaId});
UUID currentCourseAreaId = null;
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName("RR", "49er"), "49er",
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), Collections.<Series>emptyList(),
true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), currentCourseAreaId,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName("RR", "49er"), "49er",
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
Collections.<Series> emptyList(), true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), currentCourseAreaId,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
// Test for 'null'
master.apply(new UpdateSpecificRegatta(masterRegatta.getRegattaIdentifier(), /*startDate*/ null, /*endDate*/ null, currentCourseAreaId, null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false));
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
/* registrationLinkSecret*/ null));
Thread.sleep(1000);
replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -174,7 +188,8 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
RegattaConfigurationImpl config = new RegattaConfigurationImpl();
config.setDefaultCourseDesignerMode(CourseDesignerMode.BY_MARKS);
master.apply(new UpdateSpecificRegatta(masterRegatta.getRegattaIdentifier(), /*startDate*/ null, /*endDate*/ null, currentCourseAreaId, config,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false));
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
/* registrationLinkSecret*/ null));
Thread.sleep(1000);
replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -205,10 +220,13 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
Arrays.asList(new Fleet[] { new FleetImpl("Gold", 1), new FleetImpl("Silver", 2) }), emptyRaceColumnNamesList, /* trackedRegattaRegistry */ null);
Series medal = new SeriesImpl("Medal", /* isMedal */ true, /* isFleetsCanRunInParallel */ true,
Arrays.asList(new Fleet[] { new FleetImpl("Medal") }), emptyRaceColumnNamesList, /* trackedRegattaRegistry */ null);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), Arrays.asList(new Series[] { qualification, finals, medal }), /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName),
boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
Arrays.asList(new Series[] { qualification, finals, medal }), /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Thread.sleep(1000);
Regatta replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -242,10 +260,13 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
final List<String> emptyRaceColumnNamesList = Collections.emptyList();
Series qualification = new SeriesImpl("Qualification", /* isMedal */ false, /* isFleetsCanRunInParallel */ true,
Arrays.asList(new Fleet[] { new FleetImpl("Yellow"), new FleetImpl("Blue") }), emptyRaceColumnNamesList, /* trackedRegattaRegistry */ null);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), Arrays.asList(new Series[] { qualification }), /* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName),
boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
Arrays.asList(new Series[] { qualification }), /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Thread.sleep(1000);
Regatta replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -287,12 +308,13 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
final List<String> emptyRaceColumnNamesList = Collections.emptyList();
Series qualification = new SeriesImpl("Qualification", /* isMedal */ false, /* isFleetsCanRunInParallel */ true,
Arrays.asList(new Fleet[] { new FleetImpl("Yellow"), new FleetImpl("Blue") }), emptyRaceColumnNamesList, /* trackedRegattaRegistry */ null);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), Arrays.asList(new Series[] { qualification }), /* persistent */ true,
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(baseEventName, boatClassName),
boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
Arrays.asList(new Series[] { qualification }), /* persistent */ true,
DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), null,
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
/* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Thread.sleep(1000);
Regatta replicatedRegatta = replica.getRegatta(new RegattaName(masterRegatta.getName()));
assertNotNull(replicatedRegatta);
@@ -326,10 +348,12 @@ public class RegattaReplicationTest extends AbstractServerReplicationTest {
Event masterEvent = master.addEvent(eventName, /* eventDescription */ null, eventStartDate, eventEndDate, venueName, isPublic, UUID.randomUUID());
CourseArea masterCourseArea = master.addCourseAreas(masterEvent.getId(), new String[] {courseArea}, new UUID[] {UUID.randomUUID()})[0];
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(eventName, boatClassName), boatClassName,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, UUID.randomUUID(), series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), masterCourseArea.getId(),
/*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Regatta masterRegatta = master.createRegatta(RegattaImpl.getDefaultName(eventName, boatClassName),
boatClassName, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(), series,
/* persistent */ true, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT),
masterCourseArea.getId(), /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
Thread.sleep(1000);
Event replicatedEvent = replica.getEvent(masterEvent.getId());
assertNotNull(replicatedEvent);
@@ -19,6 +19,7 @@ import org.junit.Test;
import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.dto.FleetDTO;
@@ -97,6 +98,7 @@ public class TrackRaceBoatCompetitorMetadataReplicationTest extends AbstractServ
private void startTrackingOnMaster() throws Exception {
final Regatta regatta = master.createRegatta("Test regatta", "J/70",
/* canBoatsOfCompetitorsChangePerRace==true because it's a league race we're using for this test */ true,
CompetitorRegistrationType.CLOSED, /* registrationLinkSecret */ null,
/* startDate */ null, /* endDate */ null, UUID.randomUUID(),
/* start with no series */ Collections.emptySet(),
/* persistent */ true, new LowPoint(), /* defaultCourseAreaId */ UUID.randomUUID(),
@@ -33,6 +33,7 @@ import com.sap.sailing.domain.base.impl.KilometersPerHourSpeedWithBearingImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
@@ -70,8 +71,8 @@ public class StatisticsTest {
@Before
public void setUp() {
regatta = new DynamicTrackedRegattaImpl(new RegattaImpl(EmptyRaceLogStore.INSTANCE,
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, false,
/* startDate */ null, /* endDate */null, null, null, "a", null));
EmptyRegattaLogStore.INSTANCE, RegattaImpl.getDefaultName("regatta", boatClass.getName()), boatClass, false,
CompetitorRegistrationType.CLOSED, /* startDate */ null, /* endDate */null, null, null, "a", null));
final Course course = new CourseImpl("course",
Arrays.asList(new Waypoint[] { waypoint1, waypoint2, waypoint3 }));
@@ -81,6 +81,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.CourseDesignerMode;
import com.sap.sailing.domain.common.DeviceIdentifier;
import com.sap.sailing.domain.common.MasterDataImportObjectCreationCount;
@@ -231,8 +232,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null, regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
@@ -554,9 +557,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
}
@@ -710,9 +714,10 @@ public class MasterDataImportTest {
series.add(new SeriesImpl("testSeries", false, /* isFleetsCanRunInParallel */ true, fleets, emptyRaceColumnNamesList, sourceService));
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(RegattaImpl.getDefaultName("testRegatta", "29er"), "29er",
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
}
@@ -874,9 +879,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
@@ -1033,9 +1039,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
}
@@ -1145,9 +1152,11 @@ public class MasterDataImportTest {
destService));
Regatta regattaNotToOverride = destService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null,
regattaUUID, seriesNotToOverride, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */null, regattaUUID,
seriesNotToOverride, true, new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
for (String name : raceColumnNamesNotToOverride) {
seriesNotToOverride.get(0).addRaceColumn(name, destService);
@@ -1234,9 +1243,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */ true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
@@ -1343,9 +1353,11 @@ public class MasterDataImportTest {
destService));
Regatta regattaToOverride = destService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null,
regattaUUID, seriesToOverride, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */null, regattaUUID,
seriesToOverride, true, new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
for (String name : raceColumnNamesToOverride) {
seriesToOverride.get(0).addRaceColumn(name, destService);
@@ -1452,10 +1464,12 @@ public class MasterDataImportTest {
new UUID[] { UUID.randomUUID() })[0];
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME),
TEST_BOAT_CLASS_NAME, /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */
null, /* endDate */null, UUID.randomUUID(), new ArrayList<Series>(), true, new LowPoint(),
defaultCourseArea.getId(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
defaultCourseArea.getId(), /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
// Let's use the setters directly because we are not testing replication
RegattaConfigurationImpl configuration = new RegattaConfigurationImpl();
configuration.setDefaultCourseDesignerMode(CourseDesignerMode.BY_MAP);
@@ -1536,10 +1550,11 @@ public class MasterDataImportTest {
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(),
defaultCourseArea.getId(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), defaultCourseArea.getId(), /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
}
@@ -1670,9 +1685,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
@@ -1913,8 +1929,10 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null, regattaUUID, series, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, series, true,
new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0, /* useStartTimeInference */true,
/* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
series.get(0).addRaceColumn(name, sourceService);
@@ -2142,9 +2160,11 @@ public class MasterDataImportTest {
UUID regattaUUID = UUID.randomUUID();
Regatta regatta = sourceService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */ null, /* endDate */null,
regattaUUID, seriesOnSource, true, new LowPoint(), courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0,
/* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */null, regattaUUID, seriesOnSource,
true, new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
for (String name : raceColumnNames) {
seriesOnSource.get(0).addRaceColumn(name, sourceService);
}
@@ -2269,9 +2289,11 @@ public class MasterDataImportTest {
Regatta regattaOnTarget = destService.createRegatta(
RegattaImpl.getDefaultName(TEST_REGATTA_NAME, TEST_BOAT_CLASS_NAME), TEST_BOAT_CLASS_NAME,
/* canBoatsOfCompetitorsChangePerRace */ true, /* startDate */null, /* endDate */null,
regattaUUID, seriesOnTarget, true, new LowPoint(),
courseAreaUUID, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */null, /* endDate */null, regattaUUID, seriesOnTarget,
true, new LowPoint(), courseAreaUUID, /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false,
OneDesignRankingMetric::new);
raceColumnOnTarget.setTrackedRace(defaultFleetOnTarget, new DummyTrackedRace(raceId, createCompetitorsAndBoatsMap(boatClass, competitors),
regattaOnTarget, null, sourceService.getWindStore()));
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.regattalog.impl.EmptyRegattaLogStore;
@@ -73,7 +74,8 @@ public class RaceTrackerStartStopTest {
boatClass = new BoatClassImpl(BOATCLASSNAME, /* typicallyStartsUpwind */ true);
regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName(EVENTNAME, boatClass.getName()), boatClass,
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */
null, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), UUID.randomUUID(), null);
racingEventService.getRegattasByName().put(EVENTNAME, regatta);
TrackedRegatta trackedRegatta1 = racingEventService.getOrCreateTrackedRegatta(regatta);
@@ -32,6 +32,7 @@ import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.ScoringSchemeType;
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
@@ -89,7 +90,7 @@ public class RemoveLeaderboardTest {
boatClass = new BoatClassImpl(BOATCLASSNAME, /* typicallyStartsUpwind */ true);
regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE,
RegattaImpl.getDefaultName(EVENTNAME, boatClass.getName()), boatClass, /* canBoatsOfCompetitorsChangePerRace*/ true,
RegattaImpl.getDefaultName(EVENTNAME, boatClass.getName()), boatClass, /* canBoatsOfCompetitorsChangePerRace*/ true, CompetitorRegistrationType.CLOSED,
/*startDate*/ null, /*endDate*/ null, /* trackedRegattaRegistry */
null, DomainFactory.INSTANCE.createScoringScheme(ScoringSchemeType.LOW_POINT), UUID.randomUUID(), null);
TrackedRegatta trackedRegatta1 = server.getOrCreateTrackedRegatta(regatta);
@@ -33,6 +33,7 @@ import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.RegattaName;
import com.sap.sailing.domain.common.dto.FleetDTO;
@@ -138,19 +139,25 @@ public class SearchServiceTest {
new SeriesCreationParametersDTO(Collections.singletonList(new FleetDTO("Default", /* order */-1, Color.RED)),
/* medal */false, /* fleetsCanRunInParallel */ true, /* startsWithZero */false, /* firstColumnIsNonDiscardableCarryForward */false,
/* discardingThresholds */null, /* hasSplitFleetContiguousScoring */false, /* maximumNumberOfDiscards */ null));
pfingstbusch29er = server.apply(new AddSpecificRegatta(RegattaImpl.getDefaultName("Pfingstbusch", "29er"), "29er",
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, UUID.randomUUID(),
pfingstbusch29er = server.apply(new AddSpecificRegatta(RegattaImpl.getDefaultName("Pfingstbusch", "29er"),
"29er", /* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
new RegattaCreationParametersDTO(seriesCreationParams), /* persistent */
true, new LowPoint(), kielAlpha.getId(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, RankingMetrics.ONE_DESIGN));
true, new LowPoint(), kielAlpha.getId(), /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
RankingMetrics.ONE_DESIGN));
server.apply(new AddColumnToSeries(pfingstbusch29er.getRegattaIdentifier(), "Default", "R1"));
server.apply(new AddColumnToSeries(pfingstbusch29er.getRegattaIdentifier(), "Default", "R2"));
server.apply(new AddColumnToSeries(pfingstbusch29er.getRegattaIdentifier(), "Default", "R3"));
RegattaLeaderboard pfingstbusch29erLeaderboard = server.apply(new CreateRegattaLeaderboard(pfingstbusch29er.getRegattaIdentifier(),
/* leaderboardDisplayName */ null, /* discardThresholds */ new int[0]));
pfingstbusch470 = server.apply(new AddSpecificRegatta(RegattaImpl.getDefaultName("Pfingstbusch", "470"), "470",
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null,
UUID.randomUUID(), new RegattaCreationParametersDTO(seriesCreationParams), /* persistent */
true, new LowPoint(), kielBravo.getId(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, RankingMetrics.ONE_DESIGN));
pfingstbusch470 = server.apply(new AddSpecificRegatta(RegattaImpl.getDefaultName("Pfingstbusch", "470"), "470",
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
new RegattaCreationParametersDTO(seriesCreationParams), /* persistent */
true, new LowPoint(), kielBravo.getId(), /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
RankingMetrics.ONE_DESIGN));
server.apply(new AddColumnToSeries(pfingstbusch470.getRegattaIdentifier(), "Default", "R1"));
server.apply(new AddColumnToSeries(pfingstbusch470.getRegattaIdentifier(), "Default", "R2"));
server.apply(new AddColumnToSeries(pfingstbusch470.getRegattaIdentifier(), "Default", "R3"));
@@ -172,10 +179,13 @@ public class SearchServiceTest {
flensburg = aalEvent.getVenue();
final CourseAreaImpl flensburgStandard = new CourseAreaImpl("Standard", UUID.randomUUID());
flensburg.addCourseArea(flensburgStandard);
aalRegatta = server.apply(new AddSpecificRegatta(RegattaImpl.getDefaultName("Aalregatta", "ORC"), "ORC",
/* canBoatsOfCompetitorsChangePerRace */ true, /*startDate*/ null, /*endDate*/ null, UUID.randomUUID(),
aalRegatta = server.apply(new AddSpecificRegatta(RegattaImpl.getDefaultName("Aalregatta", "ORC"), "ORC",
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
/* registrationLinkSecret */ null, /* startDate */ null, /* endDate */ null, UUID.randomUUID(),
new RegattaCreationParametersDTO(seriesCreationParams), /* persistent */
true, new LowPoint(), flensburgStandard.getId(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false, RankingMetrics.ONE_DESIGN));
true, new LowPoint(), flensburgStandard.getId(), /* buoyZoneRadiusInHullLengths */2.0,
/* useStartTimeInference */ true, /* controlTrackingFromStartAndFinishTimes */ false,
RankingMetrics.ONE_DESIGN));
server.apply(new AddColumnToSeries(aalRegatta.getRegattaIdentifier(), "Default", "R1"));
server.apply(new AddColumnToSeries(aalRegatta.getRegattaIdentifier(), "Default", "R2"));
RegattaLeaderboard aalRegattaLeaderboard = server.apply(new CreateRegattaLeaderboard(aalRegatta.getRegattaIdentifier(),
@@ -48,6 +48,7 @@ import com.sap.sailing.domain.base.configuration.DeviceConfigurationMatcher;
import com.sap.sailing.domain.base.configuration.RegattaConfiguration;
import com.sap.sailing.domain.base.impl.DynamicCompetitorWithBoat;
import com.sap.sailing.domain.common.CompetitorDescriptor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DataImportSubProgress;
import com.sap.sailing.domain.common.MasterDataImportObjectCreationCount;
@@ -335,7 +336,8 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
* @param controlTrackingFromStartAndFinishTimes
* cannot be {@code true} if {@link useStartTimeInference} is also {@code true}
*/
Regatta createRegatta(String regattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, Serializable id, Iterable<? extends Series> series,
Regatta createRegatta(String regattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace,
CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret, TimePoint startDate, TimePoint endDate, Serializable id, Iterable<? extends Series> series,
boolean persistent, ScoringScheme scoringScheme, Serializable defaultCourseAreaId, Double buoyZoneRadiusInHullLengths,
boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor);
@@ -346,7 +348,7 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
Regatta updateRegatta(RegattaIdentifier regattaIdentifier, TimePoint startDate, TimePoint endDate,
Serializable newDefaultCourseAreaId, RegattaConfiguration regattaConfiguration,
Iterable<? extends Series> series, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes);
boolean controlTrackingFromStartAndFinishTimes, String registrationLinkSecret);
/**
* Adds <code>raceDefinition</code> to the {@link Regatta} such that it will appear in {@link Regatta#getAllRaces()}
@@ -493,7 +495,8 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
* the call
*/
Util.Pair<Regatta, Boolean> getOrCreateRegattaWithoutReplication(String fullRegattaName, String boatClassName,
boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, Serializable id,
boolean canBoatsOfCompetitorsChangePerRace, CompetitorRegistrationType competitorRegistrationType,
String registrationLinkSecret, TimePoint startDate, TimePoint endDate, Serializable id,
Iterable<? extends Series> series, boolean persistent, ScoringScheme scoringScheme,
Serializable defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor);
@@ -111,6 +111,7 @@ import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.RemoteSailingServerReferenceImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorDescriptor;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.DataImportProgress;
import com.sap.sailing.domain.common.DataImportSubProgress;
import com.sap.sailing.domain.common.DeviceIdentifier;
@@ -1496,7 +1497,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
Regatta result = regattasByName.get(name);
if (result == null) {
result = new RegattaImpl(getRaceLogStore(), getRegattaLogStore(), name, getBaseDomainFactory()
.getOrCreateBoatClass(boatClassName), /* canBoatsOfCompetitorsChangePerRace*/ false,
.getOrCreateBoatClass(boatClassName), /* canBoatsOfCompetitorsChangePerRace*/ false, CompetitorRegistrationType.CLOSED,
/* startDate */null, /* endDate */null, this,
getBaseDomainFactory().createScoringScheme(ScoringSchemeType.LOW_POINT), id, /* course area */ null);
logger.info("Created default regatta " + result.getName() + " (" + hashCode() + ") on " + this);
@@ -1516,7 +1517,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
}
@Override
public Regatta createRegatta(String fullRegattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate,
public Regatta createRegatta(String fullRegattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace,
CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret, TimePoint startDate, TimePoint endDate,
Serializable id, Iterable<? extends Series> series, boolean persistent, ScoringScheme scoringScheme,
Serializable defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
RankingMetricConstructor rankingMetricConstructor) {
@@ -1524,7 +1526,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
throw new IllegalArgumentException("Cannot set both of useStartTimeInference and controlTrackingFromStartAndFinishTimes to true");
}
com.sap.sse.common.Util.Pair<Regatta, Boolean> regattaWithCreatedFlag = getOrCreateRegattaWithoutReplication(
fullRegattaName, boatClassName, canBoatsOfCompetitorsChangePerRace, startDate, endDate, id, series, persistent, scoringScheme,
fullRegattaName, boatClassName, canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, registrationLinkSecret, startDate, endDate, id, series, persistent, scoringScheme,
defaultCourseAreaId, buoyZoneRadiusInHullLengths, useStartTimeInference, controlTrackingFromStartAndFinishTimes, rankingMetricConstructor);
Regatta regatta = regattaWithCreatedFlag.getA();
if (regattaWithCreatedFlag.getB()) {
@@ -1556,14 +1558,17 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
@Override
public com.sap.sse.common.Util.Pair<Regatta, Boolean> getOrCreateRegattaWithoutReplication(String fullRegattaName,
String boatClassName, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, Serializable id,
Iterable<? extends Series> series, boolean persistent, ScoringScheme scoringScheme,
Serializable defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
String boatClassName, boolean canBoatsOfCompetitorsChangePerRace,
CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret, TimePoint startDate,
TimePoint endDate, Serializable id, Iterable<? extends Series> series, boolean persistent,
ScoringScheme scoringScheme, Serializable defaultCourseAreaId, Double buoyZoneRadiusInHullLengths,
boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
RankingMetricConstructor rankingMetricConstructor) {
CourseArea courseArea = getCourseArea(defaultCourseAreaId);
Regatta regatta = new RegattaImpl(getRaceLogStore(), getRegattaLogStore(), fullRegattaName,
getBaseDomainFactory().getOrCreateBoatClass(boatClassName), canBoatsOfCompetitorsChangePerRace, startDate, endDate, series, persistent,
getBaseDomainFactory().getOrCreateBoatClass(boatClassName), canBoatsOfCompetitorsChangePerRace, competitorRegistrationType, startDate, endDate, series, persistent,
scoringScheme, id, courseArea, buoyZoneRadiusInHullLengths, useStartTimeInference, controlTrackingFromStartAndFinishTimes, rankingMetricConstructor);
regatta.setRegistrationLinkSecret(registrationLinkSecret);
boolean wasCreated = addAndConnectRegatta(persistent, defaultCourseAreaId, regatta);
if (wasCreated) {
logger.info("Created regatta " + regatta.getName() + " (" + hashCode() + ") on " + this);
@@ -1764,11 +1769,13 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
if (regatta.getDefaultCourseArea() != null) {
courseAreaId = regatta.getDefaultCourseArea().getId();
}
replicate(new AddSpecificRegatta(regatta.getName(), regatta.getBoatClass() == null ? null : regatta
.getBoatClass().getName(), regatta.canBoatsOfCompetitorsChangePerRace(),
regatta.getStartDate(), regatta.getEndDate(), regatta.getId(),
replicate(new AddSpecificRegatta(regatta.getName(),
regatta.getBoatClass() == null ? null : regatta.getBoatClass().getName(),
regatta.canBoatsOfCompetitorsChangePerRace(), regatta.getCompetitorRegistrationType(),
/* registrationLinkSecret */ null, regatta.getStartDate(), regatta.getEndDate(), regatta.getId(),
getSeriesWithoutRaceColumnsConstructionParametersAsMap(regatta), regatta.isPersistent(),
regatta.getScoringScheme(), courseAreaId, regatta.getBuoyZoneRadiusInHullLengths(), regatta.useStartTimeInference(), regatta.isControlTrackingFromStartAndFinishTimes(),
regatta.getScoringScheme(), courseAreaId, regatta.getBuoyZoneRadiusInHullLengths(),
regatta.useStartTimeInference(), regatta.isControlTrackingFromStartAndFinishTimes(),
regatta.getRankingMetricType()));
RegattaIdentifier regattaIdentifier = regatta.getRegattaIdentifier();
for (RaceDefinition race : regatta.getAllRaces()) {
@@ -2469,7 +2476,8 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
@Override
public Regatta updateRegatta(RegattaIdentifier regattaIdentifier, TimePoint startDate, TimePoint endDate,
Serializable newDefaultCourseAreaId, RegattaConfiguration newRegattaConfiguration,
Iterable<? extends Series> series, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes) {
Iterable<? extends Series> series, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
String registrationLinkSecret) {
if (useStartTimeInference && controlTrackingFromStartAndFinishTimes) {
throw new IllegalArgumentException("Cannot set both of useStartTimeInference and controlTrackingFromStartAndFinishTimes to true");
}
@@ -2483,6 +2491,7 @@ public class RacingEventServiceImpl implements RacingEventService, ClearStateTes
regatta.setEndDate(endDate);
regatta.setBuoyZoneRadiusInHullLengths(buoyZoneRadiusInHullLengths);
regatta.setControlTrackingFromStartAndFinishTimes(controlTrackingFromStartAndFinishTimes);
regatta.setRegistrationLinkSecret(registrationLinkSecret);
if (regatta.useStartTimeInference() != useStartTimeInference) {
regatta.setUseStartTimeInference(useStartTimeInference);
final DynamicTrackedRegatta trackedRegatta = getTrackedRegatta(regatta);
@@ -11,6 +11,7 @@ import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Series;
import com.sap.sailing.domain.base.impl.FleetImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.RankingMetrics;
import com.sap.sailing.domain.common.dto.FleetDTO;
import com.sap.sailing.domain.common.dto.RegattaCreationParametersDTO;
@@ -33,14 +34,18 @@ public class AddSpecificRegatta extends AbstractAddRegattaOperation {
private final boolean useStartTimeInference;
private final boolean controlTrackingFromStartAndFinishTimes;
private final boolean canBoatsOfCompetitorsChangePerRace;
private final CompetitorRegistrationType competitorRegistrationType;
private final RankingMetrics rankingMetricType;
private final String registrationLinkSecret;
public AddSpecificRegatta(String regattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace, TimePoint startDate, TimePoint endDate, Serializable id,
public AddSpecificRegatta(String regattaName, String boatClassName, boolean canBoatsOfCompetitorsChangePerRace,
CompetitorRegistrationType competitorRegistrationType, String registrationLinkSecret, TimePoint startDate, TimePoint endDate, Serializable id,
RegattaCreationParametersDTO seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds,
boolean persistent, ScoringScheme scoringScheme, Serializable defaultCourseAreaId, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
boolean controlTrackingFromStartAndFinishTimes, RankingMetrics rankingMetricType) {
super(regattaName, boatClassName, startDate, endDate, id);
this.canBoatsOfCompetitorsChangePerRace = canBoatsOfCompetitorsChangePerRace;
this.competitorRegistrationType = competitorRegistrationType;
this.seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndStartsWithZeroScoreAndDiscardingThresholds = seriesNamesWithFleetNamesAndFleetOrderingAndMedalAndDiscardingThresholds;
this.persistent = persistent;
this.scoringScheme = scoringScheme;
@@ -49,11 +54,13 @@ public class AddSpecificRegatta extends AbstractAddRegattaOperation {
this.controlTrackingFromStartAndFinishTimes = controlTrackingFromStartAndFinishTimes;
this.rankingMetricType = rankingMetricType;
this.buoyZoneRadiusInHullLengths = buoyZoneRadiusInHullLengths;
this.registrationLinkSecret = registrationLinkSecret;
}
@Override
public Regatta internalApplyTo(RacingEventService toState) throws Exception {
Regatta regatta = toState.createRegatta(getRegattaName(), getBoatClassName(), canBoatsOfCompetitorsChangePerRace, getStartDate(), getEndDate(), getId(), createSeries(toState),
Regatta regatta = toState.createRegatta(getRegattaName(), getBoatClassName(), canBoatsOfCompetitorsChangePerRace,
competitorRegistrationType, registrationLinkSecret, getStartDate(), getEndDate(), getId(), createSeries(toState),
persistent, scoringScheme, defaultCourseAreaId, buoyZoneRadiusInHullLengths, useStartTimeInference, controlTrackingFromStartAndFinishTimes, RankingMetricsFactory.getRankingMetricConstructor(rankingMetricType));
return regatta;
}
@@ -20,9 +20,12 @@ public class UpdateSpecificRegatta extends AbstractRacingEventServiceOperation<R
private final boolean controlTrackingFromStartAndFinishTimes;
private final TimePoint startDate;
private final TimePoint endDate;
private final String registrationLinkSecret;
public UpdateSpecificRegatta(RegattaIdentifier regattaIdentifier, TimePoint startDate, TimePoint endDate, UUID newDefaultCourseAreaId,
RegattaConfiguration newConfiguration, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes) {
public UpdateSpecificRegatta(RegattaIdentifier regattaIdentifier, TimePoint startDate, TimePoint endDate,
UUID newDefaultCourseAreaId, RegattaConfiguration newConfiguration, Double buoyZoneRadiusInHullLengths,
boolean useStartTimeInference, boolean controlTrackingFromStartAndFinishTimes,
String registrationLinkSecret) {
this.regattaIdentifier = regattaIdentifier;
this.startDate = startDate;
this.endDate = endDate;
@@ -31,11 +34,12 @@ public class UpdateSpecificRegatta extends AbstractRacingEventServiceOperation<R
this.useStartTimeInference = useStartTimeInference;
this.controlTrackingFromStartAndFinishTimes = controlTrackingFromStartAndFinishTimes;
this.buoyZoneRadiusInHullLengths = buoyZoneRadiusInHullLengths;
this.registrationLinkSecret = registrationLinkSecret;
}
@Override
public Regatta internalApplyTo(RacingEventService toState) throws Exception {
Regatta regatta = toState.updateRegatta(regattaIdentifier, startDate, endDate, newDefaultCourseAreaId, newConfiguration, null, buoyZoneRadiusInHullLengths, useStartTimeInference, controlTrackingFromStartAndFinishTimes);
Regatta regatta = toState.updateRegatta(regattaIdentifier, startDate, endDate, newDefaultCourseAreaId, newConfiguration, null, buoyZoneRadiusInHullLengths, useStartTimeInference, controlTrackingFromStartAndFinishTimes, registrationLinkSecret);
return regatta;
}
@@ -30,6 +30,7 @@ import com.sap.sailing.domain.base.impl.PersonImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.SeriesImpl;
import com.sap.sailing.domain.base.impl.TeamImpl;
import com.sap.sailing.domain.common.CompetitorRegistrationType;
import com.sap.sailing.domain.common.FleetColors;
import com.sap.sailing.domain.common.LeaderboardNameConstants;
import com.sap.sailing.domain.common.ScoringSchemeType;
@@ -101,7 +102,8 @@ public class StructureImporter {
RegattaImpl regatta = new RegattaImpl(RegattaImpl.getDefaultName(event.getTitle(), ((Division) event
.getRaceOrDivisionOrRegattaSeriesResult().get(0)).getTitle()),
baseDomainFactory.getOrCreateBoatClass(result.getA().getBoatClass()),
/* canBoatsOfCompetitorsChangePerRace */ true, startDate, endDate, getSeries(buildStructure), false,
/* canBoatsOfCompetitorsChangePerRace */ true, CompetitorRegistrationType.CLOSED,
startDate, endDate, getSeries(buildStructure), false,
this.baseDomainFactory.createScoringScheme(ScoringSchemeType.LOW_POINT), event.getEventID(), null, OneDesignRankingMetric::new);
addSpecificRegattas.add(regatta);
}