From 5ece6b257ad37f45acd8de82030d5d486208d05d Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 15:03:49 +0100 Subject: [PATCH 01/12] added failing (deadlocking) test case for CompetitorDeregistrator Change-Id: Ic854ab429493530948ffa424f1df6d7365a39150 --- .../test/CompetitorDeregistrationTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java new file mode 100755 index 00000000000..80993ca0df5 --- /dev/null +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java @@ -0,0 +1,36 @@ +package com.sap.sailing.domain.regattalog.tracking.analyzing.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import java.util.Collections; +import java.util.Set; + +import org.junit.Test; + +import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEvent; +import com.sap.sailing.domain.abstractlog.regatta.RegattaLogEventVisitor; +import com.sap.sailing.domain.abstractlog.regatta.events.impl.RegattaLogRegisterCompetitorEventImpl; +import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorDeregistrator; +import com.sap.sailing.domain.abstractlog.shared.analyzing.CompetitorsInLogAnalyzer; +import com.sap.sailing.domain.base.Competitor; +import com.sap.sailing.domain.base.impl.CompetitorImpl; +import com.sap.sse.common.impl.MillisecondsTimePoint; + +public class CompetitorDeregistrationTest extends AbstractRegattaLogTrackingTest { + private final Competitor competitor = new CompetitorImpl("comp", "Comp", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null); + private final Competitor competitor2 = new CompetitorImpl("comp2", "Comp2", null, null, null, null, null, /* timeOnTimeFactor */ null, /* timeOnDistanceAllowancePerNauticalMile */ null); + + @Test + public void testCompetitorDeregistration() { + log.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), author, competitor)); + log.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), author, competitor2)); + final CompetitorDeregistrator deregistrator = new CompetitorDeregistrator<>(log, + Collections.singleton(competitor2), author); + deregistrator.analyze(); + final Set competitors = new CompetitorsInLogAnalyzer<>(log).analyze(); + assertEquals(1, competitors.size()); + assertSame(competitor, competitors.iterator().next()); + } +} From b59db4943dfeee4c6d001a9483576fdeca0aaa81 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 15:18:03 +0100 Subject: [PATCH 02/12] bug 3533: deadlock in CompetitorDeregistrator: fixed by separating finding the events from revoking them Change-Id: I52a0d149edcb89914e6847fd4c81f3796eb6f318 --- .../test/CompetitorDeregistrationTest.java | 3 +- .../analyzing/CompetitorDeregistrator.java | 41 ++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) mode change 100755 => 100644 java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java old mode 100755 new mode 100644 index 80993ca0df5..693e7df1e24 --- a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java +++ b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java @@ -28,7 +28,8 @@ public class CompetitorDeregistrationTest extends AbstractRegattaLogTrackingTest log.add(new RegattaLogRegisterCompetitorEventImpl(MillisecondsTimePoint.now(), author, competitor2)); final CompetitorDeregistrator deregistrator = new CompetitorDeregistrator<>(log, Collections.singleton(competitor2), author); - deregistrator.analyze(); + final Set events = deregistrator.analyze(); + deregistrator.deregister(events); final Set competitors = new CompetitorsInLogAnalyzer<>(log).analyze(); assertEquals(1, competitors.size()); assertSame(competitor, competitors.iterator().next()); diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorDeregistrator.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorDeregistrator.java index f1316b292b4..06c05304b64 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorDeregistrator.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/shared/analyzing/CompetitorDeregistrator.java @@ -1,6 +1,7 @@ package com.sap.sailing.domain.abstractlog.shared.analyzing; import java.util.HashSet; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -14,14 +15,21 @@ import com.sap.sailing.domain.common.abstractlog.NotRevokableException; import com.sap.sse.common.Util; /** - * Generates events that close the events that are responsible for the {@link #mapping} that is passed to the - * constructor. + * Finds the competitor registration events for a given set of {@link Competitor competitors} that must be + * {@link AbstractLog#revokeEvent(AbstractLogEventAuthor, AbstractLogEvent) revoked} in order to deregister the + * competitors. Note that the de-registration cannot be performed during analysis because + * {@link BaseLogAnalyzer#analyze()} obtains a read lock on the log whereas + * {@link AbstractLog#revokeEvent(AbstractLogEventAuthor, AbstractLogEvent)} requires a write lock, and upgrading from a + * read to a write lock is not possible.

+ * + * Clients must call {@link #deregister} with the result of {@link #analyze()} in order to actually perform the + * deregistration. * * @author Jan Bross * */ public class CompetitorDeregistrator, EventT extends AbstractLogEvent, VisitorT> -extends BaseLogAnalyzer { +extends BaseLogAnalyzer> { private static final Logger logger = Logger.getLogger(CompetitorDeregistrator.class.getName()); protected final Iterable competitorsToDeregister; @@ -34,24 +42,29 @@ extends BaseLogAnalyzer { } @Override - protected Void performAnalysis() { - HashSet competitorSet = new HashSet(); + protected Set performAnalysis() { + final Set result = new HashSet<>(); + final HashSet competitorSet = new HashSet(); Util.addAll(competitorsToDeregister, competitorSet); - for (EventT event : log.getUnrevokedEventsDescending()) { if (event instanceof RegisterCompetitorEvent) { RegisterCompetitorEvent registerEvent = (RegisterCompetitorEvent) event; if (competitorSet.contains(registerEvent.getCompetitor())) { - try { - log.revokeEvent(eventAuthor, event, - "unregistering competitor because no longer selected for registration"); - } catch (NotRevokableException e) { - logger.log(Level.WARNING, "could not unregister competitor by adding RevokeEvent", e); - } + result.add(event); } } } - - return null; + return result; + } + + public void deregister(final Set competitorRegistrationEvents) { + for (final EventT event : competitorRegistrationEvents) { + try { + log.revokeEvent(eventAuthor, event, + "unregistering competitor because no longer selected for registration"); + } catch (NotRevokableException e) { + logger.log(Level.WARNING, "could not unregister competitor by adding RevokeEvent", e); + } + } } } From 0a074cb73375f169bb832a6dc6ef19b08b0b8872 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 15:52:32 +0100 Subject: [PATCH 03/12] "amending" commit b59db4943dfeee4c6d001a9483576fdeca0aaa81, adding the two classes that use the changed protocol of CompetitorDeregistrator Change-Id: I50d58d556396d1dfbb9d53aaf3bb726ebdccd05f --- .../src/com/sap/sailing/domain/base/impl/RegattaImpl.java | 2 +- .../domain/leaderboard/impl/AbstractLeaderboardImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java index 75982559fa0..6c39ac72caa 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/base/impl/RegattaImpl.java @@ -792,6 +792,6 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene public void deregisterCompetitors(Iterable competitors) { RegattaLog regattaLog = getRegattaLike().getRegattaLog(); CompetitorDeregistrator deregisterer = new CompetitorDeregistrator<>(regattaLog, competitors, regattaLogEventAuthorForRegatta); - deregisterer.analyze(); + deregisterer.deregister(deregisterer.analyze()); } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java index 4c3ef7f9c9f..be0e19e182e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractLeaderboardImpl.java @@ -224,6 +224,6 @@ public abstract class AbstractLeaderboardImpl extends AbstractSimpleLeaderboardI public void deregisterCompetitors(Iterable competitors) { RegattaLog regattaLog = getRegattaLike().getRegattaLog(); CompetitorDeregistrator deregisterer = new CompetitorDeregistrator<>(regattaLog, competitors, regattaLogEventAuthorForAbstractLeaderboard); - deregisterer.analyze(); + deregisterer.deregister(deregisterer.analyze()); } } From 502eba54059d1fb0dbce04779b375e4ca00fec6e Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 15:54:51 +0100 Subject: [PATCH 04/12] added test for competiotr deregistration deadlock Change-Id: I4430894be7762e65ef92ffab95140bc71ac4360a --- .../tracking/analyzing/test/CompetitorDeregistrationTest.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java diff --git a/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java b/java/com.sap.sailing.domain.shared.android.test/src/com/sap/sailing/domain/regattalog/tracking/analyzing/test/CompetitorDeregistrationTest.java old mode 100644 new mode 100755 From 5e189d7e0ed77613cded44a617652e004b054239 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 15:55:12 +0100 Subject: [PATCH 05/12] removed unused text message Change-Id: Ida3758ee0f2b694ab939cbe88ff5b0d106810ba7 --- .../com/sap/sailing/gwt/common/client/i18n/TextMessages.java | 1 - .../sap/sailing/gwt/common/client/i18n/TextMessages.properties | 1 - .../sailing/gwt/common/client/i18n/TextMessages_de.properties | 1 - .../sailing/gwt/common/client/i18n/TextMessages_ru.properties | 1 - .../sailing/gwt/common/client/i18n/TextMessages_zh.properties | 1 - 5 files changed, 5 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java index 45104e186c4..69e1aad771f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.java @@ -139,7 +139,6 @@ public interface TextMessages extends Messages { String latestRaceResultsHeadline(); String latestRaceResultsIsNew(); String latestRaceResultsIsUpdated(); - String latestRaceResultsRaceCountLabel(); String latestRaceResultsRaceCountUnit(); String latestRaceResultsRefresh(); String leaderboardQuickAccessLabel(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties index 7365690323b..68759ed7726 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages.properties @@ -128,7 +128,6 @@ headerSponsoring=Sponsoring latestRaceResultsHeadline=Latest Official Race Results latestRaceResultsIsNew=New latestRaceResultsIsUpdated=Updated -latestRaceResultsRaceCountLabel=Result after latestRaceResultsRaceCountUnit=races latestRaceResultsRefresh=refresh leaderboardQuickAccessLabel=Leaderboard Quick Access diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties index 66836911be6..9076a2dfd83 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_de.properties @@ -128,7 +128,6 @@ headerSponsoring=Sponsoren latestRaceResultsHeadline=Letzten ofiziellen Ergebnisse latestRaceResultsIsNew=Neu latestRaceResultsIsUpdated=Aktualisiert -latestRaceResultsRaceCountLabel=Ergebnis nach latestRaceResultsRaceCountUnit=Rennen latestRaceResultsRefresh=aktualisieren leaderboardQuickAccessLabel=Ergebnisliste Schnellzugang diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_ru.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_ru.properties index 672db2ce8f1..46a2645ad4b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_ru.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_ru.properties @@ -128,7 +128,6 @@ headerSponsoring=Sponsoring latestRaceResultsHeadline=Latest Official Race Results latestRaceResultsIsNew=New latestRaceResultsIsUpdated=Updated -latestRaceResultsRaceCountLabel=Result after latestRaceResultsRaceCountUnit=races latestRaceResultsRefresh=refresh leaderboardQuickAccessLabel=Leaderboard Quick Access diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_zh.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_zh.properties index 09b2d649884..28c706f9abe 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_zh.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/i18n/TextMessages_zh.properties @@ -159,7 +159,6 @@ headerSponsoring=Sponsoring latestRaceResultsHeadline=Latest Official Race Results latestRaceResultsIsNew=New latestRaceResultsIsUpdated=Updated -latestRaceResultsRaceCountLabel=Result after latestRaceResultsRaceCountUnit=races latestRaceResultsRefresh=refresh leaderboardQuickAccessLabel=Leaderboard Quick Access From 2b0c5c56467d45e4e352ed7713563aecd5bf0957 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 16:06:42 +0100 Subject: [PATCH 06/12] removed sapSportsOn message as it isn't used anywhere Change-Id: I5fe925c2ad1a1936857ca8eafeb2d8c5aa6b4a6a --- .../java/com/sap/sailing/gwt/ui/client/StringMessages.properties | 1 - .../com/sap/sailing/gwt/ui/client/StringMessages_de.properties | 1 - .../com/sap/sailing/gwt/ui/client/StringMessages_ru.properties | 1 - .../com/sap/sailing/gwt/ui/client/StringMessages_zh.properties | 1 - 4 files changed, 4 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 856fab754ca..2d6caa36b5d 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -1289,7 +1289,6 @@ any=Any urlProviders=URL-based result providers pleaseSelectAURLProvider=Please select a URL-based result provider... sampleURL=Sample URL: {0} -sapSportsOn=SAP Sports on followSapSports=Follow SAP Sports liveNow=Live now analyseRace=Analyze race diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index ccf16bf9687..0bdfad72aa7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -1276,7 +1276,6 @@ any=Any urlProviders=URL-basierte Ergebnisdienste pleaseSelectAURLProvider=Bitte einen URL-basierten Ergebnisdienst auswählen... sampleURL=Beispiel-URL: {0} -sapSportsOn=SAP Sports bei followSapSports=SAP Sports folgen liveNow=Jetzt live analyseRace=Wettfahrt analysieren diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties index bd2a1016eb6..2bfd77c5109 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties @@ -1219,7 +1219,6 @@ any=Any urlProviders=URL-based result providers pleaseSelectAURLProvider=Please select a URL-based result provider... sampleURL=Sample URL: {0} -sapSportsOn=SAP Sports on followSapSports=Follow SAP Sports liveNow=Прямой эфир analyseRace=анализировать Гонка diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties index c3f713cad4b..b9a029c3962 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties @@ -1271,7 +1271,6 @@ any=Any urlProviders=URL-based result providers pleaseSelectAURLProvider=Please select a URL-based result provider... sampleURL=Sample URL: {0} -sapSportsOn=SAP Sports on followSapSports=Follow SAP Sports liveNow=Live now analyseRace=Analyze race From 460d805620686241bd2bbbe148309c68bb3789e6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 16:11:13 +0100 Subject: [PATCH 07/12] removed sapSportsOn message fron StringMessages.java Change-Id: I9316e181d623a41a3e807849b861236db4d6c7b8 --- .../main/java/com/sap/sailing/gwt/ui/client/StringMessages.java | 1 - 1 file changed, 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 673a5e59c7f..753320d32b9 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1323,7 +1323,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c String urlProviders(); String pleaseSelectAURLProvider(); String sampleURL(String sampleURL); - String sapSportsOn(); String followSapSports(); String liveNow(); String analyseRace(); From 8518b7400fc40862929a080d7e69da000b49d2ba Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 16:52:17 +0100 Subject: [PATCH 08/12] the boolean return value of Track.add is no longer useful if Track replaces equal fixes; reverting to void Change-Id: I70d698fff4b4f1d77a00a36f65548cf9d5c53710 --- .../domain/tracking/impl/TrackImpl.java | 27 +++++++++++++++---- .../sailing/domain/tracking/DynamicTrack.java | 4 +-- .../tracking/impl/CrossTrackErrorCache.java | 4 +-- .../impl/DynamicGPSFixMovingTrackImpl.java | 4 +-- .../tracking/impl/DynamicGPSFixTrackImpl.java | 4 +-- .../tracking/impl/DynamicTrackImpl.java | 4 +-- .../tracking/impl/DynamicTrackedRaceImpl.java | 3 ++- .../domain/tracking/impl/GPSFixTrackImpl.java | 6 ++--- .../domain/tracking/impl/WindTrackImpl.java | 5 ++-- 9 files changed, 38 insertions(+), 23 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java index f45ead7b68d..28b94e62df0 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java @@ -15,6 +15,16 @@ import com.sap.sse.concurrent.NamedReentrantReadWriteLock; import com.sap.sse.util.impl.ArrayListNavigableSet; import com.sap.sse.util.impl.UnmodifiableNavigableSet; +/** + * A track of fixes, ordered by their {@link Timed#getTimePoint() time stamp}. The underlying navigable set by default + * uses the time stamp not only as the ordering but also the equality criterion. {@link #add(Timed) Adding} a fix that + * has a time point equal to that of another fix already part of the track will replace the existing fix with the new + * one. + * + * @author Axel Uhl (D043530) + * + * @param + */ public class TrackImpl implements Track { private static final long serialVersionUID = -4075853657857657528L; /** @@ -312,20 +322,27 @@ public class TrackImpl implements Track { return result; } - protected boolean add(FixType fix) { + protected void add(FixType fix) { lockForWrite(); try { - return addWithoutLocking(fix); + addWithoutLocking(fix); } finally { unlockAfterWrite(); } } /** - * The caller must ensure to hold the write lock for this track when calling this methos + * The caller must ensure to hold the write lock for this track when calling this method. + * If an equal fix already exists, it is replaced by {@code fix}. Note that this is different + * from the semantics of the underlying {@link #fixes} set where trying to add an element for which + * an equal element already exists in the set will leave the set unchanged. */ - protected boolean addWithoutLocking(FixType fix) { - return getInternalRawFixes().add(fix); + protected void addWithoutLocking(FixType fix) { + final boolean equalFixExisted = !getInternalRawFixes().add(fix); + if (equalFixExisted) { + getInternalFixes().remove(fix); + getInternalFixes().add(fix); + } } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java index e1e728cf9c6..69d12dcc699 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java @@ -4,7 +4,7 @@ import com.sap.sse.common.Timed; public interface DynamicTrack extends Track { /** - * @return true if the element was added, false otherwise. + * Adds the fix to this track. An equal fix will be replaced. */ - boolean add(FixType fix); + void add(FixType fix); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CrossTrackErrorCache.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CrossTrackErrorCache.java index e8fe7b6b5c8..d91f677779b 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CrossTrackErrorCache.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/CrossTrackErrorCache.java @@ -113,8 +113,8 @@ public class CrossTrackErrorCache extends AbstractRaceChangeListener { } } - public boolean add(CrossTrackErrorSumAndNumberOfFixes entry) { - return getInternalRawFixes().add(entry); + public void add(CrossTrackErrorSumAndNumberOfFixes entry) { + getInternalRawFixes().add(entry); } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java index 474da3db2e6..636f598116d 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java @@ -51,8 +51,8 @@ public class DynamicGPSFixMovingTrackImpl extends GPSFixTrackImpl extends GPSFixTrackImpl extends TrackImpl * Simply makes the superclass method public as now we need to expose it via the {@link DynamicTrack} interface. */ @Override - public boolean add(FixType fix) { - return super.add(fix); + public void add(FixType fix) { + super.add(fix); } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java index c6b2997f97c..5fa9c5434b5 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicTrackedRaceImpl.java @@ -861,7 +861,8 @@ DynamicTrackedRace, GPSTrackListener { public boolean recordWind(Wind wind, WindSource windSource, boolean applyFilter) { final boolean result; if (!applyFilter || takesWindFixWithTimePoint(wind.getTimePoint())) { - result = getOrCreateWindTrack(windSource).add(wind); + getOrCreateWindTrack(windSource).add(wind); + result = true; updated(wind.getTimePoint()); triggerManeuverCacheRecalculationForAllCompetitors(); notifyListeners(wind, windSource); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java index 1259e536ac1..c29a9ca71c9 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java @@ -1100,13 +1100,12 @@ public class GPSFixTrackImpl extends TrackImpl } @Override - protected boolean add(FixType fix) { - final boolean result; + protected void add(FixType fix) { final boolean firstFixInTrack; lockForWrite(); try { firstFixInTrack = getRawFixes().isEmpty(); - result = addWithoutLocking(fix); + addWithoutLocking(fix); if (!validityCachingSuspended) { invalidateValidityAndEstimatedSpeedAndDistanceCaches(fix); } @@ -1133,7 +1132,6 @@ public class GPSFixTrackImpl extends TrackImpl for (GPSTrackListener listener : getListeners()) { listener.gpsFixReceived(fix, getTrackedItem(), firstFixInTrack); } - return result; } protected void setMillisecondsOverWhichToAverage(long millisecondsOverWhichToAverage) { diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java index 796f25602a5..71f3254412e 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java @@ -108,11 +108,10 @@ public class WindTrackImpl extends TrackImpl implements WindTrack { } @Override - public boolean add(Wind wind) { + public void add(Wind wind) { final CompactWindImpl compactWind = new CompactWindImpl(wind); - final boolean result = super.add(compactWind); + super.add(compactWind); notifyListenersAboutReceive(compactWind); - return result; } private void notifyListenersAboutReceive(Wind wind) { From b6e3e249fbefa1ad94b4e1d8b59d29d5cee25a96 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 16:53:03 +0100 Subject: [PATCH 09/12] Revert "removed sapSportsOn message as it isn't used anywhere" This reverts commit 2b0c5c56467d45e4e352ed7713563aecd5bf0957. --- .../java/com/sap/sailing/gwt/ui/client/StringMessages.properties | 1 + .../com/sap/sailing/gwt/ui/client/StringMessages_de.properties | 1 + .../com/sap/sailing/gwt/ui/client/StringMessages_ru.properties | 1 + .../com/sap/sailing/gwt/ui/client/StringMessages_zh.properties | 1 + 4 files changed, 4 insertions(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties index 2d6caa36b5d..856fab754ca 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties @@ -1289,6 +1289,7 @@ any=Any urlProviders=URL-based result providers pleaseSelectAURLProvider=Please select a URL-based result provider... sampleURL=Sample URL: {0} +sapSportsOn=SAP Sports on followSapSports=Follow SAP Sports liveNow=Live now analyseRace=Analyze race diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties index 0bdfad72aa7..ccf16bf9687 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties @@ -1276,6 +1276,7 @@ any=Any urlProviders=URL-basierte Ergebnisdienste pleaseSelectAURLProvider=Bitte einen URL-basierten Ergebnisdienst auswählen... sampleURL=Beispiel-URL: {0} +sapSportsOn=SAP Sports bei followSapSports=SAP Sports folgen liveNow=Jetzt live analyseRace=Wettfahrt analysieren diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties index 2bfd77c5109..bd2a1016eb6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_ru.properties @@ -1219,6 +1219,7 @@ any=Any urlProviders=URL-based result providers pleaseSelectAURLProvider=Please select a URL-based result provider... sampleURL=Sample URL: {0} +sapSportsOn=SAP Sports on followSapSports=Follow SAP Sports liveNow=Прямой эфир analyseRace=анализировать Гонка diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties index b9a029c3962..c3f713cad4b 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_zh.properties @@ -1271,6 +1271,7 @@ any=Any urlProviders=URL-based result providers pleaseSelectAURLProvider=Please select a URL-based result provider... sampleURL=Sample URL: {0} +sapSportsOn=SAP Sports on followSapSports=Follow SAP Sports liveNow=Live now analyseRace=Analyze race From a5f5cdfea963960bd07c57591aa20ad3908ec2b6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 16:53:17 +0100 Subject: [PATCH 10/12] Revert "removed sapSportsOn message fron StringMessages.java" This reverts commit 460d805620686241bd2bbbe148309c68bb3789e6. --- .../main/java/com/sap/sailing/gwt/ui/client/StringMessages.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java index 753320d32b9..673a5e59c7f 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java @@ -1323,6 +1323,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c String urlProviders(); String pleaseSelectAURLProvider(); String sampleURL(String sampleURL); + String sapSportsOn(); String followSapSports(); String liveNow(); String analyseRace(); From c90f36ccccf0d4477fd3b3f352a681d1846e5bb0 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 17:38:14 +0100 Subject: [PATCH 11/12] offer add(fix, replace) on Track to allow optional replacement of fixes in a track Change-Id: I312a8693f04440f529412f048bfdccd34c404109 --- .../domain/tracking/impl/TrackImpl.java | 25 ++++++++++++++++--- .../sailing/domain/tracking/DynamicTrack.java | 18 +++++++++++++ .../impl/DynamicGPSFixMovingTrackImpl.java | 5 ++++ .../tracking/impl/DynamicGPSFixTrackImpl.java | 7 +++++- .../tracking/impl/DynamicTrackImpl.java | 5 ++++ .../domain/tracking/impl/GPSFixTrackImpl.java | 2 +- .../domain/tracking/impl/WindTrackImpl.java | 9 +++++-- 7 files changed, 63 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java index f45ead7b68d..de350e75ac7 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/tracking/impl/TrackImpl.java @@ -313,19 +313,36 @@ public class TrackImpl implements Track { } protected boolean add(FixType fix) { + return add(fix, /* replace */ false); + } + + protected boolean add(FixType fix, boolean replace) { lockForWrite(); try { - return addWithoutLocking(fix); + return addWithoutLocking(fix, replace); } finally { unlockAfterWrite(); } } /** - * The caller must ensure to hold the write lock for this track when calling this methos + * The caller must ensure to hold the write lock for this track when calling this method. + * + * @param replace + * whether or not to replace an existing fix in the track that is equal to {@link #fix} as defined by the + * comparator used for the {@link #fixes} set. By default this is a comparator only comparing the + * fixes' time stamps. Subclasses may use different comparator implementations. */ - protected boolean addWithoutLocking(FixType fix) { - return getInternalRawFixes().add(fix); + protected boolean addWithoutLocking(FixType fix, boolean replace) { + final boolean result; + final boolean added = getInternalRawFixes().add(fix); + if (!added && replace) { + getInternalRawFixes().remove(fix); + result = getInternalFixes().add(fix); + } else { + result = added; + } + return result; } @Override diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java index e1e728cf9c6..970e9fbf522 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/DynamicTrack.java @@ -4,7 +4,25 @@ import com.sap.sse.common.Timed; public interface DynamicTrack extends Track { /** + * Tries to add {@code fix} to this track. If an {@link #equals(Object) equal} fix already exists + * in this track, the track remains unchanged and {@code false} will be returned. + * * @return true if the element was added, false otherwise. */ boolean add(FixType fix); + + /** + * Tries to add {@code fix} to this track. If an {@link #equals(Object) equal} fix already exists + * in this track and {@code replace} is {@code false}, the track remains unchanged and {@code false} will be returned. + * If {@code replace} is {@code true}, an equal (by definition of the comparator used for the fixes set) fix will + * replace the fix contained in this track. + * + * @param replace + * whether or not to replace an existing fix in the track that is equal to {@link #fix} as defined by the + * comparator used for the {@link #fixes} set. By default this is a comparator only comparing the fixes' + * time stamps. Subclasses may use different comparator implementations. + * + * @return true if the element was added, false otherwise. + */ + boolean add(FixType fix, boolean replace); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java index 474da3db2e6..c124560d0a0 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java @@ -55,6 +55,11 @@ public class DynamicGPSFixMovingTrackImpl extends GPSFixTrackImpl extends GPSFixTrackImpl extends TrackImpl public boolean add(FixType fix) { return super.add(fix); } + + @Override + public boolean add(FixType fix, boolean replace) { + return super.add(fix, replace); + } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java index 1259e536ac1..208b4059cd4 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/GPSFixTrackImpl.java @@ -1106,7 +1106,7 @@ public class GPSFixTrackImpl extends TrackImpl lockForWrite(); try { firstFixInTrack = getRawFixes().isEmpty(); - result = addWithoutLocking(fix); + result = addWithoutLocking(fix, /* replace */ false); if (!validityCachingSuspended) { invalidateValidityAndEstimatedSpeedAndDistanceCaches(fix); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java index 796f25602a5..8ce0c7194ed 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/WindTrackImpl.java @@ -108,9 +108,14 @@ public class WindTrackImpl extends TrackImpl implements WindTrack { } @Override - public boolean add(Wind wind) { + public boolean add(Wind fix) { + return super.add(fix); + } + + @Override + public boolean add(Wind wind, boolean replace) { final CompactWindImpl compactWind = new CompactWindImpl(wind); - final boolean result = super.add(compactWind); + final boolean result = super.add(compactWind, replace); notifyListenersAboutReceive(compactWind); return result; } From c1bda954b8bd9ae48ca2eef47de793ea57edd794 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Wed, 23 Mar 2016 17:41:18 +0100 Subject: [PATCH 12/12] use add(fix, replace=true) for addGPSFix on the GPSFixTrack implementation classes, having new fixes with equal time point replace previous ones Change-Id: I970c51e46d451c73040c1be9dd77168dc12f11a5 --- .../domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java | 2 +- .../sailing/domain/tracking/impl/DynamicGPSFixTrackImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java index c124560d0a0..77064a32927 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/DynamicGPSFixMovingTrackImpl.java @@ -47,7 +47,7 @@ public class DynamicGPSFixMovingTrackImpl extends GPSFixTrackImpl extends GPSFixTrackImpl