Merge branch 'master' into tracapi

This commit is contained in:
Axel Uhl committed 2014-05-31 02:08:51 +02:00
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);
@@ -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
@@ -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() {
@@ -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;
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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) {
@@ -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;
}
}
@@ -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;
}
}