From 988847c018608f04a985e8fb9fd41167993e483c Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Fri, 20 Mar 2015 10:54:04 +0100 Subject: [PATCH 01/20] Introduced additional data for queries --- .../shared/impl/NullAdditionalResultData.java | 13 ++++++++ .../datamining/impl/TestProcessorQuery.java | 9 +++--- .../sse/datamining/AdditionalQueryData.java | 16 ++++++++++ .../src/com/sap/sse/datamining/Query.java | 4 +++ .../datamining/factories/QueryFactory.java | 6 ++-- .../impl/NullAdditionalQueryData.java | 31 +++++++++++++++++++ .../sse/datamining/impl/ProcessorQuery.java | 21 +++++++++++-- .../impl/SimpleAdditionalQueryData.java | 28 +++++++++++++++++ 8 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/AdditionalQueryData.java create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/NullAdditionalQueryData.java create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleAdditionalQueryData.java diff --git a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/NullAdditionalResultData.java b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/NullAdditionalResultData.java index aebf28bc631..6efa9cca66d 100644 --- a/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/NullAdditionalResultData.java +++ b/java/com.sap.sse.datamining.shared/src/com/sap/sse/datamining/shared/impl/NullAdditionalResultData.java @@ -3,6 +3,19 @@ package com.sap.sse.datamining.shared.impl; import com.sap.sse.datamining.shared.AdditionalResultData; import com.sap.sse.datamining.shared.Unit; +/** + * Null Object pattern for {@link AdditionalResultData} with the values: + * + * + * @author Lennart Hensler (D054527) + */ public class NullAdditionalResultData implements AdditionalResultData { private static final long serialVersionUID = -8129840449690994767L; diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java index d156c39b4c0..1f28a183f0b 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java @@ -19,6 +19,7 @@ import java.util.concurrent.TimeoutException; import org.junit.Test; import com.sap.sse.common.Util.Pair; +import com.sap.sse.datamining.AdditionalQueryData; import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.Query; import com.sap.sse.datamining.components.FilterCriterion; @@ -107,7 +108,7 @@ public class TestProcessorQuery { */ private Query createQueryWithStandardWorkflow(Collection dataSource) { final ThreadPoolExecutor executor = ConcurrencyTestsUtil.getExecutor(); - ProcessorQuery> query = new ProcessorQuery>(dataSource, stringMessages, Locale.ENGLISH) { + ProcessorQuery> query = new ProcessorQuery>(dataSource, stringMessages, Locale.ENGLISH, AdditionalQueryData.NULL_INSTANCE) { @Override protected Processor, ?> createFirstProcessor() { Processor, Map> sumAggregator = processorFactory.createAggregationProcessor(this, AggregatorType.Sum, Double.class); @@ -175,7 +176,7 @@ public class TestProcessorQuery { Collection dataSource = new ArrayList<>(); dataSource.add(new Number(10)); ProcessorQuery> query = new ProcessorQuery>( - dataSource, stringMessages, Locale.ENGLISH) { + dataSource, stringMessages, Locale.ENGLISH, AdditionalQueryData.NULL_INSTANCE) { @SuppressWarnings("unchecked") @Override protected Processor, ?> createFirstProcessor() { @@ -211,7 +212,7 @@ public class TestProcessorQuery { Collection dataSource = new ArrayList<>(); dataSource.add(new Number(10)); ProcessorQuery> query = new ProcessorQuery>( - dataSource, stringMessages, Locale.ENGLISH) { + dataSource, stringMessages, Locale.ENGLISH, AdditionalQueryData.NULL_INSTANCE) { @SuppressWarnings("unchecked") @Override protected Processor, ?> createFirstProcessor() { @@ -275,7 +276,7 @@ public class TestProcessorQuery { public void testQueryWithTimeoutAndNonBlockingProcess() throws TimeoutException { final String keyValue = "Sum"; ProcessorQuery> query = new ProcessorQuery>( - createDataSource(), stringMessages, Locale.ENGLISH) { + createDataSource(), stringMessages, Locale.ENGLISH, AdditionalQueryData.NULL_INSTANCE) { @SuppressWarnings("unchecked") @Override protected Processor, ?> createFirstProcessor() { diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/AdditionalQueryData.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/AdditionalQueryData.java new file mode 100644 index 00000000000..8af0a3a8dc9 --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/AdditionalQueryData.java @@ -0,0 +1,16 @@ +package com.sap.sse.datamining; + +import java.util.UUID; + +import com.sap.sse.datamining.Query.QueryType; +import com.sap.sse.datamining.impl.NullAdditionalQueryData; + +public interface AdditionalQueryData { + + public AdditionalQueryData NULL_INSTANCE = new NullAdditionalQueryData(); + + public QueryType getType(); + + public UUID getDataRetrieverChainID(); + +} \ No newline at end of file diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/Query.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/Query.java index 04eb48ee2a3..496772a4b19 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/Query.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/Query.java @@ -7,8 +7,12 @@ import com.sap.sse.datamining.shared.QueryResult; public interface Query { + public enum QueryType { STATISTIC, DIMENSION_VALUES, OTHER } + public QueryState getState(); + public AdditionalQueryData getAdditionalData(); + public QueryResult run(); public QueryResult run(long timeout, TimeUnit unit) throws TimeoutException; diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/factories/QueryFactory.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/factories/QueryFactory.java index a8af2e4a719..f09da22d822 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/factories/QueryFactory.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/factories/QueryFactory.java @@ -15,11 +15,13 @@ import com.sap.sse.datamining.DataRetrieverChainBuilder; import com.sap.sse.datamining.DataRetrieverChainDefinition; import com.sap.sse.datamining.Query; import com.sap.sse.datamining.QueryDefinition; +import com.sap.sse.datamining.Query.QueryType; import com.sap.sse.datamining.components.FilterCriterion; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.functions.ParameterProvider; import com.sap.sse.datamining.impl.ProcessorQuery; +import com.sap.sse.datamining.impl.SimpleAdditionalQueryData; import com.sap.sse.datamining.impl.components.GroupedDataEntry; import com.sap.sse.datamining.impl.criterias.AndCompoundFilterCriterion; import com.sap.sse.datamining.impl.criterias.CompoundFilterCriterion; @@ -32,7 +34,7 @@ public class QueryFactory { public Query createQuery(DataSourceType dataSource, QueryDefinition queryDefinition, ResourceBundleStringMessages stringMessages, ExecutorService executor) { - return new ProcessorQuery(dataSource, stringMessages, queryDefinition.getLocale()) { + return new ProcessorQuery(dataSource, stringMessages, queryDefinition.getLocale(), new SimpleAdditionalQueryData(QueryType.STATISTIC, queryDefinition.getDataRetrieverChainDefinition().getID())) { @Override protected Processor createFirstProcessor() { ProcessorFactory processorFactory = new ProcessorFactory(executor); @@ -118,7 +120,7 @@ public class QueryFactory { DataRetrieverChainDefinition dataRetrieverChainDefinition, int retrieverLevel, Iterable> dimensions, Locale locale, ResourceBundleStringMessages stringMessages, ExecutorService executor) { - return new ProcessorQuery, DataSource>(dataSource, stringMessages, locale) { + return new ProcessorQuery, DataSource>(dataSource, stringMessages, locale, new SimpleAdditionalQueryData(QueryType.DIMENSION_VALUES, dataRetrieverChainDefinition.getID())) { @Override protected Processor createFirstProcessor() { ProcessorFactory processorFactory = new ProcessorFactory(executor); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/NullAdditionalQueryData.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/NullAdditionalQueryData.java new file mode 100644 index 00000000000..f34aff788bf --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/NullAdditionalQueryData.java @@ -0,0 +1,31 @@ +package com.sap.sse.datamining.impl; + +import java.util.UUID; + +import com.sap.sse.datamining.AdditionalQueryData; +import com.sap.sse.datamining.Query.QueryType; + +/** + * Null Object pattern for {@link AdditionalQueryData} with the values: + *
    + *
  • Type: {@link QueryType#OTHER}
  • + *
  • Data Retriever Chain ID: {@link UUID#UUID(long, long) UUID(0, 0)}
  • + *
+ * + * @author Lennart Hensler (D054527) + */ +public class NullAdditionalQueryData implements AdditionalQueryData { + + private final UUID nullUUID = new UUID(0, 0); + + @Override + public QueryType getType() { + return QueryType.OTHER; + } + + @Override + public UUID getDataRetrieverChainID() { + return nullUUID; + } + +} diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java index 8af304773ae..7fd709fcaa4 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java @@ -14,14 +14,17 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; +import com.sap.sse.datamining.AdditionalQueryData; import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.Query; import com.sap.sse.datamining.QueryState; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.OverwritingResultDataBuilder; +import com.sap.sse.datamining.shared.AdditionalResultData; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.QueryResult; import com.sap.sse.datamining.shared.QueryResultState; +import com.sap.sse.datamining.shared.impl.NullAdditionalResultData; import com.sap.sse.datamining.shared.impl.QueryResultImpl; import com.sap.sse.i18n.ResourceBundleStringMessages; @@ -36,26 +39,33 @@ public abstract class ProcessorQuery implements private final ResourceBundleStringMessages stringMessages; private final Locale locale; + private final AdditionalQueryData additionalData; private final Object monitorObject = new Object(); private Thread workingThread; private QueryState state; /** - * Creates a query that returns a result without any additional data (like the calculation time or the retrieved data amount).
+ * Creates a query + *
    + *
  • with no {@link AdditionalQueryData} (more exactly with {@link NullAdditionalQueryData} as additional data).
  • + *
  • that returns a result without {@link AdditionalResultData} (more exactly with {@link NullAdditionalResultData} as additional data).
  • + *
+ * * This is useful for non user specific queries, like retrieving the dimension values. */ public ProcessorQuery(DataSourceType dataSource) { - this(dataSource, null, null); + this(dataSource, null, null, AdditionalQueryData.NULL_INSTANCE); } /** * Creates a query that returns a result with additional data. */ - public ProcessorQuery(DataSourceType dataSource, ResourceBundleStringMessages stringMessages, Locale locale) { + public ProcessorQuery(DataSourceType dataSource, ResourceBundleStringMessages stringMessages, Locale locale, AdditionalQueryData additionalData) { this.dataSource = dataSource; this.stringMessages = stringMessages; this.locale = locale; + this.additionalData = additionalData; state = QueryState.NOT_STARTED; resultReceiver = new ProcessResultReceiver(); @@ -68,6 +78,11 @@ public abstract class ProcessorQuery implements public QueryState getState() { return state; } + + @Override + public AdditionalQueryData getAdditionalData() { + return additionalData; + } @Override public QueryResult run() { diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleAdditionalQueryData.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleAdditionalQueryData.java new file mode 100644 index 00000000000..485ca1debbe --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleAdditionalQueryData.java @@ -0,0 +1,28 @@ +package com.sap.sse.datamining.impl; + +import java.util.UUID; + +import com.sap.sse.datamining.AdditionalQueryData; +import com.sap.sse.datamining.Query.QueryType; + +public class SimpleAdditionalQueryData implements AdditionalQueryData { + + private final QueryType type; + private final UUID dataRetrieverChainID; + + public SimpleAdditionalQueryData(QueryType type, UUID dataRetrieverChainID) { + this.type = type; + this.dataRetrieverChainID = dataRetrieverChainID; + } + + @Override + public QueryType getType() { + return type; + } + + @Override + public UUID getDataRetrieverChainID() { + return dataRetrieverChainID; + } + +} From 30a62a68fba94d79c8bd926eb44135d1c8b7ce6b Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Mar 2015 11:27:03 +0100 Subject: [PATCH 02/20] started to work on bug2715 by adding a method on TrackedLegOfCompetitor and support method on TrackedRace to calculate distance travled specifically for gate starts --- .../state/impl/ReadonlyRaceStateImpl.java | 3 +- .../tracking/TrackedLegOfCompetitor.java | 14 +++++ .../sailing/domain/tracking/TrackedRace.java | 10 ++++ .../impl/TrackedLegOfCompetitorImpl.java | 22 ++++++++ .../domain/tracking/impl/TrackedRaceImpl.java | 20 ++++++- .../SSETheme_GWT sdm.launch | 54 +++++++++---------- .../com.sap.sse.gwt.theme/SSETheme_GWT.launch | 52 +++++++++--------- 7 files changed, 120 insertions(+), 55 deletions(-) diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java index 015ea9c72e0..277e75a8d6c 100644 --- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java +++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/race/state/impl/ReadonlyRaceStateImpl.java @@ -133,7 +133,8 @@ public class ReadonlyRaceStateImpl implements ReadonlyRaceState, RaceLogChangedL this.cachedRacingProcedureType = determineInitialProcedureType(); this.cachedRaceStatus = RaceLogRaceStatus.UNKNOWN; this.cachedPassId = raceLog.getCurrentPassId(); - // TODO bug 2083: make sure the listener registration is "weak" in the sense that it is removed when this race state is no longer strongly referenced + // see resolved bug 2083: make sure the listener registration is "weak" in the sense that it is removed when + // this race state is no longer strongly referenced this.raceLog.addListener(new WeakRaceLogChangedVisitor(this.raceLog, this)); // We known that recreateRacingProcedure calls update() when done, therefore this RaceState // will be fully initialized after this line diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java index bf54ed9a0b5..ce921bd846a 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedLegOfCompetitor.java @@ -39,6 +39,20 @@ public interface TrackedLegOfCompetitor extends Serializable { */ Distance getDistanceTraveled(TimePoint timePoint); + /** + * When a race uses a gate start, competitors are free to choose their start time point within the gate opening + * time. During this time a pathfinder boat, also called "rabbit," progresses on port tack until the gate launch + * time is over. After the gate launch time, competitors may still start until the gate closes, but that's usually + * not a useful option because starting after the gate launch time usually means losing time towards the next mark. + *

+ * + * Depending on when a competitor starts, they will have different distances to sail: early starters a bit more, + * late starters a bit less. To normalize and make comparable, for the first leg of a gate start race, this method + * adds the distance between the competitor and the port side of the start line at the time point when the competitor + * starts. + */ + Distance getDistanceTraveledConsideringGateStart(TimePoint timePoint); + /** * Estimates how much the competitor still has to go to the end waypoint of this leg, projected onto the wind * direction. If the competitor already finished this leg, a zero, non-null distance will result. diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index c39bc0aa624..7975fe961a2 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.SortedSet; import com.sap.sailing.domain.abstractlog.race.RaceLog; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; import com.sap.sailing.domain.abstractlog.shared.events.DeviceMappingEvent; import com.sap.sailing.domain.base.Competitor; @@ -31,6 +32,7 @@ import com.sap.sailing.domain.common.TrackedRaceStatusEnum; import com.sap.sailing.domain.common.WindSource; import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.dto.TrackedRaceDTO; +import com.sap.sailing.domain.common.racelog.RacingProcedureType; import com.sap.sailing.domain.racelog.tracking.GPSFixStore; import com.sap.sse.common.TimePoint; import com.sap.sse.common.Util; @@ -720,4 +722,12 @@ public interface TrackedRace extends Serializable { */ Position getCenterOfCourse(TimePoint at); + /** + * If the {@link RacingProcedure} defined by any of the {@link #attachedRaceLogs attached} {@link RaceLog}s + * has type {@link RacingProcedureType#GateStart}, this method returns true, false for + * any other type found. If no type is found, e.g., because no race log is currently attached to this tracked race, + * null is returned, meaning that the type is not known. + */ + Boolean isGateStart(); + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java index 4d8ce19263b..4aeff1139f8 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java @@ -10,6 +10,7 @@ import java.util.Set; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Leg; import com.sap.sailing.domain.base.Mark; +import com.sap.sailing.domain.base.Waypoint; import com.sap.sailing.domain.common.Bearing; import com.sap.sailing.domain.common.Distance; import com.sap.sailing.domain.common.LegType; @@ -110,6 +111,27 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { return getTrackedRace().getTrack(getCompetitor()).getDistanceTraveled(legStart.getTimePoint(), end); } } + + @Override + public Distance getDistanceTraveledConsideringGateStart(TimePoint timePoint) { + final Distance result; + final Distance preResult = getDistanceTraveled(timePoint); + final Waypoint from = getLeg().getFrom(); + final TimePoint competitorLegStartTime = getStartTime(); + if (from == getTrackedRace().getRace().getCourse().getFirstWaypoint() && getTrackedRace().isGateStart() == true + && competitorLegStartTime != null) { + final Mark portMarkOfStartLine = getTrackedRace().getStartLine(competitorLegStartTime) + .getPortMarkWhileApproachingLine(); + final Position portSideOfStartLinePosition = getTrackedRace().getOrCreateTrack(portMarkOfStartLine) + .getEstimatedPosition(competitorLegStartTime, /* extrapolate */true); + final Distance additionalDistance = portSideOfStartLinePosition.getDistance(getTrackedRace().getTrack( + getCompetitor()).getEstimatedPosition(competitorLegStartTime, /* extrapolate */false)); + result = preResult.add(additionalDistance); + } else { + result = preResult; + } + return result; + } private MarkPassing getMarkPassingForLegStart() { MarkPassing legStart = getTrackedRace().getMarkPassing(getCompetitor(), getLeg().getFrom()); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index b8d2f4d664e..7c103fc18e3 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -35,6 +35,10 @@ import com.sap.sailing.domain.abstractlog.AbstractLog; import com.sap.sailing.domain.abstractlog.AbstractLogEvent; import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; +import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; +import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; +import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRacingProcedure; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; import com.sap.sailing.domain.base.BoatClass; import com.sap.sailing.domain.base.Competitor; @@ -84,6 +88,7 @@ import com.sap.sailing.domain.common.impl.KnotSpeedImpl; import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl; import com.sap.sailing.domain.common.impl.NauticalMileDistance; import com.sap.sailing.domain.common.impl.WindSourceImpl; +import com.sap.sailing.domain.common.racelog.RacingProcedureType; import com.sap.sailing.domain.common.racelog.tracking.TransformationException; import com.sap.sailing.domain.common.scalablevalue.impl.ScalablePosition; import com.sap.sailing.domain.confidence.ConfidenceBasedWindAverager; @@ -3278,5 +3283,18 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl Iterable getWaypoints() { return markPassingsForWaypoint.keySet(); } - + + @Override + public Boolean isGateStart() { + Boolean result = null; + for (RaceLog raceLog : attachedRaceLogs.values()) { + ReadonlyRaceState raceState = RaceStateImpl.create(raceLog); + ReadonlyRacingProcedure procedure = raceState.getRacingProcedure(); + if (procedure != null && procedure.getType() != null) { + result = procedure.getType() == RacingProcedureType.GateStart; + break; + } + } + return result; + } } diff --git a/java/com.sap.sse.gwt.theme/SSETheme_GWT sdm.launch b/java/com.sap.sse.gwt.theme/SSETheme_GWT sdm.launch index e61889df28b..71c80a9b61b 100644 --- a/java/com.sap.sse.gwt.theme/SSETheme_GWT sdm.launch +++ b/java/com.sap.sse.gwt.theme/SSETheme_GWT sdm.launch @@ -1,27 +1,27 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/com.sap.sse.gwt.theme/SSETheme_GWT.launch b/java/com.sap.sse.gwt.theme/SSETheme_GWT.launch index 497ba323966..099018ea63b 100644 --- a/java/com.sap.sse.gwt.theme/SSETheme_GWT.launch +++ b/java/com.sap.sse.gwt.theme/SSETheme_GWT.launch @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + From 571d6cb93ac2900ffce7a3025d27aa2b7741905b Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Fri, 20 Mar 2015 12:16:50 +0100 Subject: [PATCH 03/20] First attempt to abort dimension value queries, but didn't work So the dimension value query managing is disabled in this commit, to be able to push an error free state. --- .../gwt/ui/server/DataMiningServiceImpl.java | 1 + .../datamining/impl/DataMiningServerImpl.java | 2 +- .../ManyQueriesPerRetrieverChainManager.java | 81 +++++++++++++++++++ ...java => SingleQueryPerSessionManager.java} | 13 ++- .../impl/StrategyPerQueryTypeManager.java | 28 +++++++ 5 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ManyQueriesPerRetrieverChainManager.java rename java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/{ConcurrentDataMiningQueryManager.java => SingleQueryPerSessionManager.java} (77%) create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/StrategyPerQueryTypeManager.java diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java index aaec9cc4349..2fd9cdaf19e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/DataMiningServiceImpl.java @@ -129,6 +129,7 @@ public class DataMiningServiceImpl extends RemoteServiceServlet implements DataM Iterable> dimensions = functionDTOsAsFunctions(dimensionDTOs); Locale locale = ResourceBundleStringMessages.Util.getLocaleFor(localeInfoName); Query> dimensionValuesQuery = getDataMiningServer().createDimensionValuesQuery(retrieverChainDefinition, retrieverLevel, dimensions, locale); +// QueryResult> result = getDataMiningServer().runNewQueryAndAbortPreviousQueries(session, dimensionValuesQuery); QueryResult> result = dimensionValuesQuery.run(); return result; } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java index 36a56a5af02..e38bf221d90 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningServerImpl.java @@ -47,7 +47,7 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer { this.stringMessages = new CompoundResourceBundleStringMessages(); this.executorService = executorService; this.queryFactory = new QueryFactory(); - dataMiningQueryManager = new ConcurrentDataMiningQueryManager(); + dataMiningQueryManager = new StrategyPerQueryTypeManager(); this.functionRegistry = functionRegistry; this.functionProvider = functionProvider; dataSourceProviderMappedByDataSourceType = new HashMap<>(); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ManyQueriesPerRetrieverChainManager.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ManyQueriesPerRetrieverChainManager.java new file mode 100644 index 00000000000..ad1ec8ea44c --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ManyQueriesPerRetrieverChainManager.java @@ -0,0 +1,81 @@ +package com.sap.sse.datamining.impl; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.sap.sse.datamining.DataMiningQueryManager; +import com.sap.sse.datamining.Query; +import com.sap.sse.datamining.shared.DataMiningSession; +import com.sap.sse.datamining.shared.QueryResult; + +public class ManyQueriesPerRetrieverChainManager implements DataMiningQueryManager { + + private final ConcurrentMap currentRetrieverChainMappedBySession; + private final Map>> queriesMappedBySession; + + public ManyQueriesPerRetrieverChainManager() { + currentRetrieverChainMappedBySession = new ConcurrentHashMap<>(); + queriesMappedBySession = new HashMap<>(); + } + + @Override + public QueryResult runNewAndAbortPrevious(DataMiningSession session, Query query) { + if (session == null || query == null) { + throw new NullPointerException(); + } + + abortPreviousQueries(session, query); + updateCurrentRetrieverChain(session, query); + registerNewQuery(session, query); + QueryResult result = query.run(); + unregisterQuery(session, query); + return result; + } + + private void abortPreviousQueries(DataMiningSession session, Query newQuery) { + final UUID newRetrieverChainID = newQuery.getAdditionalData().getDataRetrieverChainID(); + if (currentRetrieverChainMappedBySession.containsKey(session) && + !currentRetrieverChainMappedBySession.get(session).equals(newRetrieverChainID)) { + Collection> previousQueries = queriesMappedBySession.get(session); + for (Query previousQuery : previousQueries) { + previousQuery.abort(); + } + queriesMappedBySession.remove(session, previousQueries); + + currentRetrieverChainMappedBySession.remove(session); + currentRetrieverChainMappedBySession.putIfAbsent(session, newRetrieverChainID); + } + } + + private void updateCurrentRetrieverChain(DataMiningSession session, Query query) { + UUID retrieverChainID = query.getAdditionalData().getDataRetrieverChainID(); + UUID previousRetrieverChainID = currentRetrieverChainMappedBySession.putIfAbsent(session, retrieverChainID); + if (previousRetrieverChainID != null && !previousRetrieverChainID.equals(retrieverChainID)) { + currentRetrieverChainMappedBySession.replace(session, previousRetrieverChainID, retrieverChainID); + } + } + + private void registerNewQuery(DataMiningSession session, Query query) { + if (!queriesMappedBySession.containsKey(session)) { + Set> concurrentSet = Collections.newSetFromMap(new ConcurrentHashMap, Boolean>()); + queriesMappedBySession.put(session, concurrentSet); + } + + queriesMappedBySession.get(session).add(query); + } + + private void unregisterQuery(DataMiningSession session, Query finishedQuery) { + UUID retrieverChainID = finishedQuery.getAdditionalData().getDataRetrieverChainID(); + if (currentRetrieverChainMappedBySession.containsKey(session) && + currentRetrieverChainMappedBySession.get(session).equals(retrieverChainID)) { + queriesMappedBySession.get(session).remove(finishedQuery); + } + } + +} diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ConcurrentDataMiningQueryManager.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SingleQueryPerSessionManager.java similarity index 77% rename from java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ConcurrentDataMiningQueryManager.java rename to java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SingleQueryPerSessionManager.java index 478347c08b6..0e2e8e9db4c 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ConcurrentDataMiningQueryManager.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SingleQueryPerSessionManager.java @@ -8,11 +8,11 @@ import com.sap.sse.datamining.Query; import com.sap.sse.datamining.shared.DataMiningSession; import com.sap.sse.datamining.shared.QueryResult; -public class ConcurrentDataMiningQueryManager implements DataMiningQueryManager { +public class SingleQueryPerSessionManager implements DataMiningQueryManager { private final ConcurrentMap> queryMappedBySession; - public ConcurrentDataMiningQueryManager() { + public SingleQueryPerSessionManager() { queryMappedBySession = new ConcurrentHashMap<>(); } @@ -23,15 +23,14 @@ public class ConcurrentDataMiningQueryManager implements DataMiningQueryManager throw new NullPointerException(); } - abortPreviousQueries(session, query); + abortPreviousQueries(session); registerNewQuery(session, query); QueryResult result = query.run(); unregisterQuery(session, query); return result; } - private void abortPreviousQueries(DataMiningSession session, Query query) { - // TODO handle different types of queries (a statistics query doesn't have to be aborted, if a new dimension values query wants to run) + private void abortPreviousQueries(DataMiningSession session) { if (queryMappedBySession.containsKey(session)) { Query previousQuery = queryMappedBySession.get(session); previousQuery.abort(); @@ -46,8 +45,8 @@ public class ConcurrentDataMiningQueryManager implements DataMiningQueryManager } } - private void unregisterQuery(DataMiningSession session, Query query) { - queryMappedBySession.remove(session, query); + private void unregisterQuery(DataMiningSession session, Query finishedQuery) { + queryMappedBySession.remove(session, finishedQuery); } } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/StrategyPerQueryTypeManager.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/StrategyPerQueryTypeManager.java new file mode 100644 index 00000000000..bffc14138b3 --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/StrategyPerQueryTypeManager.java @@ -0,0 +1,28 @@ +package com.sap.sse.datamining.impl; + +import java.util.HashMap; +import java.util.Map; + +import com.sap.sse.datamining.DataMiningQueryManager; +import com.sap.sse.datamining.Query; +import com.sap.sse.datamining.Query.QueryType; +import com.sap.sse.datamining.shared.DataMiningSession; +import com.sap.sse.datamining.shared.QueryResult; + +public class StrategyPerQueryTypeManager implements DataMiningQueryManager { + + private final Map managersMappedByQueryType; + + public StrategyPerQueryTypeManager() { + managersMappedByQueryType = new HashMap<>(); + managersMappedByQueryType.put(QueryType.STATISTIC, new SingleQueryPerSessionManager()); + managersMappedByQueryType.put(QueryType.DIMENSION_VALUES, new ManyQueriesPerRetrieverChainManager()); + managersMappedByQueryType.put(QueryType.OTHER, new SingleQueryPerSessionManager()); + } + + @Override + public QueryResult runNewAndAbortPrevious(DataMiningSession session, Query query) { + return managersMappedByQueryType.get(query.getAdditionalData().getType()).runNewAndAbortPrevious(session, query); + } + +} From 5fd384af5c473b1225e67dbd1c302e3fe0577df6 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Mar 2015 13:34:44 +0100 Subject: [PATCH 04/20] added metric for distance including gate start consideration to leaderboard and REST API --- .../sap/sailing/domain/common/DetailType.java | 4 +- .../domain/common/dto/LegEntryDTO.java | 7 + .../domain/test/mock/MockedTrackedRace.java | 9 +- ...ockedTrackedRaceWithStartTimeAndRanks.java | 110 +-------- .../sailing/domain/tracking/TrackedRace.java | 1 - .../domain/tracking/impl/TrackedRaceImpl.java | 1 - .../gwt/ui/test/MockedTrackedRace.java | 216 +----------------- .../gwt/ui/client/DetailTypeFormatter.java | 10 + .../sailing/gwt/ui/client/StringMessages.java | 3 + .../gwt/ui/client/StringMessages.properties | 5 +- .../ui/client/StringMessages_de.properties | 7 +- .../ui/client/StringMessages_ru.properties | 5 +- .../gwt/ui/leaderboard/LeaderboardPanel.java | 35 ++- .../sailing/gwt/ui/leaderboard/LegColumn.java | 11 + .../impl/RegattaJsonSerializer.java | 2 +- .../gateway/jaxrs/api/RegattasResource.java | 39 +++- .../webservices/api/v1/index.html | 4 + .../webservices/api/v1/racesGetDoc.html | 46 ++++ .../server/masterdata/DummyTrackedRace.java | 87 +------ 19 files changed, 190 insertions(+), 412 deletions(-) create mode 100755 java/com.sap.sailing.server.gateway/webservices/api/v1/racesGetDoc.html diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java index 395ca3fa6ad..6f2b92a95dd 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/DetailType.java @@ -15,12 +15,14 @@ import java.io.Serializable; * */ public enum DetailType implements Serializable { - DISTANCE_TRAVELED(0, ASCENDING), AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), REGATTA_RANK(0, ASCENDING), OVERALL_RANK(0, ASCENDING), + DISTANCE_TRAVELED(0, ASCENDING), DISTANCE_TRAVELED_INCLUDING_GATE_START(0, ASCENDING), + AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_RANK(0, ASCENDING), REGATTA_RANK(0, ASCENDING), OVERALL_RANK(0, ASCENDING), RANK_GAIN(0, ASCENDING), NUMBER_OF_MANEUVERS(0, ASCENDING), CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS(1, ASCENDING), VELOCITY_MADE_GOOD_IN_KNOTS(2, DESCENDING), GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), GAP_CHANGE_SINCE_LEG_START_IN_SECONDS(0, ASCENDING), SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED(0, ASCENDING), WINDWARD_DISTANCE_TO_GO_IN_METERS(0, ASCENDING), AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), RACE_DISTANCE_TRAVELED(0, ASCENDING), + RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START(0, ASCENDING), RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING), RACE_GAP_TO_LEADER_IN_SECONDS(0, ASCENDING), RACE_DISTANCE_TO_LEADER_IN_METERS(0, ASCENDING), RACE_AVERAGE_ABSOLUTE_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), RACE_AVERAGE_SIGNED_CROSS_TRACK_ERROR_IN_METERS(0, ASCENDING), diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/LegEntryDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/LegEntryDTO.java index 5e647835271..bb9f72a1e38 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/LegEntryDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/LegEntryDTO.java @@ -19,6 +19,7 @@ public class LegEntryDTO implements Serializable { private static final long serialVersionUID = -1236734337344886025L; public LegType legType; public Double distanceTraveledInMeters; + public Double distanceTraveledIncludingGateStartInMeters; public Double averageSpeedOverGroundInKnots; public int rank; public Double gapToLeaderInSeconds; @@ -62,6 +63,7 @@ public class LegEntryDTO implements Serializable { result = prime * result + ((currentSpeedOverGroundInKnots == null) ? 0 : currentSpeedOverGroundInKnots.hashCode()); result = prime * result + ((distanceTraveledInMeters == null) ? 0 : distanceTraveledInMeters.hashCode()); + result = prime * result + ((distanceTraveledIncludingGateStartInMeters == null) ? 0 : distanceTraveledIncludingGateStartInMeters.hashCode()); result = prime * result + ((estimatedTimeToNextWaypointInSeconds == null) ? 0 : estimatedTimeToNextWaypointInSeconds.hashCode()); @@ -120,6 +122,11 @@ public class LegEntryDTO implements Serializable { return false; } else if (!distanceTraveledInMeters.equals(other.distanceTraveledInMeters)) return false; + if (distanceTraveledIncludingGateStartInMeters == null) { + if (other.distanceTraveledIncludingGateStartInMeters != null) + return false; + } else if (!distanceTraveledIncludingGateStartInMeters.equals(other.distanceTraveledIncludingGateStartInMeters)) + return false; if (estimatedTimeToNextWaypointInSeconds == null) { if (other.estimatedTimeToNextWaypointInSeconds != null) return false; diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java index 38047fc975c..6a14bc2a55e 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java @@ -873,13 +873,14 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public void attachRegattaLog(RegattaLog regattaLog) { - // TODO Auto-generated method stub - } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RegattaLog fromRegattaLog) throws InterruptedException { - // TODO Auto-generated method stub - + } + + @Override + public Boolean isGateStart() { + return null; } } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java index 3da767eb984..f55c87c0fb7 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java @@ -95,7 +95,6 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public RegattaAndRaceIdentifier getRaceIdentifier() { - // TODO Auto-generated method stub return null; } @@ -106,13 +105,11 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public TimePoint getEndOfRace() { - // TODO Auto-generated method stub return null; } @Override public Iterable>> getMarkPassingsTimes() { - // TODO Auto-generated method stub return null; } @@ -123,67 +120,56 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public Iterable getTrackedLegs() { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getTrackedLeg(Leg leg) { - // TODO Auto-generated method stub return null; } @Override public TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getCurrentLeg(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getTrackedLegFinishingAt(Waypoint endOfLeg) { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getTrackedLegStartingAt(Waypoint startOfLeg) { - // TODO Auto-generated method stub return null; } @Override public GPSFixTrack getTrack(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, Leg leg) { - // TODO Auto-generated method stub return null; } @Override public long getUpdateCount() { - // TODO Auto-generated method stub return 0; } @Override public int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint) { - // TODO Auto-generated method stub return 0; } @@ -199,37 +185,31 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public Iterable getMarkPassingsInOrder(Waypoint waypoint) { - // TODO Auto-generated method stub return null; } @Override public MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint) { - // TODO Auto-generated method stub return null; } @Override public GPSFixTrack getOrCreateTrack(Mark mark) { - // TODO Auto-generated method stub return null; } @Override public Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Wind getWind(Position p, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public Wind getWind(Position p, TimePoint at, Set windSourcesToExclude) { - // TODO Auto-generated method stub return null; } @@ -245,91 +225,75 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public WindTrack getOrCreateWindTrack(WindSource windSource) { - // TODO Auto-generated method stub return null; } @Override public WindTrack getOrCreateWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation) { - // TODO Auto-generated method stub return null; } @Override public void waitForNextUpdate(int sinceUpdate) throws InterruptedException { - // TODO Auto-generated method stub - } @Override public TimePoint getStartOfTracking() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getEndOfTracking() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfNewestEvent() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfOldestEvent() { - // TODO Auto-generated method stub return null; } @Override public NavigableSet getMarkPassings(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfLastEvent() { - // TODO Auto-generated method stub return null; } @Override public long getMillisecondsOverWhichToAverageSpeed() { - // TODO Auto-generated method stub return 0; } @Override public long getMillisecondsOverWhichToAverageWind() { - // TODO Auto-generated method stub return 0; } @Override public long getDelayToLiveInMillis() { - // TODO Auto-generated method stub return 0; } @Override public Wind getEstimatedWindDirection(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Tack getTack(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Tack getTack(SpeedWithBearing speedWithBearing, Wind wind, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @@ -340,113 +304,91 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public Wind getDirectionFromStartToNextMark(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public List approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to) { - // TODO Auto-generated method stub return null; } @Override public List getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) { - // TODO Auto-generated method stub return null; } @Override public boolean raceIsKnownToStartUpwind() { - // TODO Auto-generated method stub return false; } @Override public void addListener(RaceChangeListener listener) { - // TODO Auto-generated method stub - } @Override public void addListener(RaceChangeListener listener, boolean notifyAboutWindFixesAlreadyLoaded, boolean notifyAboutGPSFixesAlreadyLoaded) { - // TODO Auto-generated method stub - } @Override public void removeListener(RaceChangeListener listener) { - // TODO Auto-generated method stub - } @Override public Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public Set getWindSourcesToExclude() { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at, Set windSourcesToExclude) { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence getEstimatedWindDirectionWithConfidence(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public void setWindSourcesToExclude(Iterable windSourcesToExclude) { - // TODO Auto-generated method stub - } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, WindLegTypeAndLegBearingCache cache) { - // TODO Auto-generated method stub return null; } @Override public WindStore getWindStore() { - // TODO Auto-generated method stub return null; } @Override public Competitor getOverallLeader(TimePoint timePoint) throws NoWindException { - // TODO Auto-generated method stub return null; } @@ -458,223 +400,181 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public void waitUntilLoadingFromWindStoreComplete() { - // TODO Auto-generated method stub - } @Override public Iterable getMarks() { - // TODO Auto-generated method stub return null; } @Override public boolean hasWindData() { - // TODO Auto-generated method stub return false; } @Override public boolean hasGPSData() { - // TODO Auto-generated method stub return false; } @Override public void lockForRead(Iterable markPassings) { - // TODO Auto-generated method stub } @Override public void unlockAfterRead(Iterable markPassings) { - // TODO Auto-generated method stub } @Override public TrackedRaceStatus getStatus() { - // TODO Auto-generated method stub return null; } @Override public void waitUntilNotLoading() { - // TODO Auto-generated method stub } @Override public void detachRaceLog(Serializable identifier) { - // TODO Auto-generated method stub - } @Override public void attachRaceLog(RaceLog raceLog) { - // TODO Auto-generated method stub - } @Override public RaceLog getRaceLog(Serializable identifier) { - // TODO Auto-generated method stub return null; } @Override public void addCourseDesignChangedListener(CourseDesignChangedListener listener) { - // TODO Auto-generated method stub - } @Override public Distance getDistanceToStartLine(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceFromStarboardSideOfStartLineWhenPassingStart(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public void detachAllRaceLogs() { - // TODO Auto-generated method stub - } @Override public boolean isLive(TimePoint at) { - // TODO Auto-generated method stub return false; } @Override public Iterable getCourseSidelines() { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceToStartLine(Competitor competitor, long millisecondsBeforeRaceStart) { - // TODO Auto-generated method stub return null; } @Override public Speed getSpeed(Competitor competitor, long millisecondsBeforeRaceStart) { - // TODO Auto-generated method stub return null; } public void addStartTimeChangedListener(StartTimeChangedListener listener) { - // TODO Auto-generated method stub - } @Override public TimePoint getStartTimeReceived() { - // TODO Auto-generated method stub return null; } @Override public LineDetails getStartLine(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public LineDetails getFinishLine(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public SpeedWithConfidence getAverageWindSpeedWithConfidence(long resolutionInMillis) { - // TODO Auto-generated method stub return null; } @Override public Distance getCourseLength() { - // TODO Auto-generated method stub return null; } @Override public Speed getSpeedWhenCrossingStartLine(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceFromStarboardSideOfStartLine(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, WindLegTypeAndLegBearingCache cache) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public GPSFixStore getGPSFixStore() { - // TODO Auto-generated method stub return null; } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RaceLog forRaceLog) throws InterruptedException { - // TODO Auto-generated method stub - } @Override public void addRaceAbortedListener(RaceAbortedListener listener) { - // TODO Auto-generated method stub - } @Override public Position getCenterOfCourse(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public void attachRegattaLog(RegattaLog regattaLog) { - // TODO Auto-generated method stub - } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RegattaLog fromRegattaLog) throws InterruptedException { - // TODO Auto-generated method stub - + } + + @Override + public Boolean isGateStart() { + return null; } } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index 7975fe961a2..38c3d1b8279 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -85,7 +85,6 @@ public interface TrackedRace extends Serializable { *

  • Returns time of the last mark passing recorded for the finish line
  • *
  • TODO: Returns the time of the first passing of the finish line + the target window (defined in the * competition rules) if a target window has been defined for the race
  • - * */ TimePoint getEndOfRace(); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 7c103fc18e3..20379a7d8ca 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -37,7 +37,6 @@ import com.sap.sailing.domain.abstractlog.race.RaceLog; import com.sap.sailing.domain.abstractlog.race.analyzing.impl.StartTimeFinder; import com.sap.sailing.domain.abstractlog.race.state.ReadonlyRaceState; import com.sap.sailing.domain.abstractlog.race.state.impl.RaceStateImpl; -import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.RacingProcedure; import com.sap.sailing.domain.abstractlog.race.state.racingprocedure.ReadonlyRacingProcedure; import com.sap.sailing.domain.abstractlog.regatta.RegattaLog; import com.sap.sailing.domain.base.BoatClass; diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java index e3e876b6a22..31a28fb953e 100755 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -77,140 +77,115 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public RaceDefinition getRace() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getStartOfRace() { - // TODO Auto-generated method stub return null; } @Override public Iterable getTrackedLegs() { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getTrackedLeg(Leg leg) { - // TODO Auto-generated method stub return null; } @Override public TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getCurrentLeg(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getTrackedLegFinishingAt(Waypoint endOfLeg) { - // TODO Auto-generated method stub return null; } @Override public TrackedLeg getTrackedLegStartingAt(Waypoint startOfLeg) { - // TODO Auto-generated method stub return null; } @Override public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public TrackedLegOfCompetitor getTrackedLeg(Competitor competitor, Leg leg) { - // TODO Auto-generated method stub return null; } @Override public long getUpdateCount() { - // TODO Auto-generated method stub return 0; } @Override public int getRankDifference(Competitor competitor, Leg leg, TimePoint timePoint) { - // TODO Auto-generated method stub return 0; } @Override public int getRank(Competitor competitor) throws NoWindException { - // TODO Auto-generated method stub return 0; } @Override public int getRank(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return 0; } @Override public Iterable getMarkPassingsInOrder(Waypoint waypoint) { - // TODO Auto-generated method stub return null; } @Override public MarkPassing getMarkPassing(Competitor competitor, Waypoint waypoint) { - // TODO Auto-generated method stub return null; } @Override public DynamicGPSFixTrack getOrCreateTrack(Mark mark) { - // TODO Auto-generated method stub return null; } @Override public WindTrack getOrCreateWindTrack(WindSource windSource, long delayForWindEstimationCacheInvalidation) { - // TODO Auto-generated method stub return null; } @Override public void waitForNextUpdate(int sinceUpdate) throws InterruptedException { - // TODO Auto-generated method stub - } @Override public TimePoint getStartOfTracking() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfNewestEvent() { - // TODO Auto-generated method stub return null; } @Override public NavigableSet getMarkPassings(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public void recordFix(Competitor competitor, GPSFixMoving fix) { - // TODO Auto-generated method stub - } @Override @@ -225,80 +200,60 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public void addListener(RaceChangeListener listener) { - // TODO Auto-generated method stub - } @Override public void addListener(RaceChangeListener listener, boolean notifyAboutWindFixesAlreadyLoaded, boolean notifyAboutGPSFixesAlreadyLoaded) { - // TODO Auto-generated method stub - } @Override public void updateMarkPassings(Competitor competitor, Iterable markPassings) { - // TODO Auto-generated method stub - } @Override public void setStartTimeReceived(TimePoint start) { - // TODO Auto-generated method stub - } @Override public DynamicGPSFixTrack getTrack(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public void removeWind(Wind wind, WindSource windSource) { - // TODO Auto-generated method stub - } @Override public TimePoint getTimePointOfLastEvent() { - // TODO Auto-generated method stub return null; } @Override public void setMillisecondsOverWhichToAverageSpeed(long millisecondsOverWhichToAverageSpeed) { - // TODO Auto-generated method stub - } @Override public void setMillisecondsOverWhichToAverageWind(long millisecondsOverWhichToAverageWind) { - // TODO Auto-generated method stub - } @Override public long getMillisecondsOverWhichToAverageSpeed() { - // TODO Auto-generated method stub return 0; } @Override public long getMillisecondsOverWhichToAverageWind() { - // TODO Auto-generated method stub return 0; } @Override public Wind getEstimatedWindDirection(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public boolean hasStarted(TimePoint at) { - // TODO Auto-generated method stub return false; } @@ -319,273 +274,211 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public Serializable getId() { - // TODO Auto-generated method stub return null; } @Override public Iterable getAllRaces() { - // TODO Auto-generated method stub return null; } @Override public BoatClass getBoatClass() { - // TODO Auto-generated method stub return null; } @Override public Iterable getAllCompetitors() { - // TODO Auto-generated method stub return null; } @Override public void addRace(RaceDefinition race) { - // TODO Auto-generated method stub } @Override public void removeRace(RaceDefinition raceDefinition) { - // TODO Auto-generated method stub } @Override public RaceDefinition getRaceByName(String raceName) { - // TODO Auto-generated method stub return null; } @Override public void addRegattaListener(RegattaListener listener) { - // TODO Auto-generated method stub - } @Override public void removeRegattaListener(RegattaListener listener) { - // TODO Auto-generated method stub - } @Override public RegattaIdentifier getRegattaIdentifier() { - // TODO Auto-generated method stub return null; } @Override public Iterable getSeries() { - // TODO Auto-generated method stub return null; } @Override public Series getSeriesByName(String seriesName) { - // TODO Auto-generated method stub return null; } @Override public boolean isPersistent() { - // TODO Auto-generated method stub return false; } @Override public void addRaceColumnListener(RaceColumnListener listener) { - // TODO Auto-generated method stub } @Override public void removeRaceColumnListener(RaceColumnListener listener) { - // TODO Auto-generated method stub - } @Override public ScoringScheme getScoringScheme() { - // TODO Auto-generated method stub return null; } @Override public CourseArea getDefaultCourseArea() { - // TODO Auto-generated method stub return null; } @Override public void setDefaultCourseArea(CourseArea newCourseArea) { - // TODO Auto-generated method stub - } @Override public boolean definesSeriesDiscardThresholds() { - // TODO Auto-generated method stub return false; } @Override public RegattaAndRaceIdentifier getRaceIdentifier(RaceDefinition race) { - // TODO Auto-generated method stub return null; } @Override public RegattaConfiguration getRegattaConfiguration() { - // TODO Auto-generated method stub return null; } @Override public void setRegattaConfiguration(RegattaConfiguration configuration) { - // TODO Auto-generated method stub - } @Override public void addSeries(Series series) { - // TODO Auto-generated method stub - } @Override public boolean useStartTimeInference() { - // TODO Auto-generated method stub return false; } @Override public void removeSeries(Series series) { - // TODO Auto-generated method stub - } @Override public void setUseStartTimeInference(boolean useStartTimeInference) { - // TODO Auto-generated method stub - } @Override public RegattaLog getRegattaLog() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getStartDate() { - // TODO Auto-generated method stub return null; } @Override public void setStartDate(TimePoint startDate) { - // TODO Auto-generated method stub - } @Override public TimePoint getEndDate() { - // TODO Auto-generated method stub return null; } @Override public void setEndDate(TimePoint startDate) { - // TODO Auto-generated method stub - } @Override public RegattaLikeIdentifier getRegattaLikeIdentifier() { - // TODO Auto-generated method stub return null; } @Override public void addListener(RegattaLikeListener listener) { - // TODO Auto-generated method stub - } @Override public void removeListener(RegattaLikeListener listener) { - // TODO Auto-generated method stub - } @Override public void adjustEventToRegattaAssociation(EventFetcher eventFetcher) { - // TODO Auto-generated method stub - } }; } @Override public Iterable getTrackedRaces() { - // TODO Auto-generated method stub return null; } @Override public Iterable getTrackedRaces(BoatClass boatClass) { - // TODO Auto-generated method stub return null; } @Override public void addTrackedRace(TrackedRace trackedRace) { - // TODO Auto-generated method stub - } @Override public void removeTrackedRace(TrackedRace trackedRace) { - // TODO Auto-generated method stub - } @Override public void addRaceListener(RaceListener listener) { - // TODO Auto-generated method stub - } @Override public int getNetPoints(Competitor competitor, TimePoint timePoint) throws NoWindException { - // TODO Auto-generated method stub return 0; } @Override public DynamicTrackedRace getTrackedRace(RaceDefinition race) { - // TODO Auto-generated method stub return null; } @Override public DynamicTrackedRace getExistingTrackedRace(RaceDefinition race) { - // TODO Auto-generated method stub return null; } @Override public void removeTrackedRace(RaceDefinition raceDefinition) { - // TODO Auto-generated method stub - } @Override public DynamicTrackedRace createTrackedRace(RaceDefinition raceDefinition, Iterable sidelines, WindStore windStore, GPSFixStore gpsFixStore, long delayToLiveInMillis, long millisecondsOverWhichToAverageWind, long millisecondsOverWhichToAverageSpeed, DynamicRaceDefinitionSet raceDefinitionSetToUpdate) { - // TODO Auto-generated method stub return null; } }; @@ -593,495 +486,396 @@ public class MockedTrackedRace implements DynamicTrackedRace { @Override public Position getApproximatePosition(Waypoint waypoint, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Tack getTack(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Tack getTack(SpeedWithBearing speedWithBearing, Wind wind, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Wind getDirectionFromStartToNextMark(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public List approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to) { - // TODO Auto-generated method stub return null; } @Override public List getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) { - // TODO Auto-generated method stub return null; } @Override public boolean raceIsKnownToStartUpwind() { - // TODO Auto-generated method stub return false; } @Override public void setRaceIsKnownToStartUpwind(boolean raceIsKnownToStartUpwind) { - // TODO Auto-generated method stub } @Override public RegattaAndRaceIdentifier getRaceIdentifier() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getEndOfRace() { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Wind getWind(Position p, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public Wind getWind(Position p, TimePoint at, Set windSourcesToExclude) { - // TODO Auto-generated method stub return null; } @Override public Set getWindSources(WindSourceType type) { - // TODO Auto-generated method stub return null; } @Override public Set getWindSources() { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at, Set windSourcesToExclude) { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence getEstimatedWindDirectionWithConfidence(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public Set getWindSourcesToExclude() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getEndOfTracking() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfOldestEvent() { - // TODO Auto-generated method stub return null; } @Override public void setStartOfTrackingReceived(TimePoint startOfTrackingReceived) { - // TODO Auto-generated method stub - } @Override public void setEndOfTrackingReceived(TimePoint endOfTrackingReceived) { - // TODO Auto-generated method stub - } @Override public Iterable>> getMarkPassingsTimes() { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, WindLegTypeAndLegBearingCache cache) { - // TODO Auto-generated method stub return null; } @Override public WindTrack getOrCreateWindTrack(WindSource windSource) { - // TODO Auto-generated method stub return null; } @Override public void recordFix(Mark mark, GPSFix fix) { - // TODO Auto-generated method stub - } @Override public void removeListener(RaceChangeListener listener) { - // TODO Auto-generated method stub - } @Override public WindStore getWindStore() { - // TODO Auto-generated method stub return null; } @Override public void setWindSourcesToExclude(Iterable windSourcesToExclude) { - // TODO Auto-generated method stub } @Override public Competitor getOverallLeader(TimePoint timePoint) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public long getDelayToLiveInMillis() { - // TODO Auto-generated method stub return 0; } @Override public void setDelayToLiveInMillis(long delayToLiveInMillis) { - // TODO Auto-generated method stub - } @Override public void setAndFixDelayToLiveInMillis(long delayToLiveInMillis) { - // TODO Auto-generated method stub - } @Override public List getCompetitorsFromBestToWorst(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public void waitUntilLoadingFromWindStoreComplete() throws InterruptedException { - // TODO Auto-generated method stub } @Override public Iterable getMarks() { - // TODO Auto-generated method stub return null; } @Override public boolean hasWindData() { - // TODO Auto-generated method stub return false; } @Override public boolean hasGPSData() { - // TODO Auto-generated method stub return false; } @Override public void lockForRead(Iterable markPassings) { - // TODO Auto-generated method stub - } @Override public void unlockAfterRead(Iterable markPassings) { - // TODO Auto-generated method stub - } @Override public TrackedRaceStatus getStatus() { - // TODO Auto-generated method stub return null; } @Override public void setStatus(TrackedRaceStatus newStatus) { - // TODO Auto-generated method stub } @Override public void waitUntilNotLoading() { - // TODO Auto-generated method stub } @Override public void detachRaceLog(Serializable identifier) { - // TODO Auto-generated method stub - } @Override public void attachRaceLog(RaceLog raceLog) { - // TODO Auto-generated method stub - } @Override public RaceLog getRaceLog(Serializable identifier) { - // TODO Auto-generated method stub return null; } @Override public void onCourseDesignChangedByRaceCommittee(CourseBase courseDesign) { - // TODO Auto-generated method stub - } @Override public void addCourseDesignChangedListener(CourseDesignChangedListener listener) { - // TODO Auto-generated method stub - } @Override public Distance getDistanceToStartLine(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceFromStarboardSideOfStartLineWhenPassingStart(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public void detachAllRaceLogs() { - // TODO Auto-generated method stub - } @Override public void invalidateStartTime() { - // TODO Auto-generated method stub - } @Override public void invalidateEndTime() { - // TODO Auto-generated method stub - } @Override public boolean isLive(TimePoint at) { - // TODO Auto-generated method stub return false; } @Override public Iterable getCourseSidelines() { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceToStartLine(Competitor competitor, long millisecondsBeforeRaceStart) { - // TODO Auto-generated method stub return null; } @Override public Speed getSpeed(Competitor competitor, long millisecondsBeforeRaceStart) { - // TODO Auto-generated method stub return null; } public void onStartTimeChangedByRaceCommittee(TimePoint newStartTime) { - // TODO Auto-generated method stub - } @Override public void addStartTimeChangedListener(StartTimeChangedListener listener) { - // TODO Auto-generated method stub - } @Override public TimePoint getStartTimeReceived() { - // TODO Auto-generated method stub return null; } @Override public LineDetails getStartLine(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public LineDetails getFinishLine(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public SpeedWithConfidence getAverageWindSpeedWithConfidence(long resolutionInMillis) { - // TODO Auto-generated method stub return null; } @Override public Distance getCourseLength() { - // TODO Auto-generated method stub return null; } @Override public Speed getSpeedWhenCrossingStartLine(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceFromStarboardSideOfStartLine(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public GPSFixStore getGPSFixStore() { - // TODO Auto-generated method stub return null; } @Override public Bearing getCrossingBearing(Waypoint w, TimePoint t) { - // TODO Auto-generated method stub return null; } @Override public Util.Pair getPortAndStarboardMarks(TimePoint t, Waypoint w) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, WindLegTypeAndLegBearingCache cache) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RaceLog rorRaceLog) throws InterruptedException { - // TODO Auto-generated method stub - } @Override public void addRaceAbortedListener(RaceAbortedListener listener) { - // TODO Auto-generated method stub - } @Override public void onAbortedByRaceCommittee(Flags flag) { - // TODO Auto-generated method stub - } @Override public Position getCenterOfCourse(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public void attachRegattaLog(RegattaLog regattaLog) { - // TODO Auto-generated method stub - } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RegattaLog fromRegattaLog) throws InterruptedException { - // TODO Auto-generated method stub - + } + + @Override + public Boolean isGateStart() { + return null; } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/DetailTypeFormatter.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/DetailTypeFormatter.java index cd93dc45c18..2b1a1660fd2 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/DetailTypeFormatter.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/DetailTypeFormatter.java @@ -14,6 +14,8 @@ public class DetailTypeFormatter { switch (detailType) { case DISTANCE_TRAVELED: return stringMessages.distanceInMeters(); + case DISTANCE_TRAVELED_INCLUDING_GATE_START: + return stringMessages.distanceIncludingGateStartInMeters(); case AVERAGE_SPEED_OVER_GROUND_IN_KNOTS: return stringMessages.averageSpeedInKnots(); case RANK_GAIN: @@ -50,6 +52,8 @@ public class DetailTypeFormatter { return stringMessages.windwardDistanceToGoInMeters(); case RACE_DISTANCE_TRAVELED: return stringMessages.distanceInMeters(); + case RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START: + return stringMessages.distanceIncludingGateStartInMeters(); case RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS: return stringMessages.averageSpeedInKnots(); case RACE_GAP_TO_LEADER_IN_SECONDS: @@ -159,8 +163,10 @@ public class DetailTypeFormatter { case WINDWARD_DISTANCE_TO_OVERALL_LEADER: case WINDWARD_DISTANCE_TO_GO_IN_METERS: case DISTANCE_TRAVELED: + case DISTANCE_TRAVELED_INCLUDING_GATE_START: case RACE_DISTANCE_TO_LEADER_IN_METERS: case RACE_DISTANCE_TRAVELED: + case RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START: case AVERAGE_TACK_LOSS_IN_METERS: case AVERAGE_JIBE_LOSS_IN_METERS: case AVERAGE_MANEUVER_LOSS_IN_METERS: @@ -257,6 +263,8 @@ public class DetailTypeFormatter { return ""; case DISTANCE_TRAVELED: return stringMessages.distanceTraveledTooltip(); + case DISTANCE_TRAVELED_INCLUDING_GATE_START: + return stringMessages.distanceTraveledIncludingGateStartTooltip(); case AVERAGE_SPEED_OVER_GROUND_IN_KNOTS: return stringMessages.averageSpeedInKnotsTooltip(); case ESTIMATED_TIME_TO_NEXT_WAYPOINT_IN_SECONDS: @@ -295,6 +303,8 @@ public class DetailTypeFormatter { return stringMessages.startTackTooltip(); case RACE_DISTANCE_TRAVELED: return stringMessages.raceDistanceTraveledTooltip(); + case RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START: + return stringMessages.raceDistanceTraveledIncludingGateStartTooltip(); case RACE_GAP_TO_LEADER_IN_SECONDS: return stringMessages.gapToLeaderInSecondsTooltip(); case RACE_RANK: 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 5e31216d2b7..259c3212777 100755 --- 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 @@ -1163,4 +1163,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages, c String runningQuery(); String courseOverGroundTrueDegreesTooltip(); String courseOverGroundTrueDegrees(); + String distanceIncludingGateStartInMeters(); + String distanceTraveledIncludingGateStartTooltip(); + String raceDistanceTraveledIncludingGateStartTooltip(); } 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 f488f4a2974..c3f612a9cca 100755 --- 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 @@ -1142,4 +1142,7 @@ showCompetitorFullNameColumn=Show Competitor Full Name loadingDimensionValues=Loading dimension values runningQuery=Running Query courseOverGroundTrueDegreesTooltip=True course over ground in degrees -courseOverGroundTrueDegrees=COG \ No newline at end of file +courseOverGroundTrueDegrees=COG +distanceIncludingGateStartInMeters=Distance (w/ Gate Start) +distanceTraveledIncludingGateStartTooltip=The distance traveled from the leg start to the end\nor to the current time point, if the leg isn''t finished.\nIf the leg includes a gate start, the distance from the pin end to the starting position is included\nto make competitors comparable even when started at different times. +raceDistanceTraveledIncludingGateStartTooltip=The distance traveled from the race start to the end\nor to the current time point, if the race isn''t finished. For a gate start, the distance from the pin end to the starting position is included\nto make competitors comparable even when started at different times. \ No newline at end of file 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 6feb903dbc6..0e3d41ccfbf 100755 --- 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 @@ -165,7 +165,7 @@ chooseChart=Diagramm wählen raceNameEmpty=Rennname leer distanceTraveled=Zurückgelegte Strecke distanceTraveledTooltip=Die zurückgelegt Strecke vom Start des Schenkels bis zum Ende\noder bis zum aktuellen Zeitpunkt, falls der Schenkel noch nicht beendet ist. -raceDistanceTraveledTooltip=Die zurückgelegt Strecke vom Start des Rennens, bis zum Ende\noder bis zum aktuellen Zeitpunkt, falls das Rennen noch nicht beendet ist. +raceDistanceTraveledTooltip=Die zurückgelegte Strecke vom Start des Rennens, bis zum Ende\noder bis zum aktuellen Zeitpunkt, falls das Rennen noch nicht beendet ist. velocityMadeGoodLong=Velocity Made Good speedOverGroundLong=Speed Over Ground gapToLeaderLong=Abstand zum führenden Boot @@ -1132,4 +1132,7 @@ showCompetitorFullNameColumn=Vollen Namen anzeigen loadingDimensionValues=Lade Dimensionswerte runningQuery=Datenabfrage läuft courseOverGroundTrueDegreesTooltip=Rechtweisender Kurs über Grund in Grad -courseOverGroundTrueDegrees=KüG \ No newline at end of file +courseOverGroundTrueDegrees=KüG +distanceIncludingGateStartInMeters=Distanz (m. Torstart) +distanceTraveledIncludingGateStartTooltip=Die zurückgelegt Strecke vom Start des Schenkels bis zum Ende\noder bis zum aktuellen Zeitpunkt, falls der Schenkel noch nicht beendet ist.\nEnthält der Schenkel einen Torstart, so wird die Distanz vom Pin End bis zur Startposition des Teilnehmers hinzugezählt,\num so vergleichbare Distanzen auch für Teilneher zu erhalten, die zu verschiedenen Zeiten gestartet sind. +raceDistanceTraveledIncludingGateStartTooltip=Die zurückgelegte Strecke vom Start des Rennens, bis zum Ende\noder bis zum aktuellen Zeitpunkt, falls das Rennen noch nicht beendet ist. Bei einem Torstart wird die Distanz vom Pin End bis zur Startposition des Teilnehmers hinzugezählt,\num so vergleichbare Distanzen auch für Teilneher zu erhalten, die zu verschiedenen Zeiten gestartet sind. \ No newline at end of file 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 fb982f836b6..45b8a2e386a 100755 --- 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 @@ -1081,4 +1081,7 @@ showCompetitorFullNameColumn=Show Competitor Full Name loadingDimensionValues=Loading dimension values runningQuery=Running Query courseOverGroundTrueDegreesTooltip=True course over ground in degrees -courseOverGroundTrueDegrees=COG \ No newline at end of file +courseOverGroundTrueDegrees=COG +distanceIncludingGateStartInMeters=Distance (w/ Gate Start) +distanceTraveledIncludingGateStartTooltip=The distance traveled from the leg start to the end\nor to the current time point, if the leg isn''t finished.\nIf the leg includes a gate start, the distance from the pin end to the starting position is included\nto make competitors comparable even when started at different times. +raceDistanceTraveledIncludingGateStartTooltip=The distance traveled from the race start to the end\nor to the current time point, if the race isn''t finished. For a gate start, the distance from the pin end to the starting position is included\nto make competitors comparable even when started at different times. \ No newline at end of file diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java index 2e572b80fa9..00a5e8e692e 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardPanel.java @@ -810,6 +810,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS if (isShowAddedScores()) { double o1AddedScore = computeAddedScores(o1); double o2AddedScore = computeAddedScores(o2); + // FIXME bug 2717: need to respect the scoring scheme's isHigherBetter() flag here double result = o1AddedScore == 0. ? o2AddedScore == 0. ? 0. : isAscending() ? 1. : -1. : o2AddedScore == 0. ? isAscending() ? 1. : -1. : o2AddedScore - o1AddedScore; return result > 0 ? 1 : result < 0 ? -1 : 0; } else { @@ -840,7 +841,7 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS public static DetailType[] getAvailableRaceDetailColumnTypes() { return new DetailType[] { DetailType.RACE_GAP_TO_LEADER_IN_SECONDS, DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, - DetailType.RACE_DISTANCE_TRAVELED, + DetailType.RACE_DISTANCE_TRAVELED, DetailType.RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START, DetailType.RACE_TIME_TRAVELED, DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS, DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS, DetailType.NUMBER_OF_MANEUVERS, DetailType.DISPLAY_LEGS, DetailType.CURRENT_LEG, @@ -903,6 +904,9 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS result.put(DetailType.RACE_DISTANCE_TRAVELED, new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TRAVELED, new RaceDistanceTraveledInMeters(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this)); + result.put(DetailType.RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START, + new FormattedDoubleDetailTypeColumn(DetailType.RACE_DISTANCE_TRAVELED_INCLUDING_GATE_START, new RaceDistanceTraveledIncludingGateStartInMeters(), + LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this)); result.put(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new FormattedDoubleDetailTypeColumn(DetailType.RACE_AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new RaceAverageSpeedInKnots(), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE, LeaderboardPanel.this)); @@ -1254,6 +1258,35 @@ public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayS } } + /** + * Accumulates the distance traveled over all legs of a race and considers the specifics of a gate start. The + * first leg of a gate start gets as additional distance traveled the distance from the port side of the line to + * the point where the competitor started which helps normalize the distance traveled and make them comparable + * across early and late starters. + * + * @author Axel Uhl (D043530) + */ + private class RaceDistanceTraveledIncludingGateStartInMeters implements LegDetailField { + @Override + public Double get(LeaderboardRowDTO row) { + Double result = null; + LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceColumnName.get(getRaceColumnName()); + if (fieldsForRace != null && fieldsForRace.legDetails != null) { + for (LegEntryDTO legDetail : fieldsForRace.legDetails) { + if (legDetail != null) { + if (legDetail.distanceTraveledIncludingGateStartInMeters != null) { + if (result == null) { + result = 0.0; + } + result += legDetail.distanceTraveledIncludingGateStartInMeters; + } + } + } + } + return result; + } + } + private class CurrentLeg implements LegDetailField { @Override public Double get(LeaderboardRowDTO row) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java index 73db0d81429..e9abe69d660 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LegColumn.java @@ -54,6 +54,13 @@ public class LegColumn extends ExpandableSortableColumn { } } + private class DistanceTraveledIncludingGateStartInMeters extends AbstractLegDetailField { + @Override + protected Double getFromNonNullEntry(LegEntryDTO entry) { + return entry.distanceTraveledIncludingGateStartInMeters; + } + } + private class TimeTraveledInSeconds extends AbstractLegDetailField { @Override protected Double getFromNonNullEntry(LegEntryDTO entry) { @@ -234,6 +241,7 @@ public class LegColumn extends ExpandableSortableColumn { public static DetailType[] getAvailableLegDetailColumnTypes() { return new DetailType[] { DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, DetailType.DISTANCE_TRAVELED, + DetailType.DISTANCE_TRAVELED_INCLUDING_GATE_START, DetailType.GAP_TO_LEADER_IN_SECONDS, DetailType.GAP_CHANGE_SINCE_LEG_START_IN_SECONDS, DetailType.SIDE_TO_WHICH_MARK_AT_LEG_START_WAS_ROUNDED, DetailType.CURRENT_SPEED_OVER_GROUND_IN_KNOTS, DetailType.WINDWARD_DISTANCE_TO_GO_IN_METERS, DetailType.NUMBER_OF_MANEUVERS, @@ -251,6 +259,9 @@ public class LegColumn extends ExpandableSortableColumn { result.put(DetailType.DISTANCE_TRAVELED, new FormattedDoubleDetailTypeColumn(DetailType.DISTANCE_TRAVELED, new DistanceTraveledInMeters(), detailHeaderStyle, detailColumnStyle, leaderboardPanel)); + result.put(DetailType.DISTANCE_TRAVELED_INCLUDING_GATE_START, + new FormattedDoubleDetailTypeColumn(DetailType.DISTANCE_TRAVELED_INCLUDING_GATE_START, new DistanceTraveledIncludingGateStartInMeters(), detailHeaderStyle, detailColumnStyle, leaderboardPanel)); + result.put(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new FormattedDoubleDetailTypeColumn(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS, new AverageSpeedOverGroundInKnots(), detailHeaderStyle, detailColumnStyle, leaderboardPanel)); diff --git a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RegattaJsonSerializer.java b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RegattaJsonSerializer.java index b74ad82272b..86e0df11d89 100644 --- a/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RegattaJsonSerializer.java +++ b/java/com.sap.sailing.server.gateway.serialization/src/com/sap/sailing/server/gateway/serialization/impl/RegattaJsonSerializer.java @@ -35,7 +35,7 @@ public class RegattaJsonSerializer implements JsonSerializer { result.put(FIELD_NAME, regatta.getName()); result.put(FIELD_START_DATE, regatta.getStartDate() != null ? regatta.getStartDate().asMillis() : null); - result.put(FIELD_END_DATE, regatta.getStartDate() != null ? regatta.getEndDate().asMillis() : null); + result.put(FIELD_END_DATE, regatta.getEndDate() != null ? regatta.getEndDate().asMillis() : null); result.put(FIELD_SCORINGSYSTEM, regatta.getScoringScheme().getType().name()); result.put(FIELD_BOATCLASS, regatta.getBoatClass() != null ? regatta.getBoatClass().getName(): null); diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java index f1ae8aa36fc..b273979f313 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/api/RegattasResource.java @@ -594,7 +594,34 @@ public class RegattasResource extends AbstractSailingServerResource { } return response; } - + + @GET + @Produces("application/json;charset=UTF-8") + @Path("{regattaname}/races") + public Response getRaces(@PathParam("regattaname") String regattaName) { + Response response; + Regatta regatta = findRegattaByName(regattaName); + if (regatta == null) { + response = Response.status(Status.NOT_FOUND) + .entity("Could not find a regatta with name '" + regattaName + "'.").type(MediaType.TEXT_PLAIN) + .build(); + } else { + JSONObject jsonRaceResults = new JSONObject(); + jsonRaceResults.put("regatta", regatta.getName()); + JSONArray jsonRaces = new JSONArray(); + jsonRaceResults.put("races", jsonRaces); + for (RaceDefinition race : regatta.getAllRaces()) { + JSONObject jsonRace = new JSONObject(); + jsonRaces.add(jsonRace); + jsonRace.put("name", race.getName()); + jsonRace.put("id", race.getId().toString()); + } + String json = jsonRaceResults.toJSONString(); + return Response.ok(json, MediaType.APPLICATION_JSON).build(); + } + return response; + } + @GET @Produces("application/json;charset=UTF-8") @Path("{regattaname}/races/{racename}/competitors/legs") @@ -685,6 +712,12 @@ public class RegattasResource extends AbstractSailingServerResource { if (distanceTraveled != null) { jsonCompetitorInLeg.put("distanceTraveled-m", UnitSerializationUtil.distanceDecimalFormatter.format(distanceTraveled.getMeters())); } + Distance distanceTraveledIncludingGateStart = trackedLegOfCompetitor.getDistanceTraveledConsideringGateStart(timePoint); + if (distanceTraveledIncludingGateStart != null) { + jsonCompetitorInLeg.put("distanceTraveledIncludingGateStart-m", + UnitSerializationUtil.distanceDecimalFormatter + .format(distanceTraveledIncludingGateStart.getMeters())); + } try { Integer rank = ranks.get(competitor); jsonCompetitorInLeg.put("rank", rank); @@ -786,6 +819,10 @@ public class RegattasResource extends AbstractSailingServerResource { if (distanceTraveled != null) { jsonCompetitorInLeg.put("distanceTraveled-m", roundDouble(distanceTraveled.getMeters(), 2)); } + Distance distanceTraveledConsideringGateStart = currentLegOfCompetitor.getDistanceTraveledConsideringGateStart(timePoint); + if (distanceTraveledConsideringGateStart != null) { + jsonCompetitorInLeg.put("distanceTraveledConsideringGateStart-m", roundDouble(distanceTraveledConsideringGateStart.getMeters(), 2)); + } Double gapToLeaderInSeconds = currentLegOfCompetitor.getGapToLeaderInSeconds(timePoint, WindPositionMode.LEG_MIDDLE); if(gapToLeaderInSeconds != null) { diff --git a/java/com.sap.sailing.server.gateway/webservices/api/v1/index.html b/java/com.sap.sailing.server.gateway/webservices/api/v1/index.html index fd83b6ab453..918842bb1c7 100644 --- a/java/com.sap.sailing.server.gateway/webservices/api/v1/index.html +++ b/java/com.sap.sailing.server.gateway/webservices/api/v1/index.html @@ -52,6 +52,10 @@ name to make sure you get to the event you're interested in. /api/v1/regattas/{name} Gets the details of a regatta + + /api/v1/regattas/{name}/races + Gets the list of races in a regatta + /api/v1/regattas/{name}/entries Gets the entries of a regatta diff --git a/java/com.sap.sailing.server.gateway/webservices/api/v1/racesGetDoc.html b/java/com.sap.sailing.server.gateway/webservices/api/v1/racesGetDoc.html new file mode 100755 index 00000000000..bf096d454da --- /dev/null +++ b/java/com.sap.sailing.server.gateway/webservices/api/v1/racesGetDoc.html @@ -0,0 +1,46 @@ + + + + + + + + SAP Sailing Analytics Webservices API Version 1.0 Beta + + +

    SAP Sailing Analytics Webservices API Version 1.0 Beta

    +

    URL: /api/v1/regattas/{regattaname}/races

    + +Description: +

    The service gets the names and IDs of all races in a regatta

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Webservice Type:REST
    Output format:Json
    Mandatory parameters:None
    Optional parameters:None
    Request method:GET
    Example:http://www.sapsailing.com/sailingserver/api/v1/regattas/505%20Worlds%202014/races
    +
    +Back to Web Service Overview + + diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java index d04b88dce89..aec6039ed13 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java @@ -210,91 +210,73 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials { @Override public void waitForNextUpdate(int sinceUpdate) throws InterruptedException { - // TODO Auto-generated method stub - } @Override public TimePoint getStartOfTracking() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getEndOfTracking() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfNewestEvent() { - // TODO Auto-generated method stub return null; } @Override public TimePoint getTimePointOfOldestEvent() { - // TODO Auto-generated method stub return null; } @Override public NavigableSet getMarkPassings(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public void lockForRead(Iterable markPassings) { - // TODO Auto-generated method stub - } @Override public void unlockAfterRead(Iterable markPassings) { - // TODO Auto-generated method stub - } @Override public TimePoint getTimePointOfLastEvent() { - // TODO Auto-generated method stub return null; } @Override public long getMillisecondsOverWhichToAverageSpeed() { - // TODO Auto-generated method stub return 0; } @Override public long getMillisecondsOverWhichToAverageWind() { - // TODO Auto-generated method stub return 0; } @Override public long getDelayToLiveInMillis() { - // TODO Auto-generated method stub return 0; } @Override public Wind getEstimatedWindDirection(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Tack getTack(Competitor competitor, TimePoint timePoint) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Tack getTack(SpeedWithBearing speedWithBearing, Wind wind, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @@ -305,328 +287,269 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials { @Override public Wind getDirectionFromStartToNextMark(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public List approximate(Competitor competitor, Distance maxDistance, TimePoint from, TimePoint to) { - // TODO Auto-generated method stub return null; } @Override public List getManeuvers(Competitor competitor, TimePoint from, TimePoint to, boolean waitForLatest) { - // TODO Auto-generated method stub return null; } @Override public boolean raceIsKnownToStartUpwind() { - // TODO Auto-generated method stub return false; } @Override public boolean hasWindData() { - // TODO Auto-generated method stub return false; } @Override public boolean hasGPSData() { - // TODO Auto-generated method stub return false; } @Override public void addListener(RaceChangeListener listener) { - // TODO Auto-generated method stub - } @Override public void addListener(RaceChangeListener listener, boolean notifyAboutWindFixesAlreadyLoaded, boolean notifyAboutGPSFixesAlreadyLoaded) { - // TODO Auto-generated method stub - } @Override public void removeListener(RaceChangeListener listener) { - // TODO Auto-generated method stub } @Override public Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public Set getWindSourcesToExclude() { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence> getWindWithConfidence(Position p, TimePoint at, Set windSourcesToExclude) { - // TODO Auto-generated method stub return null; } @Override public WindWithConfidence getEstimatedWindDirectionWithConfidence(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public void setWindSourcesToExclude(Iterable windSourcesToExclude) { - // TODO Auto-generated method stub } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, WindLegTypeAndLegBearingCache cache) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint timePoint, boolean waitForLatestAnalyses, WindLegTypeAndLegBearingCache cache) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalysis) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public WindStore getWindStore() { - // TODO Auto-generated method stub return null; } @Override public Competitor getOverallLeader(TimePoint timePoint) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public List getCompetitorsFromBestToWorst(TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getAverageAbsoluteCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly, boolean waitForLatestAnalyses) throws NoWindException { - // TODO Auto-generated method stub return null; } @Override public void waitUntilLoadingFromWindStoreComplete() throws InterruptedException { - // TODO Auto-generated method stub - } @Override public TrackedRaceStatus getStatus() { - // TODO Auto-generated method stub return null; } @Override public void waitUntilNotLoading() { - // TODO Auto-generated method stub - } @Override public void detachRaceLog(Serializable identifier) { - // TODO Auto-generated method stub - } @Override public void detachAllRaceLogs() { - // TODO Auto-generated method stub - } @Override public void attachRaceLog(RaceLog raceLog) { - // TODO Auto-generated method stub - } @Override public RaceLog getRaceLog(Serializable identifier) { - // TODO Auto-generated method stub return null; } @Override public void addCourseDesignChangedListener(CourseDesignChangedListener listener) { - // TODO Auto-generated method stub } @Override public Distance getDistanceToStartLine(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceFromStarboardSideOfStartLineWhenPassingStart(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public boolean isLive(TimePoint at) { - // TODO Auto-generated method stub return false; } @Override public Iterable getCourseSidelines() { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceToStartLine(Competitor competitor, long millisecondsBeforeRaceStart) { - // TODO Auto-generated method stub return null; } @Override public Speed getSpeed(Competitor competitor, long millisecondsBeforeRaceStart) { - // TODO Auto-generated method stub return null; } public void addStartTimeChangedListener(StartTimeChangedListener listener) { - // TODO Auto-generated method stub } @Override public TimePoint getStartTimeReceived() { - // TODO Auto-generated method stub return null; } @Override public LineDetails getStartLine(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public LineDetails getFinishLine(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public SpeedWithConfidence getAverageWindSpeedWithConfidence(long resolutionInMillis) { - // TODO Auto-generated method stub return null; } @Override public Distance getCourseLength() { - // TODO Auto-generated method stub return null; } @Override public Speed getSpeedWhenCrossingStartLine(Competitor competitor) { - // TODO Auto-generated method stub return null; } @Override public Distance getDistanceFromStarboardSideOfStartLine(Competitor competitor, TimePoint timePoint) { - // TODO Auto-generated method stub return null; } @Override public GPSFixStore getGPSFixStore() { - // TODO Auto-generated method stub return null; } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RaceLog forRaceLog) throws InterruptedException { - // TODO Auto-generated method stub - } @Override public void addRaceAbortedListener(RaceAbortedListener listener) { - // TODO Auto-generated method stub - } @Override public Position getCenterOfCourse(TimePoint at) { - // TODO Auto-generated method stub return null; } @Override public void attachRegattaLog(RegattaLog regattaLog) { - // TODO Auto-generated method stub - } @Override public void waitForLoadingFromGPSFixStoreToFinishRunning(RegattaLog fromRegattaLog) throws InterruptedException { - // TODO Auto-generated method stub - + } + + @Override + public Boolean isGateStart() { + return null; } } From 495cd85bd0254cb8406b362d37a0c5f54c764289 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Mar 2015 14:18:59 +0100 Subject: [PATCH 05/20] added distance-considering-gate-start metric also at race level --- .../domain/test/mock/MockedTrackedRace.java | 10 +++++++ ...ockedTrackedRaceWithStartTimeAndRanks.java | 10 +++++++ .../impl/AbstractSimpleLeaderboardImpl.java | 2 ++ .../sailing/domain/tracking/TrackedRace.java | 12 +++++++++ .../impl/TrackedLegOfCompetitorImpl.java | 12 ++------- .../domain/tracking/impl/TrackedRaceImpl.java | 27 +++++++++++++++++++ .../gwt/ui/test/MockedTrackedRace.java | 10 +++++++ ...iCompetitorRaceChartSettingsComponent.java | 1 + .../gwt/ui/server/SailingServiceImpl.java | 6 +++++ .../server/masterdata/DummyTrackedRace.java | 10 +++++++ 10 files changed, 90 insertions(+), 10 deletions(-) diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java index 6a14bc2a55e..04e8278966f 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRace.java @@ -883,4 +883,14 @@ public class MockedTrackedRace implements DynamicTrackedRace { public Boolean isGateStart() { return null; } + + @Override + public Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint) { + return null; + } + + @Override + public Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint) { + return null; + } } diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java index f55c87c0fb7..a00788e3bbd 100755 --- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java +++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/mock/MockedTrackedRaceWithStartTimeAndRanks.java @@ -577,4 +577,14 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace { return null; } + @Override + public Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint) { + return null; + } + + @Override + public Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint) { + return null; + } + } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java index 23ed35dc8c5..0313806617c 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/AbstractSimpleLeaderboardImpl.java @@ -1634,6 +1634,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race result.currentSpeedOverGroundInKnots = speedOverGroundInKnots == null ? null : speedOverGroundInKnots; Distance distanceTraveled = trackedLeg.getDistanceTraveled(timePoint); result.distanceTraveledInMeters = distanceTraveled == null ? null : distanceTraveled.getMeters(); + Distance distanceTraveledConsideringGateStart = trackedLeg.getDistanceTraveledConsideringGateStart(timePoint); + result.distanceTraveledIncludingGateStartInMeters = distanceTraveledConsideringGateStart == null ? null : distanceTraveledConsideringGateStart.getMeters(); result.estimatedTimeToNextWaypointInSeconds = trackedLeg.getEstimatedTimeToNextMarkInSeconds(timePoint, WindPositionMode.EXACT, cache); result.timeInMilliseconds = time.asMillis(); result.finished = trackedLeg.hasFinishedLeg(timePoint); diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java index 38c3d1b8279..ca31082a2ac 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/TrackedRace.java @@ -474,6 +474,11 @@ public interface TrackedRace extends Serializable { */ Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint); + /** + * See {@link TrackedLegOfCompetitor#getDistanceTraveledConsideringGateStart(TimePoint)} + */ + Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint); + Distance getWindwardDistanceToOverallLeader(Competitor competitor, TimePoint timePoint, WindPositionMode windPositionMode) throws NoWindException; /** @@ -728,5 +733,12 @@ public interface TrackedRace extends Serializable { * null is returned, meaning that the type is not known. */ Boolean isGateStart(); + + /** + * If the race was started with a gate start (see {@link #isGateStart()}, this method returns the distance between + * the competitor's starting position and the port side of the start line (pin end); otherwise, returns a zero + * distance. + */ + Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint); } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java index 4aeff1139f8..8e2347a71c2 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedLegOfCompetitorImpl.java @@ -117,16 +117,8 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor { final Distance result; final Distance preResult = getDistanceTraveled(timePoint); final Waypoint from = getLeg().getFrom(); - final TimePoint competitorLegStartTime = getStartTime(); - if (from == getTrackedRace().getRace().getCourse().getFirstWaypoint() && getTrackedRace().isGateStart() == true - && competitorLegStartTime != null) { - final Mark portMarkOfStartLine = getTrackedRace().getStartLine(competitorLegStartTime) - .getPortMarkWhileApproachingLine(); - final Position portSideOfStartLinePosition = getTrackedRace().getOrCreateTrack(portMarkOfStartLine) - .getEstimatedPosition(competitorLegStartTime, /* extrapolate */true); - final Distance additionalDistance = portSideOfStartLinePosition.getDistance(getTrackedRace().getTrack( - getCompetitor()).getEstimatedPosition(competitorLegStartTime, /* extrapolate */false)); - result = preResult.add(additionalDistance); + if (from == getTrackedRace().getRace().getCourse().getFirstWaypoint()) { + result = preResult.add(getTrackedRace().getAdditionalGateStartDistance(getCompetitor(), timePoint)); } else { result = preResult; } diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index 20379a7d8ca..b8fd895d254 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -892,8 +892,17 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl } } + @Override + public Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint) { + return getDistanceTraveled(competitor, timePoint, /* consider gate start */ true); + } + @Override public Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint) { + return getDistanceTraveled(competitor, timePoint, /* consider gate start */ false); + } + + private Distance getDistanceTraveled(Competitor competitor, TimePoint timePoint, boolean considerGateStart) { final Distance result; NavigableSet markPassings = getMarkPassings(competitor); try { @@ -3296,4 +3305,22 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl } return result; } + + @Override + public Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint) { + final Distance result; + final Leg startLeg = getRace().getCourse().getFirstLeg(); + final TrackedLegOfCompetitor competitorLeg; + if (startLeg != null && isGateStart() == true && (competitorLeg=getTrackedLeg(competitor, startLeg)).hasStartedLeg(timePoint)) { + TimePoint competitorLegStartTime = competitorLeg.getStartTime(); + final Mark portMarkOfStartLine = getStartLine(competitorLegStartTime).getPortMarkWhileApproachingLine(); + final Position portSideOfStartLinePosition = getOrCreateTrack(portMarkOfStartLine) + .getEstimatedPosition(competitorLegStartTime, /* extrapolate */true); + result = portSideOfStartLinePosition.getDistance(getTrack(competitor).getEstimatedPosition(competitorLegStartTime, /* extrapolate */false)); + } else { + result = Distance.NULL; + } + return result; + } + } diff --git a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java index 31a28fb953e..e25f4979549 100755 --- a/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java +++ b/java/com.sap.sailing.gwt.ui.test/src/com/sap/sailing/gwt/ui/test/MockedTrackedRace.java @@ -878,4 +878,14 @@ public class MockedTrackedRace implements DynamicTrackedRace { return null; } + @Override + public Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint) { + return null; + } + + @Override + public Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint) { + return null; + } + } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/MultiCompetitorRaceChartSettingsComponent.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/MultiCompetitorRaceChartSettingsComponent.java index ba8e73a0ffa..3f61f3ddb98 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/MultiCompetitorRaceChartSettingsComponent.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/shared/charts/MultiCompetitorRaceChartSettingsComponent.java @@ -27,6 +27,7 @@ public class MultiCompetitorRaceChartSettingsComponent extends AbstractChartSett availableDetailsTypes = new ArrayList(); availableDetailsTypes.add(DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER); availableDetailsTypes.add(DetailType.DISTANCE_TRAVELED); + availableDetailsTypes.add(DetailType.DISTANCE_TRAVELED_INCLUDING_GATE_START); availableDetailsTypes.add(DetailType.VELOCITY_MADE_GOOD_IN_KNOTS); availableDetailsTypes.add(DetailType.GAP_TO_LEADER_IN_SECONDS); availableDetailsTypes.add(DetailType.RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java index d2148fb3f51..68f836f55fd 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/server/SailingServiceImpl.java @@ -2746,6 +2746,12 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S result = distanceTraveled == null ? null : distanceTraveled.getMeters(); } break; + case DISTANCE_TRAVELED_INCLUDING_GATE_START: + if (trackedLeg != null) { + Distance distanceTraveledConsideringGateStart = trackedRace.getDistanceTraveledIncludingGateStart(competitor, timePoint); + result = distanceTraveledConsideringGateStart == null ? null : distanceTraveledConsideringGateStart.getMeters(); + } + break; case GAP_TO_LEADER_IN_SECONDS: if (trackedLeg != null) { result = trackedLeg.getGapToLeaderInSeconds(timePoint, WindPositionMode.LEG_MIDDLE, cache); diff --git a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java index aec6039ed13..61d72e3b8ba 100755 --- a/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java +++ b/java/com.sap.sailing.server/src/com/sap/sailing/server/masterdata/DummyTrackedRace.java @@ -552,4 +552,14 @@ public class DummyTrackedRace extends TrackedRaceWithWindEssentials { return null; } + @Override + public Distance getDistanceTraveledIncludingGateStart(Competitor competitor, TimePoint timePoint) { + return null; + } + + @Override + public Distance getAdditionalGateStartDistance(Competitor competitor, TimePoint timePoint) { + return null; + } + } From aa3e4fee4c799add0f205b9c5a74f40e33c802bf Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Fri, 20 Mar 2015 14:40:32 +0100 Subject: [PATCH 06/20] fixed race distance query in TrackedRaceImpl so that distances can be queried for all finished legs --- .../domain/tracking/impl/TrackedRaceImpl.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java index b8fd895d254..0fa7853bb80 100755 --- a/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java +++ b/java/com.sap.sailing.domain/src/com/sap/sailing/domain/tracking/impl/TrackedRaceImpl.java @@ -911,22 +911,29 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl result = null; } else { TimePoint end = timePoint; + final TrackedLegOfCompetitor trackedLegOfCompetitor; if (markPassings.last().getWaypoint() == getRace().getCourse().getLastWaypoint() && timePoint.compareTo(markPassings.last().getTimePoint()) > 0) { - // competitor has finished race; use time point of crossing the finish line + // competitor has finished race at or before the requested time point; use time point of crossing the finish line end = markPassings.last().getTimePoint(); - } else if (markPassings.last().getWaypoint() != getRace().getCourse().getLastWaypoint() + } else if ((trackedLegOfCompetitor=getTrackedLeg(competitor, timePoint)) == null || + (!trackedLegOfCompetitor.hasFinishedLeg(timePoint) && ((getEndOfTracking() != null && timePoint.after(getEndOfTracking())) - || getStatus().getStatus() == TrackedRaceStatusEnum.FINISHED)) { + || getStatus().getStatus() == TrackedRaceStatusEnum.FINISHED))) { // If the race is no longer tracking and hence no more data can be expected, and the competitor - // hasn't finished the race, no valid distance traveled can be determined - // for the competitor in this race. + // hasn't finished a leg after the requested time point, no valid distance traveled can be determined + // for the competitor in this race the the time point requested end = null; } if (end == null) { result = null; } else { - result = getTrack(competitor).getDistanceTraveled(markPassings.first().getTimePoint(), end); + final Distance preResult = getTrack(competitor).getDistanceTraveled(markPassings.first().getTimePoint(), end); + if (considerGateStart && preResult != null) { + result = preResult.add(getAdditionalGateStartDistance(competitor, timePoint)); + } else { + result = preResult; + } } } return result; From bb65e01ed41a9abbfe65b882661c7f1653ffa797 Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Sat, 21 Mar 2015 12:41:45 +0100 Subject: [PATCH 07/20] Added a priority to the ProcessorInstruction and made it Comparable --- ...estLeaderboardGroupRetrievalProcessor.java | 2 +- ...OfRaceInLeaderboardRetrievalProcessor.java | 4 +- .../components/GPSFixRetrievalProcessor.java | 4 +- .../LeaderboardGroupRetrievalProcessor.java | 19 ++++---- .../LeaderboardRetrievalProcessor.java | 4 +- .../MarkPassingRetrievalProcessor.java | 4 +- ...ckedLegOfCompetitorRetrievalProcessor.java | 4 +- .../TrackedLegRetrievalProcessor.java | 4 +- .../TrackedRaceRetrievalProcessor.java | 4 +- .../impl/TestDataRetrieverChainCreation.java | 23 ++++------ .../datamining/impl/TestProcessorQuery.java | 2 +- .../TestRetrieverFilterProcessorChain.java | 4 +- ...mpetitorWithContextRetrievalProcessor.java | 4 +- ...TestRaceWithContextRetrievalProcessor.java | 4 +- .../TestRegattaRetrievalProcessor.java | 4 +- .../impl/SimpleDataRetrieverChainBuilder.java | 12 ++--- .../SimpleDataRetrieverChainDefinition.java | 2 +- ...tiDimensionalNestingGroupingProcessor.java | 2 +- .../AbstractRetrievalProcessor.java | 16 ++++++- .../AbstractSimpleRetrievalProcessor.java | 13 +++++- .../ParallelFilteringProcessor.java | 2 +- ...oupedElementsValueExtractionProcessor.java | 2 +- .../impl/components/ProcessorInstruction.java | 45 ++++++++++++++++++- .../ProcessorInstructionPriority.java | 33 ++++++++++++++ ...ctParallelStoringAggregationProcessor.java | 3 +- 25 files changed, 156 insertions(+), 64 deletions(-) create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstructionPriority.java diff --git a/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/impl/components/TestLeaderboardGroupRetrievalProcessor.java b/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/impl/components/TestLeaderboardGroupRetrievalProcessor.java index 2de830a3a3f..190b38265a6 100644 --- a/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/impl/components/TestLeaderboardGroupRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/impl/components/TestLeaderboardGroupRetrievalProcessor.java @@ -46,7 +46,7 @@ public class TestLeaderboardGroupRetrievalProcessor { Collection> resultReceivers = new ArrayList<>(); resultReceivers.add(receiver); - retriever = new LeaderboardGroupRetrievalProcessor(ConcurrencyTestsUtil.getExecutor(), resultReceivers); + retriever = new LeaderboardGroupRetrievalProcessor(ConcurrencyTestsUtil.getExecutor(), resultReceivers, 0); } private Map getGroupsInService() { diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/CompetitorOfRaceInLeaderboardRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/CompetitorOfRaceInLeaderboardRetrievalProcessor.java index 570b50c914e..660cf7551f1 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/CompetitorOfRaceInLeaderboardRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/CompetitorOfRaceInLeaderboardRetrievalProcessor.java @@ -16,8 +16,8 @@ public class CompetitorOfRaceInLeaderboardRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public CompetitorOfRaceInLeaderboardRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(HasLeaderboardContext.class, HasRaceResultOfCompetitorContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(HasLeaderboardContext.class, HasRaceResultOfCompetitorContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/GPSFixRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/GPSFixRetrievalProcessor.java index 97f4dc71ab4..84ae262d54f 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/GPSFixRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/GPSFixRetrievalProcessor.java @@ -16,8 +16,8 @@ import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor; public class GPSFixRetrievalProcessor extends AbstractSimpleRetrievalProcessor { - public GPSFixRetrievalProcessor(ExecutorService executor, Collection> resultReceivers) { - super(HasTrackedLegOfCompetitorContext.class, HasGPSFixContext.class, executor, resultReceivers); + public GPSFixRetrievalProcessor(ExecutorService executor, Collection> resultReceivers, int retrievalLevel) { + super(HasTrackedLegOfCompetitorContext.class, HasGPSFixContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java index 57a8d713c6d..deb4030e573 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardGroupRetrievalProcessor.java @@ -14,19 +14,18 @@ public class LeaderboardGroupRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public LeaderboardGroupRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(RacingEventService.class, LeaderboardGroupWithContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(RacingEventService.class, LeaderboardGroupWithContext.class, executor, resultReceivers, retrievalLevel); } @Override protected Iterable retrieveData(RacingEventService element) { - final PolarDataService polarDataService = element.getPolarDataService(); - return element - .getLeaderboardGroups() - .values() - .stream() - .map(lg -> new LeaderboardGroupWithContext(lg, polarDataService)) - .collect(Collectors.toSet()); - } + final PolarDataService polarDataService = element.getPolarDataService(); + return element.getLeaderboardGroups() + .values() + .stream() + .map(lg -> new LeaderboardGroupWithContext(lg, polarDataService)) + .collect(Collectors.toSet()); + } } diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardRetrievalProcessor.java index 04b52fdbdea..fea7c3b1cb7 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/LeaderboardRetrievalProcessor.java @@ -15,8 +15,8 @@ public class LeaderboardRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public LeaderboardRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(LeaderboardGroupWithContext.class, HasLeaderboardContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(LeaderboardGroupWithContext.class, HasLeaderboardContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java index 4dec85496f6..6065d611818 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/MarkPassingRetrievalProcessor.java @@ -19,8 +19,8 @@ public class MarkPassingRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public MarkPassingRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(HasTrackedRaceContext.class, HasMarkPassingContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(HasTrackedRaceContext.class, HasMarkPassingContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegOfCompetitorRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegOfCompetitorRetrievalProcessor.java index 8c25a0029cd..8298d7d3d0a 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegOfCompetitorRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegOfCompetitorRetrievalProcessor.java @@ -15,8 +15,8 @@ public class TrackedLegOfCompetitorRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public TrackedLegOfCompetitorRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(HasTrackedLegContext.class, HasTrackedLegOfCompetitorContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(HasTrackedLegContext.class, HasTrackedLegOfCompetitorContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegRetrievalProcessor.java index 2e61e0051a3..22c616f4be7 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedLegRetrievalProcessor.java @@ -15,8 +15,8 @@ public class TrackedLegRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public TrackedLegRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(HasTrackedRaceContext.class, HasTrackedLegContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(HasTrackedRaceContext.class, HasTrackedLegContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedRaceRetrievalProcessor.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedRaceRetrievalProcessor.java index 176f16fded0..d22f810047e 100644 --- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedRaceRetrievalProcessor.java +++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/impl/components/TrackedRaceRetrievalProcessor.java @@ -18,8 +18,8 @@ public class TrackedRaceRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public TrackedRaceRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(HasLeaderboardContext.class, HasTrackedRaceContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(HasLeaderboardContext.class, HasTrackedRaceContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestDataRetrieverChainCreation.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestDataRetrieverChainCreation.java index 6d625a16089..67b8d1a1f57 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestDataRetrieverChainCreation.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestDataRetrieverChainCreation.java @@ -46,20 +46,15 @@ public class TestDataRetrieverChainCreation { @Before public void initializeRetrieverChain() { dataRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>((Class>)(Class) Collection.class, Test_HasLegOfCompetitorContext.class, "TestRetrieverChain"); - Class, Test_Regatta>> regattaRetrieverClass = (Class, Test_Regatta>>)(Class) TestRegattaRetrievalProcessor.class; - dataRetrieverChainDefinition.startWith(regattaRetrieverClass, Test_Regatta.class, "regatta"); + dataRetrieverChainDefinition.startWith(TestRegattaRetrievalProcessor.class, Test_Regatta.class, "regatta"); - Class> raceRetrieverClass = - (Class>)(Class) TestRaceWithContextRetrievalProcessor.class; - dataRetrieverChainDefinition.addAfter(regattaRetrieverClass, - raceRetrieverClass, - Test_HasRaceContext.class, "race"); + dataRetrieverChainDefinition.addAfter(TestRegattaRetrievalProcessor.class, + TestRaceWithContextRetrievalProcessor.class, + Test_HasRaceContext.class, "race"); - Class> legRetrieverClass = - (Class>)(Class) TestLegOfCompetitorWithContextRetrievalProcessor.class; - dataRetrieverChainDefinition.endWith(raceRetrieverClass, - legRetrieverClass, - Test_HasLegOfCompetitorContext.class, "legOfCompetitor"); + dataRetrieverChainDefinition.endWith(TestRaceWithContextRetrievalProcessor.class, + TestLegOfCompetitorWithContextRetrievalProcessor.class, + Test_HasLegOfCompetitorContext.class, "legOfCompetitor"); } @Before @@ -179,8 +174,8 @@ public class TestDataRetrieverChainCreation { dataRetrieverChainDefinition.startWith(regattaRetrieverClass, Test_Regatta.class, "regatta"); dataRetrieverChainDefinition.addAfter(regattaRetrieverClass, - (Class>)(Class) Processor.class, - Test_HasRaceContext.class, "race"); + (Class>)(Class) Processor.class, + Test_HasRaceContext.class, "race"); } @SuppressWarnings("unchecked") diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java index 1f28a183f0b..6eef188f92e 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java @@ -136,7 +136,7 @@ public class TestProcessorQuery { @SuppressWarnings("unchecked") Processor, Number> retrievalProcessor = new AbstractSimpleRetrievalProcessor, Number>((Class>)(Class) Iterable.class, Number.class, - ConcurrencyTestsUtil.getExecutor(), retrievalResultReceivers) { + ConcurrencyTestsUtil.getExecutor(), retrievalResultReceivers, 0) { @Override protected Iterable retrieveData(Iterable element) { return element; diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestRetrieverFilterProcessorChain.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestRetrieverFilterProcessorChain.java index d325e2e0ee0..bd255a03721 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestRetrieverFilterProcessorChain.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestRetrieverFilterProcessorChain.java @@ -72,7 +72,7 @@ public class TestRetrieverFilterProcessorChain { resultReceivers.add(retrievalProcessor); @SuppressWarnings("unchecked") Processor>, Iterable> layeredRetrievalProcessor = new AbstractSimpleRetrievalProcessor>, Iterable>((Class>>)(Class) Iterable.class, (Class>)(Class) Iterable.class, - ConcurrencyTestsUtil.getExecutor(), resultReceivers) { + ConcurrencyTestsUtil.getExecutor(), resultReceivers, 0) { @Override protected Iterable> retrieveData(Iterable> element) { return element; @@ -114,7 +114,7 @@ public class TestRetrieverFilterProcessorChain { Collection> retrievalResultReceivers = new ArrayList<>(); retrievalResultReceivers.add(filtrationProcessor); - retrievalProcessor = new AbstractSimpleRetrievalProcessor, Integer>((Class>)(Class) Iterable.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), retrievalResultReceivers) { + retrievalProcessor = new AbstractSimpleRetrievalProcessor, Integer>((Class>)(Class) Iterable.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), retrievalResultReceivers, 1) { @Override protected Iterable retrieveData(Iterable element) { return element; diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestLegOfCompetitorWithContextRetrievalProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestLegOfCompetitorWithContextRetrievalProcessor.java index 5ca0668e0c0..3f98d00d7d6 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestLegOfCompetitorWithContextRetrievalProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestLegOfCompetitorWithContextRetrievalProcessor.java @@ -15,8 +15,8 @@ import com.sap.sse.datamining.test.functions.registry.test_contexts.Test_HasRace public class TestLegOfCompetitorWithContextRetrievalProcessor extends AbstractSimpleRetrievalProcessor{ - public TestLegOfCompetitorWithContextRetrievalProcessor(ExecutorService executor, Collection> resultReceivers) { - super(Test_HasRaceContext.class, Test_HasLegOfCompetitorContext.class, executor, resultReceivers); + public TestLegOfCompetitorWithContextRetrievalProcessor(ExecutorService executor, Collection> resultReceivers, int retrievalLevel) { + super(Test_HasRaceContext.class, Test_HasLegOfCompetitorContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRaceWithContextRetrievalProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRaceWithContextRetrievalProcessor.java index 227d46c414a..1962e9bf34a 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRaceWithContextRetrievalProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRaceWithContextRetrievalProcessor.java @@ -15,8 +15,8 @@ public class TestRaceWithContextRetrievalProcessor extends AbstractSimpleRetrievalProcessor { public TestRaceWithContextRetrievalProcessor(ExecutorService executor, - Collection> resultReceivers) { - super(Test_Regatta.class, Test_HasRaceContext.class, executor, resultReceivers); + Collection> resultReceivers, int retrievalLevel) { + super(Test_Regatta.class, Test_HasRaceContext.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRegattaRetrievalProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRegattaRetrievalProcessor.java index 363a49010cf..49f4d4e913c 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRegattaRetrievalProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/TestRegattaRetrievalProcessor.java @@ -11,8 +11,8 @@ public class TestRegattaRetrievalProcessor extends AbstractSimpleRetrievalProcessor, Test_Regatta> { @SuppressWarnings("unchecked") - public TestRegattaRetrievalProcessor(ExecutorService executor, Collection> resultReceivers) { - super((Class>)(Class) Collection.class, Test_Regatta.class, executor, resultReceivers); + public TestRegattaRetrievalProcessor(ExecutorService executor, Collection> resultReceivers, int retrievalLevel) { + super((Class>)(Class) Collection.class, Test_Regatta.class, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainBuilder.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainBuilder.java index bf348f3e6d1..1b2ada2339f 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainBuilder.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainBuilder.java @@ -146,24 +146,24 @@ public class SimpleDataRetrieverChainBuilder implements DataRetr FilterCriterion filter = (FilterCriterion) filters.get(retrieverTypeIndex); Class> retrieverType = (Class>)(Class) dataRetrieverTypeWithInformation.getRetrieverType(); - return createRetriever(retrieverType, retrievedDataType, resultReceivers, filter); + return createRetriever(retrieverType, retrievedDataType, resultReceivers, filter, retrieverTypeIndex); } private Processor createRetriever(Class> retrieverType, Class retrievedDataType, - Collection> resultReceivers, FilterCriterion filter) { + Collection> resultReceivers, FilterCriterion filter, int retrieverTypeIndex) { Constructor> retrieverConstructor = null; try { - retrieverConstructor = retrieverType.getConstructor(ExecutorService.class, Collection.class); + retrieverConstructor = retrieverType.getConstructor(ExecutorService.class, Collection.class, int.class); } catch (NoSuchMethodException | SecurityException e) { throw new IllegalArgumentException("Couldn't get an usable constructor from the given retrieverType '" + retrieverType.getSimpleName() + "'", e); } - return constructRetriever(retrieverConstructor, retrievedDataType, resultReceivers, filter); + return constructRetriever(retrieverConstructor, retrievedDataType, resultReceivers, filter, retrieverTypeIndex); } private Processor constructRetriever(Constructor> retrieverConstructor, Class retrievedDataType, - Collection> resultReceivers, FilterCriterion filter) { + Collection> resultReceivers, FilterCriterion filter, int retrieverTypeIndex) { try { Collection> retrievalResultReceivers = resultReceivers; if (filter != null) { @@ -173,7 +173,7 @@ public class SimpleDataRetrieverChainBuilder implements DataRetr retrievalResultReceivers.add(filteringProcessor); } - return retrieverConstructor.newInstance(executor, retrievalResultReceivers); + return retrieverConstructor.newInstance(executor, retrievalResultReceivers, retrieverTypeIndex); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { throw new UnsupportedOperationException("Couldn't create a data retriever instance with the constructor " diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainDefinition.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainDefinition.java index 5d0601d37b6..089f5b5fb91 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainDefinition.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/SimpleDataRetrieverChainDefinition.java @@ -105,7 +105,7 @@ public class SimpleDataRetrieverChainDefinition implem private void checkThatRetrieverHasUsableConstructor( Class> retrieverType) { try { - retrieverType.getConstructor(ExecutorService.class, Collection.class); + retrieverType.getConstructor(ExecutorService.class, Collection.class, int.class); } catch (NoSuchMethodException | SecurityException e) { throw new IllegalArgumentException("Couldn't get an usable constructor from the given nextRetrieverType '" + retrieverType.getSimpleName() + "'", e); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java index dd14636f264..7fddfff4632 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java @@ -47,7 +47,7 @@ public abstract class AbstractParallelMultiDimensionalNestingGroupingProcessor> createInstruction(final DataType element) { - return new ProcessorInstruction>(this) { + return new ProcessorInstruction>(this, ProcessorInstructionPriority.Grouping) { @Override public GroupedDataEntry computeResult() { return new GroupedDataEntry(createCompoundKeyFor(element, diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java index b034e213923..aa26d5d52b9 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java @@ -11,17 +11,29 @@ import com.sap.sse.datamining.components.Processor; public abstract class AbstractRetrievalProcessor extends AbstractPartitioningParallelProcessor { + private final int retrievalLevel; + private final Lock retrievedDataAmountLock; private int retrievedDataAmount; - public AbstractRetrievalProcessor(Class inputType, Class resultType, ExecutorService executor, Collection> resultReceivers) { + /** + * + * @param inputType + * @param resultType + * @param executor + * @param resultReceivers + * @param retrievalLevel The position of this retriever in it's chain. 0 represents the first. + */ + public AbstractRetrievalProcessor(Class inputType, Class resultType, + ExecutorService executor, Collection> resultReceivers, int retrievalLevel) { super(inputType, resultType, executor, resultReceivers); + this.retrievalLevel = retrievalLevel; retrievedDataAmountLock = new ReentrantLock(); } @Override protected ProcessorInstruction createInstruction(final WorkingType partialElement) { - return new ProcessorInstruction(this) { + return new ProcessorInstruction(this, ProcessorInstructionPriority.createRetrievalPriority(retrievalLevel)) { @Override public ResultType computeResult() { incrementRetrievedDataAmount(); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleRetrievalProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleRetrievalProcessor.java index da6dd203ace..1ca2d5b5f4b 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleRetrievalProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleRetrievalProcessor.java @@ -8,8 +8,17 @@ import com.sap.sse.datamining.components.Processor; public abstract class AbstractSimpleRetrievalProcessor extends AbstractRetrievalProcessor { - public AbstractSimpleRetrievalProcessor(Class inputType, Class resultType, ExecutorService executor, Collection> resultReceivers) { - super(inputType, resultType, executor, resultReceivers); + /** + * + * @param inputType + * @param resultType + * @param executor + * @param resultReceivers + * @param retrievalLevel The position of this retriever in it's chain. 0 represents the first. + */ + public AbstractSimpleRetrievalProcessor(Class inputType, Class resultType, + ExecutorService executor, Collection> resultReceivers, int retrievalLevel) { + super(inputType, resultType, executor, resultReceivers, retrievalLevel); } @Override diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java index fe85edfe804..fde5b08cdc9 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java @@ -24,7 +24,7 @@ public class ParallelFilteringProcessor extends AbstractSimpleParalle @Override protected ProcessorInstruction createInstruction(final InputType element) { - return new ProcessorInstruction(this) { + return new ProcessorInstruction(this, ProcessorInstructionPriority.Filtration) { @Override public InputType computeResult() { if (filterCriterion.matches(element)) { diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java index 4be26b7c5e8..1059f7096a3 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java @@ -31,7 +31,7 @@ public class ParallelGroupedElementsValueExtractionProcessor> createInstruction(final GroupedDataEntry element) { - return new ProcessorInstruction>(this) { + return new ProcessorInstruction>(this, ProcessorInstructionPriority.Extraction) { @Override public GroupedDataEntry computeResult() { FunctionReturnType value = extractionFunction.tryToInvoke(element.getDataEntry(), parameterProvider); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java index 4f76014e04f..b03d8083dc8 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java @@ -1,11 +1,49 @@ package com.sap.sse.datamining.impl.components; -public abstract class ProcessorInstruction implements Runnable { +public abstract class ProcessorInstruction implements Runnable, Comparable> { private final AbstractPartitioningParallelProcessor processor; + private final int priority; + /** + * Creates an instruction with a priority of 0, which is the highest priority.
    + * Use only, if no processor in the chain creates instruction with priorities other than 0 or + * if the chain doesn't use priorities at all. + * If this isn't the case use + * {@link #ProcessorInstruction(AbstractPartitioningParallelProcessor, ProcessorInstructionPriority)} + * instead. + * + * @param processor The processor, that processes this instruction + */ public ProcessorInstruction(AbstractPartitioningParallelProcessor processor) { + this(processor, 0); + } + + /** + * Creates an instruction with the given {@linkplain ProcessorInstructionPriority priority}. + * + * @param processor The processor, that processes this instruction + * @param priority The priority of this instruction + */ + public ProcessorInstruction(AbstractPartitioningParallelProcessor processor, + ProcessorInstructionPriority priority) { + this(processor, priority.asIntValue()); + } + + /** + * Creates an instruction with the given priority as int.
    + * Use only, if you need instructions with custom priorities and if you know what you're doing! + * If this isn't the case use + * {@link #ProcessorInstruction(AbstractPartitioningParallelProcessor, ProcessorInstructionPriority)} + * instead. + * + * @param processor The processor, that processes this instruction + * @param priority The priority of this instruction. 0 is the highest priority. + */ + public ProcessorInstruction(AbstractPartitioningParallelProcessor processor, + int priority) { this.processor = processor; + this.priority = priority; } @Override @@ -25,5 +63,10 @@ public abstract class ProcessorInstruction implements Runnable { } protected abstract ResultType computeResult() throws Exception; + + @Override + public int compareTo(ProcessorInstruction instruction) { + return Integer.compare(priority, instruction.priority); + } } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstructionPriority.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstructionPriority.java new file mode 100644 index 00000000000..095813cd2d2 --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstructionPriority.java @@ -0,0 +1,33 @@ +package com.sap.sse.datamining.impl.components; + +public class ProcessorInstructionPriority { + + public static final ProcessorInstructionPriority Aggregation = new ProcessorInstructionPriority(0); + public static final ProcessorInstructionPriority Extraction = new ProcessorInstructionPriority(1); + public static final ProcessorInstructionPriority Filtration = new ProcessorInstructionPriority(1); + public static final ProcessorInstructionPriority Grouping = new ProcessorInstructionPriority(2); + + private static final int retrievalBasePriority = Integer.MAX_VALUE; + + /** + * Creates a priority for the given retrieverLevel, where the level 0 + * represents the first retriever in the chain. + * + * @param retrievalLevel The position of the retriever in its chain + * @return A priority for the given retrieverLevel + */ + public static ProcessorInstructionPriority createRetrievalPriority(int retrievalLevel) { + return new ProcessorInstructionPriority(retrievalBasePriority - retrievalLevel); + } + + private final int intValue; + + private ProcessorInstructionPriority(int intValue) { + this.intValue = intValue; + } + + public int asIntValue() { + return intValue; + } + +} diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java index ff331b7e88d..5d4a75461ed 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java @@ -9,6 +9,7 @@ import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; import com.sap.sse.datamining.impl.components.ProcessorInstruction; +import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; public abstract class AbstractParallelStoringAggregationProcessor extends AbstractSimpleParallelProcessor { @@ -28,7 +29,7 @@ public abstract class AbstractParallelStoringAggregationProcessor createInstruction(final InputType element) { - return new ProcessorInstruction(this) { + return new ProcessorInstruction(this, ProcessorInstructionPriority.Aggregation) { @Override public AggregatedType computeResult() { storeLock.lock(); From dfb1753782fb0e17397bdeb253b2e5ce27f928de Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Sat, 21 Mar 2015 13:21:17 +0100 Subject: [PATCH 08/20] Renamed ProcessorInstruction to AbstractProcessorInstruction --- .../mining/AbstractEnrichingProcessor.java | 6 ++-- .../datamining/impl/TestProcessorQuery.java | 6 ++-- ...estAbstractParallelProcessorFinishing.java | 4 +-- ...elProcessorWithManySimpleInstructions.java | 4 +-- ...ningOfAbstractSimpleParallelProcessor.java | 4 +-- .../BlockingInstructionWrapper.java | 31 ------------------- .../util/components/BlockingProcessor.java | 6 ++-- ...tiDimensionalNestingGroupingProcessor.java | 4 +-- ...AbstractPartitioningParallelProcessor.java | 6 ++-- ...java => AbstractProcessorInstruction.java} | 10 +++--- .../AbstractRetrievalProcessor.java | 4 +-- .../AbstractSimpleParallelProcessor.java | 2 +- .../ParallelFilteringProcessor.java | 4 +-- ...oupedElementsValueExtractionProcessor.java | 4 +-- ...ctParallelStoringAggregationProcessor.java | 6 ++-- 15 files changed, 35 insertions(+), 66 deletions(-) delete mode 100644 java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingInstructionWrapper.java rename java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/{ProcessorInstruction.java => AbstractProcessorInstruction.java} (82%) diff --git a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/AbstractEnrichingProcessor.java b/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/AbstractEnrichingProcessor.java index 9f559fc97fd..07878ce2a14 100644 --- a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/AbstractEnrichingProcessor.java +++ b/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/AbstractEnrichingProcessor.java @@ -6,7 +6,7 @@ import java.util.concurrent.ExecutorService; import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; -import com.sap.sse.datamining.impl.components.ProcessorInstruction; +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; public abstract class AbstractEnrichingProcessor extends AbstractSimpleParallelProcessor { @@ -17,8 +17,8 @@ public abstract class AbstractEnrichingProcessor extends } @Override - protected ProcessorInstruction createInstruction(final InputType element) { - return new ProcessorInstruction(this) { + protected AbstractProcessorInstruction createInstruction(final InputType element) { + return new AbstractProcessorInstruction(this) { @Override public ResultType computeResult() { diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java index 6eef188f92e..39020129b0e 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java @@ -31,7 +31,7 @@ import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor; import com.sap.sse.datamining.impl.components.GroupedDataEntry; import com.sap.sse.datamining.impl.components.ParallelFilteringProcessor; -import com.sap.sse.datamining.impl.components.ProcessorInstruction; +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; import com.sap.sse.datamining.impl.criterias.AbstractFilterCriterion; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.QueryResult; @@ -287,8 +287,8 @@ public class TestProcessorQuery { ConcurrencyTestsUtil.getExecutor(), resultReceivers) { @Override - protected ProcessorInstruction> createInstruction(final Iterable element) { - return new ProcessorInstruction>(this) { + protected AbstractProcessorInstruction> createInstruction(final Iterable element) { + return new AbstractProcessorInstruction>(this) { @Override public Map computeResult() { Map result = new HashMap<>(); diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorFinishing.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorFinishing.java index 1257432ce29..405d9f83e55 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorFinishing.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorFinishing.java @@ -69,8 +69,8 @@ public class TestAbstractParallelProcessorFinishing { private AbstractSimpleParallelProcessor createProcessor(Collection> receivers) { return new AbstractSimpleParallelProcessor(Integer.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), receivers) { @Override - protected ProcessorInstruction createInstruction(Integer partialElement) { - return new ProcessorInstruction(this) { + protected AbstractProcessorInstruction createInstruction(Integer partialElement) { + return new AbstractProcessorInstruction(this) { @Override public Integer computeResult() { while (instructionIsWorking) { diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorWithManySimpleInstructions.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorWithManySimpleInstructions.java index cba5e82ae58..fea514ad2ed 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorWithManySimpleInstructions.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestAbstractParallelProcessorWithManySimpleInstructions.java @@ -38,8 +38,8 @@ public class TestAbstractParallelProcessorWithManySimpleInstructions { receivers.add(receiver); processor = new AbstractSimpleParallelProcessor(Integer.class, Integer.class, ConcurrencyTestsUtil.getExecutor(), receivers) { @Override - protected ProcessorInstruction createInstruction(final Integer element) { - return new ProcessorInstruction(this) { + protected AbstractProcessorInstruction createInstruction(final Integer element) { + return new AbstractProcessorInstruction(this) { @Override public Integer computeResult() { return element; diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestPartitioningOfAbstractSimpleParallelProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestPartitioningOfAbstractSimpleParallelProcessor.java index 6aa0cf9bdb6..858f2d25aa8 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestPartitioningOfAbstractSimpleParallelProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestPartitioningOfAbstractSimpleParallelProcessor.java @@ -27,8 +27,8 @@ public class TestPartitioningOfAbstractSimpleParallelProcessor { } @Override - protected ProcessorInstruction createInstruction(Integer partialElement) { - return new ProcessorInstruction(this) { + protected AbstractProcessorInstruction createInstruction(Integer partialElement) { + return new AbstractProcessorInstruction(this) { @Override public Integer computeResult() { return 0; diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingInstructionWrapper.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingInstructionWrapper.java deleted file mode 100644 index 6e242468fdd..00000000000 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingInstructionWrapper.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.sap.sse.datamining.test.util.components; - -import com.sap.sse.datamining.test.util.ConcurrencyTestsUtil; - -public class BlockingInstructionWrapper implements Runnable { - - private Runnable innerInstruction; - - private boolean workIsInProgress; - - public BlockingInstructionWrapper(Runnable innerInstruction) { - this.innerInstruction = innerInstruction; - workIsInProgress = true; - } - - @Override - public void run() { - while (workIsInProgress) { - ConcurrencyTestsUtil.sleepFor(100); - } - innerInstruction.run(); - } - - /** - * Tells the instruction, that the work is now done. It won't block it's inner instruction anymore and calls the run method of it. - */ - public void workIsNowFinished() { - workIsInProgress = false; - } - -} diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingProcessor.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingProcessor.java index 45a33e1d8bd..cbfbe313606 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingProcessor.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/BlockingProcessor.java @@ -6,7 +6,7 @@ import java.util.concurrent.ExecutorService; import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; -import com.sap.sse.datamining.impl.components.ProcessorInstruction; +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; public abstract class BlockingProcessor extends AbstractSimpleParallelProcessor { private final long timeToBlockInMillis; @@ -19,8 +19,8 @@ public abstract class BlockingProcessor extends AbstractS } @Override - protected ProcessorInstruction createInstruction(InputType element) { - return new ProcessorInstruction(this) { + protected AbstractProcessorInstruction createInstruction(InputType element) { + return new AbstractProcessorInstruction(this) { @Override public ResultType computeResult() throws Exception { Thread.sleep(timeToBlockInMillis); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java index 7fddfff4632..3265d2deb48 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractParallelMultiDimensionalNestingGroupingProcessor.java @@ -46,8 +46,8 @@ public abstract class AbstractParallelMultiDimensionalNestingGroupingProcessor> createInstruction(final DataType element) { - return new ProcessorInstruction>(this, ProcessorInstructionPriority.Grouping) { + protected AbstractProcessorInstruction> createInstruction(final DataType element) { + return new AbstractProcessorInstruction>(this, ProcessorInstructionPriority.Grouping) { @Override public GroupedDataEntry computeResult() { return new GroupedDataEntry(createCompoundKeyFor(element, diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractPartitioningParallelProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractPartitioningParallelProcessor.java index 215f8369dff..0332a450a18 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractPartitioningParallelProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractPartitioningParallelProcessor.java @@ -36,7 +36,7 @@ public abstract class AbstractPartitioningParallelProcessor instruction = createInstruction(partialElement); + final AbstractProcessorInstruction instruction = createInstruction(partialElement); if (isInstructionValid(instruction)) { unfinishedInstructionsCounter.getAndIncrement(); try { @@ -51,7 +51,7 @@ public abstract class AbstractPartitioningParallelProcessor instruction) { + private boolean isInstructionValid(AbstractProcessorInstruction instruction) { return instruction != null; } @@ -76,7 +76,7 @@ public abstract class AbstractPartitioningParallelProcessor createInstruction(final WorkingType partialElement); + protected abstract AbstractProcessorInstruction createInstruction(final WorkingType partialElement); protected abstract Iterable partitionElement(InputType element); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java similarity index 82% rename from java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java rename to java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java index b03d8083dc8..28e7b2b1b6e 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ProcessorInstruction.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java @@ -1,6 +1,6 @@ package com.sap.sse.datamining.impl.components; -public abstract class ProcessorInstruction implements Runnable, Comparable> { +public abstract class AbstractProcessorInstruction implements Runnable, Comparable> { private final AbstractPartitioningParallelProcessor processor; private final int priority; @@ -15,7 +15,7 @@ public abstract class ProcessorInstruction implements Runnable, Comp * * @param processor The processor, that processes this instruction */ - public ProcessorInstruction(AbstractPartitioningParallelProcessor processor) { + public AbstractProcessorInstruction(AbstractPartitioningParallelProcessor processor) { this(processor, 0); } @@ -25,7 +25,7 @@ public abstract class ProcessorInstruction implements Runnable, Comp * @param processor The processor, that processes this instruction * @param priority The priority of this instruction */ - public ProcessorInstruction(AbstractPartitioningParallelProcessor processor, + public AbstractProcessorInstruction(AbstractPartitioningParallelProcessor processor, ProcessorInstructionPriority priority) { this(processor, priority.asIntValue()); } @@ -40,7 +40,7 @@ public abstract class ProcessorInstruction implements Runnable, Comp * @param processor The processor, that processes this instruction * @param priority The priority of this instruction. 0 is the highest priority. */ - public ProcessorInstruction(AbstractPartitioningParallelProcessor processor, + public AbstractProcessorInstruction(AbstractPartitioningParallelProcessor processor, int priority) { this.processor = processor; this.priority = priority; @@ -65,7 +65,7 @@ public abstract class ProcessorInstruction implements Runnable, Comp protected abstract ResultType computeResult() throws Exception; @Override - public int compareTo(ProcessorInstruction instruction) { + public int compareTo(AbstractProcessorInstruction instruction) { return Integer.compare(priority, instruction.priority); } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java index aa26d5d52b9..f4a37f3980f 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractRetrievalProcessor.java @@ -32,8 +32,8 @@ public abstract class AbstractRetrievalProcessor createInstruction(final WorkingType partialElement) { - return new ProcessorInstruction(this, ProcessorInstructionPriority.createRetrievalPriority(retrievalLevel)) { + protected AbstractProcessorInstruction createInstruction(final WorkingType partialElement) { + return new AbstractProcessorInstruction(this, ProcessorInstructionPriority.createRetrievalPriority(retrievalLevel)) { @Override public ResultType computeResult() { incrementRetrievedDataAmount(); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleParallelProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleParallelProcessor.java index ad896208d46..5f71e9320c4 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleParallelProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractSimpleParallelProcessor.java @@ -21,6 +21,6 @@ public abstract class AbstractSimpleParallelProcessor //Redefinition of the method to set the parameter name to element instead of partial element. //This makes the implementation of sub classes more fluent. @Override - protected abstract ProcessorInstruction createInstruction(InputType element); + protected abstract AbstractProcessorInstruction createInstruction(InputType element); } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java index fde5b08cdc9..eda6d7b992e 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelFilteringProcessor.java @@ -23,8 +23,8 @@ public class ParallelFilteringProcessor extends AbstractSimpleParalle } @Override - protected ProcessorInstruction createInstruction(final InputType element) { - return new ProcessorInstruction(this, ProcessorInstructionPriority.Filtration) { + protected AbstractProcessorInstruction createInstruction(final InputType element) { + return new AbstractProcessorInstruction(this, ProcessorInstructionPriority.Filtration) { @Override public InputType computeResult() { if (filterCriterion.matches(element)) { diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java index 1059f7096a3..a9b911ea7e1 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/ParallelGroupedElementsValueExtractionProcessor.java @@ -30,8 +30,8 @@ public class ParallelGroupedElementsValueExtractionProcessor> createInstruction(final GroupedDataEntry element) { - return new ProcessorInstruction>(this, ProcessorInstructionPriority.Extraction) { + protected AbstractProcessorInstruction> createInstruction(final GroupedDataEntry element) { + return new AbstractProcessorInstruction>(this, ProcessorInstructionPriority.Extraction) { @Override public GroupedDataEntry computeResult() { FunctionReturnType value = extractionFunction.tryToInvoke(element.getDataEntry(), parameterProvider); diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java index 5d4a75461ed..98830b2a119 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/aggregators/AbstractParallelStoringAggregationProcessor.java @@ -8,7 +8,7 @@ import java.util.concurrent.locks.ReentrantLock; import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; -import com.sap.sse.datamining.impl.components.ProcessorInstruction; +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; public abstract class AbstractParallelStoringAggregationProcessor @@ -28,8 +28,8 @@ public abstract class AbstractParallelStoringAggregationProcessor createInstruction(final InputType element) { - return new ProcessorInstruction(this, ProcessorInstructionPriority.Aggregation) { + protected AbstractProcessorInstruction createInstruction(final InputType element) { + return new AbstractProcessorInstruction(this, ProcessorInstructionPriority.Aggregation) { @Override public AggregatedType computeResult() { storeLock.lock(); From 4d22ac15b98c416f97f38aa8e791044513f22b4c Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Sat, 21 Mar 2015 13:32:01 +0100 Subject: [PATCH 09/20] Added a test for the processor instruction order in a PriorityQueue --- .../TestProcessorInstructionOrdering.java | 34 +++++++++++++++++++ .../components/NullProcessorInstruction.java | 23 +++++++++++++ .../AbstractProcessorInstruction.java | 4 +++ 3 files changed, 61 insertions(+) create mode 100644 java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestProcessorInstructionOrdering.java create mode 100644 java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/NullProcessorInstruction.java diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestProcessorInstructionOrdering.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestProcessorInstructionOrdering.java new file mode 100644 index 00000000000..1c82a50f93c --- /dev/null +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/components/TestProcessorInstructionOrdering.java @@ -0,0 +1,34 @@ +package com.sap.sse.datamining.impl.components; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.util.PriorityQueue; +import java.util.Queue; + +import org.junit.Test; + +import com.sap.sse.datamining.test.util.components.NullProcessorInstruction; + +public class TestProcessorInstructionOrdering { + + @Test + public void testOrderInPriorityQueue() { + Queue> priorityQueue = new PriorityQueue<>(); + + priorityQueue.add(new NullProcessorInstruction<>(null, ProcessorInstructionPriority.createRetrievalPriority(0))); + priorityQueue.add(new NullProcessorInstruction<>(null, ProcessorInstructionPriority.createRetrievalPriority(1))); + priorityQueue.add(new NullProcessorInstruction<>(null, ProcessorInstructionPriority.Grouping)); + priorityQueue.add(new NullProcessorInstruction<>(null, ProcessorInstructionPriority.Extraction)); + priorityQueue.add(new NullProcessorInstruction<>(null, ProcessorInstructionPriority.Filtration)); + priorityQueue.add(new NullProcessorInstruction<>(null, ProcessorInstructionPriority.Aggregation)); + + assertThat(priorityQueue.poll().getPriority(), is(0)); + assertThat(priorityQueue.poll().getPriority(), is(1)); + assertThat(priorityQueue.poll().getPriority(), is(1)); + assertThat(priorityQueue.poll().getPriority(), is(2)); + assertThat(priorityQueue.poll().getPriority(), is(Integer.MAX_VALUE - 1)); + assertThat(priorityQueue.poll().getPriority(), is(Integer.MAX_VALUE)); + } + +} diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/NullProcessorInstruction.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/NullProcessorInstruction.java new file mode 100644 index 00000000000..886ed20a877 --- /dev/null +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/components/NullProcessorInstruction.java @@ -0,0 +1,23 @@ +package com.sap.sse.datamining.test.util.components; + +import com.sap.sse.datamining.impl.components.AbstractPartitioningParallelProcessor; +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; +import com.sap.sse.datamining.impl.components.ProcessorInstructionPriority; + +public class NullProcessorInstruction extends AbstractProcessorInstruction { + + public NullProcessorInstruction(AbstractPartitioningParallelProcessor processor, + ProcessorInstructionPriority priority) { + super(processor, priority); + } + + @Override + protected ResultType computeResult() throws Exception { + return null; + } + + public int getPriority() { + return super.getPriority(); + } + +} diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java index 28e7b2b1b6e..619899b0ccb 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/components/AbstractProcessorInstruction.java @@ -64,6 +64,10 @@ public abstract class AbstractProcessorInstruction implements Runnab protected abstract ResultType computeResult() throws Exception; + protected int getPriority() { + return priority; + } + @Override public int compareTo(AbstractProcessorInstruction instruction) { return Integer.compare(priority, instruction.priority); From ca0f192621a0c8a6f4778b99ff352c88e69bdf4d Mon Sep 17 00:00:00 2001 From: fmittag Date: Sun, 22 Mar 2015 14:23:59 +0200 Subject: [PATCH 10/20] improved and unified the way the live state for a race or a raceColumn is calculated --- .../domain/common/dto/RaceColumnDTO.java | 52 +++++---------- .../sailing/domain/common/dto/RaceDTO.java | 63 +++++++++++++++++++ .../place/event/regatta/RegattaPhaseRace.java | 25 +++++--- .../event/regatta/RegattaPhaseRace.ui.xml | 2 +- .../regattaraces/EventRegattaRacesRace.java | 27 +------- 5 files changed, 97 insertions(+), 72 deletions(-) diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceColumnDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceColumnDTO.java index 094e7e07891..8adda83ea37 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceColumnDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceColumnDTO.java @@ -12,7 +12,6 @@ import java.util.Set; import com.sap.sailing.domain.common.LeaderboardNameConstants; import com.sap.sailing.domain.common.RaceIdentifier; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.TimingConstants; import com.sap.sse.common.Util; public class RaceColumnDTO extends NamedDTO implements Serializable { @@ -25,13 +24,25 @@ public class RaceColumnDTO extends NamedDTO implements Serializable { private double effectiveFactor; private Map raceLogTrackingInfos; + public enum RaceColumnLiveState { NOT_TRACKED, TRACKED, TRACKED_AND_LIVE }; + public RaceColumnDTO() { trackedRaceIdentifiersPerFleet = new HashMap(); raceLogTrackingInfos = new HashMap(); racesPerFleet = new HashMap(); fleets = new ArrayList(); } - + + public RaceColumnLiveState getLiveState(long serverTimePointAsMillis) { + RaceColumnLiveState result = RaceColumnLiveState.NOT_TRACKED; + if (hasLiveRaces(serverTimePointAsMillis) && hasGPSData() && hasWindData()) { + result = RaceColumnLiveState.TRACKED_AND_LIVE; + } else if (hasTrackedRaces()) { + result = RaceColumnLiveState.TRACKED; + } + return result; + } + public String getRaceColumnName() { return getName(); } @@ -144,42 +155,11 @@ public class RaceColumnDTO extends NamedDTO implements Serializable { * point of the "live" interval as defined above. */ public boolean isLive(FleetDTO fleet, long serverTimePointAsMillis) { - final Date startOfLivePeriod; - final Date endOfLivePeriod; + boolean result = false; final RaceDTO raceDTO = racesPerFleet.get(fleet); - if (raceDTO == null || raceDTO.trackedRace == null || !raceDTO.trackedRace.hasGPSData || !raceDTO.trackedRace.hasWindData) { - startOfLivePeriod = null; - endOfLivePeriod = null; - } else { - if (raceDTO.startOfRace == null) { - startOfLivePeriod = raceDTO.trackedRace.startOfTracking; - } else { - startOfLivePeriod = new Date(raceDTO.startOfRace.getTime() - TimingConstants.PRE_START_PHASE_DURATION_IN_MILLIS); - } - if (raceDTO.endOfRace == null) { - if (raceDTO.trackedRace.timePointOfNewestEvent != null) { - endOfLivePeriod = new Date(raceDTO.trackedRace.timePointOfNewestEvent.getTime() - + TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS); - } else { - endOfLivePeriod = null; - } - } else { - endOfLivePeriod = new Date(raceDTO.endOfRace.getTime() + TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS); - } + if(raceDTO != null) { + result = raceDTO.isLive(serverTimePointAsMillis); } - - // if an empty timepoint is given then take the start of the race - if (serverTimePointAsMillis == 0) { - serverTimePointAsMillis = startOfLivePeriod.getTime()+1; - } - - // whenLastTrackedRaceWasLive is null if there is no tracked race for fleet, or the tracked race hasn't started yet at the server time - // when this DTO was assembled, or there were no GPS or wind data - final boolean result = - startOfLivePeriod != null && - endOfLivePeriod != null && - startOfLivePeriod.getTime() <= serverTimePointAsMillis && - serverTimePointAsMillis <= endOfLivePeriod.getTime(); return result; } diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceDTO.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceDTO.java index 42798eb83c0..eba9caf39b7 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceDTO.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/dto/RaceDTO.java @@ -4,6 +4,7 @@ import java.util.Date; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; import com.sap.sailing.domain.common.RegattaNameAndRaceName; +import com.sap.sailing.domain.common.TimingConstants; /** * Master data about a single race that is to be transferred to the client.

    @@ -14,6 +15,8 @@ import com.sap.sailing.domain.common.RegattaNameAndRaceName; public class RaceDTO extends NamedDTO { private static final long serialVersionUID = 2613189982608149975L; + public enum RaceLiveState { NOT_TRACKED, TRACKED, TRACKED_AND_LIVE, TRACKED_BUT_NOT_SCHEDULED }; + /** * Tells if this race is currently being tracked, meaning that a {@link RaceTracker} is * listening for incoming GPS fixes, mark passings etc., to update a {@link TrackedRace} object @@ -46,6 +49,20 @@ public class RaceDTO extends NamedDTO { this.isTracked = isCurrentlyTracked; } + public RaceLiveState getLiveState(long serverTimePointAsMillis) { + RaceLiveState result = RaceLiveState.NOT_TRACKED; + if(trackedRace != null && trackedRace.hasGPSData && trackedRace.hasWindData) { + result = RaceLiveState.TRACKED; + if(isLive(serverTimePointAsMillis)) { + result = RaceLiveState.TRACKED_AND_LIVE; + if(startOfRace == null) { + result = RaceLiveState.TRACKED_BUT_NOT_SCHEDULED; + } + } + } + return result; + } + public RegattaAndRaceIdentifier getRaceIdentifier() { return new RegattaNameAndRaceName(regattaName, getName()); } @@ -54,6 +71,52 @@ public class RaceDTO extends NamedDTO { return regattaName; } + /** + * @see {@link TrackedRace#isLive} for further explanation. + * @param serverTimePointAsMillis + * the time point (in server clock time) at which to determine whether the race is/was live + * @return true if serverTimePointAsMillis is between (inclusively) the start and end time + * point of the "live" interval as defined above. + */ + public boolean isLive(long serverTimePointAsMillis) { + final Date startOfLivePeriod; + final Date endOfLivePeriod; + if (trackedRace == null || !trackedRace.hasGPSData || !trackedRace.hasWindData) { + startOfLivePeriod = null; + endOfLivePeriod = null; + } else { + if (startOfRace == null) { + startOfLivePeriod = trackedRace.startOfTracking; + } else { + startOfLivePeriod = new Date(startOfRace.getTime() - TimingConstants.PRE_START_PHASE_DURATION_IN_MILLIS); + } + if (endOfRace == null) { + if (trackedRace.timePointOfNewestEvent != null) { + endOfLivePeriod = new Date(trackedRace.timePointOfNewestEvent.getTime() + + TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS); + } else { + endOfLivePeriod = null; + } + } else { + endOfLivePeriod = new Date(endOfRace.getTime() + TimingConstants.IS_LIVE_GRACE_PERIOD_IN_MILLIS); + } + } + + // if an empty timepoint is given then take the start of the race + if (serverTimePointAsMillis == 0) { + serverTimePointAsMillis = startOfLivePeriod.getTime()+1; + } + + // whenLastTrackedRaceWasLive is null if there is no tracked race for fleet, or the tracked race hasn't started yet at the server time + // when this DTO was assembled, or there were no GPS or wind data + final boolean result = + startOfLivePeriod != null && + endOfLivePeriod != null && + startOfLivePeriod.getTime() <= serverTimePointAsMillis && + serverTimePointAsMillis <= endOfLivePeriod.getTime(); + return result; + } + @Override public int hashCode() { final int prime = 31; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.java index c0ba7b96fdc..7af7ec300a8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.java @@ -6,6 +6,7 @@ import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.UIObject; import com.sap.sailing.domain.common.dto.RaceColumnDTO; +import com.sap.sailing.domain.common.dto.RaceColumnDTO.RaceColumnLiveState; import com.sap.sse.gwt.client.player.Timer; public class RegattaPhaseRace extends UIObject { @@ -14,7 +15,7 @@ public class RegattaPhaseRace extends UIObject { interface RegattaPhaseRaceUiBinder extends UiBinder { } - @UiField DivElement raceStatus; + @UiField DivElement raceColumnStatus; private enum DataStatusEnum { FINISHED ("finished"), LIVE("live"), SCHEDULED("scheduled"); @@ -31,14 +32,20 @@ public class RegattaPhaseRace extends UIObject { RegattaResources.INSTANCE.css().ensureInjected(); setElement(uiBinder.createAndBindUi(this)); - DataStatusEnum dataStatus; - if(raceColumn.hasLiveRaces(timerForClientServerOffset.getLiveTimePointInMillis())) { - dataStatus = DataStatusEnum.LIVE; - } else if (raceColumn.hasTrackedRaces()) { - dataStatus = DataStatusEnum.FINISHED; - } else { - dataStatus = DataStatusEnum.SCHEDULED; + DataStatusEnum dataStatus = DataStatusEnum.SCHEDULED; + RaceColumnLiveState liveState = raceColumn.getLiveState(timerForClientServerOffset.getLiveTimePointInMillis()); + + switch(liveState) { + case NOT_TRACKED: + dataStatus = DataStatusEnum.SCHEDULED; + break; + case TRACKED: + dataStatus = DataStatusEnum.FINISHED; + break; + case TRACKED_AND_LIVE: + dataStatus = DataStatusEnum.LIVE; + break; } - raceStatus.setAttribute(DataStatusEnum.ATTRIBUTE_NAME, dataStatus.attributeValue); + raceColumnStatus.setAttribute(DataStatusEnum.ATTRIBUTE_NAME, dataStatus.attributeValue); } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.ui.xml b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.ui.xml index 6fce59d923c..4149f5300dd 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.ui.xml +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regatta/RegattaPhaseRace.ui.xml @@ -5,5 +5,5 @@ -

    +
    diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java index d29a4f4747c..63998b49fb5 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java @@ -23,8 +23,6 @@ import com.sap.sse.gwt.client.player.Timer; public class EventRegattaRacesRace extends Composite { private static EventRegattaRacesRaceUiBinder uiBinder = GWT.create(EventRegattaRacesRaceUiBinder.class); - private enum SimpleRaceStates { NOT_TRACKED, TRACKED, TRACKED_AND_LIVE, TRACKED_BUT_NOT_SCHEDULED }; - interface EventRegattaRacesRaceUiBinder extends UiBinder { } @@ -62,16 +60,12 @@ public class EventRegattaRacesRace extends Composite { private final DateTimeFormat raceTimeFormat = DateTimeFormat.getFormat("EEE, h:mm a"); - private final FleetDTO fleet; - private final RaceColumnDTO raceColumn; private final RaceDTO race; private final Timer timerForClientServerOffset; private Element[] allConditionalElements; public EventRegattaRacesRace(StrippedLeaderboardDTO leaderboard, FleetDTO fleet, RaceColumnDTO raceColumn, Timer timerForClientServerOffset, EventPlaceNavigator pageNavigator) { - this.fleet = fleet; - this.raceColumn = raceColumn; this.timerForClientServerOffset = timerForClientServerOffset; race = raceColumn.getRace(fleet); @@ -97,25 +91,6 @@ public class EventRegattaRacesRace extends Composite { updateUI(); } - private SimpleRaceStates getSimpleRaceState() { - SimpleRaceStates simpleRaceState = SimpleRaceStates.NOT_TRACKED; - - if(race != null && race.trackedRace != null && race.trackedRace.hasGPSData && race.trackedRace.hasWindData) { - simpleRaceState = SimpleRaceStates.TRACKED; - if(isLive()) { - simpleRaceState = SimpleRaceStates.TRACKED_AND_LIVE; - if(race.startOfRace == null) { - simpleRaceState = SimpleRaceStates.TRACKED_BUT_NOT_SCHEDULED; - } - } - } - return simpleRaceState; - } - - private boolean isLive() { - return raceColumn.isLive(fleet, timerForClientServerOffset.getLiveTimePointInMillis()); - } - private void updateUI() { averageRaceWind.setInnerText("tbd."); @@ -123,7 +98,7 @@ public class EventRegattaRacesRace extends Composite { hideElement(el); } - switch(getSimpleRaceState()) { + switch(race.getLiveState(timerForClientServerOffset.getLiveTimePointInMillis())) { case NOT_TRACKED: showElement(raceNotTrackedDiv); break; From 02eb1f3cf1427b20f7c5eb30f68d0dd87898556d Mon Sep 17 00:00:00 2001 From: fmittag Date: Sun, 22 Mar 2015 18:14:15 +0200 Subject: [PATCH 11/20] fixed a UI problem with race which can be null --- .../place/event/regattaraces/EventRegattaRacesRace.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java index 63998b49fb5..c468b802713 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/client/place/event/regattaraces/EventRegattaRacesRace.java @@ -16,6 +16,7 @@ import com.sap.sailing.domain.common.dto.CompetitorDTO; import com.sap.sailing.domain.common.dto.FleetDTO; import com.sap.sailing.domain.common.dto.RaceColumnDTO; import com.sap.sailing.domain.common.dto.RaceDTO; +import com.sap.sailing.domain.common.dto.RaceDTO.RaceLiveState; import com.sap.sailing.gwt.home.client.place.event.EventPlaceNavigator; import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO; import com.sap.sse.gwt.client.player.Timer; @@ -98,7 +99,8 @@ public class EventRegattaRacesRace extends Composite { hideElement(el); } - switch(race.getLiveState(timerForClientServerOffset.getLiveTimePointInMillis())) { + RaceLiveState liveState = race != null ? race.getLiveState(timerForClientServerOffset.getLiveTimePointInMillis()) : RaceLiveState.NOT_TRACKED; + switch(liveState) { case NOT_TRACKED: showElement(raceNotTrackedDiv); break; From 11fe706981259a8de91ce5c414e307b7e586e495 Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Sun, 22 Mar 2015 20:20:03 +0100 Subject: [PATCH 12/20] Implemented DataMiningExecutorService, that uses a BlockingPriorityQueue --- .../datamining/test/util/ConcurrencyTestsUtil.java | 9 ++++----- .../sse/datamining/impl/TestProcessorQuery.java | 6 +++--- .../datamining/test/util/ConcurrencyTestsUtil.java | 11 +++++------ .../datamining/impl/DataMiningExecutorService.java | 13 +++++++++++++ .../impl/DataMiningFrameworkActivator.java | 14 ++------------ 5 files changed, 27 insertions(+), 26 deletions(-) create mode 100644 java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningExecutorService.java diff --git a/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/test/util/ConcurrencyTestsUtil.java b/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/test/util/ConcurrencyTestsUtil.java index 68f60053c4a..51d4f7562cd 100644 --- a/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/test/util/ConcurrencyTestsUtil.java +++ b/java/com.sap.sailing.datamining.test/src/com/sap/sailing/datamining/test/util/ConcurrencyTestsUtil.java @@ -2,18 +2,17 @@ package com.sap.sailing.datamining.test.util; import static org.junit.Assert.fail; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.ExecutorService; import com.sap.sse.datamining.components.Processor; +import com.sap.sse.datamining.impl.DataMiningExecutorService; public class ConcurrencyTestsUtil { private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3); - private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS, new LinkedBlockingQueue()); + private static final ExecutorService executor = new DataMiningExecutorService(THREAD_POOL_SIZE); - public static ThreadPoolExecutor getExecutor() { + public static ExecutorService getExecutor() { return executor; } diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java index 39020129b0e..899d1ca1af8 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -27,11 +27,11 @@ import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.factories.ProcessorFactory; import com.sap.sse.datamining.functions.Function; import com.sap.sse.datamining.functions.ParameterProvider; +import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; import com.sap.sse.datamining.impl.components.AbstractSimpleParallelProcessor; import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor; import com.sap.sse.datamining.impl.components.GroupedDataEntry; import com.sap.sse.datamining.impl.components.ParallelFilteringProcessor; -import com.sap.sse.datamining.impl.components.AbstractProcessorInstruction; import com.sap.sse.datamining.impl.criterias.AbstractFilterCriterion; import com.sap.sse.datamining.shared.GroupKey; import com.sap.sse.datamining.shared.QueryResult; @@ -107,7 +107,7 @@ public class TestProcessorQuery { * their length, extracts the cross sum and aggregates these as sum. */ private Query createQueryWithStandardWorkflow(Collection dataSource) { - final ThreadPoolExecutor executor = ConcurrencyTestsUtil.getExecutor(); + final ExecutorService executor = ConcurrencyTestsUtil.getExecutor(); ProcessorQuery> query = new ProcessorQuery>(dataSource, stringMessages, Locale.ENGLISH, AdditionalQueryData.NULL_INSTANCE) { @Override protected Processor, ?> createFirstProcessor() { diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/ConcurrencyTestsUtil.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/ConcurrencyTestsUtil.java index 0a41904484b..df2cd35d5ae 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/ConcurrencyTestsUtil.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/test/util/ConcurrencyTestsUtil.java @@ -8,19 +8,18 @@ import static org.junit.Assert.fail; import java.util.Collection; import java.util.Map; import java.util.Map.Entry; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.ExecutorService; import com.sap.sse.datamining.components.Processor; +import com.sap.sse.datamining.impl.DataMiningExecutorService; import com.sap.sse.datamining.shared.GroupKey; public class ConcurrencyTestsUtil extends TestsUtil { - + private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3); - private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS, new LinkedBlockingQueue()); + private static final ExecutorService executor = new DataMiningExecutorService(THREAD_POOL_SIZE); - public static ThreadPoolExecutor getExecutor() { + public static ExecutorService getExecutor() { return executor; } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningExecutorService.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningExecutorService.java new file mode 100644 index 00000000000..860009ee402 --- /dev/null +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningExecutorService.java @@ -0,0 +1,13 @@ +package com.sap.sse.datamining.impl; + +import java.util.concurrent.PriorityBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class DataMiningExecutorService extends ThreadPoolExecutor { + + public DataMiningExecutorService(int corePoolSize) { + super(corePoolSize, corePoolSize, 60, TimeUnit.SECONDS, new PriorityBlockingQueue()); + } + +} diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java index 09ff46514bf..0b618db412a 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/DataMiningFrameworkActivator.java @@ -3,10 +3,6 @@ package com.sap.sse.datamining.impl; import java.util.Collection; import java.util.HashSet; import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.osgi.framework.BundleActivator; @@ -27,8 +23,8 @@ import com.sap.sse.i18n.impl.ResourceBundleStringMessagesImpl; public class DataMiningFrameworkActivator implements BundleActivator { private static final Logger logger = Logger.getLogger(DataMiningFrameworkActivator.class.getName()); - private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3); private static final String STRING_MESSAGES_BASE_NAME = "stringmessages/StringMessages"; + private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3); private static DataMiningFrameworkActivator INSTANCE; @@ -38,13 +34,7 @@ public class DataMiningFrameworkActivator implements BundleActivator { private final ModifiableDataMiningServer dataMiningServer; public DataMiningFrameworkActivator() { - ExecutorService executor = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS, - new LinkedBlockingQueue(), new RejectedExecutionHandler() { - @Override - public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { - r.run(); - } - }); + ExecutorService executor = new DataMiningExecutorService(THREAD_POOL_SIZE); FunctionManager functionManager = new FunctionManager(); DataRetrieverChainDefinitionRegistry dataRetrieverChainDefinitionRegistry = new SimpleDataRetrieverChainDefinitionRegistry(); From bc6edb22f18c1db94a5ba561b826d6e6304de06b Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Sun, 22 Mar 2015 21:07:17 +0100 Subject: [PATCH 13/20] Improved the data mining test coverage --- .../datamining/impl/TestProcessorQuery.java | 78 ++++++++++++++++++- .../sse/datamining/impl/ProcessorQuery.java | 2 +- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java index 899d1ca1af8..7aa33fedf14 100644 --- a/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java +++ b/java/com.sap.sse.datamining.test/src/com/sap/sse/datamining/impl/TestProcessorQuery.java @@ -13,6 +13,7 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -22,6 +23,7 @@ import com.sap.sse.common.Util.Pair; import com.sap.sse.datamining.AdditionalQueryData; import com.sap.sse.datamining.AdditionalResultDataBuilder; import com.sap.sse.datamining.Query; +import com.sap.sse.datamining.QueryState; import com.sap.sse.datamining.components.FilterCriterion; import com.sap.sse.datamining.components.Processor; import com.sap.sse.datamining.factories.ProcessorFactory; @@ -64,6 +66,7 @@ public class TestProcessorQuery { public void testStandardWorkflow() throws InterruptedException, ExecutionException { Collection dataSource = createDataSource(); Query queryWithStandardWorkflow = createQueryWithStandardWorkflow(dataSource); + assertThat(queryWithStandardWorkflow.getState(), is(QueryState.NOT_STARTED)); QueryResult expectedResult = buildExpectedResult(dataSource); verifyResult(queryWithStandardWorkflow.run(), expectedResult); } @@ -198,6 +201,7 @@ public class TestProcessorQuery { } catch (TimeoutException e) { // A timeout exception is expected } + assertThat(query.getState(), is(QueryState.TIMED_OUT)); ConcurrencyTestsUtil.sleepFor(1000); // Wait if a result is received assertThat("The processing should be aborted, but received elements", receivedElementOrFinished, is(false)); @@ -235,7 +239,9 @@ public class TestProcessorQuery { } }); queryRunner.start(); - ConcurrencyTestsUtil.sleepFor(500); + ConcurrencyTestsUtil.sleepFor(250); + assertThat(query.getState(), is(QueryState.RUNNING)); + ConcurrencyTestsUtil.sleepFor(250); query.abort(); ConcurrencyTestsUtil.sleepFor(1000); // Wait if a result is received @@ -313,5 +319,75 @@ public class TestProcessorQuery { expectedResult.put(new GenericGroupKey(keyValue), 10358.0); assertThat(query.run(500, TimeUnit.MILLISECONDS).getResults(), is(expectedResult)); } + + @Test + public void testQueryWithSevereFailure() { + Query query = new ProcessorQuery(0.0) { + @SuppressWarnings("unchecked") + @Override + protected Processor createFirstProcessor() { + Collection, ?>> resultReceivers = new ArrayList<>(); + resultReceivers.add(this.getResultReceiver()); + return new AbstractSimpleParallelProcessor>(Double.class, + (Class>)(Class) Map.class, + ConcurrencyTestsUtil.getExecutor(), + resultReceivers) { + @Override + protected AbstractProcessorInstruction> createInstruction(Double element) { + return new AbstractProcessorInstruction>(this) { + @Override + protected Map computeResult() throws Exception { + throw new RejectedExecutionException("This should cause an error during the query processing"); + } + }; + } + @Override + protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) { + } + }; + } + }; + try { + query.run(); + fail("The previous line should throw a runtime exception"); + } catch (RuntimeException e) { + // A RuntimeException wiht a RejectedExecitonException is expected + if (!(e.getCause() instanceof RejectedExecutionException)) { + throw e; + } + } + assertThat(query.getState(), is(QueryState.ERROR)); + } + + @Test + public void testQueryWithFailure() { + Query query = new ProcessorQuery(0.0) { + @SuppressWarnings("unchecked") + @Override + protected Processor createFirstProcessor() { + Collection, ?>> resultReceivers = new ArrayList<>(); + resultReceivers.add(this.getResultReceiver()); + return new AbstractSimpleParallelProcessor>(Double.class, + (Class>)(Class) Map.class, + ConcurrencyTestsUtil.getExecutor(), + resultReceivers) { + @Override + protected AbstractProcessorInstruction> createInstruction(Double element) { + return new AbstractProcessorInstruction>(this) { + @Override + protected Map computeResult() throws Exception { + throw new NullPointerException("This should cause a failure during the query processing"); + } + }; + } + @Override + protected void setAdditionalData(AdditionalResultDataBuilder additionalDataBuilder) { + } + }; + } + }; + query.run(); + assertThat(query.getState(), is(QueryState.FAILURE)); + } } diff --git a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java index 7fd709fcaa4..5cc5ee649a2 100644 --- a/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java +++ b/java/com.sap.sse.datamining/src/com/sap/sse/datamining/impl/ProcessorQuery.java @@ -253,7 +253,7 @@ public abstract class ProcessorQuery implements @Override public void finish() throws InterruptedException { synchronized (monitorObject) { - state = QueryState.NORMAL; + state = state == QueryState.RUNNING ? QueryState.NORMAL : state; monitorObject.notify(); } } From 2d52d85efb585530c2a481c094f279fb3ff24851 Mon Sep 17 00:00:00 2001 From: Lennart Hensler Date: Sun, 22 Mar 2015 22:38:15 +0100 Subject: [PATCH 14/20] Fixed the result chart resizing --- .../gwt/ui/datamining/DataMiningEntryPoint.java | 8 ++++---- .../ui/datamining/presentation/ResultsChart.java | 15 +++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java index d92f91de3c2..94f78638ae6 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/DataMiningEntryPoint.java @@ -49,11 +49,11 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { SplitLayoutPanel splitPanel = new SplitLayoutPanel(); rootPanel.add(splitPanel); - DockLayoutPanel dockPanel = new DockLayoutPanel(Unit.PX); - dockPanel.addNorth(createLogoAndTitlePanel(), 68); + DockLayoutPanel selectionDockPanel = new DockLayoutPanel(Unit.PX); + selectionDockPanel.addNorth(createLogoAndTitlePanel(), 68); BufferingQueryDefinitionProviderWithControls queryDefinitionProviderWithControls = new BufferingQueryDefinitionProviderWithControls(session, getStringMessages(), sailingService, dataMiningService, this); queryDefinitionProviderWithControls.getEntryWidget().addStyleName("dataMiningPanel"); - dockPanel.add(queryDefinitionProviderWithControls.getEntryWidget()); + selectionDockPanel.add(queryDefinitionProviderWithControls.getEntryWidget()); ResultsPresenter resultsPresenter = new ResultsChart(getStringMessages()); if (GwtHttpRequestUtils.getBooleanParameter("benchmark", false)) { @@ -63,7 +63,7 @@ public class DataMiningEntryPoint extends AbstractSailingEntryPoint { splitPanel.addSouth(resultsPresenter.getWidget(), 400); } - splitPanel.add(dockPanel); + splitPanel.add(selectionDockPanel); QueryRunner queryRunner = new SimpleQueryRunner(session, getStringMessages(), dataMiningService, this, queryDefinitionProviderWithControls, resultsPresenter); queryDefinitionProviderWithControls.addControl(queryRunner.getEntryWidget()); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/ResultsChart.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/ResultsChart.java index e3183ddc598..083dc279d53 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/ResultsChart.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/datamining/presentation/ResultsChart.java @@ -22,17 +22,17 @@ import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsData; import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter; import org.moxieapps.gwt.highcharts.client.labels.YAxisLabels; +import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.text.shared.AbstractRenderer; -import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ValueListBox; import com.google.gwt.user.client.ui.Widget; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.shared.panels.ResizingFlowPanel; import com.sap.sailing.gwt.ui.client.shared.panels.ResizingSimplePanel; import com.sap.sailing.gwt.ui.datamining.ResultsPresenter; import com.sap.sse.datamining.shared.GroupKey; @@ -76,7 +76,7 @@ public class ResultsChart implements ResultsPresenter { }; private final StringMessages stringMessages; - private final FlowPanel mainPanel; + private final DockLayoutPanel mainPanel; private final HorizontalPanel sortByPanel; private final ValueListBox> keyComparatorListBox; @@ -95,17 +95,12 @@ public class ResultsChart implements ResultsPresenter { super(); this.stringMessages = stringMessages; - mainPanel = new ResizingFlowPanel() { - @Override - public void onResize() { - presentationPanel.onResize(); - } - }; + mainPanel = new DockLayoutPanel(Unit.PX); sortByPanel = new HorizontalPanel(); sortByPanel.setSpacing(5); sortByPanel.setVisible(false); - mainPanel.add(sortByPanel); + mainPanel.addNorth(sortByPanel, 50); sortByPanel.add(new Label(stringMessages.sortBy())); keyComparatorListBox = new ValueListBox<>(new AbstractRenderer>() { @Override From 7c50d96d9a51919e029e811f499b055969148442 Mon Sep 17 00:00:00 2001 From: Frederik Petersen Date: Mon, 23 Mar 2015 08:45:43 +0100 Subject: [PATCH 15/20] Fixed noSuchElement problem in before start situations in live races --- .../polars/mining/PolarFixFilterCriteria.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarFixFilterCriteria.java b/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarFixFilterCriteria.java index 0721d7d8536..1d21d6641fc 100644 --- a/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarFixFilterCriteria.java +++ b/java/com.sap.sailing.polars/src/com/sap/sailing/polars/mining/PolarFixFilterCriteria.java @@ -2,6 +2,7 @@ package com.sap.sailing.polars.mining; import java.util.Collection; import java.util.Iterator; +import java.util.NavigableSet; import com.sap.sailing.domain.base.Competitor; import com.sap.sailing.domain.base.Course; @@ -88,20 +89,23 @@ public class PolarFixFilterCriteria implements FilterCriterion markPassingsAtCompetitorsLastWayPoint = trackedRace.getMarkPassingsInOrder( - wayPoint).iterator(); - for (int i = 0; i < ((int) Math.max(Math.round(pctOfLeadingCompetitorsToInclude - * getNumberOfCompetitors(trackedRace)), 1)); i++) { - if (markPassingsAtCompetitorsLastWayPoint.hasNext()) { - if (markPassingsAtCompetitorsLastWayPoint.next().getCompetitor().equals(competitor)) { - result = true; + NavigableSet markPassingsOfCompetitor = trackedRace.getMarkPassings(competitor); + if (!markPassingsOfCompetitor.isEmpty()) { + Waypoint wayPoint = markPassingsOfCompetitor.last().getWaypoint(); + if (wayPoint != null) { + Iterator markPassingsAtCompetitorsLastWayPoint = trackedRace.getMarkPassingsInOrder( + wayPoint).iterator(); + for (int i = 0; i < ((int) Math.max( + Math.round(pctOfLeadingCompetitorsToInclude * getNumberOfCompetitors(trackedRace)), 1)); i++) { + if (markPassingsAtCompetitorsLastWayPoint.hasNext()) { + if (markPassingsAtCompetitorsLastWayPoint.next().getCompetitor().equals(competitor)) { + result = true; + break; + } + } else { + result = false; break; } - } else { - result = false; - break; } } } From 780053e17f82e9624c34de3c46a9ec7b93521d65 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 23 Mar 2015 09:58:19 +0000 Subject: [PATCH 16/20] Updated api v1 (markdown) --- wiki/tracking-app/api-v1.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/wiki/tracking-app/api-v1.md b/wiki/tracking-app/api-v1.md index a54b0148cb4..5c4d87f0949 100644 --- a/wiki/tracking-app/api-v1.md +++ b/wiki/tracking-app/api-v1.md @@ -294,8 +294,7 @@ In contrast to the _Tracking App_, we won't perform a check-in. However, we can This information is represented in a URL with the following structure: ``` -http:///buoy-tender/checkin - &leaderboard_name= +http:///buoy-tender/checkin?leaderboard_name= ``` _also see [Tracking App Check-In Information](#tracking-checkin-info) for additional notes that might apply_ From 91630cbfbdf5d57ee51ac5a80b3f03818eb33794 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 23 Mar 2015 14:28:27 +0100 Subject: [PATCH 17/20] use only a single selection model for the multi-mark control points table --- .../sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java index 13f9200f9c6..48c9d2f841e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java @@ -71,7 +71,7 @@ public abstract class CourseManagementWidget implements IsWidget { waypoints = new WaypointTableWrapper>( /* multiSelection */ false, sailingService, stringMessages, errorReporter); multiMarkControlPoints = new ControlPointTableWrapper>( - /* multiSelection */ true, sailingService, stringMessages, errorReporter); + /* multiSelection */ false, sailingService, stringMessages, errorReporter); marks = new MarkTableWrapper>( /* multiSelection */ true, sailingService, stringMessages, errorReporter); From 6436be635a3711b5404425ad9772badd875432b7 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 23 Mar 2015 14:33:52 +0100 Subject: [PATCH 18/20] fixed selection model type for multi-marks control points table --- .../sailing/gwt/ui/adminconsole/CourseManagementWidget.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java index 48c9d2f841e..d0fbe2008fd 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CourseManagementWidget.java @@ -34,7 +34,7 @@ import com.sap.sse.gwt.client.dialog.DataEntryDialog; public abstract class CourseManagementWidget implements IsWidget { protected final MarkTableWrapper> marks; - protected final ControlPointTableWrapper> multiMarkControlPoints; + protected final ControlPointTableWrapper> multiMarkControlPoints; protected final WaypointTableWrapper> waypoints; protected final Grid mainPanel; @@ -70,7 +70,7 @@ public abstract class CourseManagementWidget implements IsWidget { waypoints = new WaypointTableWrapper>( /* multiSelection */ false, sailingService, stringMessages, errorReporter); - multiMarkControlPoints = new ControlPointTableWrapper>( + multiMarkControlPoints = new ControlPointTableWrapper>( /* multiSelection */ false, sailingService, stringMessages, errorReporter); marks = new MarkTableWrapper>( /* multiSelection */ true, sailingService, stringMessages, errorReporter); From e9328229d9fdbbb1469c13e90ad470216e436d59 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 23 Mar 2015 15:25:51 +0100 Subject: [PATCH 19/20] also fixed sorting of selection checkbox column consistently for all users --- .../ui/adminconsole/CompetitorTableWrapper.java | 2 +- .../adminconsole/DeviceMappingTableWrapper.java | 6 +----- .../sailing/gwt/ui/adminconsole/TableWrapper.java | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorTableWrapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorTableWrapper.java index e9dd77dc910..2c4f907eeb1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorTableWrapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/CompetitorTableWrapper.java @@ -32,7 +32,7 @@ public class CompetitorTableWrapper> ext public CompetitorTableWrapper(SailingServiceAsync sailingService, StringMessages stringMessages,ErrorReporter errorReporter, boolean multiSelection, boolean enablePager) { super(sailingService, stringMessages, errorReporter, multiSelection, enablePager); - ListHandler competitorColumnListHandler = new ListHandler(dataProvider.getList()); + ListHandler competitorColumnListHandler = getColumnSortHandler(); // competitors table TextColumn competitorNameColumn = new TextColumn() { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceMappingTableWrapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceMappingTableWrapper.java index 8768b9019c9..339a10e99a1 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceMappingTableWrapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/DeviceMappingTableWrapper.java @@ -31,7 +31,6 @@ public class DeviceMappingTableWrapper extends TableWrapper() { @Override @@ -40,12 +39,9 @@ public class DeviceMappingTableWrapper extends TableWrapper listHandler = new ListHandler(dataProvider.getList()); - + ListHandler listHandler = getColumnSortHandler(); TextColumn itemTypeCol = new TextColumn() { @Override public String getValue(DeviceMappingDTO mapping) { diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TableWrapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TableWrapper.java index d1f56bf7bbc..fe76cdfad71 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TableWrapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/TableWrapper.java @@ -4,6 +4,7 @@ import java.util.Collection; import com.google.gwt.core.client.GWT; import com.google.gwt.user.cellview.client.CellTable; +import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler; import com.google.gwt.user.cellview.client.SimplePager; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.VerticalPanel; @@ -17,7 +18,9 @@ import com.sap.sailing.gwt.ui.client.shared.controls.SelectionCheckboxColumn; import com.sap.sse.gwt.client.ErrorReporter; /** - * Implementing classes still have to add the table to the main panel. + * Implementing classes still have to add the table to the main panel. The table created and wrapped by this object + * offers already a {@link ListHandler} for sorting. Subclasses can obtain the table's default column sort handler + * created by this class's constructor by calling {@link #getColumnSortHandler}. */ public abstract class TableWrapper> implements IsWidget { protected final CellTable table; @@ -28,6 +31,7 @@ public abstract class TableWrapper> implements Is protected final ErrorReporter errorReporter; private final AdminConsoleTableResources tableRes = GWT.create(AdminConsoleTableResources.class); + private final ListHandler columnSortHandler; @Override public Widget asWidget() { @@ -39,6 +43,9 @@ public abstract class TableWrapper> implements Is this.sailingService = sailingService; this.errorReporter = errorReporter; table = new CellTable(10000, tableRes); + this.dataProvider = new ListDataProvider(); + this.columnSortHandler = new ListHandler(dataProvider.getList()); + table.addColumnSortHandler(this.columnSortHandler); if (multiSelection) { SelectionCheckboxColumn selectionCheckboxColumn = new SelectionCheckboxColumn( tableRes.cellTableStyle().cellTableCheckboxSelected(), @@ -49,6 +56,7 @@ public abstract class TableWrapper> implements Is return dataProvider; } }; + columnSortHandler.setComparator(selectionCheckboxColumn, selectionCheckboxColumn.getComparator()); @SuppressWarnings("unchecked") S typedSelectionModel = (S) selectionCheckboxColumn.getSelectionModel(); selectionModel = typedSelectionModel; @@ -60,7 +68,6 @@ public abstract class TableWrapper> implements Is selectionModel = typedSelectionModel; table.setSelectionModel(selectionModel); } - this.dataProvider = new ListDataProvider(); mainPanel = new VerticalPanel(); dataProvider.addDataDisplay(table); mainPanel.add(table); @@ -72,6 +79,10 @@ public abstract class TableWrapper> implements Is } } + public ListHandler getColumnSortHandler() { + return columnSortHandler; + } + public CellTable getTable() { return table; } From f88a3f474fa94ecf6e9da6c3c368dbd4438da530 Mon Sep 17 00:00:00 2001 From: Axel Uhl Date: Mon, 23 Mar 2015 15:30:28 +0100 Subject: [PATCH 20/20] added some more table sortability --- .../gwt/ui/adminconsole/RaceTableWrapper.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceTableWrapper.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceTableWrapper.java index a51397326e7..3224e80c7c8 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceTableWrapper.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/RaceTableWrapper.java @@ -1,5 +1,6 @@ package com.sap.sailing.gwt.ui.adminconsole; +import java.util.Comparator; import java.util.HashMap; import java.util.Map; @@ -10,6 +11,7 @@ import com.google.gwt.user.cellview.client.Column; import com.google.gwt.user.cellview.client.TextColumn; import com.google.gwt.view.client.SelectionModel; import com.sap.sailing.domain.common.RegattaNameAndRaceName; +import com.sap.sailing.domain.common.impl.NaturalComparator; import com.sap.sailing.gwt.ui.adminconsole.AbstractLeaderboardConfigPanel.RaceColumnDTOAndFleetDTOWithNameBasedEquality; import com.sap.sailing.gwt.ui.adminconsole.LeaderboardConfigPanel.AnchorCell; import com.sap.sailing.gwt.ui.adminconsole.LeaderboardConfigPanel.AnchorTemplates; @@ -45,14 +47,26 @@ extends TableWrapper { } } }; - + raceNameColumn.setSortable(true); + getColumnSortHandler().setComparator(raceNameColumn, new Comparator() { + @Override + public int compare(RaceColumnDTOAndFleetDTOWithNameBasedEquality o1, RaceColumnDTOAndFleetDTOWithNameBasedEquality o2) { + return new NaturalComparator().compare(o1.getA().getName(), o2.getA().getName()); + } + }); TextColumn fleetNameColumn = new TextColumn() { @Override public String getValue(RaceColumnDTOAndFleetDTOWithNameBasedEquality object) { return object.getB().getName(); } }; - + fleetNameColumn.setSortable(true); + getColumnSortHandler().setComparator(fleetNameColumn, new Comparator() { + @Override + public int compare(RaceColumnDTOAndFleetDTOWithNameBasedEquality o1, RaceColumnDTOAndFleetDTOWithNameBasedEquality o2) { + return new NaturalComparator().compare(o1.getB().getName(), o2.getB().getName()); + } + }); table.addColumn(raceNameColumn, stringMessages.race()); table.addColumn(fleetNameColumn, stringMessages.fleet()); }