15c87fd0adc3c7373237f9069b0f43e542fa31dc
java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/racelog/tracking/TrackingTimesRevocationErrorCode.java
| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | +package com.sap.sailing.domain.common.racelog.tracking; |
|
| 2 | + |
|
| 3 | +/** |
|
| 4 | + * Error codes for the revocation of tracking times. These are used to report errors that occur during the revocation |
|
| 5 | + * process, e.g. when there is no regatta leaderboard or when there are no automated tracking times. |
|
| 6 | + * |
|
| 7 | + * @see com.sap.sailing.domain.racelogtracking.TrackingTimesRevocationReport |
|
| 8 | + * |
|
| 9 | + * @author Axel Uhl (d043530) |
|
| 10 | + * |
|
| 11 | + */ |
|
| 12 | +public enum TrackingTimesRevocationErrorCode { |
|
| 13 | + NO_REGATTA_LEADERBOARD, |
|
| 14 | + NO_AUTOMATED_TRACKING_TIMES |
|
| 15 | +} |
|
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/RaceLogTrackingAdapter.java
| ... | ... | @@ -140,4 +140,6 @@ public interface RaceLogTrackingAdapter { |
| 140 | 140 | */ |
| 141 | 141 | void copyPairingListFromOtherLeaderboard(RegattaLeaderboard sourceLeaderboard, RegattaLeaderboard targetLeaderboard, |
| 142 | 142 | String fromRaceColumnName, String toRaceColumnInclusiveName) throws NotFoundException; |
| 143 | + |
|
| 144 | + TrackingTimesRevocationReport revokeExplicitTrackingTimes(RegattaLeaderboard leaderboard, RacingEventService raceLogResolver); |
|
| 143 | 145 | } |
java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/TrackingTimesRevocationReport.java
| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | +package com.sap.sailing.domain.racelogtracking; |
|
| 2 | + |
|
| 3 | +import java.util.Map; |
|
| 4 | +import java.util.Set; |
|
| 5 | + |
|
| 6 | +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; |
|
| 7 | +import com.sap.sailing.domain.base.Fleet; |
|
| 8 | +import com.sap.sailing.domain.base.RaceColumn; |
|
| 9 | +import com.sap.sailing.domain.common.racelog.tracking.TrackingTimesRevocationErrorCode; |
|
| 10 | +import com.sap.sse.common.TimePoint; |
|
| 11 | +import com.sap.sse.common.Util.Pair; |
|
| 12 | + |
|
| 13 | +public interface TrackingTimesRevocationReport { |
|
| 14 | + /** |
|
| 15 | + * @return {@code null} means no error |
|
| 16 | + */ |
|
| 17 | + TrackingTimesRevocationErrorCode getErrorCode(); |
|
| 18 | + |
|
| 19 | + void revoked(RaceColumn raceColumn, Fleet fleet, RaceLogEvent event); |
|
| 20 | + |
|
| 21 | + void notRevokedBecauseOfMissingStartOrFinishTime(RaceColumn raceColumn, Fleet fleet, TimePoint startTime, TimePoint finishedTime); |
|
| 22 | + |
|
| 23 | + void notRevokedBecauseNotForTracking(RaceColumn raceColumn, Fleet fleet); |
|
| 24 | + |
|
| 25 | + Map<Pair<RaceColumn, Fleet>, Pair<TimePoint, TimePoint>> getNotRevokedBecauseOfMissingStartOfFinishTime(); |
|
| 26 | + |
|
| 27 | + Map<Pair<RaceColumn, Fleet>, Set<RaceLogEvent>> getRevokedEvents(); |
|
| 28 | + |
|
| 29 | + Iterable<Pair<RaceColumn, Fleet>> getNotRevokedBecauseNotForTracking(); |
|
| 30 | + |
|
| 31 | +} |
java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingAdapterImpl.java
| ... | ... | @@ -22,8 +22,14 @@ import org.osgi.framework.ServiceReference; |
| 22 | 22 | import com.sap.sailing.domain.abstractlog.impl.LastEventOfTypeFinder; |
| 23 | 23 | import com.sap.sailing.domain.abstractlog.impl.LogEventAuthorImpl; |
| 24 | 24 | import com.sap.sailing.domain.abstractlog.race.RaceLog; |
| 25 | +import com.sap.sailing.domain.abstractlog.race.RaceLogEndOfTrackingEvent; |
|
| 25 | 26 | import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; |
| 27 | +import com.sap.sailing.domain.abstractlog.race.RaceLogStartOfTrackingEvent; |
|
| 28 | +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.FinishedTimeFinder; |
|
| 26 | 29 | import com.sap.sailing.domain.abstractlog.race.analyzing.impl.LastPublishedCourseDesignFinder; |
| 30 | +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; |
|
| 31 | +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinderResult; |
|
| 32 | +import com.sap.sailing.domain.abstractlog.race.analyzing.impl.TrackingTimesEventFinder; |
|
| 27 | 33 | import com.sap.sailing.domain.abstractlog.race.impl.RaceLogCourseDesignChangedEventImpl; |
| 28 | 34 | import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogDenoteForTrackingEvent; |
| 29 | 35 | import com.sap.sailing.domain.abstractlog.race.tracking.RaceLogStartTrackingEvent; |
| ... | ... | @@ -67,6 +73,7 @@ import com.sap.sailing.domain.leaderboard.Leaderboard; |
| 67 | 73 | import com.sap.sailing.domain.leaderboard.RegattaLeaderboard; |
| 68 | 74 | import com.sap.sailing.domain.racelogtracking.DeviceMappingWithRegattaLogEvent; |
| 69 | 75 | import com.sap.sailing.domain.racelogtracking.RaceLogTrackingAdapter; |
| 76 | +import com.sap.sailing.domain.racelogtracking.TrackingTimesRevocationReport; |
|
| 70 | 77 | import com.sap.sailing.domain.regattalike.LeaderboardThatHasRegattaLike; |
| 71 | 78 | import com.sap.sailing.domain.tracking.RaceHandle; |
| 72 | 79 | import com.sap.sailing.domain.tracking.RaceTrackingHandler; |
| ... | ... | @@ -463,4 +470,50 @@ public class RaceLogTrackingAdapterImpl implements RaceLogTrackingAdapter { |
| 463 | 470 | copyCompetitors(sourceRaceColumn, sourceFleet, Collections.singleton(new Pair<>(targetRaceColumn, targetFleet))); |
| 464 | 471 | } |
| 465 | 472 | } |
| 473 | + |
|
| 474 | + @Override |
|
| 475 | + public TrackingTimesRevocationReport revokeExplicitTrackingTimes(RegattaLeaderboard leaderboard, RacingEventService service) { |
|
| 476 | + final TrackingTimesRevocationReportImpl result = new TrackingTimesRevocationReportImpl(/* error code */ null /* meaning no error */); |
|
| 477 | + for (final RaceColumn raceColumn : leaderboard.getRaceColumns()) { |
|
| 478 | + for (final Fleet fleet : raceColumn.getFleets()) { |
|
| 479 | + final RaceLog raceLog = raceColumn.getRaceLog(fleet); |
|
| 480 | + if (raceLog != null) { |
|
| 481 | + // handle only races denoted for smartphone tracking: |
|
| 482 | + if (new RaceLogTrackingStateAnalyzer(raceLog).analyze().isForTracking()) { |
|
| 483 | + final StartTimeFinder startTimeFinder = new StartTimeFinder(service, raceLog); |
|
| 484 | + final StartTimeFinderResult startTimeFinderResult = startTimeFinder.analyze(); |
|
| 485 | + final FinishedTimeFinder finishedTimeFinder = new FinishedTimeFinder(raceLog); |
|
| 486 | + final TimePoint finishedTime = finishedTimeFinder.analyze(); |
|
| 487 | + final TrackingTimesEventFinder trackingTimesEventFinder = new TrackingTimesEventFinder(raceLog); |
|
| 488 | + if (startTimeFinderResult != null && startTimeFinderResult.getStartTime() != null && finishedTime != null) { |
|
| 489 | + Pair<RaceLogStartOfTrackingEvent, RaceLogEndOfTrackingEvent> trackingTimes; |
|
| 490 | + while ((trackingTimes = trackingTimesEventFinder.analyze()) != null) { |
|
| 491 | + if (trackingTimes.getA() != null) { |
|
| 492 | + try { |
|
| 493 | + raceLog.revokeEvent(service.getServerAuthor(), trackingTimes.getA(), "revoke explicit start of tracking time"); |
|
| 494 | + result.revoked(raceColumn, fleet, trackingTimes.getA()); |
|
| 495 | + } catch (NotRevokableException e) { |
|
| 496 | + logger.log(Level.WARNING, "could not revoke explicit start of tracking time by adding RevokeEvent", e); |
|
| 497 | + } |
|
| 498 | + } |
|
| 499 | + if (trackingTimes.getB() != null) { |
|
| 500 | + try { |
|
| 501 | + raceLog.revokeEvent(service.getServerAuthor(), trackingTimes.getB(), "revoke explicit end of tracking time"); |
|
| 502 | + result.revoked(raceColumn, fleet, trackingTimes.getB()); |
|
| 503 | + } catch (NotRevokableException e) { |
|
| 504 | + logger.log(Level.WARNING, "could not revoke explicit end of tracking time by adding RevokeEvent", e); |
|
| 505 | + } |
|
| 506 | + } |
|
| 507 | + } |
|
| 508 | + } else { |
|
| 509 | + result.notRevokedBecauseOfMissingStartOrFinishTime(raceColumn, fleet, startTimeFinderResult != null ? startTimeFinderResult.getStartTime() : null, finishedTime); |
|
| 510 | + } |
|
| 511 | + } else { |
|
| 512 | + result.notRevokedBecauseNotForTracking(raceColumn, fleet); |
|
| 513 | + } |
|
| 514 | + } |
|
| 515 | + } |
|
| 516 | + } |
|
| 517 | + return result; |
|
| 518 | + } |
|
| 466 | 519 | } |
java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/TrackingTimesRevocationReportImpl.java
| ... | ... | @@ -0,0 +1,68 @@ |
| 1 | +package com.sap.sailing.domain.racelogtracking.impl; |
|
| 2 | + |
|
| 3 | +import java.util.ArrayList; |
|
| 4 | +import java.util.Collections; |
|
| 5 | +import java.util.HashSet; |
|
| 6 | +import java.util.LinkedHashMap; |
|
| 7 | +import java.util.List; |
|
| 8 | +import java.util.Map; |
|
| 9 | +import java.util.Set; |
|
| 10 | + |
|
| 11 | +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; |
|
| 12 | +import com.sap.sailing.domain.base.Fleet; |
|
| 13 | +import com.sap.sailing.domain.base.RaceColumn; |
|
| 14 | +import com.sap.sailing.domain.common.racelog.tracking.TrackingTimesRevocationErrorCode; |
|
| 15 | +import com.sap.sailing.domain.racelogtracking.TrackingTimesRevocationReport; |
|
| 16 | +import com.sap.sse.common.TimePoint; |
|
| 17 | +import com.sap.sse.common.Util.Pair; |
|
| 18 | + |
|
| 19 | +public class TrackingTimesRevocationReportImpl implements TrackingTimesRevocationReport { |
|
| 20 | + private final Map<Pair<RaceColumn, Fleet>, Set<RaceLogEvent>> revokedEvents; |
|
| 21 | + private final Map<Pair<RaceColumn, Fleet>, Pair<TimePoint, TimePoint>> notRevokedBecauseOfMissingStartOrFinishTime; |
|
| 22 | + private final List<Pair<RaceColumn, Fleet>> notRevokedBecauseNotForTracking; |
|
| 23 | + private final TrackingTimesRevocationErrorCode errorCode; |
|
| 24 | + |
|
| 25 | + public TrackingTimesRevocationReportImpl(TrackingTimesRevocationErrorCode errorCode) { |
|
| 26 | + super(); |
|
| 27 | + this.errorCode = errorCode; |
|
| 28 | + this.revokedEvents = new LinkedHashMap<>(); |
|
| 29 | + this.notRevokedBecauseOfMissingStartOrFinishTime = new LinkedHashMap<>(); |
|
| 30 | + this.notRevokedBecauseNotForTracking = new ArrayList<>(); |
|
| 31 | + } |
|
| 32 | + |
|
| 33 | + @Override |
|
| 34 | + public TrackingTimesRevocationErrorCode getErrorCode() { |
|
| 35 | + return errorCode; |
|
| 36 | + } |
|
| 37 | + |
|
| 38 | + @Override |
|
| 39 | + public void revoked(RaceColumn raceColumn, Fleet fleet, RaceLogEvent event) { |
|
| 40 | + final Set<RaceLogEvent> set = revokedEvents.computeIfAbsent(new Pair<>(raceColumn, fleet), k->new HashSet<>()); |
|
| 41 | + set.add(event); |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + @Override |
|
| 45 | + public void notRevokedBecauseOfMissingStartOrFinishTime(RaceColumn raceColumn, Fleet fleet, TimePoint startTime, TimePoint finishedTime) { |
|
| 46 | + notRevokedBecauseOfMissingStartOrFinishTime.put(new Pair<>(raceColumn, fleet), new Pair<>(startTime, finishedTime)); |
|
| 47 | + } |
|
| 48 | + |
|
| 49 | + @Override |
|
| 50 | + public void notRevokedBecauseNotForTracking(RaceColumn raceColumn, Fleet fleet) { |
|
| 51 | + notRevokedBecauseNotForTracking.add(new Pair<>(raceColumn, fleet)); |
|
| 52 | + } |
|
| 53 | + |
|
| 54 | + @Override |
|
| 55 | + public Map<Pair<RaceColumn, Fleet>, Pair<TimePoint, TimePoint>> getNotRevokedBecauseOfMissingStartOfFinishTime() { |
|
| 56 | + return Collections.unmodifiableMap(notRevokedBecauseOfMissingStartOrFinishTime); |
|
| 57 | + } |
|
| 58 | + |
|
| 59 | + @Override |
|
| 60 | + public Map<Pair<RaceColumn, Fleet>, Set<RaceLogEvent>> getRevokedEvents() { |
|
| 61 | + return Collections.unmodifiableMap(revokedEvents); |
|
| 62 | + } |
|
| 63 | + |
|
| 64 | + @Override |
|
| 65 | + public Iterable<Pair<RaceColumn, Fleet>> getNotRevokedBecauseNotForTracking() { |
|
| 66 | + return Collections.unmodifiableList(notRevokedBecauseNotForTracking); |
|
| 67 | + } |
|
| 68 | +} |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleResources.java
| ... | ... | @@ -118,6 +118,9 @@ public interface AdminConsoleResources extends ClientBundle { |
| 118 | 118 | |
| 119 | 119 | @Source("com/sap/sailing/gwt/ui/client/images/compose_mail_small.png") |
| 120 | 120 | ImageResource inviteBuoyTenders(); |
| 121 | + |
|
| 122 | + @Source("com/sap/sailing/gwt/ui/client/images/eraser-icon.png") |
|
| 123 | + ImageResource eraser(); |
|
| 121 | 124 | |
| 122 | 125 | @Source("com/sap/sailing/gwt/ui/client/images/ajax-loader.gif") |
| 123 | 126 | ImageResource loaderGif(); |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceLogTrackingEventManagementImagesBarCell.java
| ... | ... | @@ -4,6 +4,7 @@ import java.util.ArrayList; |
| 4 | 4 | |
| 5 | 5 | import com.google.gwt.core.client.GWT; |
| 6 | 6 | import com.google.gwt.text.shared.SafeHtmlRenderer; |
| 7 | +import com.sap.sailing.domain.common.LeaderboardType; |
|
| 7 | 8 | import com.sap.sailing.gwt.ui.client.StringMessages; |
| 8 | 9 | import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; |
| 9 | 10 | import com.sap.sse.gwt.client.IconResources; |
| ... | ... | @@ -17,6 +18,7 @@ public class RaceLogTrackingEventManagementImagesBarCell extends ImagesBarCell { |
| 17 | 18 | public final static String ACTION_MAP_DEVICES = "ACTION_MAP_DEVICES"; |
| 18 | 19 | public final static String ACTION_INVITE_BUOY_TENDERS = "ACTION_INVITE_BUOY_TENDERS"; |
| 19 | 20 | public static final String ACTION_SHOW_REGATTA_LOG = "ACTION_SHOW_REGATTA_LOG"; |
| 21 | + public static final String ACTION_REVOKE_EXPLICIT_TRACKING_TIMES = "ACTION_REVOKE_EXPLICIT_TRACKING_TIMES"; |
|
| 20 | 22 | private static AdminConsoleResources resources = GWT.create(AdminConsoleResources.class); |
| 21 | 23 | private final StringMessages stringMessages; |
| 22 | 24 | |
| ... | ... | @@ -48,11 +50,14 @@ public class RaceLogTrackingEventManagementImagesBarCell extends ImagesBarCell { |
| 48 | 50 | makeImagePrototype(resources.inviteBuoyTenders()))); |
| 49 | 51 | result.add(new ImageSpec(ACTION_SHOW_REGATTA_LOG, stringMessages.regattaLog(), |
| 50 | 52 | makeImagePrototype(resources.flagIcon()))); |
| 53 | + if (selectedLeaderboard.type == LeaderboardType.RegattaLeaderboard) { |
|
| 54 | + result.add(new ImageSpec(ACTION_REVOKE_EXPLICIT_TRACKING_TIMES, stringMessages.revokeExplicitTrackingTimes(), |
|
| 55 | + makeImagePrototype(resources.eraser()))); |
|
| 56 | + } |
|
| 51 | 57 | result.add(new ImageSpec(DefaultActions.CHANGE_OWNERSHIP.name(), stringMessages.actionChangeOwnership(), |
| 52 | 58 | IconResources.INSTANCE.changeOwnershipIcon())); |
| 53 | 59 | result.add(new ImageSpec(DefaultActions.CHANGE_ACL.name(), stringMessages.actionChangeACL(), |
| 54 | 60 | IconResources.INSTANCE.changeACLIcon())); |
| 55 | - |
|
| 56 | 61 | return result; |
| 57 | 62 | } |
| 58 | 63 | } |
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/SmartphoneTrackingEventManagementPanel.java
| ... | ... | @@ -59,6 +59,7 @@ import com.sap.sailing.gwt.ui.shared.RaceLogSetFinishingAndFinishTimeDTO; |
| 59 | 59 | import com.sap.sailing.gwt.ui.shared.RaceLogSetStartTimeAndProcedureDTO; |
| 60 | 60 | import com.sap.sailing.gwt.ui.shared.RegattaDTO; |
| 61 | 61 | import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; |
| 62 | +import com.sap.sailing.gwt.ui.shared.TrackingTimesRevocationReportDTO; |
|
| 62 | 63 | import com.sap.sse.common.Distance; |
| 63 | 64 | import com.sap.sse.common.Util; |
| 64 | 65 | import com.sap.sse.common.Util.Pair; |
| ... | ... | @@ -208,6 +209,8 @@ public class SmartphoneTrackingEventManagementPanel extends AbstractLeaderboardC |
| 208 | 209 | DefaultActions.UPDATE, t -> openChooseEventDialogAndSendMails(t.getName())); |
| 209 | 210 | leaderboardActionColumn.addAction(RaceLogTrackingEventManagementImagesBarCell.ACTION_SHOW_REGATTA_LOG, |
| 210 | 211 | DefaultActions.UPDATE, t -> showRegattaLog()); |
| 212 | + leaderboardActionColumn.addAction(RaceLogTrackingEventManagementImagesBarCell.ACTION_REVOKE_EXPLICIT_TRACKING_TIMES, |
|
| 213 | + DefaultActions.UPDATE, t -> revokeExplicitTrackingTimes()); |
|
| 211 | 214 | leaderboardActionColumn.addAction(DefaultActionsImagesBarCell.ACTION_CHANGE_OWNERSHIP, DefaultActions.UPDATE, |
| 212 | 215 | configOwnership::openOwnershipDialog); |
| 213 | 216 | leaderboardActionColumn.addAction(DefaultActionsImagesBarCell.ACTION_CHANGE_ACL, DefaultActions.UPDATE, |
| ... | ... | @@ -223,6 +226,66 @@ public class SmartphoneTrackingEventManagementPanel extends AbstractLeaderboardC |
| 223 | 226 | selectionCheckboxColumn.getSelectionManager()); |
| 224 | 227 | } |
| 225 | 228 | |
| 229 | + private void revokeExplicitTrackingTimes() { |
|
| 230 | + if (Window.confirm(stringMessages.confirmRevokeExplicitTrackingTimes(getSelectedLeaderboard().getName()))) { |
|
| 231 | + sailingServiceWrite.revokeExplicitTrackingTimes(getSelectedLeaderboard().getName(), new AsyncCallback<TrackingTimesRevocationReportDTO>() { |
|
| 232 | + @Override |
|
| 233 | + public void onFailure(Throwable caught) { |
|
| 234 | + errorReporter.reportError(stringMessages.errorRevokingExplicitTrackingTimes(getSelectedLeaderboard().getName(), caught.getMessage())); |
|
| 235 | + } |
|
| 236 | + |
|
| 237 | + @Override |
|
| 238 | + public void onSuccess(TrackingTimesRevocationReportDTO result) { |
|
| 239 | + Window.alert(result.getErrorCode() == null ? |
|
| 240 | + stringMessages.successfullyRevokedExplicitTrackingTimes(getSelectedLeaderboard().getName(), i18n(result)) : |
|
| 241 | + stringMessages.errorRevokingExplicitTrackingTimes(getSelectedLeaderboard().getName(), i18n(result))); |
|
| 242 | + loadAndRefreshLeaderboard(getSelectedLeaderboard().getName()); |
|
| 243 | + } |
|
| 244 | + |
|
| 245 | + private String i18n(TrackingTimesRevocationReportDTO report) { |
|
| 246 | + final StringBuilder result = new StringBuilder(); |
|
| 247 | + if (report.getErrorCode() != null) { |
|
| 248 | + switch (report.getErrorCode()) { |
|
| 249 | + case NO_REGATTA_LEADERBOARD: |
|
| 250 | + result.append(stringMessages.noRegattaLeaderboard(getSelectedLeaderboard().getName())).append("\n"); |
|
| 251 | + break; |
|
| 252 | + case NO_AUTOMATED_TRACKING_TIMES: |
|
| 253 | + result.append(stringMessages.noAutomatedTrackingTimes(getSelectedLeaderboard().getName())).append("\n"); |
|
| 254 | + break; |
|
| 255 | + default: |
|
| 256 | + result.append(stringMessages.unknownError(report.getErrorCode().name())).append("\n"); |
|
| 257 | + } |
|
| 258 | + } else { |
|
| 259 | + result.append(stringMessages.revokedTrackingTimesForEvents()).append("\n"); |
|
| 260 | + report.getRevokedEvents().forEach((raceColumnAndFleet, events)->{ |
|
| 261 | + final String raceColumnName = raceColumnAndFleet.getA().getName(); |
|
| 262 | + final String fleetName = raceColumnAndFleet.getB().getName(); |
|
| 263 | + result.append(" - ").append(raceColumnName).append(" / ").append(fleetName).append("\n"); |
|
| 264 | + events.forEach(event->{ |
|
| 265 | + result.append(" - ").append(event.getType()).append(" (").append(event.getLogicalTimePoint()).append(")\n"); |
|
| 266 | + }); |
|
| 267 | + }); |
|
| 268 | + result.append(stringMessages.notRevokedTrackingTimesBecauseNotForTracking()).append("\n"); |
|
| 269 | + report.getNotRevokedBecauseNotForTracking().forEach(raceColumnAndFleet->{ |
|
| 270 | + final String raceColumnName = raceColumnAndFleet.getA().getName(); |
|
| 271 | + final String fleetName = raceColumnAndFleet.getB().getName(); |
|
| 272 | + result.append(" - ").append(raceColumnName).append(" / ").append(fleetName).append("\n"); |
|
| 273 | + }); |
|
| 274 | + result.append(stringMessages.notRevokedTrackingTimesBecauseOfMissingStartOrFinishTime()).append("\n"); |
|
| 275 | + report.getNotRevokedBecauseOfMissingStartOrFinishTime().forEach((raceColumnAndFleet, startAndEndTime)->{ |
|
| 276 | + final String raceColumnName = raceColumnAndFleet.getA().getName(); |
|
| 277 | + final String fleetName = raceColumnAndFleet.getB().getName(); |
|
| 278 | + result.append(" - ").append(raceColumnName).append(" / ").append(fleetName) |
|
| 279 | + .append(" (").append(stringMessages.startTime()).append(": ").append(startAndEndTime.getA()) |
|
| 280 | + .append(", ").append(stringMessages.finishedTime()).append(": ").append(startAndEndTime.getB()).append(")\n"); |
|
| 281 | + }); |
|
| 282 | + } |
|
| 283 | + return result.toString(); |
|
| 284 | + } |
|
| 285 | + }); |
|
| 286 | + } |
|
| 287 | + } |
|
| 288 | + |
|
| 226 | 289 | private RaceLogTrackingState getTrackingState( |
| 227 | 290 | RaceColumnDTOAndFleetDTOWithNameBasedEquality race) { |
| 228 | 291 | return race.getA().getRaceLogTrackingInfo(race.getB()).raceLogTrackingState; |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceWrite.java
| ... | ... | @@ -84,6 +84,7 @@ import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO; |
| 84 | 84 | import com.sap.sailing.gwt.ui.shared.TracTracConfigurationWithSecurityDTO; |
| 85 | 85 | import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO; |
| 86 | 86 | import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO; |
| 87 | +import com.sap.sailing.gwt.ui.shared.TrackingTimesRevocationReportDTO; |
|
| 87 | 88 | import com.sap.sailing.gwt.ui.shared.TypedDeviceMappingDTO; |
| 88 | 89 | import com.sap.sailing.gwt.ui.shared.UrlDTO; |
| 89 | 90 | import com.sap.sailing.gwt.ui.shared.VenueDTO; |
| ... | ... | @@ -762,4 +763,6 @@ public interface SailingServiceWrite extends FileStorageManagementGwtService, Sa |
| 762 | 763 | |
| 763 | 764 | void copyPairingListFromOtherLeaderboard(String sourceLeaderboardName, String targetLeaderboardName, String fromRaceColumnName, |
| 764 | 765 | String toRaceColumnInclusiveName) throws UnauthorizedException, NotFoundException; |
| 766 | + |
|
| 767 | + TrackingTimesRevocationReportDTO revokeExplicitTrackingTimes(String leaderboardName) throws NotFoundException; |
|
| 765 | 768 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceWriteAsync.java
| ... | ... | @@ -13,6 +13,7 @@ import org.apache.shiro.authz.UnauthorizedException; |
| 13 | 13 | import com.google.gwt.user.client.rpc.AsyncCallback; |
| 14 | 14 | import com.sap.sailing.domain.base.Fleet; |
| 15 | 15 | import com.sap.sailing.domain.base.RaceColumn; |
| 16 | +import com.sap.sailing.domain.base.Regatta; |
|
| 16 | 17 | import com.sap.sailing.domain.common.CompetitorDescriptor; |
| 17 | 18 | import com.sap.sailing.domain.common.CompetitorRegistrationType; |
| 18 | 19 | import com.sap.sailing.domain.common.DataImportProgress; |
| ... | ... | @@ -41,6 +42,7 @@ import com.sap.sailing.domain.common.orc.ORCCertificate; |
| 41 | 42 | import com.sap.sailing.domain.common.orc.impl.ORCPerformanceCurveLegImpl; |
| 42 | 43 | import com.sap.sailing.domain.common.security.SecuredDomainType; |
| 43 | 44 | import com.sap.sailing.domain.common.security.SecuredDomainType.EventActions; |
| 45 | +import com.sap.sailing.domain.leaderboard.RegattaLeaderboard; |
|
| 44 | 46 | import com.sap.sailing.expeditionconnector.ExpeditionDeviceConfiguration; |
| 45 | 47 | import com.sap.sailing.gwt.ui.adminconsole.RaceLogSetTrackingTimesDTO; |
| 46 | 48 | import com.sap.sailing.gwt.ui.adminconsole.RemoteSailingServerEventsSelectionDialog; |
| ... | ... | @@ -70,6 +72,7 @@ import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO; |
| 70 | 72 | import com.sap.sailing.gwt.ui.shared.TracTracConfigurationWithSecurityDTO; |
| 71 | 73 | import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO; |
| 72 | 74 | import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO; |
| 75 | +import com.sap.sailing.gwt.ui.shared.TrackingTimesRevocationReportDTO; |
|
| 73 | 76 | import com.sap.sailing.gwt.ui.shared.TypedDeviceMappingDTO; |
| 74 | 77 | import com.sap.sailing.gwt.ui.shared.UrlDTO; |
| 75 | 78 | import com.sap.sailing.gwt.ui.shared.VenueDTO; |
| ... | ... | @@ -776,4 +779,18 @@ public interface SailingServiceWriteAsync extends FileStorageManagementGwtServic |
| 776 | 779 | |
| 777 | 780 | void copyPairingListFromOtherLeaderboard(String sourceLeaderboardName, String targetLeaderboardName, String fromRaceColumnName, |
| 778 | 781 | String toRaceColumnInclusiveName, AsyncCallback<Void> asyncCallback); |
| 782 | + |
|
| 783 | + /** |
|
| 784 | + * For the leaderboard identified by {@code leaderboardName}, revokes the explicit tracking times for all its |
|
| 785 | + * {@link RaceColumn}/{@link Fleet} combinations where the race log of that slot has a valid race start time and |
|
| 786 | + * valid finishing/finished times ("blue flag") in the Race Log. Multiple revocation events may be required because |
|
| 787 | + * due to priorities and time order, some tracking time events may "shadow" other such events that become valid |
|
| 788 | + * after revoking the one currently valid. The process continues until no more valid start/end tracking events exist |
|
| 789 | + * in that race log. |
|
| 790 | + * <p> |
|
| 791 | + * |
|
| 792 | + * Precondition: The leaderboard must be a {@link RegattaLeaderboard}, and the corresponding regatta must be in more |
|
| 793 | + * {@link Regatta#isControlTrackingFromStartAndFinishTimes()} |
|
| 794 | + */ |
|
| 795 | + void revokeExplicitTrackingTimes(String leaderboardName, AsyncCallback<TrackingTimesRevocationReportDTO> asyncCallback); |
|
| 779 | 796 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
| ... | ... | @@ -105,6 +105,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, |
| 105 | 105 | String event(); |
| 106 | 106 | String startTime(); |
| 107 | 107 | String endTime(); |
| 108 | + String finishedTime(); |
|
| 108 | 109 | String startOfTracking(); |
| 109 | 110 | String endOfTracking(); |
| 110 | 111 | String regatta(); |
| ... | ... | @@ -2555,4 +2556,14 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, |
| 2555 | 2556 | String ipsLockedForUserCreationAbuse(); |
| 2556 | 2557 | String unableToLoadIpsBlockedForUserCreationAbuse(); |
| 2557 | 2558 | String sourceCode(); |
| 2559 | + String revokeExplicitTrackingTimes(); |
|
| 2560 | + String confirmRevokeExplicitTrackingTimes(String leaderboardName); |
|
| 2561 | + String errorRevokingExplicitTrackingTimes(String leaderboardName, String message); |
|
| 2562 | + String successfullyRevokedExplicitTrackingTimes(String leaderboardName, String formattedAndTranslatedReport); |
|
| 2563 | + String revokedTrackingTimesForEvents(); |
|
| 2564 | + String notRevokedTrackingTimesBecauseNotForTracking(); |
|
| 2565 | + String notRevokedTrackingTimesBecauseOfMissingStartOrFinishTime(); |
|
| 2566 | + String noRegattaLeaderboard(String leaderboardName); |
|
| 2567 | + String noAutomatedTrackingTimes(String leaderboardName); |
|
| 2568 | + String unknownError(String name); |
|
| 2558 | 2569 | } |
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
| ... | ... | @@ -111,6 +111,7 @@ regattaName=Regatta name |
| 111 | 111 | eventName=Event name |
| 112 | 112 | event=Event |
| 113 | 113 | startTime=Start time |
| 114 | +finishedTime=Finished time |
|
| 114 | 115 | endTime=End time |
| 115 | 116 | startOfTracking=Start of tracking |
| 116 | 117 | endOfTracking=End of tracking |
| ... | ... | @@ -2591,3 +2592,13 @@ unlock=Unlock |
| 2591 | 2592 | ipsLockedForUserCreationAbuse=IPs Locked for User Creation Abuse |
| 2592 | 2593 | unableToLoadIpsBlockedForUserCreationAbuse=Unable to load IPs Blocked for User Creation Abuse |
| 2593 | 2594 | sourceCode=Source Code |
| 2595 | +revokeExplicitTrackingTimes=Revoke explicit tracking times for races with valid start and finishing times |
|
| 2596 | +confirmRevokeExplicitTrackingTimes=Really revoke explicit tracking times for all races of leaderboard {0} that have valid start and finishing times? |
|
| 2597 | +errorRevokingExplicitTrackingTimes=Error revoking explicit tracking times for leaderboard {0}: {1} |
|
| 2598 | +successfullyRevokedExplicitTrackingTimes=Successfully revoked explicit tracking times for leaderboard {0}: {1} |
|
| 2599 | +revokedTrackingTimesForEvents=Revoked tracking times for events: |
|
| 2600 | +notRevokedTrackingTimesBecauseNotForTracking=Not revoked tracking times for events that are not tracked: |
|
| 2601 | +notRevokedTrackingTimesBecauseOfMissingStartOrFinishTime=Not revoked tracking times for events with missing start or finish time: |
|
| 2602 | +noRegattaLeaderboard=Leaderboard {0} is not a regatta leaderboard. |
|
| 2603 | +noAutomatedTrackingTimes=Leaderboard {0} has no automated tracking times. |
|
| 2604 | +unknownError=Unknown error: {0} |
|
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
| ... | ... | @@ -112,6 +112,7 @@ regattaName=Name der Regatta |
| 112 | 112 | eventName=Event-Name |
| 113 | 113 | event=Veranstaltung |
| 114 | 114 | startTime=Startzeit |
| 115 | +finishedTime=Zielenlauf-Endezeit |
|
| 115 | 116 | endTime=Schlusszeit |
| 116 | 117 | startOfTracking=Start des Trackings |
| 117 | 118 | endOfTracking=Ende des Trackings |
| ... | ... | @@ -2585,3 +2586,13 @@ unlock=Entsperren |
| 2585 | 2586 | ipsLockedForUserCreationAbuse=Wegen Missbrauchs bei der Benutzererstellung gesperrte IPs |
| 2586 | 2587 | unableToLoadIpsBlockedForUserCreationAbuse=Wegen Missbrauchs der Benutzererstellung blockierte IPs können nicht geladen werden |
| 2587 | 2588 | sourceCode=Quellcode |
| 2589 | +revokeExplicitTrackingTimes=Explizite Tracking-Zeiten zurücksetzen für Rennen mit gültigen Start- und Endzeitpunkten |
|
| 2590 | +confirmRevokeExplicitTrackingTimes=Wirklich explizite Tracking-Zeiten zurücksetzen für Rennen mit gültigen Start- und Endzeitpunkten der Rangliste {0}? |
|
| 2591 | +errorRevokingExplicitTrackingTimes=Fehler beim Zurücksetzen expliziter Tracking-Zeiten für Rennen mit gültigen Start- und Endzeitpunkten der Rangliste {0}: {1} |
|
| 2592 | +successfullyRevokedExplicitTrackingTimes=Explizite Tracking-Zeiten erfolgreich zurückgesetzt für Rangliste {0}: {1} |
|
| 2593 | +revokedTrackingTimesForEvents=Widerrufene explizite Tracking-Zeiten: |
|
| 2594 | +notRevokedTrackingTimesBecauseNotForTracking=Nicht widerrufene explizite Tracking-Zeiten für nicht getrackte Rennen: |
|
| 2595 | +notRevokedTrackingTimesBecauseOfMissingStartOrFinishTime=Nicht widerrufene explizite Tracking-Zeiten für Rennen mit ungültigen Start- oder Endzeitpunkten: |
|
| 2596 | +noRegattaLeaderboard=Rangliste {0} ist keine Regatta-Rangliste. |
|
| 2597 | +noAutomatedTrackingTimes=Rangliste {0} nutzt keine automatisierten Tracking-Zeiten, auf die zurückgesetzt werden könnte. |
|
| 2598 | +unknownError=Unbekannter Fehler: {0} |
|
| ... | ... | \ No newline at end of file |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceWriteImpl.java
| ... | ... | @@ -207,6 +207,7 @@ import com.sap.sailing.domain.common.racelog.tracking.DoesNotHaveRegattaLogExcep |
| 207 | 207 | import com.sap.sailing.domain.common.racelog.tracking.MarkAlreadyUsedInRaceException; |
| 208 | 208 | import com.sap.sailing.domain.common.racelog.tracking.NotDenotableForRaceLogTrackingException; |
| 209 | 209 | import com.sap.sailing.domain.common.racelog.tracking.NotDenotedForRaceLogTrackingException; |
| 210 | +import com.sap.sailing.domain.common.racelog.tracking.TrackingTimesRevocationErrorCode; |
|
| 210 | 211 | import com.sap.sailing.domain.common.security.SecuredDomainType; |
| 211 | 212 | import com.sap.sailing.domain.common.security.SecuredDomainType.EventActions; |
| 212 | 213 | import com.sap.sailing.domain.common.tagging.RaceLogNotFoundException; |
| ... | ... | @@ -288,6 +289,7 @@ import com.sap.sailing.gwt.ui.shared.SwissTimingRaceRecordDTO; |
| 288 | 289 | import com.sap.sailing.gwt.ui.shared.TracTracConfigurationWithSecurityDTO; |
| 289 | 290 | import com.sap.sailing.gwt.ui.shared.TracTracRaceRecordDTO; |
| 290 | 291 | import com.sap.sailing.gwt.ui.shared.TrackFileImportDeviceIdentifierDTO; |
| 292 | +import com.sap.sailing.gwt.ui.shared.TrackingTimesRevocationReportDTO; |
|
| 291 | 293 | import com.sap.sailing.gwt.ui.shared.TypedDeviceMappingDTO; |
| 292 | 294 | import com.sap.sailing.gwt.ui.shared.UrlDTO; |
| 293 | 295 | import com.sap.sailing.gwt.ui.shared.VenueDTO; |
| ... | ... | @@ -4195,4 +4197,23 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili |
| 4195 | 4197 | getRaceLogTrackingAdapter().copyPairingListFromOtherLeaderboard((RegattaLeaderboard) sourceLeaderboard, |
| 4196 | 4198 | (RegattaLeaderboard) targetLeaderboard, fromRaceColumnName, toRaceColumnInclusiveName); |
| 4197 | 4199 | } |
| 4200 | + |
|
| 4201 | + @Override |
|
| 4202 | + public TrackingTimesRevocationReportDTO revokeExplicitTrackingTimes(String leaderboardName) throws NotFoundException { |
|
| 4203 | + final Leaderboard leaderboard = getLeaderboardByName(leaderboardName); |
|
| 4204 | + getService().getSecurityService().checkCurrentUserUpdatePermission(leaderboard); |
|
| 4205 | + final TrackingTimesRevocationReportDTO result; |
|
| 4206 | + if (leaderboard instanceof RegattaLeaderboard) { |
|
| 4207 | + final Regatta regatta = ((RegattaLeaderboard) leaderboard).getRegatta(); |
|
| 4208 | + if (regatta.isControlTrackingFromStartAndFinishTimes()) { |
|
| 4209 | + result = new TrackingTimesRevocationReportDTO(getRaceLogTrackingAdapter().revokeExplicitTrackingTimes( |
|
| 4210 | + (RegattaLeaderboard) leaderboard, /* raceLogResolver */ getService())); |
|
| 4211 | + } else { |
|
| 4212 | + result = new TrackingTimesRevocationReportDTO(TrackingTimesRevocationErrorCode.NO_AUTOMATED_TRACKING_TIMES); |
|
| 4213 | + } |
|
| 4214 | + } else { |
|
| 4215 | + result = new TrackingTimesRevocationReportDTO(TrackingTimesRevocationErrorCode.NO_REGATTA_LEADERBOARD); |
|
| 4216 | + } |
|
| 4217 | + return result; |
|
| 4218 | + } |
|
| 4198 | 4219 | } |
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/TrackingTimesRevocationReportDTO.java
| ... | ... | @@ -0,0 +1,97 @@ |
| 1 | +package com.sap.sailing.gwt.ui.shared; |
|
| 2 | + |
|
| 3 | +import java.util.ArrayList; |
|
| 4 | +import java.util.HashMap; |
|
| 5 | +import java.util.HashSet; |
|
| 6 | +import java.util.LinkedHashMap; |
|
| 7 | +import java.util.Map.Entry; |
|
| 8 | +import java.util.Set; |
|
| 9 | + |
|
| 10 | +import com.google.gwt.core.shared.GwtIncompatible; |
|
| 11 | +import com.google.gwt.user.client.rpc.IsSerializable; |
|
| 12 | +import com.sap.sailing.domain.abstractlog.race.RaceLogEvent; |
|
| 13 | +import com.sap.sailing.domain.base.Fleet; |
|
| 14 | +import com.sap.sailing.domain.base.RaceColumn; |
|
| 15 | +import com.sap.sailing.domain.common.dto.FleetDTO; |
|
| 16 | +import com.sap.sailing.domain.common.dto.RaceColumnDTO; |
|
| 17 | +import com.sap.sailing.domain.common.racelog.tracking.TrackingTimesRevocationErrorCode; |
|
| 18 | +import com.sap.sailing.domain.racelogtracking.TrackingTimesRevocationReport; |
|
| 19 | +import com.sap.sse.common.TimePoint; |
|
| 20 | +import com.sap.sse.common.Util.Pair; |
|
| 21 | + |
|
| 22 | +public class TrackingTimesRevocationReportDTO implements IsSerializable { |
|
| 23 | + private LinkedHashMap<Pair<RaceColumnDTO, FleetDTO>, HashSet<RaceLogEventDTO>> revokedEvents; |
|
| 24 | + private LinkedHashMap<Pair<RaceColumnDTO, FleetDTO>, Pair<TimePoint, TimePoint>> notRevokedBecauseOfMissingStartOrFinishTime; |
|
| 25 | + private ArrayList<Pair<RaceColumnDTO, FleetDTO>> notRevokedBecauseNotForTracking; |
|
| 26 | + private TrackingTimesRevocationErrorCode errorCode; |
|
| 27 | + |
|
| 28 | + @Deprecated |
|
| 29 | + TrackingTimesRevocationReportDTO() { |
|
| 30 | + // for GWT serialization |
|
| 31 | + } |
|
| 32 | + |
|
| 33 | + @GwtIncompatible |
|
| 34 | + public TrackingTimesRevocationReportDTO(TrackingTimesRevocationErrorCode errorCode) { |
|
| 35 | + this.errorCode = errorCode; |
|
| 36 | + } |
|
| 37 | + |
|
| 38 | + @GwtIncompatible |
|
| 39 | + public TrackingTimesRevocationReportDTO(TrackingTimesRevocationReport report) { |
|
| 40 | + this.errorCode = report.getErrorCode(); |
|
| 41 | + this.revokedEvents = new LinkedHashMap<>(); |
|
| 42 | + for (final Entry<Pair<RaceColumn, Fleet>, Set<RaceLogEvent>> e : report.getRevokedEvents().entrySet()) { |
|
| 43 | + revokedEvents.put( |
|
| 44 | + new Pair<>(toDTO(e.getKey().getA()), toDTO(e.getKey().getB())), |
|
| 45 | + new HashSet<>(e.getValue().stream().map(this::toDTO) |
|
| 46 | + .collect(java.util.stream.Collectors.toSet()))); |
|
| 47 | + } |
|
| 48 | + this.notRevokedBecauseOfMissingStartOrFinishTime = new LinkedHashMap<>(); |
|
| 49 | + for (final Entry<Pair<RaceColumn, Fleet>, Pair<TimePoint, TimePoint>> e : report.getNotRevokedBecauseOfMissingStartOfFinishTime().entrySet()) { |
|
| 50 | + notRevokedBecauseOfMissingStartOrFinishTime.put( |
|
| 51 | + new Pair<>(toDTO(e.getKey().getA()), toDTO(e.getKey().getB())), |
|
| 52 | + e.getValue()); |
|
| 53 | + } |
|
| 54 | + this.notRevokedBecauseNotForTracking = new ArrayList<>(); |
|
| 55 | + for (final Pair<RaceColumn, Fleet> e : report.getNotRevokedBecauseNotForTracking()) { |
|
| 56 | + notRevokedBecauseNotForTracking.add(new Pair<>(toDTO(e.getA()), toDTO(e.getB()))); |
|
| 57 | + } |
|
| 58 | + } |
|
| 59 | + |
|
| 60 | + /** |
|
| 61 | + * @return {@code null} means no error |
|
| 62 | + */ |
|
| 63 | + public TrackingTimesRevocationErrorCode getErrorCode() { |
|
| 64 | + return errorCode; |
|
| 65 | + } |
|
| 66 | + |
|
| 67 | + public HashMap<Pair<RaceColumnDTO, FleetDTO>, HashSet<RaceLogEventDTO>> getRevokedEvents() { |
|
| 68 | + return revokedEvents; |
|
| 69 | + } |
|
| 70 | + |
|
| 71 | + public HashMap<Pair<RaceColumnDTO, FleetDTO>, Pair<TimePoint, TimePoint>> getNotRevokedBecauseOfMissingStartOrFinishTime() { |
|
| 72 | + return notRevokedBecauseOfMissingStartOrFinishTime; |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + public ArrayList<Pair<RaceColumnDTO, FleetDTO>> getNotRevokedBecauseNotForTracking() { |
|
| 76 | + return notRevokedBecauseNotForTracking; |
|
| 77 | + } |
|
| 78 | + |
|
| 79 | + @GwtIncompatible |
|
| 80 | + private FleetDTO toDTO(Fleet fleet) { |
|
| 81 | + return new FleetDTO(fleet.getName(), fleet.getOrdering(), fleet.getColor()); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + @GwtIncompatible |
|
| 85 | + private RaceColumnDTO toDTO(final RaceColumn raceColumn) { |
|
| 86 | + return new RaceColumnDTO(raceColumn.getName(), raceColumn.isOneAlwaysStaysOne()); |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + @GwtIncompatible |
|
| 90 | + private RaceLogEventDTO toDTO(RaceLogEvent raceLogEvent) { |
|
| 91 | + return new RaceLogEventDTO(raceLogEvent.getPassId(), raceLogEvent.getAuthor().getName(), |
|
| 92 | + raceLogEvent.getAuthor().getPriority(), |
|
| 93 | + raceLogEvent.getCreatedAt() != null ? raceLogEvent.getCreatedAt().asDate() : null, |
|
| 94 | + raceLogEvent.getLogicalTimePoint() != null ? raceLogEvent.getLogicalTimePoint().asDate() : null, |
|
| 95 | + raceLogEvent.getClass().getSimpleName(), raceLogEvent.getShortInfo()); |
|
| 96 | + } |
|
| 97 | +} |
java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/eraser-icon.png
| ... | ... | Binary files /dev/null and b/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/eraser-icon.png differ |