fixed tests for TestLapConfiguration

This commit is contained in:
Axel Uhl
2019-12-19 23:50:08 +01:00
parent eca8485780
commit d44477f676
9 changed files with 97 additions and 64 deletions
@@ -7,7 +7,9 @@ import static org.junit.Assume.assumeNoException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.junit.Before; import org.junit.Before;
@@ -17,9 +19,11 @@ import com.sap.sailing.domain.common.MarkType;
import com.sap.sailing.domain.common.PassingInstruction; import com.sap.sailing.domain.common.PassingInstruction;
import com.sap.sailing.domain.coursetemplate.ControlPointTemplate; import com.sap.sailing.domain.coursetemplate.ControlPointTemplate;
import com.sap.sailing.domain.coursetemplate.CourseTemplate; import com.sap.sailing.domain.coursetemplate.CourseTemplate;
import com.sap.sailing.domain.coursetemplate.MarkRole;
import com.sap.sailing.domain.coursetemplate.MarkTemplate; import com.sap.sailing.domain.coursetemplate.MarkTemplate;
import com.sap.sailing.domain.coursetemplate.WaypointTemplate; import com.sap.sailing.domain.coursetemplate.WaypointTemplate;
import com.sap.sailing.domain.coursetemplate.impl.CourseTemplateImpl; import com.sap.sailing.domain.coursetemplate.impl.CourseTemplateImpl;
import com.sap.sailing.domain.coursetemplate.impl.MarkRoleImpl;
import com.sap.sailing.domain.coursetemplate.impl.MarkRolePairImpl; import com.sap.sailing.domain.coursetemplate.impl.MarkRolePairImpl;
import com.sap.sailing.domain.coursetemplate.impl.MarkTemplateImpl; import com.sap.sailing.domain.coursetemplate.impl.MarkTemplateImpl;
import com.sap.sailing.domain.coursetemplate.impl.RepeatablePartImpl; import com.sap.sailing.domain.coursetemplate.impl.RepeatablePartImpl;
@@ -29,32 +33,48 @@ import com.sap.sse.common.Util;
public class TestLapConfiguration { public class TestLapConfiguration {
private CourseTemplate courseTemplate; private CourseTemplate courseTemplate;
private MarkTemplate startBoat; private MarkTemplate startBoat;
private MarkRole startBoatRole;
private MarkTemplate pin; private MarkTemplate pin;
private MarkRole pinRole;
private MarkTemplate top; private MarkTemplate top;
private MarkRole one;
private MarkTemplate gateLeft; private MarkTemplate gateLeft;
private MarkRole threeP;
private MarkTemplate gateRight; private MarkTemplate gateRight;
private MarkRole threeS;
private ControlPointTemplate startFinish; private ControlPointTemplate startFinish;
private ControlPointTemplate gate; private ControlPointTemplate gate;
private Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles;
@Before @Before
public void setUp() { public void setUp() {
startBoat = new MarkTemplateImpl("Start Boat", "SB", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.STARTBOAT); startBoat = new MarkTemplateImpl("Start Boat", "SB", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.STARTBOAT);
startBoatRole = new MarkRoleImpl(UUID.randomUUID(), "Start Boat", "SB");
pin = new MarkTemplateImpl("Pin End", "Pin", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY); pin = new MarkTemplateImpl("Pin End", "Pin", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY);
pinRole = new MarkRoleImpl(UUID.randomUUID(), "Pin End", "P");
top = new MarkTemplateImpl("Windward Mark", "1", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY); top = new MarkTemplateImpl("Windward Mark", "1", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY);
one = new MarkRoleImpl(UUID.randomUUID(), "Windward Mark", "1");
gateLeft = new MarkTemplateImpl("Leeward Gate Port", "4p", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY); gateLeft = new MarkTemplateImpl("Leeward Gate Port", "4p", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY);
threeP = new MarkRoleImpl(UUID.randomUUID(), "Leeward Gate Port", "3p");
gateRight = new MarkTemplateImpl("Leeward Gate Starboard", "4s", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY); gateRight = new MarkTemplateImpl("Leeward Gate Starboard", "4s", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY);
startFinish = new MarkRolePairImpl("Start/Finish", "Start/Finish", startBoat, pin); threeS = new MarkRoleImpl(UUID.randomUUID(), "Leeward Gate Starboard", "3s");
gate = new MarkRolePairImpl("Leeward Gate", "Leeward Gate", gateLeft, gateRight); startFinish = new MarkRolePairImpl("Start/Finish", "S/F", startBoatRole, pinRole);
courseTemplate = new CourseTemplateImpl(UUID.randomUUID(), "L", gate = new MarkRolePairImpl("Leeward Gate", "LG", threeP, threeS);
shortName, defaultMarkTemplatesForMarkRoles = new HashMap<>();
defaultMarkTemplatesForMarkRoles.put(startBoatRole, startBoat);
defaultMarkTemplatesForMarkRoles.put(pinRole, pin);
defaultMarkTemplatesForMarkRoles.put(one, top);
defaultMarkTemplatesForMarkRoles.put(threeP, gateLeft);
defaultMarkTemplatesForMarkRoles.put(threeS, gateRight);
courseTemplate = new CourseTemplateImpl(UUID.randomUUID(), "Windward/Leeward", "L",
/* marks */ Arrays.asList(startBoat, pin, top, gateLeft, gateRight), /* marks */ Arrays.asList(startBoat, pin, top, gateLeft, gateRight),
/* waypoints */ Arrays.asList(new WaypointTemplateImpl(startFinish, PassingInstruction.Line), /* waypoints */ Arrays.asList(new WaypointTemplateImpl(startFinish, PassingInstruction.Line),
new WaypointTemplateImpl(top, PassingInstruction.Port), new WaypointTemplateImpl(one, PassingInstruction.Port),
new WaypointTemplateImpl(gate, PassingInstruction.Gate), new WaypointTemplateImpl(gate, PassingInstruction.Gate),
new WaypointTemplateImpl(top, PassingInstruction.Port), new WaypointTemplateImpl(one, PassingInstruction.Port),
new WaypointTemplateImpl(startFinish, PassingInstruction.Line)), new WaypointTemplateImpl(startFinish, PassingInstruction.Line)),
defaultMarkTemplatesForMarkRoles,
/* associatedRoles */ Collections.emptyMap(), /* associatedRoles */ Collections.emptyMap(),
defaultMarkTemplatesForRoles,
/* optionaImageURL */ null, new RepeatablePartImpl(/* zeroBasedIndexOfRepeatablePartStart */ 1, /* optionaImageURL */ null, new RepeatablePartImpl(/* zeroBasedIndexOfRepeatablePartStart */ 1,
/* zeroBasedIndexOfRepeatablePartEnd */ 3), /* Default Number of Laps */ 1); /* zeroBasedIndexOfRepeatablePartEnd */ 3), /* Default Number of Laps */ 1);
} }
@@ -62,7 +82,7 @@ public class TestLapConfiguration {
@Test @Test
public void testSimpleCourseWithOneLap() { public void testSimpleCourseWithOneLap() {
final Iterable<WaypointTemplate> waypointsOfOneLapper = courseTemplate.getWaypointTemplates(1); final Iterable<WaypointTemplate> waypointsOfOneLapper = courseTemplate.getWaypointTemplates(1);
final List<ControlPointTemplate> expected = Arrays.asList(startFinish, top, startFinish); final List<ControlPointTemplate> expected = Arrays.asList(startFinish, one, startFinish);
verify(waypointsOfOneLapper, expected); verify(waypointsOfOneLapper, expected);
} }
@@ -79,14 +99,14 @@ public class TestLapConfiguration {
@Test @Test
public void testSimpleCourseWithTwoLaps() { public void testSimpleCourseWithTwoLaps() {
final Iterable<WaypointTemplate> waypointsOfOneLapper = courseTemplate.getWaypointTemplates(2); final Iterable<WaypointTemplate> waypointsOfOneLapper = courseTemplate.getWaypointTemplates(2);
final List<ControlPointTemplate> expected = Arrays.asList(startFinish, top, gate, top, startFinish); final List<ControlPointTemplate> expected = Arrays.asList(startFinish, one, gate, one, startFinish);
verify(waypointsOfOneLapper, expected); verify(waypointsOfOneLapper, expected);
} }
@Test @Test
public void testSimpleCourseWithThreeLaps() { public void testSimpleCourseWithThreeLaps() {
final Iterable<WaypointTemplate> waypointsOfOneLapper = courseTemplate.getWaypointTemplates(3); final Iterable<WaypointTemplate> waypointsOfOneLapper = courseTemplate.getWaypointTemplates(3);
final List<ControlPointTemplate> expected = Arrays.asList(startFinish, top, gate, top, gate, top, startFinish); final List<ControlPointTemplate> expected = Arrays.asList(startFinish, one, gate, one, gate, one, startFinish);
verify(waypointsOfOneLapper, expected); verify(waypointsOfOneLapper, expected);
} }
@@ -94,13 +114,13 @@ public class TestLapConfiguration {
public void testExceptionInCaseMarkIsMissing() { public void testExceptionInCaseMarkIsMissing() {
startBoat = new MarkTemplateImpl("Start Boat", "SB", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.STARTBOAT); startBoat = new MarkTemplateImpl("Start Boat", "SB", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.STARTBOAT);
pin = new MarkTemplateImpl("Pin End", "Pin", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY); pin = new MarkTemplateImpl("Pin End", "Pin", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY);
startFinish = new MarkRolePairImpl("Start/Finish","Start/Finish", startBoat, pin); startFinish = new MarkRolePairImpl("Start/Finish","Start/Finish", startBoatRole, pinRole);
try { try {
courseTemplate = new CourseTemplateImpl("Test", courseTemplate = new CourseTemplateImpl("Test", "T",
shortName,
/* marks */ Arrays.asList(startBoat), /* marks */ Arrays.asList(startBoat),
/* waypoints */ Arrays.asList(new WaypointTemplateImpl(startFinish, PassingInstruction.Line)), /* waypoints */ Arrays.asList(new WaypointTemplateImpl(startFinish, PassingInstruction.Line)),
/* associatedRoles */ Collections.emptyMap(), defaultMarkTemplatesForRoles, /* optionaImageURL */ null); /* defaultMarkRolesForMarkTemplates */ Collections.emptyMap(),
/* defaultMarkTemplatesForRoles */ Collections.emptyMap(), /* optionaImageURL */ null);
fail("Expected an IllegalArgumentException due to missing mark <pin> but it wasn't thrown"); fail("Expected an IllegalArgumentException due to missing mark <pin> but it wasn't thrown");
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
// expected // expected
@@ -109,13 +129,11 @@ public class TestLapConfiguration {
@Test @Test
public void testZeroLapsOkIfNoRepeatablePart() { public void testZeroLapsOkIfNoRepeatablePart() {
startBoat = new MarkTemplateImpl("Start Boat", "SB", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.STARTBOAT); courseTemplate = new CourseTemplateImpl("Test", "T",
pin = new MarkTemplateImpl("Pin End", "Pin", /* color */ null, /* shape */ null, /* pattern */ null, MarkType.BUOY);
startFinish = new MarkRolePairImpl("Start/Finish", "Start/Finish", startBoat, pin);
courseTemplate = new CourseTemplateImpl("Test", shortName,
/* marks */ Arrays.asList(startBoat, pin), /* marks */ Arrays.asList(startBoat, pin),
/* waypoints */ Arrays.asList(new WaypointTemplateImpl(startFinish, PassingInstruction.Line)), /* waypoints */ Arrays.asList(new WaypointTemplateImpl(startFinish, PassingInstruction.Line)),
/* associatedRoles */ Collections.emptyMap(), defaultMarkTemplatesForRoles, /* optionaImageURL */ null); defaultMarkTemplatesForMarkRoles,
/* defaultMarkTemplatesForRoles */ Collections.emptyMap(), /* optionaImageURL */ null);
try { try {
courseTemplate.getWaypointTemplates(0); courseTemplate.getWaypointTemplates(0);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@@ -7,7 +7,7 @@ import com.sap.sse.common.Named;
* What a {@link WaypointTemplate} references. It is a template for the construction of a {@link ControlPoint} and * What a {@link WaypointTemplate} references. It is a template for the construction of a {@link ControlPoint} and
* references the {@link MarkRole}s that describe the "logical" marks. The {@link MarkTemplate}s from which the mark * references the {@link MarkRole}s that describe the "logical" marks. The {@link MarkTemplate}s from which the mark
* properties are to be drawn during construction of the actual {@link ControlPoint} are provided by the * properties are to be drawn during construction of the actual {@link ControlPoint} are provided by the
* {@link CourseTemplate} (see {@link CourseTemplate#getDefaultMarkTemplateForRole(MarkRole)}). * {@link CourseTemplate} (see {@link CourseTemplate#getDefaultMarkTemplateForMarkRole(MarkRole)}).
* *
* @author Axel Uhl (d043530) * @author Axel Uhl (d043530)
* *
@@ -109,7 +109,7 @@ public interface CourseTemplate extends WithOptionalRepeatablePart, NamedWithUUI
/** /**
* @return the value set contains at least all {@link MarkRole}s reachable through the {@link #getWaypointTemplates() * @return the value set contains at least all {@link MarkRole}s reachable through the {@link #getWaypointTemplates()
* waypoint template sequence}; the keys for those values are what clients get when calling * waypoint template sequence}; the keys for those values are what clients get when calling
* {@link #getDefaultMarkTemplateForRole(MarkRole)} for the value. Optionally, additional default role * {@link #getDefaultMarkTemplateForMarkRole(MarkRole)} for the value. Optionally, additional default role
* assignment for "spare" marks, such as the "1" role for alternative windward mark templates may be returned * assignment for "spare" marks, such as the "1" role for alternative windward mark templates may be returned
* by this method. * by this method.
*/ */
@@ -135,7 +135,7 @@ public interface CourseTemplate extends WithOptionalRepeatablePart, NamedWithUUI
* to create the {@link Mark} that acts in the role identified by {@code markRole}. Short for * to create the {@link Mark} that acts in the role identified by {@code markRole}. Short for
* {@link #getDefaultMarkTemplatesForMarkRoles()}.{@link Map#get(Object) get(markRole)}. * {@link #getDefaultMarkTemplatesForMarkRoles()}.{@link Map#get(Object) get(markRole)}.
*/ */
MarkTemplate getDefaultMarkTemplateForRole(MarkRole markRole); MarkTemplate getDefaultMarkTemplateForMarkRole(MarkRole markRole);
MarkRole getMarkRoleByIdIfContainedInCourseTemplate(UUID markRoleId); MarkRole getMarkRoleByIdIfContainedInCourseTemplate(UUID markRoleId);
@@ -5,6 +5,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@@ -25,9 +26,9 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
private final ArrayList<WaypointTemplate> waypoints; private final ArrayList<WaypointTemplate> waypoints;
private final Map<MarkTemplate, MarkRole> defaultRolesForMarkTemplates; private final Map<MarkTemplate, MarkRole> defaultMarkRolesForMarkTemplates;
private final Map<MarkRole, MarkTemplate> defaultMarkTemplatesForRoles; private final Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles;
private Iterable<String> tags = new ArrayList<>(); private Iterable<String> tags = new ArrayList<>();
@@ -40,43 +41,45 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
/** /**
* Creates a course template with a random UUID and no repeatable part. * Creates a course template with a random UUID and no repeatable part.
*
* @param marks * @param marks
* all mark templates made available in this course template * all mark templates made available in this course template
* @param waypoints * @param waypoints
* may refer only to {@link MarkTemplate}s provided in the {@code marks} parameter * may refer only to {@link MarkTemplate}s provided in the {@code marks} parameter
* @param defaultRolesForMarkTemplates * @param defaultMarkTemplatesForMarkRoles
* all {@link MarkRole}s reachable through {@code waypoints} must appear as keys in this map's key set;
* the values represent the {@link MarkTemplate} to use when instantiating this course template for the
* key role
* @param defaultMarkRolesForMarkTemplates
* for those mark templates referenced as values in {@code defaultMarkTemplatesForRoles}, the value in * for those mark templates referenced as values in {@code defaultMarkTemplatesForRoles}, the value in
* this map has to be the key in {@code defaultMarkTemplatesForRoles}; for all other * this map has to be the key in {@code defaultMarkTemplatesForRoles}; for all other
* {@link MarkTemplates}s from {@code marks} it is optional whether a mapping to a default * {@link MarkTemplates}s from {@code marks} it is optional whether a mapping to a default
* {@link MarkRole} is provided in this map * {@link MarkRole} is provided in this map
* @param defaultMarkTemplatesForRoles
* all {@link MarkRole}s reachable through {@code waypoints} must appear as keys in this map's key set;
* the values represent the {@link MarkTemplate} to use when instantiating this course template for the
* key role
*/ */
public CourseTemplateImpl(String name, String shortName, Iterable<MarkTemplate> marks, public CourseTemplateImpl(String name, String shortName, Iterable<MarkTemplate> marks,
Iterable<WaypointTemplate> waypoints, Iterable<WaypointTemplate> waypoints, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles,
Map<MarkTemplate, MarkRole> defaultRolesForMarkTemplates, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForRoles, URL optionalImageURL) { Map<MarkTemplate, MarkRole> defaultMarkRolesForMarkTemplates, URL optionalImageURL) {
this(UUID.randomUUID(), name, shortName, marks, waypoints, defaultRolesForMarkTemplates, this(UUID.randomUUID(), name, shortName, marks, waypoints, defaultMarkTemplatesForMarkRoles,
defaultMarkTemplatesForRoles, optionalImageURL); defaultMarkRolesForMarkTemplates, optionalImageURL);
} }
/** /**
* Creates a course with the given UUID and no repeatable part. * Creates a course with the given UUID and no repeatable part.
* @param shortName TODO
*/ */
public CourseTemplateImpl(UUID id, String name, String shortName, Iterable<MarkTemplate> marks, public CourseTemplateImpl(UUID id, String name, String shortName, Iterable<MarkTemplate> marks,
Iterable<WaypointTemplate> waypoints, Iterable<WaypointTemplate> waypoints, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles,
Map<MarkTemplate, MarkRole> defaultRolesForMarkTemplates, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForRoles, URL optionalImageURL) { Map<MarkTemplate, MarkRole> defaultMarkRolesForMarkTemplates, URL optionalImageURL) {
this(id, name, shortName, marks, waypoints, defaultRolesForMarkTemplates, defaultMarkTemplatesForRoles, this(id, name, shortName, marks, waypoints, defaultMarkTemplatesForMarkRoles, defaultMarkRolesForMarkTemplates,
optionalImageURL, /* optionalRepeatablePart */ null, /* default number of laps */ null); optionalImageURL, /* optionalRepeatablePart */ null, /* default number of laps */ null);
} }
/**
* @param defaultMarkRolesForMarkTemplates
* will be extended according to and checked for consistency against {@code defaultMarkTemplatesForMarkRoles}
*/
public CourseTemplateImpl(UUID id, String name, String shortName, Iterable<MarkTemplate> marks, public CourseTemplateImpl(UUID id, String name, String shortName, Iterable<MarkTemplate> marks,
Iterable<WaypointTemplate> waypoints, Iterable<WaypointTemplate> waypoints, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles,
Map<MarkTemplate, MarkRole> defaultRolesForMarkTemplates, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForRoles, Map<MarkTemplate, MarkRole> defaultMarkRolesForMarkTemplates, URL optionalImageURL,
URL optionalImageURL, RepeatablePart optionalRepeatablePart, Integer defaultNumberOfLaps) { RepeatablePart optionalRepeatablePart, Integer defaultNumberOfLaps) {
super(name, id); super(name, id);
this.shortName = shortName; this.shortName = shortName;
this.defaultNumberOfLaps = defaultNumberOfLaps; this.defaultNumberOfLaps = defaultNumberOfLaps;
@@ -89,8 +92,15 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
Util.addAll(marks, this.marks); Util.addAll(marks, this.marks);
this.optionalImageURL = optionalImageURL; this.optionalImageURL = optionalImageURL;
this.optionalRepeatablePart = optionalRepeatablePart; this.optionalRepeatablePart = optionalRepeatablePart;
this.defaultRolesForMarkTemplates = new HashMap<>(defaultRolesForMarkTemplates); this.defaultMarkRolesForMarkTemplates = new HashMap<>(defaultMarkRolesForMarkTemplates);
this.defaultMarkTemplatesForRoles = new HashMap<>(defaultMarkTemplatesForRoles); this.defaultMarkTemplatesForMarkRoles = new HashMap<>(defaultMarkTemplatesForMarkRoles);
for (final Entry<MarkRole, MarkTemplate> e : defaultMarkTemplatesForMarkRoles.entrySet()) {
final MarkRole previousDefaultMarkRole = this.defaultMarkRolesForMarkTemplates.put(e.getValue(), e.getKey());
if (previousDefaultMarkRole != null && previousDefaultMarkRole != e.getKey()) {
throw new IllegalArgumentException("Inconsistent default mark role assignment: mark template "+e.getValue()+
" was assigned to mark role "+previousDefaultMarkRole+" but now shall default to mark role "+e.getKey());
}
}
validateWaypointsAgainstRolesAndMappingSymmetry(); validateWaypointsAgainstRolesAndMappingSymmetry();
} }
@@ -103,20 +113,20 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
private void validateWaypointsAgainstRolesAndMappingSymmetry() { private void validateWaypointsAgainstRolesAndMappingSymmetry() {
for (final WaypointTemplate waypoint : waypoints) { for (final WaypointTemplate waypoint : waypoints) {
for (final MarkRole markRole : waypoint.getControlPointTemplate().getMarkRoles()) { for (final MarkRole markRole : waypoint.getControlPointTemplate().getMarkRoles()) {
if (!defaultMarkTemplatesForRoles.containsKey(markRole)) { if (!defaultMarkTemplatesForMarkRoles.containsKey(markRole)) {
throw new IllegalArgumentException("Mark role "+markRole+" used by waypoint template "+ throw new IllegalArgumentException("Mark role "+markRole+" used by waypoint template "+
waypoint+" in course template "+this+" is not providing a default mark template"); waypoint+" in course template "+this+" is not providing a default mark template");
} }
if (!Util.contains(marks, defaultMarkTemplatesForRoles.get(markRole))) { if (!Util.contains(marks, defaultMarkTemplatesForMarkRoles.get(markRole))) {
throw new IllegalArgumentException("Mark template " + defaultMarkTemplatesForRoles.get(markRole) throw new IllegalArgumentException("Mark template " + defaultMarkTemplatesForMarkRoles.get(markRole)
+ " used by role " + markRole + " used by waypoint template " + waypoint + " used by role " + markRole + " used by waypoint template " + waypoint
+ " in course template " + this + " is not provided in the collection of marks"); + " in course template " + this + " is not provided in the collection of marks");
} }
if (!Util.equalsWithNull(defaultRolesForMarkTemplates.get(defaultMarkTemplatesForRoles.get(markRole)), markRole)) { if (!Util.equalsWithNull(defaultMarkRolesForMarkTemplates.get(defaultMarkTemplatesForMarkRoles.get(markRole)), markRole)) {
throw new IllegalArgumentException("Mark template " + defaultMarkTemplatesForRoles.get(markRole) throw new IllegalArgumentException("Mark template " + defaultMarkTemplatesForMarkRoles.get(markRole)
+ " used as default for mark role " + markRole + " used as default for mark role " + markRole
+ " does not use that same mark role as its default but instead refers to " + " does not use that same mark role as its default but instead refers to "
+ defaultRolesForMarkTemplates.get(defaultMarkTemplatesForRoles.get(markRole)) + defaultMarkRolesForMarkTemplates.get(defaultMarkTemplatesForMarkRoles.get(markRole))
+ " as its default role"); + " as its default role");
} }
} }
@@ -129,13 +139,13 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
} }
@Override @Override
public MarkTemplate getDefaultMarkTemplateForRole(MarkRole markRole) { public MarkTemplate getDefaultMarkTemplateForMarkRole(MarkRole markRole) {
return defaultMarkTemplatesForRoles.get(markRole); return defaultMarkTemplatesForMarkRoles.get(markRole);
} }
@Override @Override
public Map<MarkRole, MarkTemplate> getDefaultMarkTemplatesForMarkRoles() { public Map<MarkRole, MarkTemplate> getDefaultMarkTemplatesForMarkRoles() {
return defaultMarkTemplatesForRoles; return defaultMarkTemplatesForMarkRoles;
} }
@Override @Override
@@ -186,18 +196,18 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
@Override @Override
public Map<MarkTemplate, MarkRole> getDefaultMarkRolesForMarkTemplates() { public Map<MarkTemplate, MarkRole> getDefaultMarkRolesForMarkTemplates() {
return defaultRolesForMarkTemplates; return defaultMarkRolesForMarkTemplates;
} }
@Override @Override
public MarkRole getOptionalAssociatedRole(MarkTemplate markTemplate) { public MarkRole getOptionalAssociatedRole(MarkTemplate markTemplate) {
return defaultRolesForMarkTemplates.get(markTemplate); return defaultMarkRolesForMarkTemplates.get(markTemplate);
} }
@Override @Override
public MarkRole getMarkRoleByIdIfContainedInCourseTemplate(UUID markRoleId) { public MarkRole getMarkRoleByIdIfContainedInCourseTemplate(UUID markRoleId) {
MarkRole result = null; MarkRole result = null;
for (MarkRole markRole : defaultRolesForMarkTemplates.values()) { for (MarkRole markRole : defaultMarkRolesForMarkTemplates.values()) {
if (markRole.getId().equals(markRoleId)) { if (markRole.getId().equals(markRoleId)) {
result = markRole; result = markRole;
break; break;
@@ -207,8 +217,8 @@ public class CourseTemplateImpl extends NamedWithUUIDImpl implements CourseTempl
} }
public void setAssociatedRoles(Map<MarkTemplate, MarkRole> associatedRoles) { public void setAssociatedRoles(Map<MarkTemplate, MarkRole> associatedRoles) {
this.defaultRolesForMarkTemplates.clear(); this.defaultMarkRolesForMarkTemplates.clear();
this.defaultRolesForMarkTemplates.putAll(associatedRoles); this.defaultMarkRolesForMarkTemplates.putAll(associatedRoles);
} }
@Override @Override
@@ -25,4 +25,9 @@ public class WaypointTemplateImpl implements WaypointTemplate {
return passingInstruction; return passingInstruction;
} }
@Override
public String toString() {
return "WaypointTemplateImpl [passingInstruction=" + passingInstruction + ", controlPointTemplate="
+ controlPointTemplate + "]";
}
} }
@@ -131,7 +131,7 @@ public class CourseTemplateJsonDeserializer implements JsonDeserializer<CourseTe
.get(CourseTemplateJsonSerializer.FIELD_DEFAULT_NUMBER_OF_LAPS); .get(CourseTemplateJsonSerializer.FIELD_DEFAULT_NUMBER_OF_LAPS);
final Integer defaultNumberOfLaps = defaultNumberOfLapsNumber == null ? null : defaultNumberOfLapsNumber.intValue(); final Integer defaultNumberOfLaps = defaultNumberOfLapsNumber == null ? null : defaultNumberOfLapsNumber.intValue();
final CourseTemplateImpl courseTemplate = new CourseTemplateImpl(null, courseTemplateName, final CourseTemplateImpl courseTemplate = new CourseTemplateImpl(null, courseTemplateName,
courseTemplateShortName, allMarkTemplatesById.values(), waypoints, defaultMarkRolesForMarkTemplates, defaultMarkTemplatesForMarkRoles, courseTemplateShortName, allMarkTemplatesById.values(), waypoints, defaultMarkTemplatesForMarkRoles, defaultMarkRolesForMarkTemplates,
optionalImageURL, optionalRepeatablePart, defaultNumberOfLaps); optionalImageURL, optionalRepeatablePart, defaultNumberOfLaps);
courseTemplate.setTags(tags); courseTemplate.setTags(tags);
return courseTemplate; return courseTemplate;
@@ -53,7 +53,7 @@ public class CourseTemplateJsonSerializer implements JsonSerializer<CourseTempla
final JSONArray allMarkRoles = new JSONArray(); final JSONArray allMarkRoles = new JSONArray();
courseTemplate.getMarkRoles().forEach(markRole -> { courseTemplate.getMarkRoles().forEach(markRole -> {
final JSONObject markRoleEntry = markRoleJsonSerializer.serialize(markRole); final JSONObject markRoleEntry = markRoleJsonSerializer.serialize(markRole);
markRoleEntry.put(FIELD_ASSOCIATED_MARK_TEMPLATE_ID, courseTemplate.getDefaultMarkTemplateForRole(markRole).getId().toString()); markRoleEntry.put(FIELD_ASSOCIATED_MARK_TEMPLATE_ID, courseTemplate.getDefaultMarkTemplateForMarkRole(markRole).getId().toString());
allMarkRoles.add(markRoleEntry); allMarkRoles.add(markRoleEntry);
}); });
result.put(FIELD_ALL_MARK_ROLES, allMarkRoles); result.put(FIELD_ALL_MARK_ROLES, allMarkRoles);
@@ -368,7 +368,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
final List<String> tags = new ArrayList<>(); final List<String> tags = new ArrayList<>();
tagsDbObject.forEach(t -> tags.add(t.toString())); tagsDbObject.forEach(t -> tags.add(t.toString()));
final CourseTemplateImpl courseTemplateImpl = new CourseTemplateImpl(id, name, shortName, markTemplates, final CourseTemplateImpl courseTemplateImpl = new CourseTemplateImpl(id, name, shortName, markTemplates,
waypointTemplates, associatedRoles, defaultMarkTemplatesForRoles, optionalImageURL, optionalRepeatablePart, defaultNumberOfLaps); waypointTemplates, defaultMarkTemplatesForRoles, associatedRoles, optionalImageURL, optionalRepeatablePart, defaultNumberOfLaps);
courseTemplateImpl.setTags(tags); courseTemplateImpl.setTags(tags);
return courseTemplateImpl; return courseTemplateImpl;
} }
@@ -402,8 +402,8 @@ public class SharedSailingDataImpl implements ReplicatingSharedSailingData, Clea
CourseTemplate existingCourseTemplate = courseTemplatesById.get(uuid); CourseTemplate existingCourseTemplate = courseTemplatesById.get(uuid);
CourseTemplateImpl courseTemplate = new CourseTemplateImpl(uuid, name, CourseTemplateImpl courseTemplate = new CourseTemplateImpl(uuid, name,
shortName, existingCourseTemplate.getMarkTemplates(), shortName, existingCourseTemplate.getMarkTemplates(),
existingCourseTemplate.getWaypointTemplates(), existingCourseTemplate.getDefaultMarkRolesForMarkTemplates(), existingCourseTemplate.getWaypointTemplates(), existingCourseTemplate.getDefaultMarkTemplatesForMarkRoles(),
existingCourseTemplate.getDefaultMarkTemplatesForMarkRoles(), optionalImageURL, existingCourseTemplate.getRepeatablePart(), existingCourseTemplate.getDefaultNumberOfLaps()); existingCourseTemplate.getDefaultMarkRolesForMarkTemplates(), optionalImageURL, existingCourseTemplate.getRepeatablePart(), existingCourseTemplate.getDefaultNumberOfLaps());
courseTemplate.setTags(tags); courseTemplate.setTags(tags);
mongoObjectFactory.storeCourseTemplate(courseTemplate); mongoObjectFactory.storeCourseTemplate(courseTemplate);
@@ -418,8 +418,8 @@ public class SharedSailingDataImpl implements ReplicatingSharedSailingData, Clea
Map<MarkTemplate, MarkRole> defaultMarkRolesForMarkTemplates, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles, Map<MarkTemplate, MarkRole> defaultMarkRolesForMarkTemplates, Map<MarkRole, MarkTemplate> defaultMarkTemplatesForMarkRoles,
RepeatablePart optionalRepeatablePart, Iterable<String> tags, URL optionalImageURL, Integer defaultNumberOfLaps) { RepeatablePart optionalRepeatablePart, Iterable<String> tags, URL optionalImageURL, Integer defaultNumberOfLaps) {
final CourseTemplateImpl courseTemplate = new CourseTemplateImpl(idOfNewCourseTemplate, courseTemplateName, final CourseTemplateImpl courseTemplate = new CourseTemplateImpl(idOfNewCourseTemplate, courseTemplateName,
courseTemplateShortName, marks, waypoints, defaultMarkRolesForMarkTemplates, courseTemplateShortName, marks, waypoints, defaultMarkTemplatesForMarkRoles,
defaultMarkTemplatesForMarkRoles, optionalImageURL, optionalRepeatablePart, defaultNumberOfLaps); defaultMarkRolesForMarkTemplates, optionalImageURL, optionalRepeatablePart, defaultNumberOfLaps);
courseTemplate.setTags(tags); courseTemplate.setTags(tags);
mongoObjectFactory.storeCourseTemplate(courseTemplate); mongoObjectFactory.storeCourseTemplate(courseTemplate);
courseTemplatesById.put(courseTemplate.getId(), courseTemplate); courseTemplatesById.put(courseTemplate.getId(), courseTemplate);