mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-30 15:57:11 +00:00
Merge branch 'master' into tracapi
This commit is contained in:
commit
3267116a38
98 files changed
+2532
-1672
No files matched your search
@@ -44,9 +44,11 @@ import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.domain.common.media.MediaTrack;
|
||||
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sailing.domain.common.racelog.tracking.TypeBasedServiceFinderFactory;
|
||||
import com.sap.sailing.domain.leaderboard.EventResolver;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroupResolver;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardRegistry;
|
||||
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.ScoringScheme;
|
||||
@@ -85,7 +87,7 @@ import com.sap.sailing.server.masterdata.DataImportLockWithProgress;
|
||||
*
|
||||
*/
|
||||
public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetcher, RegattaRegistry, RaceFetcher,
|
||||
LeaderboardRegistry, TrackerManager {
|
||||
LeaderboardRegistry, EventResolver, LeaderboardGroupResolver, TrackerManager {
|
||||
@Override
|
||||
Regatta getRegatta(RegattaName regattaName);
|
||||
|
||||
@@ -222,16 +224,10 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
*/
|
||||
Map<String, LeaderboardGroup> getLeaderboardGroups();
|
||||
|
||||
/**
|
||||
* @param groupName The name of the requested leaderboard group
|
||||
* @return The leaderboard group with the name <code>groupName</code>, or <code>null</code> if theres no such group
|
||||
*/
|
||||
LeaderboardGroup getLeaderboardGroupByName(String groupName);
|
||||
|
||||
/**
|
||||
* Creates a new group with the name <code>groupName</code>, the description <code>desciption</code> and the
|
||||
* leaderboards with the names in <code>leaderboardNames</code> and saves it in the database.
|
||||
*
|
||||
* @param id TODO
|
||||
* @param groupName
|
||||
* The name of the new group
|
||||
* @param description
|
||||
@@ -240,10 +236,11 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
* @param leaderboardNames
|
||||
* The names of the leaderboards, which should be contained by the new group.<br />
|
||||
* If there isn't a leaderboard with one of these names an {@link IllegalArgumentException} is thrown.
|
||||
*
|
||||
* @return The new leaderboard group
|
||||
*/
|
||||
LeaderboardGroup addLeaderboardGroup(String groupName, String description, boolean displayGroupsInReverseOrder,
|
||||
List<String> leaderboardNames, int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType);
|
||||
LeaderboardGroup addLeaderboardGroup(UUID id, String groupName, String description,
|
||||
boolean displayGroupsInReverseOrder, List<String> leaderboardNames, int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType);
|
||||
|
||||
/**
|
||||
* Removes the group with the name <code>groupName</code> from the service and the database.
|
||||
@@ -332,17 +329,8 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
Iterable<Event> getAllEvents();
|
||||
|
||||
/**
|
||||
* Returns the event with given id. When no event is found, <b>null</b> is returned.
|
||||
*
|
||||
* @param id
|
||||
* The id of the event.
|
||||
* @return The event with given id.
|
||||
*/
|
||||
Event getEvent(Serializable id);
|
||||
|
||||
/**
|
||||
* Creates a new event with the name <code>eventName</code>, the venue<code>venue</code> and the
|
||||
* regattas with the names in <code>regattaNames</code> and saves it in the database.
|
||||
* Creates a new event with the name <code>eventName</code>, the venue <code>venue</code> and the regattas with the
|
||||
* names in <code>regattaNames</code>, saves it in the database and replicates it. Use for TESTING only!
|
||||
*
|
||||
* @param eventName
|
||||
* The name of the new event
|
||||
@@ -361,9 +349,8 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
Event addEvent(String eventName, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, UUID id);
|
||||
|
||||
/**
|
||||
* Updates a sailing event with the name <code>eventName</code>, the venue<code>venue</code> and the
|
||||
* regattas with the names in <code>regattaNames</code> and updates it in the database.
|
||||
* @param id TODO
|
||||
* Updates a sailing event with the name <code>eventName</code>, the venue<code>venue</code> and the regattas with
|
||||
* the names in <code>regattaNames</code> and updates it in the database.
|
||||
* @param eventName
|
||||
* The name of the event to update
|
||||
* @param startDate
|
||||
@@ -374,12 +361,14 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
* The name of the venue of the event
|
||||
* @param isPublic
|
||||
* Indicates whether the event is public accessible via the publication URL or not
|
||||
* @param regattaNames
|
||||
* The names of the regattas contained in the event.<br />
|
||||
* @param leaderboardGroupIds
|
||||
* TODO
|
||||
* @param imageURLs TODO
|
||||
* @param videoURLs TODO
|
||||
*
|
||||
* @return The new event
|
||||
*/
|
||||
void updateEvent(UUID id, String eventName, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, List<String> regattaNames);
|
||||
void updateEvent(UUID id, String eventName, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, Iterable<UUID> leaderboardGroupIds, Iterable<URL> imageURLs, Iterable<URL> videoURLs);
|
||||
|
||||
/**
|
||||
* Renames a sailing event. If a sailing event by the name <code>oldName</code> does not exist in {@link #getEvents()},
|
||||
@@ -468,7 +457,7 @@ public interface RacingEventService extends TrackedRegattaRegistry, RegattaFetch
|
||||
ConcurrentHashMap<String, Regatta> getPersistentRegattasForRaceIDs();
|
||||
|
||||
Event createEventWithoutReplication(String eventName, TimePoint startDate, TimePoint endDate, String venue, boolean isPublic,
|
||||
UUID id);
|
||||
UUID id, Iterable<URL> imageURLs, Iterable<URL> videoURLs);
|
||||
|
||||
void setRegattaForRace(Regatta regatta, String raceIdAsString);
|
||||
|
||||
|
||||
+48
-12
@@ -159,7 +159,6 @@ import com.sap.sailing.server.operationaltransformation.RemoveWindFix;
|
||||
import com.sap.sailing.server.operationaltransformation.RenameEvent;
|
||||
import com.sap.sailing.server.operationaltransformation.SetDataImportDeleteProgressFromMapTimer;
|
||||
import com.sap.sailing.server.operationaltransformation.TrackRegatta;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateEvent;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateMarkPassings;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateMediaTrackDurationOperation;
|
||||
import com.sap.sailing.server.operationaltransformation.UpdateMediaTrackStartTimeOperation;
|
||||
@@ -246,9 +245,11 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
* {@link #renameLeaderboard(String, String)}.
|
||||
*/
|
||||
private final NamedReentrantReadWriteLock leaderboardsByNameLock;
|
||||
|
||||
|
||||
private final ConcurrentHashMap<String, LeaderboardGroup> leaderboardGroupsByName;
|
||||
|
||||
private final ConcurrentHashMap<UUID, LeaderboardGroup> leaderboardGroupsByID;
|
||||
|
||||
/**
|
||||
* See {@link #leaderboardsByNameLock}
|
||||
*/
|
||||
@@ -407,6 +408,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
raceTrackersByID = new ConcurrentHashMap<>();
|
||||
raceTrackersByIDLocks = new ConcurrentHashMap<>();
|
||||
leaderboardGroupsByName = new ConcurrentHashMap<>();
|
||||
leaderboardGroupsByID = new ConcurrentHashMap<>();
|
||||
leaderboardGroupsByNameLock = new NamedReentrantReadWriteLock("leaderboardGroupsByName for "+this, /* fair */ false);
|
||||
leaderboardsByName = new ConcurrentHashMap<String, Leaderboard>();
|
||||
leaderboardsByNameLock = new NamedReentrantReadWriteLock("leaderboardsByName for "+this, /* fair */ false);
|
||||
@@ -436,6 +438,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
loadStoredRegattas();
|
||||
loadRaceIDToRegattaAssociations();
|
||||
loadStoredLeaderboardsAndGroups();
|
||||
loadLinksFromEventsToLeaderboardGroups();
|
||||
loadMediaLibary();
|
||||
loadStoredDeviceConfigurations();
|
||||
loadAllRemoteSailingServersAndSchedulePeriodicEventCacheRefresh();
|
||||
@@ -507,6 +510,10 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLinksFromEventsToLeaderboardGroups() {
|
||||
domainObjectFactory.loadLeaderboardGroupLinksForEvents(/* eventResolver */ this, /* leaderboardGroupResolver */ this);
|
||||
}
|
||||
|
||||
private void loadAllRemoteSailingServersAndSchedulePeriodicEventCacheRefresh() {
|
||||
for (RemoteSailingServerReference sailingServer : domainObjectFactory.loadAllRemoteSailingServerReferences()) {
|
||||
remoteSailingServerSet.add(sailingServer);
|
||||
@@ -560,6 +567,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
LockUtil.lockForWrite(leaderboardGroupsByNameLock);
|
||||
try {
|
||||
leaderboardGroupsByName.put(leaderboardGroup.getName(), leaderboardGroup);
|
||||
leaderboardGroupsByID.put(leaderboardGroup.getId(), leaderboardGroup);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardGroupsByNameLock);
|
||||
}
|
||||
@@ -1794,11 +1802,16 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
public LeaderboardGroup getLeaderboardGroupByName(String groupName) {
|
||||
return leaderboardGroupsByName.get(groupName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardGroup getLeaderboardGroupByID(UUID leaderboardGroupID) {
|
||||
return leaderboardGroupsByID.get(leaderboardGroupID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardGroup addLeaderboardGroup(String groupName, String description,
|
||||
boolean displayGroupsInReverseOrder, List<String> leaderboardNames,
|
||||
int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType) {
|
||||
public LeaderboardGroup addLeaderboardGroup(UUID id, String groupName,
|
||||
String description, boolean displayGroupsInReverseOrder,
|
||||
List<String> leaderboardNames, int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType) {
|
||||
ArrayList<Leaderboard> leaderboards = new ArrayList<>();
|
||||
for (String leaderboardName : leaderboardNames) {
|
||||
Leaderboard leaderboard = leaderboardsByName.get(leaderboardName);
|
||||
@@ -1808,7 +1821,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
leaderboards.add(leaderboard);
|
||||
}
|
||||
}
|
||||
LeaderboardGroup result = new LeaderboardGroupImpl(groupName, description, displayGroupsInReverseOrder,
|
||||
LeaderboardGroup result = new LeaderboardGroupImpl(id, groupName, description, displayGroupsInReverseOrder,
|
||||
leaderboards);
|
||||
if (overallLeaderboardScoringSchemeType != null) {
|
||||
// create overall leaderboard and its discards settings
|
||||
@@ -1822,6 +1835,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
throw new IllegalArgumentException("Leaderboard group with name " + groupName + " already exists");
|
||||
}
|
||||
leaderboardGroupsByName.put(groupName, result);
|
||||
leaderboardGroupsByID.put(result.getId(), result);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardGroupsByNameLock);
|
||||
}
|
||||
@@ -1835,6 +1849,9 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
LockUtil.lockForWrite(leaderboardGroupsByNameLock);
|
||||
try {
|
||||
leaderboardGroup = leaderboardGroupsByName.remove(groupName);
|
||||
if (leaderboardGroup != null) {
|
||||
leaderboardGroupsByID.remove(leaderboardGroup.getId());
|
||||
}
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardGroupsByNameLock);
|
||||
}
|
||||
@@ -2065,6 +2082,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
LockUtil.lockForWrite(leaderboardGroupsByNameLock);
|
||||
try {
|
||||
leaderboardGroupsByName.clear();
|
||||
leaderboardGroupsByID.clear();
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(leaderboardGroupsByNameLock);
|
||||
}
|
||||
@@ -2110,6 +2128,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
leaderboardGroupsByName.putAll((Map<String, LeaderboardGroup>) ois.readObject());
|
||||
logoutput.append("Received " + leaderboardGroupsByName.size() + " NEW leaderboard groups\n");
|
||||
for (LeaderboardGroup lg : leaderboardGroupsByName.values()) {
|
||||
leaderboardGroupsByID.put(lg.getId(), lg);
|
||||
logoutput.append(String.format("%3s\n", lg.toString()));
|
||||
}
|
||||
|
||||
@@ -2163,16 +2182,22 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
}
|
||||
}
|
||||
|
||||
// Used for TESTING only
|
||||
@Override
|
||||
public Event addEvent(String eventName, TimePoint startDate, TimePoint endDate, String venue, boolean isPublic, UUID id) {
|
||||
Event result = createEventWithoutReplication(eventName, startDate, endDate, venue, isPublic, id);
|
||||
replicate(new CreateEvent(eventName, startDate, endDate, venue, isPublic, id));
|
||||
Event result = createEventWithoutReplication(eventName, startDate, endDate, venue, isPublic, id,
|
||||
/* imageURLs */ Collections.<URL>emptyList(), /* videoURLs */ Collections.<URL>emptyList());
|
||||
replicate(new CreateEvent(eventName, startDate, endDate, venue, isPublic, id, /* imageURLs */
|
||||
Collections.<URL> emptyList(), /* videoURLs */Collections.<URL> emptyList()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Event createEventWithoutReplication(String eventName, TimePoint startDate, TimePoint endDate, String venue, boolean isPublic, UUID id) {
|
||||
public Event createEventWithoutReplication(String eventName, TimePoint startDate, TimePoint endDate, String venue,
|
||||
boolean isPublic, UUID id, Iterable<URL> imageURLs, Iterable<URL> videoURLs) {
|
||||
Event result = new EventImpl(eventName, startDate, endDate, venue, isPublic, id);
|
||||
result.setImageURLs(imageURLs);
|
||||
result.setVideoURLs(videoURLs);
|
||||
if (eventsById.containsKey(result.getId())) {
|
||||
throw new IllegalArgumentException("Event with ID " + result.getId()
|
||||
+ " already exists which is pretty surprising...");
|
||||
@@ -2184,7 +2209,7 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
|
||||
@Override
|
||||
public void updateEvent(UUID id, String eventName, TimePoint startDate, TimePoint endDate, String venueName,
|
||||
boolean isPublic, List<String> regattaNames) {
|
||||
boolean isPublic, Iterable<UUID> leaderboardGroupIds, Iterable<URL> imageURLs, Iterable<URL> videoURLs) {
|
||||
final Event event = eventsById.get(id);
|
||||
if (event == null) {
|
||||
throw new IllegalArgumentException("Sailing event with ID " + id + " does not exist.");
|
||||
@@ -2194,9 +2219,20 @@ public class RacingEventServiceImpl implements RacingEventServiceWithTestSupport
|
||||
event.setEndDate(endDate);
|
||||
event.setPublic(isPublic);
|
||||
event.getVenue().setName(venueName);
|
||||
// TODO need to update regattas if they are once linked to event objects
|
||||
List<LeaderboardGroup> leaderboardGroups = new ArrayList<>();
|
||||
for (UUID lgid : leaderboardGroupIds) {
|
||||
LeaderboardGroup lg = getLeaderboardGroupByID(lgid);
|
||||
if (lg != null) {
|
||||
leaderboardGroups.add(lg);
|
||||
} else {
|
||||
logger.info("Couldn't find leaderboard group with ID "+lgid+" while updating event "+event.getName());
|
||||
}
|
||||
}
|
||||
event.setLeaderboardGroups(leaderboardGroups);
|
||||
event.setImageURLs(imageURLs);
|
||||
event.setVideoURLs(videoURLs);
|
||||
// TODO consider use diffutils to compute diff between old and new leaderboard groups list and apply the patch to keep changes minimial
|
||||
mongoObjectFactory.storeEvent(event);
|
||||
replicate(new UpdateEvent(id, eventName, startDate, endDate, venueName, isPublic, regattaNames));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-2
@@ -31,13 +31,15 @@ import com.sap.sailing.server.gateway.deserialization.impl.EventBaseJsonDeserial
|
||||
import com.sap.sailing.server.gateway.deserialization.impl.VenueJsonDeserializer;
|
||||
|
||||
/**
|
||||
* A set of {@link RemoteSailingServerReference}s including a cache of their {@link Event}s that is
|
||||
* A set of {@link RemoteSailingServerReference}s including a cache of their {@link EventBase events} that is
|
||||
* periodically updated.
|
||||
*
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class RemoteSailingServerSet {
|
||||
private static final int POLLING_INTERVAL_IN_SECONDS = 60;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RemoteSailingServerSet.class.getName());
|
||||
|
||||
/**
|
||||
@@ -55,7 +57,7 @@ public class RemoteSailingServerSet {
|
||||
remoteSailingServers = new ConcurrentHashMap<>();
|
||||
cachedEventsForRemoteSailingServers = new ConcurrentHashMap<>();
|
||||
scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { updateRemoteSailingServerReferenceEventCaches(); } },
|
||||
/* initialDelay */ 0, /* period */ 60, TimeUnit.SECONDS);
|
||||
/* initialDelay */ 0, POLLING_INTERVAL_IN_SECONDS, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
/**
|
||||
* Adds one or more leaderboard groups to an event. Leaderboard group(s) and event are specified by their UUID.
|
||||
* The event including the leaderboard group links is updated to the database.
|
||||
*
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class AddLeaderboardGroupToEvent extends AbstractRacingEventServiceOperation<Iterable<LeaderboardGroup>> {
|
||||
private static Logger logger = Logger.getLogger(AddLeaderboardGroupToEvent.class.getName());
|
||||
private static final long serialVersionUID = 5061411909275963501L;
|
||||
private final UUID eventId;
|
||||
private final UUID[] leaderboardGroupIds;
|
||||
|
||||
public AddLeaderboardGroupToEvent(UUID eventId, UUID... leaderboardGroupIds) {
|
||||
super();
|
||||
this.eventId = eventId;
|
||||
this.leaderboardGroupIds = leaderboardGroupIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<LeaderboardGroup> internalApplyTo(RacingEventService toState) throws Exception {
|
||||
boolean updated = false;
|
||||
Event event = toState.getEvent(eventId);
|
||||
List<LeaderboardGroup> result = new ArrayList<>();
|
||||
if (event != null) {
|
||||
for (UUID leaderboardGroupId : leaderboardGroupIds) {
|
||||
final LeaderboardGroup leaderboardGroup = toState.getLeaderboardGroupByID(leaderboardGroupId);
|
||||
if (leaderboardGroup != null) {
|
||||
event.addLeaderboardGroup(leaderboardGroup);
|
||||
result.add(leaderboardGroup);
|
||||
updated = true;
|
||||
} else {
|
||||
logger.info("Leaderboard group with ID " + leaderboardGroupId
|
||||
+ " not found. Cannot add leaderboard group to event with ID " + eventId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.info("Event with ID " + eventId + " not found. Cannot add leaderboard groups with IDs "
|
||||
+ Arrays.toString(leaderboardGroupIds) + " to it.");
|
||||
}
|
||||
if (updated) {
|
||||
toState.getMongoObjectFactory().storeEvent(event); // updated==true implies event!=null
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-2
@@ -1,5 +1,6 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
@@ -21,14 +22,19 @@ public class CreateEvent extends AbstractEventOperation<Event> {
|
||||
private final TimePoint endDate;
|
||||
private final boolean isPublic;
|
||||
private final String eventName;
|
||||
private final Iterable<URL> videoURLs;
|
||||
private final Iterable<URL> imageURLs;
|
||||
|
||||
public CreateEvent(String eventName, TimePoint startDate, TimePoint endDate, String venue, boolean isPublic, UUID id) {
|
||||
public CreateEvent(String eventName, TimePoint startDate, TimePoint endDate, String venue, boolean isPublic,
|
||||
UUID id, Iterable<URL> imageURLs, Iterable<URL> videoURLs) {
|
||||
super(id);
|
||||
this.eventName = eventName;
|
||||
this.startDate = startDate;
|
||||
this.endDate = endDate;
|
||||
this.venue = venue;
|
||||
this.isPublic = isPublic;
|
||||
this.imageURLs = imageURLs;
|
||||
this.videoURLs = videoURLs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +55,7 @@ public class CreateEvent extends AbstractEventOperation<Event> {
|
||||
|
||||
@Override
|
||||
public Event internalApplyTo(RacingEventService toState) {
|
||||
return toState.createEventWithoutReplication(getEventName(), startDate, endDate, venue, isPublic, getId());
|
||||
return toState.createEventWithoutReplication(getEventName(), startDate, endDate, venue, isPublic, getId(), imageURLs, videoURLs);
|
||||
}
|
||||
|
||||
}
|
||||
+5
-2
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
@@ -9,6 +10,7 @@ import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public class CreateLeaderboardGroup extends AbstractLeaderboardGroupOperation<LeaderboardGroup> {
|
||||
private static final long serialVersionUID = -5028997286564650805L;
|
||||
private final UUID id;
|
||||
private final String description;
|
||||
private final boolean displayGroupsInReverseOrder;
|
||||
private final List<String> leaderboardNames;
|
||||
@@ -18,6 +20,7 @@ public class CreateLeaderboardGroup extends AbstractLeaderboardGroupOperation<Le
|
||||
public CreateLeaderboardGroup(String leaderboardGroupName, String description, boolean displayGroupsInReverseOrder, List<String> leaderboardNames,
|
||||
int[] overallLeaderboardDiscardThresholds, ScoringSchemeType overallLeaderboardScoringSchemeType) {
|
||||
super(leaderboardGroupName);
|
||||
this.id = UUID.randomUUID();
|
||||
this.description = description;
|
||||
this.displayGroupsInReverseOrder = displayGroupsInReverseOrder;
|
||||
this.leaderboardNames = leaderboardNames;
|
||||
@@ -40,8 +43,8 @@ public class CreateLeaderboardGroup extends AbstractLeaderboardGroupOperation<Le
|
||||
@Override
|
||||
public LeaderboardGroup internalApplyTo(RacingEventService toState) {
|
||||
// TODO see bug 729: try to move addLeaderboardGroup implementation here and synthesize and apply this operation there
|
||||
return toState.addLeaderboardGroup(getLeaderboardGroupName(), description, displayGroupsInReverseOrder, leaderboardNames,
|
||||
overallLeaderboardDiscardThresholds, overallLeaderboardScoringSchemeType);
|
||||
return toState.addLeaderboardGroup(id, getLeaderboardGroupName(), description, displayGroupsInReverseOrder,
|
||||
leaderboardNames, overallLeaderboardDiscardThresholds, overallLeaderboardScoringSchemeType);
|
||||
}
|
||||
|
||||
}
|
||||
+74
-9
@@ -3,6 +3,7 @@ package com.sap.sailing.server.operationaltransformation;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -25,6 +26,7 @@ import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.common.impl.MasterDataImportObjectCreationCountImpl;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
@@ -93,6 +95,17 @@ public class ImportMasterDataOperation extends
|
||||
i++;
|
||||
progress.setCurrentSubProgressPct((double) i / numOfGroupsToImport);
|
||||
}
|
||||
progress.setNameOfCurrentSubProgress("Updating Event-LeaderboardGroup links");
|
||||
progress.setOverAllProgressPct(0.4);
|
||||
progress.setCurrentSubProgressPct(0);
|
||||
final Iterable<Event> allEvents = masterData.getAllEvents();
|
||||
int numOfEventsToHandle = Util.size(allEvents);
|
||||
int eventCounter = 0;
|
||||
for (Event e : allEvents) {
|
||||
updateLinksToLeaderboardGroups(toState, e);
|
||||
eventCounter++;
|
||||
progress.setCurrentSubProgressPct((double) eventCounter / numOfEventsToHandle);
|
||||
}
|
||||
progress.setNameOfCurrentSubProgress("Importing wind tracks");
|
||||
progress.setOverAllProgressPct(0.5);
|
||||
progress.setCurrentSubProgressPct(0);
|
||||
@@ -104,6 +117,59 @@ public class ImportMasterDataOperation extends
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all links from <code>eventReceived</code> to its leaderboard groups are established also on the
|
||||
* local event after import as long as those leaderboard groups are part of the actual import. For this subset of
|
||||
* leaderboard groups, equality of ordering is established between the <code>eventReceived</code>'s leaderboard
|
||||
* group sequence and the local event's leaderboard group sequence. This may require temporarily removing
|
||||
* leaderboard groups from the local event and re-adding them at the end which may change the ordering with respect
|
||||
* to other, non-imported leaderboard groups.
|
||||
* <p>
|
||||
*
|
||||
* Loops over the imported event's leaderboard groups and for those part of the import tries to find by ID each of
|
||||
* them in the local event's leaderboard group sequence. If not found, it is appended at the end. If found after the
|
||||
* position of the previous leaderboard group handled, it is left in place. Otherwise, it is removed and added again
|
||||
* at the end.
|
||||
*/
|
||||
private void updateLinksToLeaderboardGroups(RacingEventService racingEventService, Event eventReceived) {
|
||||
boolean changed = false;
|
||||
int positionOfLastLeaderboardGroupFoundInLocalEvent = -1;
|
||||
Event eventAfterImport = racingEventService.getEvent(eventReceived.getId());
|
||||
Collection<LeaderboardGroup> leaderboardGroupsReceived = masterData.getLeaderboardGroups();
|
||||
for (LeaderboardGroup lgInEventReceived : eventReceived.getLeaderboardGroups()) {
|
||||
if (leaderboardGroupsReceived.contains(lgInEventReceived)) {
|
||||
// it shall also be referenced by eventAfterImport, with a position that shall be greater than
|
||||
// positionOfLastLeaderboardGroupFoundInLocalEvent.
|
||||
int pos = 0;
|
||||
boolean found = false;
|
||||
for (LeaderboardGroup importedLg : eventAfterImport.getLeaderboardGroups()) {
|
||||
if (importedLg.getId().equals(lgInEventReceived.getId())) {
|
||||
found = true;
|
||||
if (pos < positionOfLastLeaderboardGroupFoundInLocalEvent) {
|
||||
// need to move lgInEventReceived; move to end
|
||||
eventAfterImport.removeLeaderboardGroup(importedLg);
|
||||
eventAfterImport.addLeaderboardGroup(importedLg);
|
||||
positionOfLastLeaderboardGroupFoundInLocalEvent = Util.size(eventAfterImport.getLeaderboardGroups())-1;
|
||||
changed = true;
|
||||
} else {
|
||||
positionOfLastLeaderboardGroupFoundInLocalEvent = pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
if (!found) {
|
||||
eventAfterImport.addLeaderboardGroup(racingEventService.getLeaderboardGroupByID(lgInEventReceived.getId()));
|
||||
positionOfLastLeaderboardGroupFoundInLocalEvent = Util.size(eventAfterImport.getLeaderboardGroups())-1;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
racingEventService.getMongoObjectFactory().storeEvent(eventAfterImport);
|
||||
}
|
||||
}
|
||||
|
||||
private void createLeaderboardGroupWithAllRelatedObjects(final RacingEventService toState,
|
||||
LeaderboardGroup leaderboardGroup) {
|
||||
Map<String, Leaderboard> existingLeaderboards = toState.getLeaderboards();
|
||||
@@ -144,6 +210,7 @@ public class ImportMasterDataOperation extends
|
||||
}
|
||||
|
||||
}
|
||||
// TODO bug 1975: as an aftermath of bug 1970, with LeaderboardGroup now implementing WithID, match making could happen by ID
|
||||
LeaderboardGroup existingLeaderboardGroup = toState.getLeaderboardGroupByName(leaderboardGroup.getName());
|
||||
if (existingLeaderboardGroup != null && override) {
|
||||
logger.info(String.format("Leaderboard Group with name %1$s already existed and will be overridden.",
|
||||
@@ -163,10 +230,10 @@ public class ImportMasterDataOperation extends
|
||||
overallLeaderboardDiscardThresholds = rule.getDiscardIndexResultsStartingWithHowManyRaces();
|
||||
overallLeaderboardScoringSchemeType = metaLeaderboard.getScoringScheme().getType();
|
||||
}
|
||||
leaderboardGroup = toState.addLeaderboardGroup(leaderboardGroup.getName(),
|
||||
leaderboardGroup.getDescription(), leaderboardGroup.isDisplayGroupsInReverseOrder(),
|
||||
leaderboardNames, overallLeaderboardDiscardThresholds,
|
||||
overallLeaderboardScoringSchemeType);
|
||||
leaderboardGroup = toState.addLeaderboardGroup(leaderboardGroup.getId(),
|
||||
leaderboardGroup.getName(), leaderboardGroup.getDescription(),
|
||||
leaderboardGroup.isDisplayGroupsInReverseOrder(), leaderboardNames,
|
||||
overallLeaderboardDiscardThresholds, overallLeaderboardScoringSchemeType);
|
||||
creationCount.addOneLeaderboardGroup(leaderboardGroup.getName());
|
||||
} else {
|
||||
leaderboardGroup = existingLeaderboardGroup;
|
||||
@@ -375,7 +442,8 @@ public class ImportMasterDataOperation extends
|
||||
TimePoint endDate = event.getEndDate();
|
||||
String venueName = event.getVenue().getName();
|
||||
boolean isPublic = event.isPublic();
|
||||
Event newEvent = toState.createEventWithoutReplication(name, startDate, endDate, venueName, isPublic, id);
|
||||
Event newEvent = toState.createEventWithoutReplication(name, startDate, endDate, venueName, isPublic, id,
|
||||
event.getImageURLs(), event.getVideoURLs());
|
||||
creationCount.addOneEvent(newEvent.getId().toString());
|
||||
} else {
|
||||
logger.info(String.format("Event with name %1$s already exists and hasn't been overridden.",
|
||||
@@ -400,10 +468,7 @@ public class ImportMasterDataOperation extends
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param iterable
|
||||
* @param uuid
|
||||
* @return true if course with given id exists in iterable
|
||||
* @return true if course with given id exists in <code>iterable</code>
|
||||
*/
|
||||
private boolean existsInSet(Iterable<CourseArea> iterable, UUID uuid) {
|
||||
for (CourseArea area : iterable) {
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.base.Event;
|
||||
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
|
||||
import com.sap.sailing.server.RacingEventService;
|
||||
import com.sap.sailing.server.RacingEventServiceOperation;
|
||||
|
||||
public class RemoveLeaderboardGroupFromEvent extends AbstractRacingEventServiceOperation<Boolean> {
|
||||
private static final long serialVersionUID = 5061411909275963501L;
|
||||
private static Logger logger = Logger.getLogger(RemoveLeaderboardGroupFromEvent.class.getName());
|
||||
private final UUID eventId;
|
||||
private final UUID[] leaderboardGroupIds;
|
||||
|
||||
public RemoveLeaderboardGroupFromEvent(UUID eventId, UUID... leaderboardGroupIds) {
|
||||
super();
|
||||
this.eventId = eventId;
|
||||
this.leaderboardGroupIds = leaderboardGroupIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean internalApplyTo(RacingEventService toState) throws Exception {
|
||||
boolean updated = false;
|
||||
Event event = toState.getEvent(eventId);
|
||||
if (event != null) {
|
||||
for (UUID leaderboardGroupId : leaderboardGroupIds) {
|
||||
final LeaderboardGroup leaderboardGroup = toState.getLeaderboardGroupByID(leaderboardGroupId);
|
||||
if (leaderboardGroup != null) {
|
||||
event.removeLeaderboardGroup(leaderboardGroup);
|
||||
updated = true;
|
||||
} else {
|
||||
logger.info("Leaderboard group with ID " + leaderboardGroupId
|
||||
+ " not found. Cannot remove leaderboard group from event with ID " + eventId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.info("Event with ID " + eventId + " not found. Cannot remove leaderboard groups with IDs "
|
||||
+ Arrays.toString(leaderboardGroupIds) + " from it.");
|
||||
}
|
||||
if (updated) {
|
||||
toState.getMongoObjectFactory().storeEvent(event); // updated==true implies event!=null
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformClientOp(RacingEventServiceOperation<?> serverOp) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RacingEventServiceOperation<?> transformServerOp(RacingEventServiceOperation<?> clientOp) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+10
-5
@@ -1,6 +1,6 @@
|
||||
package com.sap.sailing.server.operationaltransformation;
|
||||
|
||||
import java.util.List;
|
||||
import java.net.URL;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
@@ -13,17 +13,22 @@ public class UpdateEvent extends AbstractEventOperation<Void> {
|
||||
private final TimePoint startDate;
|
||||
private final TimePoint endDate;
|
||||
private final boolean isPublic;
|
||||
private final List<String> regattaNames;
|
||||
private final Iterable<UUID> leaderboardGroupIds;
|
||||
private final String eventName;
|
||||
private final Iterable<URL> imageURLs;
|
||||
private final Iterable<URL> videoURLs;
|
||||
|
||||
public UpdateEvent(UUID id, String eventName, TimePoint startDate, TimePoint endDate, String venueName, boolean isPublic, List<String> regattaNames) {
|
||||
public UpdateEvent(UUID id, String eventName, TimePoint startDate, TimePoint endDate, String venueName,
|
||||
boolean isPublic, Iterable<UUID> leaderboardGroupIds, Iterable<URL> imageURLs, Iterable<URL> videoURLs) {
|
||||
super(id);
|
||||
this.eventName = eventName;
|
||||
this.startDate = startDate;
|
||||
this.endDate = endDate;
|
||||
this.venueName = venueName;
|
||||
this.isPublic = isPublic;
|
||||
this.regattaNames = regattaNames;
|
||||
this.leaderboardGroupIds = leaderboardGroupIds;
|
||||
this.imageURLs = imageURLs;
|
||||
this.videoURLs = videoURLs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,7 +45,7 @@ public class UpdateEvent extends AbstractEventOperation<Void> {
|
||||
|
||||
@Override
|
||||
public Void internalApplyTo(RacingEventService toState) {
|
||||
toState.updateEvent(getId(), eventName, startDate, endDate, venueName, isPublic, regattaNames);
|
||||
toState.updateEvent(getId(), eventName, startDate, endDate, venueName, isPublic, leaderboardGroupIds, imageURLs, videoURLs);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user