diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkConfiguration.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkConfiguration.java index 0601fcbbf0c..81d0d13bf4b 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkConfiguration.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkConfiguration.java @@ -10,7 +10,7 @@ package com.sap.sailing.domain.coursetemplate; * */ public interface FreestyleMarkConfiguration

extends MarkConfiguration

{ - CommonMarkProperties getFreestyleProperties(); + FreestyleMarkProperties getFreestyleProperties(); /** * @return a non-{@code null} object if this mark configuration originated from a {@link MarkProperties} object diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkProperties.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkProperties.java new file mode 100644 index 00000000000..67cdae678ce --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/FreestyleMarkProperties.java @@ -0,0 +1,10 @@ +package com.sap.sailing.domain.coursetemplate; + +/** + * While sharing most of @{@link CommonMarkProperties}, {@link MarkProperties} do have the distinct + * {@link FreestyleMarkConfiguration} property tags. + * + */ +public interface FreestyleMarkProperties extends CommonMarkProperties, HasTags { + void setTags(Iterable tags); +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/MarkProperties.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/MarkProperties.java index 93d4d2495a7..e20e861b304 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/MarkProperties.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/MarkProperties.java @@ -39,7 +39,7 @@ import com.sap.sse.security.shared.WithQualifiedObjectIdentifier; * @author Axel Uhl (d043530) * */ -public interface MarkProperties extends CommonMarkProperties, NamedWithUUID, HasTags, WithQualifiedObjectIdentifier { +public interface MarkProperties extends FreestyleMarkProperties, NamedWithUUID, WithQualifiedObjectIdentifier { void setColor(Color color); void setShape(String shape); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkConfigurationImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkConfigurationImpl.java index cbf3b5cd056..fb02a5d441c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkConfigurationImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkConfigurationImpl.java @@ -1,6 +1,7 @@ package com.sap.sailing.domain.coursetemplate.impl; import com.sap.sailing.domain.coursetemplate.CommonMarkProperties; +import com.sap.sailing.domain.coursetemplate.FreestyleMarkProperties; import com.sap.sailing.domain.coursetemplate.FreestyleMarkConfiguration; import com.sap.sailing.domain.coursetemplate.MarkConfigurationVisitor; import com.sap.sailing.domain.coursetemplate.MarkProperties; @@ -10,10 +11,10 @@ public class FreestyleMarkConfigurationImpl

extends MarkConfigurationImpl

private static final long serialVersionUID = 8167307943855869321L; private final MarkProperties optionalMarkProperties; - private final CommonMarkProperties freestyleProperties; + private final FreestyleMarkProperties freestyleProperties; public FreestyleMarkConfigurationImpl(MarkTemplate optionalMarkTemplate, MarkProperties optionalMarkProperties, - CommonMarkProperties freestyleProperties, P annotation) { + FreestyleMarkProperties freestyleProperties, P annotation) { super(optionalMarkTemplate, annotation); this.optionalMarkProperties = optionalMarkProperties; this.freestyleProperties = freestyleProperties; @@ -35,7 +36,7 @@ public class FreestyleMarkConfigurationImpl

extends MarkConfigurationImpl

} @Override - public CommonMarkProperties getFreestyleProperties() { + public FreestyleMarkProperties getFreestyleProperties() { return freestyleProperties; } diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkPropertiesImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkPropertiesImpl.java new file mode 100644 index 00000000000..c77b77c6bc1 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/FreestyleMarkPropertiesImpl.java @@ -0,0 +1,31 @@ +package com.sap.sailing.domain.coursetemplate.impl; + +import com.sap.sailing.domain.common.MarkType; +import com.sap.sailing.domain.coursetemplate.CommonMarkProperties; +import com.sap.sailing.domain.coursetemplate.FreestyleMarkProperties; +import com.sap.sse.common.Color; + +public class FreestyleMarkPropertiesImpl extends CommonMarkPropertiesImpl implements FreestyleMarkProperties { + private static final long serialVersionUID = -925045903410189747L; + private Iterable tags; + + public FreestyleMarkPropertiesImpl(String name, String shortName, Color color, String shape, String pattern, MarkType type, Iterable tags) { + super(name, shortName, color, shape, pattern, type); + this.tags = tags; + } + + public FreestyleMarkPropertiesImpl(final CommonMarkProperties commonMarkProperties, Iterable tags) { + this(commonMarkProperties.getName(), commonMarkProperties.getShortName(), commonMarkProperties.getColor(), + commonMarkProperties.getShape(), commonMarkProperties.getPattern(), commonMarkProperties.getType(), tags); + } + + @Override + public Iterable getTags() { + return this.tags; + } + + @Override + public void setTags(Iterable tags) { + this.tags = tags; + } +} diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/MarkPropertiesImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/MarkPropertiesImpl.java index 8d4343a75e4..4847d0d8cdc 100755 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/MarkPropertiesImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/coursetemplate/impl/MarkPropertiesImpl.java @@ -6,7 +6,6 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import com.sap.sailing.domain.common.MarkType; -import com.sap.sailing.domain.coursetemplate.CommonMarkProperties; import com.sap.sailing.domain.coursetemplate.MarkProperties; import com.sap.sailing.domain.coursetemplate.MarkRole; import com.sap.sailing.domain.coursetemplate.MarkTemplate; @@ -14,10 +13,9 @@ import com.sap.sailing.domain.coursetemplate.Positioning; import com.sap.sse.common.Color; import com.sap.sse.common.TimePoint; -public class MarkPropertiesImpl extends CommonMarkPropertiesImpl implements MarkProperties { +public class MarkPropertiesImpl extends FreestyleMarkPropertiesImpl implements MarkProperties { private static final long serialVersionUID = -5588202720707030502L; private Positioning positioningInformation; - private Iterable tags; private UUID id; private final ConcurrentHashMap lastUsedMarkTemplate = new ConcurrentHashMap<>(); @@ -29,12 +27,7 @@ public class MarkPropertiesImpl extends CommonMarkPropertiesImpl implements Mark public MarkPropertiesImpl(UUID id, String name, String shortName, Color color, String shape, String pattern, MarkType type) { - super(name, shortName, color, shape, pattern, type); - this.id = id; - } - - public MarkPropertiesImpl(UUID id, final CommonMarkProperties commonMarkProperties) { - super(commonMarkProperties); + super(name, shortName, color, shape, pattern, type, /* tags */ null); this.id = id; } @@ -78,15 +71,6 @@ public class MarkPropertiesImpl extends CommonMarkPropertiesImpl implements Mark this.positioningInformation = positioningInformation; } - @Override - public Iterable getTags() { - return this.tags; - } - - public void setTags(Iterable tags) { - this.tags = tags; - } - @Override public Map getLastUsedMarkTemplate() { return Collections.unmodifiableMap(lastUsedMarkTemplate); diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/CourseConfiguration.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/CourseConfiguration.java index fce37a91f28..4ab9921408d 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/CourseConfiguration.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/CourseConfiguration.java @@ -70,7 +70,7 @@ public class CourseConfiguration extends JsonWrapper { public MarkConfiguration getMarkConfigurationByEffectiveName(String name) { MarkConfiguration result = null; for (MarkConfiguration markConfiguration : getMarkConfigurations()) { - MarkAppearance effectiveProperties = markConfiguration.getEffectiveProperties(); + FreestyleProperties effectiveProperties = markConfiguration.getEffectiveProperties(); if (effectiveProperties != null && name.equals(effectiveProperties.getName())) { result = markConfiguration; break; diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkAppearance.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/FreestyleProperties.java similarity index 67% rename from java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkAppearance.java rename to java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/FreestyleProperties.java index d5afafff9cf..1f3d4459ed3 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkAppearance.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/FreestyleProperties.java @@ -1,10 +1,13 @@ package com.sap.sailing.selenium.api.coursetemplate; +import java.util.Set; + +import org.json.JSONArray; import org.json.simple.JSONObject; import com.sap.sailing.selenium.api.core.JsonWrapper; -public class MarkAppearance extends JsonWrapper { +public class FreestyleProperties extends JsonWrapper { private static final String FIELD_NAME = "name"; private static final String FIELD_SHORT_NAME = "shortName"; @@ -12,13 +15,14 @@ public class MarkAppearance extends JsonWrapper { private static final String FIELD_SHAPE = "shape"; private static final String FIELD_PATTERN = "pattern"; private static final String FIELD_MARK_TYPE = "markType"; + private static final String FIELD_TAG = "tag"; - public MarkAppearance(final JSONObject json) { + public FreestyleProperties(final JSONObject json) { super(json); } - public MarkAppearance(final String name, final String shortName, final String color, final String shape, - final String pattern, final String markType) { + public FreestyleProperties(final String name, final String shortName, final String color, final String shape, + final String pattern, final String markType, Set tags) { super(new JSONObject()); getJson().put(FIELD_NAME, name); getJson().put(FIELD_SHORT_NAME, shortName); @@ -26,6 +30,8 @@ public class MarkAppearance extends JsonWrapper { getJson().put(FIELD_SHAPE, shape); getJson().put(FIELD_PATTERN, pattern); getJson().put(FIELD_MARK_TYPE, markType); + JSONArray jsonTags = new JSONArray(tags); + getJson().put(FIELD_TAG, jsonTags); } public String getName() { diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkConfiguration.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkConfiguration.java index c6a016faccf..3c96c687f6e 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkConfiguration.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkConfiguration.java @@ -4,6 +4,7 @@ import static org.junit.Assert.assertEquals; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -38,7 +39,7 @@ public class MarkConfiguration extends JsonWrapper { public static MarkConfiguration createFreestyle(final UUID markTemplateId, final UUID markPropertiesId, final UUID associatedRoleId, final String name, final String shortName, final String color, - final String shape, final String pattern, final String markType) { + final String shape, final String pattern, final String markType, Set tags) { MarkConfiguration markConfiguration = new MarkConfiguration(new JSONObject()); markConfiguration.getJson().put(FIELD_ID, UUID.randomUUID().toString()); if (markTemplateId != null) { @@ -51,7 +52,7 @@ public class MarkConfiguration extends JsonWrapper { markConfiguration.getJson().put(FIELD_ASSOCIATED_ROLE_ID, associatedRoleId.toString()); } markConfiguration.getJson().put(FIELD_FREESTYLE_PROPERTIES, - new MarkAppearance(name, shortName, color, shape, pattern, markType).getJson()); + new FreestyleProperties(name, shortName, color, shape, pattern, markType, tags).getJson()); return markConfiguration; } @@ -137,14 +138,14 @@ public class MarkConfiguration extends JsonWrapper { return markTemplateId != null ? UUID.fromString((String) markTemplateId) : null; } - public MarkAppearance getEffectiveProperties() { + public FreestyleProperties getEffectiveProperties() { final JSONObject effectivePropertiesJson = (JSONObject) get(FIELD_EFFECTIVE_PROPERTIES); - return effectivePropertiesJson != null ? new MarkAppearance(effectivePropertiesJson) : null; + return effectivePropertiesJson != null ? new FreestyleProperties(effectivePropertiesJson) : null; } - public MarkAppearance getFreestyleProperties() { + public FreestyleProperties getFreestyleProperties() { final JSONObject effectivePropertiesJson = (JSONObject) get(FIELD_FREESTYLE_PROPERTIES); - return effectivePropertiesJson != null ? new MarkAppearance(effectivePropertiesJson) : null; + return effectivePropertiesJson != null ? new FreestyleProperties(effectivePropertiesJson) : null; } public boolean isStoreToInventory() { diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkProperties.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkProperties.java index ac537d890a5..bd26ffb9722 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkProperties.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/coursetemplate/MarkProperties.java @@ -1,7 +1,10 @@ package com.sap.sailing.selenium.api.coursetemplate; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; +import org.json.simple.JSONArray; import org.json.simple.JSONObject; import com.sap.sailing.domain.common.MarkType; @@ -21,6 +24,8 @@ public class MarkProperties extends JsonWrapper { private static final String FIELD_POSITIONING_DEVICE_IDENTIFIER = "device_identifier"; private static final String FIELD_POSITIONING_FIXED_POSITION_LATDEG = "latitude_deg"; private static final String FIELD_POSITIONING_FIXED_POSITION_LONDEG = "longitude_deg"; + private static final String FIELD_TAGS = "tag"; + public MarkProperties(JSONObject json) { super(json); @@ -79,6 +84,17 @@ public class MarkProperties extends JsonWrapper { final JSONObject position = (JSONObject) ((JSONObject) get(FIELD_POSITIONING)).get(FIELD_POSITIONING_POSITION); return (Double) (position == null ? null : position.get(FIELD_POSITIONING_FIXED_POSITION_LONDEG)); } + + public Set getTags() { + JSONArray jsonTags = get(FIELD_TAGS); + final Set tags = new HashSet<>(); + if(jsonTags != null) { + for(Object tag : jsonTags) { + tags.add(tag.toString()); + } + } + return tags; + } public void setLonDeg(double lonDeg) { JSONObject jsonPositioning = get(FIELD_POSITIONING); diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/CourseConfigurationTest.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/CourseConfigurationTest.java index b3ca56274c9..4ad9336eba5 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/CourseConfigurationTest.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/CourseConfigurationTest.java @@ -40,7 +40,7 @@ import com.sap.sailing.selenium.api.coursetemplate.CourseConfigurationApi; import com.sap.sailing.selenium.api.coursetemplate.CourseTemplate; import com.sap.sailing.selenium.api.coursetemplate.CourseTemplateApi; import com.sap.sailing.selenium.api.coursetemplate.DeviceMapping; -import com.sap.sailing.selenium.api.coursetemplate.MarkAppearance; +import com.sap.sailing.selenium.api.coursetemplate.FreestyleProperties; import com.sap.sailing.selenium.api.coursetemplate.MarkConfiguration; import com.sap.sailing.selenium.api.coursetemplate.MarkProperties; import com.sap.sailing.selenium.api.coursetemplate.MarkPropertiesApi; @@ -115,14 +115,14 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { final Map markConfigurationToNameMap = new HashMap<>(); for (final MarkConfiguration markConfiguration : srcMarkConfigurations) { final UUID markTemplateId = markConfiguration.getMarkTemplateId(); - MarkAppearance srcAppearance = markConfiguration.getEffectiveProperties(); + FreestyleProperties srcAppearance = markConfiguration.getEffectiveProperties(); if (srcAppearance == null) { srcAppearance = markConfiguration.getFreestyleProperties(); } Positioning srcPositioning = markConfiguration.getPositioning(); boolean found = false; for (final MarkConfiguration trgtMarkConfiguration : trgtMarkConfigurations) { - final MarkAppearance trgtAppearance = trgtMarkConfiguration.getEffectiveProperties(); + final FreestyleProperties trgtAppearance = trgtMarkConfiguration.getEffectiveProperties(); if (srcAppearance == null && trgtAppearance == null) { return; } @@ -572,14 +572,17 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { eventApi.createEvent(ctx, regattaName, "", CompetitorRegistrationType.CLOSED, ""); final RaceColumn race = regattaApi.addRaceColumn(ctx, regattaName, /* prefix */ null, 1)[0]; MarkConfiguration sb = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_sb", /* shortName */ null).getId(), "startboat", "sb", null, null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_sb", /* shortName */ null).getId(), "startboat", "sb", + null, null, null, null, Collections.emptySet()); sb.setFixedPosition(5.5, 7.1); MarkConfiguration pe = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_pe", /* shortName */ null).getId(), "pin end", "pe", null, null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_pe", /* shortName */ null).getId(), "pin end", "pe", + null, null, null, null, Collections.emptySet()); UUID randomDeviceId = UUID.randomUUID(); pe.setTrackingDeviceId(randomDeviceId); MarkConfiguration bl = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_bl", /* shortName */ null).getId(), "1", null, "#0000FF", null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_bl", /* shortName */ null).getId(), "1", null, + "#0000FF", null, null, null, Collections.emptySet()); WaypointWithMarkConfiguration wp1 = new WaypointWithMarkConfiguration("start/end", "s/e", PassingInstruction.Line, Arrays.asList(sb.getId(), pe.getId())); WaypointWithMarkConfiguration wp2 = new WaypointWithMarkConfiguration(null, null, PassingInstruction.Port, @@ -596,14 +599,17 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { @Test public void testCreateCourseTemplateWithPositioningIncluded() { MarkConfiguration sb = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_sb", /* shortName */ null).getId(), "startboat", "sb", null, null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_sb", /* shortName */ null).getId(), "startboat", "sb", + null, null, null, null, Collections.emptySet()); sb.setFixedPosition(5.5, 7.1); MarkConfiguration pe = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_pe", /* shortName */ null).getId(), "pin end", "pe", null, null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_pe", /* shortName */ null).getId(), "pin end", "pe", + null, null, null, null, Collections.emptySet()); UUID randomDeviceId = UUID.randomUUID(); pe.setTrackingDeviceId(randomDeviceId); MarkConfiguration bl = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_bl", /* shortName */ null).getId(), "1", null, "#0000FF", null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_bl", /* shortName */ null).getId(), "1", null, + "#0000FF", null, null, null, Collections.emptySet()); WaypointWithMarkConfiguration wp1 = new WaypointWithMarkConfiguration("start/end", "s/e", PassingInstruction.Line, Arrays.asList(sb.getId(), pe.getId())); WaypointWithMarkConfiguration wp2 = new WaypointWithMarkConfiguration(null, null, PassingInstruction.Port, @@ -640,7 +646,8 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { mc2.setFixedPosition(latDeg, longDeg); // overrides the 1.0 / 1.0 as provided by the mp1 MarkProperties object final MarkConfiguration mc3 = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_mp2", /* shortName */ null).getId(), "mc3", "mc3", "#0000FF", null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_mp2", /* shortName */ null).getId(), "mc3", "mc3", + "#0000FF", null, null, null, Collections.emptySet()); mc3.setFixedPosition(latDeg, longDeg); final UUID deviceId = UUID.randomUUID(); @@ -764,11 +771,11 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { final RaceColumn race = regattaApi.addRaceColumn(ctx, regattaName, /* prefix */ null, 1)[0]; final String pinEndName = "Start/Finish Pin"; MarkConfiguration sfp = MarkConfiguration.createFreestyle(null, null, null, pinEndName, "SFP", null, null, null, - MarkType.BUOY.name()); + MarkType.BUOY.name(), Collections.emptySet()); sfp.setFixedPosition(47.159776, 27.5891346); sfp.setStoreToInventory(true); MarkConfiguration sfb = MarkConfiguration.createFreestyle(null, null, null, "Start/Finish Boat", "SFB", null, - null, null, MarkType.STARTBOAT.name()); + null, null, MarkType.STARTBOAT.name(), Collections.emptySet()); sfp.setStoreToInventory(true); WaypointWithMarkConfiguration wp1 = new WaypointWithMarkConfiguration("Start", "S", PassingInstruction.Gate, Arrays.asList(sfp.getId(), sfb.getId())); @@ -810,7 +817,7 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { String markName = "some mark"; MarkConfiguration mark = MarkConfiguration.createFreestyle(null, null, null, markName, null, null, null, null, - MarkType.BUOY.name()); + MarkType.BUOY.name(), Collections.emptySet()); WaypointWithMarkConfiguration wp = new WaypointWithMarkConfiguration(null, null, PassingInstruction.Starboard, Arrays.asList(mark.getId())); @@ -875,18 +882,21 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { private void testCreateCourseConfigurationWithStoreToInventory(final ApiContext ctx, final ApiContext sharedServerCtx) { final String STARTBOAT_NAME = "startboat"; MarkConfiguration sb = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_sb", /* shortName */ null).getId(), STARTBOAT_NAME, "sb", null, null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_sb", /* shortName */ null).getId(), STARTBOAT_NAME, + "sb", null, null, null, null, Collections.emptySet()); final double startBoatLatDeg = 5.5; final double startBoatLonDeg = 7.1; sb.setFixedPosition(startBoatLatDeg, startBoatLonDeg); sb.setStoreToInventory(true); MarkConfiguration pe = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_pe", /* shortName */ null).getId(), "pin end", "pe", null, null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_pe", /* shortName */ null).getId(), "pin end", "pe", + null, null, null, null, Collections.emptySet()); pe.setStoreToInventory(true); UUID randomDeviceId = UUID.randomUUID(); pe.setTrackingDeviceId(randomDeviceId); MarkConfiguration bl = MarkConfiguration.createFreestyle(null, null, - markRoleApi.createMarkRole(sharedServerCtx, "role_bl", /* shortName */ null).getId(), "1", null, "#0000FF", null, null, null); + markRoleApi.createMarkRole(sharedServerCtx, "role_bl", /* shortName */ null).getId(), "1", null, + "#0000FF", null, null, null, Collections.emptySet()); MarkTemplate mtb2 = markTemplateApi.createMarkTemplate(sharedServerCtx, "mark template 1", "mt1", "#FFFFFF", "Cylinder", "Checkered", MarkType.BUOY.name()); MarkConfiguration b2 = MarkConfiguration.createMarkTemplateBased(mtb2.getId(), @@ -987,6 +997,32 @@ public class CourseConfigurationTest extends AbstractSeleniumTest { assertConsistentCourseConfiguration(createdCourseConfiguration); assertCourseConfigurationCompared(sharedServerCtx, simpleCourseConfiguration, createdCourseConfiguration); } + + @Test + public void createCourseConfigurationWithFreestyleUpdateForExistingMarkProperty() { + final double MP_LAT_DEG = 49.097487; + final double MP_LNG_DEG = 8.648631; + final UUID markPropertiesId = markPropertiesApi.createMarkProperties(sharedServerCtx, "mpWithPos", "mpWithPos", + /* deviceUuid */ null, "#ffffff", "shape", "pattern", MarkType.LANDMARK.name(), + Collections.emptyList(), MP_LAT_DEG, MP_LNG_DEG).getId(); + final Set tags = new HashSet<>(); + tags.add("tag1"); + final MarkConfiguration mc1 = MarkConfiguration.createFreestyle(null, markPropertiesId, null, null, null, + null, null, null, null, tags); + mc1.setStoreToInventory(true); + final WaypointWithMarkConfiguration wp1 = new WaypointWithMarkConfiguration("landmark", "landmark", + PassingInstruction.Single_Unknown, Arrays.asList(mc1.getId())); + final CourseConfiguration courseConfiguration = new CourseConfiguration("test1", Arrays.asList(mc1), + Arrays.asList(wp1)); + final String regattaName = "Regatta1"; + eventApi.createEvent(ctx, regattaName, "", CompetitorRegistrationType.CLOSED, ""); + final RaceColumn race = regattaApi.addRaceColumn(ctx, regattaName, null, 1)[0]; + courseConfigurationApi.createCourse(ctx, courseConfiguration, regattaName, + race.getRaceName(), "Default"); + MarkProperties markProperties = markPropertiesApi.getMarkProperties(sharedServerCtx, markPropertiesId); + Set updatedTags = markProperties.getTags(); + assertEquals(tags, updatedTags); + } private CourseConfiguration createSimpleCourseConfiguration(final ApiContext ctx) { List markConfigurations = new ArrayList(); diff --git a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/MarkApiTest.java b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/MarkApiTest.java index cf5041285ad..5f4c80d662a 100644 --- a/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/MarkApiTest.java +++ b/java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/test/MarkApiTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; +import java.util.Collections; import java.util.UUID; import org.junit.Before; @@ -153,11 +154,11 @@ public class MarkApiTest extends AbstractSeleniumTest { final String pinEndName = "Start/Finish Pin"; final MarkConfiguration sfp = MarkConfiguration.createFreestyle(null, null, null, pinEndName, "SFP", null, null, - null, MarkType.BUOY.name()); + null, MarkType.BUOY.name(), Collections.emptySet()); sfp.setFixedPosition(47.159776, 27.5891346); sfp.setStoreToInventory(true); final MarkConfiguration sfb = MarkConfiguration.createFreestyle(null, null, null, "Start/Finish Boat", "SFB", - null, null, null, MarkType.STARTBOAT.name()); + null, null, null, MarkType.STARTBOAT.name(), Collections.emptySet()); sfp.setStoreToInventory(true); final MarkConfiguration sft = MarkConfiguration.createMarkBased(mark.getMarkId(), null); sft.setFixedPosition(47.159776, 37.5891346); diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationBuilder.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationBuilder.java index 1544ff9d07c..649ac3845c1 100755 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationBuilder.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationBuilder.java @@ -20,7 +20,7 @@ import com.sap.sailing.domain.common.DeviceIdentifier; import com.sap.sailing.domain.common.PassingInstruction; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl; -import com.sap.sailing.domain.coursetemplate.CommonMarkProperties; +import com.sap.sailing.domain.coursetemplate.FreestyleMarkProperties; import com.sap.sailing.domain.coursetemplate.CourseConfiguration; import com.sap.sailing.domain.coursetemplate.CourseTemplate; import com.sap.sailing.domain.coursetemplate.CourseTemplateCompatibilityChecker; @@ -98,7 +98,7 @@ public class CourseConfigurationBuilder { } public MarkConfiguration addMarkConfiguration(UUID optionalMarkTemplateID, UUID optionalMarkPropertiesID, - UUID optionalMarkID, CommonMarkProperties commonMarkProperties, Positioning optionalPositioning, + UUID optionalMarkID, FreestyleMarkProperties commonMarkProperties, Positioning optionalPositioning, boolean storeToInventory, MarkRoleCreationRequest optionalMarkRoleCreationRequest) { final MarkConfiguration result; final MarkConfigurationRequestAnnotationImpl markConfigurationRequestAnnotation = new MarkConfigurationRequestAnnotationImpl( @@ -186,7 +186,7 @@ public class CourseConfigurationBuilder { } public FreestyleMarkConfiguration addFreestyleMarkConfiguration(UUID optionalMarkTemplateID, - UUID optionalMarkPropertiesID, CommonMarkProperties commonMarkProperties, MarkConfigurationRequestAnnotation markConfigurationRequestAnnotation) { + UUID optionalMarkPropertiesID, FreestyleMarkProperties commonMarkProperties, MarkConfigurationRequestAnnotation markConfigurationRequestAnnotation) { final MarkTemplate resolvedMarkTemplate = optionalMarkTemplateID == null ? null : resolveMarkTemplateByID(optionalMarkTemplateID); final MarkProperties resolvedMarkProperties = sharedSailingData.getMarkPropertiesById(optionalMarkPropertiesID); diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationJsonDeserializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationJsonDeserializer.java index 0c085b06bc4..5e85b41691c 100755 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationJsonDeserializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/deserialization/impl/CourseConfigurationJsonDeserializer.java @@ -13,7 +13,7 @@ import org.json.simple.JSONObject; import com.sap.sailing.domain.base.Regatta; import com.sap.sailing.domain.common.PassingInstruction; -import com.sap.sailing.domain.coursetemplate.CommonMarkProperties; +import com.sap.sailing.domain.coursetemplate.FreestyleMarkProperties; import com.sap.sailing.domain.coursetemplate.CourseConfiguration; import com.sap.sailing.domain.coursetemplate.CourseTemplate; import com.sap.sailing.domain.coursetemplate.MarkConfiguration; @@ -30,7 +30,7 @@ import com.sap.sailing.shared.server.SharedSailingData; public class CourseConfigurationJsonDeserializer implements JsonDeserializer> { private final SharedSailingData sharedSailingData; - private final CommonMarkPropertiesJsonDeserializer commonMarkPropertiesJsonDeserializer; + private final FreestyleMarkPropertiesJsonDeserializer commonMarkPropertiesJsonDeserializer; private final JsonDeserializer repeatablePartJsonDeserializer; private final Regatta regatta; private final PositioningJsonDeserializer positioningJsonDeserializer; @@ -38,7 +38,7 @@ public class CourseConfigurationJsonDeserializer implements JsonDeserializer { + private final CommonMarkPropertiesJsonDeserializer commonMarkPropertiesJsonDeserializer; + + public FreestyleMarkPropertiesJsonDeserializer() { + this.commonMarkPropertiesJsonDeserializer = new CommonMarkPropertiesJsonDeserializer(); + } + + @Override + public FreestyleMarkProperties deserialize(JSONObject json) throws JsonDeserializationException { + Object tagsArray = json.get(FreestyleMarkPropertiesJsonSerializer.FIELD_TAGS); + final Set tags = new HashSet<>(); + if (tagsArray != null && tagsArray instanceof JSONArray) { + for (Object tag : (JSONArray) tagsArray) { + tags.add(tag.toString()); + } + } + CommonMarkProperties commonMarkProperties = commonMarkPropertiesJsonDeserializer.deserialize(json); + return new FreestyleMarkPropertiesImpl(commonMarkProperties, tags); + } +} diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CourseConfigurationJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CourseConfigurationJsonSerializer.java index 3b359a409cc..03c5979f51c 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CourseConfigurationJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/CourseConfigurationJsonSerializer.java @@ -10,6 +10,7 @@ import org.json.simple.JSONObject; import com.sap.sailing.domain.common.DeviceIdentifier; import com.sap.sailing.domain.common.tracking.GPSFix; import com.sap.sailing.domain.coursetemplate.CommonMarkProperties; +import com.sap.sailing.domain.coursetemplate.FreestyleMarkProperties; import com.sap.sailing.domain.coursetemplate.ControlPointWithMarkConfiguration; import com.sap.sailing.domain.coursetemplate.CourseConfiguration; import com.sap.sailing.domain.coursetemplate.FreestyleMarkConfiguration; @@ -62,11 +63,13 @@ public class CourseConfigurationJsonSerializer implements JsonSerializer repeatablePartJsonSerializer; private final JsonSerializer commonMarkPropertiesJsonSerializer; + private final JsonSerializer commonMarkPropertiesWithTagsJsonSerializer; private final JsonSerializer gpsFixJsonSerializer; public CourseConfigurationJsonSerializer() { this.repeatablePartJsonSerializer = new RepeatablePartJsonSerializer(); this.commonMarkPropertiesJsonSerializer = new CommonMarkPropertiesJsonSerializer(); + this.commonMarkPropertiesWithTagsJsonSerializer = new FreestyleMarkPropertiesJsonSerializer(); this.gpsFixJsonSerializer = new GPSFixJsonSerializer(); } @@ -110,7 +113,7 @@ public class CourseConfigurationJsonSerializer implements JsonSerializer { + + public static final String FIELD_TAGS = "tag"; + + private final CommonMarkPropertiesJsonSerializer commonMarkPropertiesJsonSerializer; + + public FreestyleMarkPropertiesJsonSerializer() { + commonMarkPropertiesJsonSerializer = new CommonMarkPropertiesJsonSerializer(); + } + + @Override + public JSONObject serialize(FreestyleMarkProperties commonMarkProperties) { + JSONObject result = commonMarkPropertiesJsonSerializer.serialize(commonMarkProperties); + JSONArray jsonTags = new JSONArray(); + for (String tag : commonMarkProperties.getTags()) { + jsonTags.add(tag); + } + result.put(FIELD_TAGS, jsonTags); + return result; + } +} diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/MarkPropertiesJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/MarkPropertiesJsonSerializer.java index 92e6bfac148..2908cae78e4 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/MarkPropertiesJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/MarkPropertiesJsonSerializer.java @@ -8,14 +8,13 @@ import com.sap.sailing.server.gateway.serialization.JsonSerializer; public class MarkPropertiesJsonSerializer implements JsonSerializer { private static final String FIELD_ID = "id"; - private static final String FIELD_TAGS = "tags"; private static final String FIELD_POSITIONING = "positioning"; - private final CommonMarkPropertiesJsonSerializer commonMarkPropertiesJsonSerializer; + private final FreestyleMarkPropertiesJsonSerializer commonMarkPropertiesWithTagsJsonSerializer; private final PositioningJsonSerializer positioningJsonSerializer; public MarkPropertiesJsonSerializer(DeviceIdentifierJsonSerializer deviceIdentifierSerializer) { - this.commonMarkPropertiesJsonSerializer = new CommonMarkPropertiesJsonSerializer(); + this.commonMarkPropertiesWithTagsJsonSerializer = new FreestyleMarkPropertiesJsonSerializer(); this.positioningJsonSerializer = new PositioningJsonSerializer(deviceIdentifierSerializer); } @@ -25,8 +24,7 @@ public class MarkPropertiesJsonSerializer implements JsonSerializer tags = Collections.emptySet(); + if (effectiveProperties instanceof FreestyleMarkProperties) { + tags = ((FreestyleMarkProperties) effectiveProperties).getTags(); + }else { + tags = Collections.emptySet(); + } // If no mark properties exist yet, a new one is created - markPropertiesInInventory = getSharedSailingData().createMarkProperties(markConfiguration.getEffectiveProperties(), - /* tags */ Collections.emptySet(), optionalNonDefaultGroupOwnership); + markPropertiesInInventory = getSharedSailingData().createMarkProperties(effectiveProperties, tags, + optionalNonDefaultGroupOwnership); } else { + CommonMarkProperties effectiveProperties = markConfiguration.getEffectiveProperties(); + final Iterable tags; + if (effectiveProperties instanceof FreestyleMarkProperties) { + tags = ((FreestyleMarkProperties) effectiveProperties).getTags(); + }else { + tags = Collections.emptySet(); + } // in the case of a MarkPropertiesBasedMarkConfiguration, the following call is expected to notice // the identity between the mark properties object to update and the mark properties that constitute // the effective properties and then skip the update. markPropertiesInInventory = markPropertiesOrNull; - getSharedSailingData().updateMarkProperties(markPropertiesInInventory.getId(), markConfiguration.getEffectiveProperties(), - positioningOrNull, /* TODO tags */ Collections.emptySet()); + getSharedSailingData().updateMarkProperties(markPropertiesInInventory.getId(), effectiveProperties, + positioningOrNull, tags); } if (positioningOrNull != null) { positioningOrNull.accept(new PositioningVisitor() { @@ -316,11 +332,14 @@ public class CourseAndMarkConfigurationFactoryImpl implements CourseAndMarkConfi if (markPropertiesOrNull.hasEqualAppeareanceWith(effectiveMarkTemplate)) { effectiveConfiguration = new MarkPropertiesBasedMarkConfigurationImpl<>(markPropertiesOrNull, effectiveMarkTemplate, markConfiguration.getAnnotationInfo()); - } else { - effectiveConfiguration = new FreestyleMarkConfigurationImpl<>(effectiveMarkTemplate, - markPropertiesOrNull, effectiveMarkTemplate, markConfiguration.getAnnotationInfo()); - } - } else { + } else { + effectiveConfiguration = new FreestyleMarkConfigurationImpl<>(effectiveMarkTemplate, + markPropertiesOrNull, + new FreestyleMarkPropertiesImpl(effectiveMarkTemplate, + /* tags */ null), + markConfiguration.getAnnotationInfo()); + } + } else { effectiveConfiguration = new MarkTemplateBasedMarkConfigurationImpl<>(effectiveMarkTemplate, markConfiguration.getAnnotationInfo()); } diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/xdstorage/impl/LocalStorage.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/xdstorage/impl/LocalStorage.java index 0421e92b9df..099ff1e9244 100755 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/xdstorage/impl/LocalStorage.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/xdstorage/impl/LocalStorage.java @@ -2,6 +2,7 @@ package com.sap.sse.gwt.client.xdstorage.impl; import java.util.function.Consumer; +import com.google.gwt.core.client.GWT; import com.google.gwt.event.shared.HandlerRegistration; import com.sap.sse.gwt.client.Storage; import com.sap.sse.gwt.client.xdstorage.CrossDomainStorage; @@ -29,7 +30,11 @@ public class LocalStorage implements CrossDomainStorage { @Override public void setItem(String key, String value, Consumer callback) { - storage.setItem(key, value); + if (storage != null) { + storage.setItem(key, value); + } else { + GWT.log("Warning: cannot store "+key+"="+value+" in local storage; local storage not accessible"); + } if (callback != null) { callback.accept(null); } @@ -37,14 +42,25 @@ public class LocalStorage implements CrossDomainStorage { @Override public void getItem(String key, Consumer callback) { + final String result; + if (storage != null) { + result = storage.getItem(key); + } else { + GWT.log("Warning: cannot read "+key+" from local storage; local storage not accessible"); + result = null; + } if (callback != null) { - callback.accept(storage.getItem(key)); + callback.accept(result); } } @Override public void removeItem(String key, Consumer callback) { - storage.removeItem(key); + if (storage != null) { + storage.removeItem(key); + } else { + GWT.log("Warning: cannot remove "+key+" from local storage; local storage not accessible"); + } if (callback != null) { callback.accept(null); } @@ -52,7 +68,11 @@ public class LocalStorage implements CrossDomainStorage { @Override public void clear(Consumer callback) { - storage.clear(); + if (storage != null) { + storage.clear(); + } else { + GWT.log("Warning: cannot clear local storage; local storage not accessible"); + } if (callback != null) { callback.accept(null); } @@ -60,15 +80,29 @@ public class LocalStorage implements CrossDomainStorage { @Override public void key(int index, Consumer callback) { + final String result; + if (storage != null) { + result = storage.key(index); + } else { + GWT.log("Warning: cannot read key at index "+index+" from local storage; local storage not accessible"); + result = null; + } if (callback != null) { - callback.accept(storage.key(index)); + callback.accept(result); } } @Override public void getLength(Consumer callback) { if (callback != null) { - callback.accept(storage.getLength()); + final Integer result; + if (storage != null) { + result = storage.getLength(); + } else { + GWT.log("Warning: cannot get local storage length; local storage not accessible"); + result = null; + } + callback.accept(result); } } }