Merge remote-tracking branch 'refs/remotes/external/master' into bug1978-docked-video-component

Conflicts:
	java/com.sap.sailing.gwt.ui/SailingGWT.launch
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/AdminConsoleEntryPoint.java
	java/com.sap.sailing.server/src/com/sap/sailing/server/impl/MediaLibrary.java
This commit is contained in:
Jens Rommel committed 2014-09-24 13:54:52 +02:00
commit eb8742ea33
763 files changed
+15872 -11997

No files matched your search

@@ -18,7 +18,9 @@ package difflib;
import java.util.*;
/**
* Describes the delta between original and revised texts.
* Describes the delta between original and revised object lists. Applying the patch only uses {@link List#add(int, Object)}
* and {@link List#remove(int)} as modifying operations. In particular, no call to {@link List#set(int, Object)} needs to be
* expected.
*
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
*/
@@ -69,7 +69,7 @@ public class TracTrac {
for (TracTracRaceRecordDTO raceRecord : racesThatCanBeTracked.getB()) {
RaceRecord record = getTracTracAdapter().getSingleTracTracRaceRecord(new URL(raceRecord.jsonURL), raceRecord.id, /*loadClientParams*/true);
if (record.getRaceStatus().equals(TracTracConnectionConstants.REPLAY_STATUS)) {
if (record.getRaceStatus().equals(TracTracConnectionConstants.REPLAY_STATUS) || record.getRaceVisibility().equals(TracTracConnectionConstants.REPLAY_VISIBILITY)) {
RegattaIdentifier regattaForRaceRecord = null;
if (raceRecord.hasRememberedRegatta()) {
Regatta regatta = getService().getRememberedRegattaForRace(raceRecord.id);
@@ -85,9 +85,9 @@ public class TracTrac {
MongoRaceLogStoreFactory.INSTANCE.getMongoRaceLogStore(getService().getMongoObjectFactory(), getService().getDomainObjectFactory()),
RaceTracker.TIMEOUT_FOR_RECEIVING_RACE_DEFINITION_IN_MILLISECONDS, /*simulateWithStartTimeNow*/false,
/*tracTracUsername*/"", /*tracTracPassword*/"",
record.getRaceStatus());
record.getRaceStatus(), record.getRaceVisibility());
} else {
logger.info("Ignoring race " + record.getName() + " because it is in status " + record.getRaceStatus());
logger.info("Ignoring race " + record.getName() + " because it is in status " + record.getRaceStatus() + " and visibility " + record.getRaceVisibility());
}
}
}
@@ -107,7 +107,7 @@ public class TracTrac {
raceRecord.getTrackingStartTime().asDate(),
raceRecord
.getTrackingEndTime().asDate(), raceRecord.getRaceStartTime().asDate(),
raceRecord.getBoatClassNames(), raceRecord.getRaceStatus(), raceRecord.getJsonURL().toString(),
raceRecord.getBoatClassNames(), raceRecord.getRaceStatus(), raceRecord.getRaceVisibility(), raceRecord.getJsonURL().toString(),
hasRememberedRegatta(raceRecord.getID())));
}
return new com.sap.sse.common.Util.Pair<String, List<TracTracRaceRecordDTO>>(raceRecords.getA(), result);
@@ -7,6 +7,6 @@ Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
Export-Package: com.sap.sailing.datamining.shared,
com.sap.sailing.datamining.shared.impl
Require-Bundle: com.sap.sse.datamining.shared;bundle-version="1.0.0"
Require-Bundle: com.sap.sse.datamining.shared;bundle-version="1.0.0",
com.sap.sailing.domain.common;bundle-version="1.0.0"
Export-Package: com.sap.sailing.datamining.shared
@@ -1,7 +0,0 @@
package com.sap.sailing.datamining.shared;
public enum DataTypes {
GPSFix, TrackedLegOfCompetitor
}
@@ -1,21 +0,0 @@
package com.sap.sailing.datamining.shared;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public enum DimensionIdentifier {
RegattaName, BoatClassName, CourseAreaName, FleetName, RaceName, LegType, LegNumber, Nationality, CompetitorName, SailID, WindStrength, Year;
public static class OrdinalComparator implements Comparator<DimensionIdentifier> {
private static final List<DimensionIdentifier> dimensions = Arrays.asList(DimensionIdentifier.values());
@Override
public int compare(DimensionIdentifier dimension1, DimensionIdentifier dimension2) {
Integer ordinal1 = dimensions.indexOf(dimension1);
Integer ordinal2 = dimensions.indexOf(dimension2);
return ordinal1.compareTo(ordinal2);
}
}
}
@@ -1,26 +0,0 @@
package com.sap.sailing.datamining.shared;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.components.GrouperType;
public interface QueryDefinition extends Serializable {
public String getLocaleInfoName();
public GrouperType getGrouperType();
public StatisticType getStatisticType();
public AggregatorType getAggregatorType();
public DataTypes getDataType();
public List<DimensionIdentifier> getDimensionsToGroupBy();
public Map<DimensionIdentifier, Iterable<?>> getSelection();
}
@@ -0,0 +1,16 @@
package com.sap.sailing.datamining.shared;
import java.io.Serializable;
import com.sap.sailing.domain.common.LegType;
import com.sap.sse.datamining.shared.impl.GenericGroupKey;
@SuppressWarnings("unused")
public final class SailingDataMiningSerializationDummy implements Serializable {
private static final long serialVersionUID = 2L;
private LegType legType;
private SailingDataMiningSerializationDummy() { }
}
@@ -1,56 +0,0 @@
package com.sap.sailing.datamining.shared;
import com.sap.sse.datamining.shared.Message;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.components.ElementType;
public enum StatisticType {
Speed(ElementType.Double, Unit.Knots, 2),
Distance(ElementType.Double, Unit.Meters, 2);
private final ElementType valueType;
private final Unit unit;
private final int valueDecimals;
private StatisticType(ElementType valueType, Unit unit, int valueDecimals) {
this.valueType = valueType;
this.unit = unit;
this.valueDecimals = valueDecimals;
}
public ElementType getValueType() {
return valueType;
}
public Message getSignifierMessage() {
switch (this) {
case Distance:
return Message.Distance;
case Speed:
return Message.Speed;
}
throw new IllegalArgumentException("No message available for the statistic type '" + this + "'");
}
public Unit getUnit() {
return unit;
}
public Message getUnitMessage() {
switch (unit) {
case Knots:
return Message.Knots;
case Meters:
return Message.Meters;
case None:
return null;
}
throw new IllegalArgumentException("No message available for the unit '" + unit + "'");
}
public int getValueDecimals() {
return valueDecimals;
}
}
@@ -1,89 +0,0 @@
package com.sap.sailing.datamining.shared.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.QueryDefinition;
import com.sap.sailing.datamining.shared.StatisticType;
import com.sap.sse.datamining.shared.components.AggregatorType;
import com.sap.sse.datamining.shared.components.GrouperType;
public class SimpleQueryDefinition implements QueryDefinition {
private static final long serialVersionUID = 8408302866342877839L;
private String localeInfoName;
private GrouperType grouperType;
private StatisticType statisticType;
private AggregatorType aggregatorType;
private DataTypes dataType;
private List<DimensionIdentifier> dimensionsToGroupBy;
private Map<DimensionIdentifier, Iterable<?>> selectionMappedByDimension;
/**
* Constructor for the GWT-Serialization. Don't use this!
*/
@Deprecated
SimpleQueryDefinition() { }
public SimpleQueryDefinition(String localeInfoName, GrouperType grouperType, StatisticType statisticType, AggregatorType aggregatorType, DataTypes dataType) {
this.localeInfoName = localeInfoName;
this.grouperType = grouperType;
this.statisticType = statisticType;
this.aggregatorType = aggregatorType;
this.dataType = dataType;
dimensionsToGroupBy = new ArrayList<DimensionIdentifier>();
selectionMappedByDimension = new HashMap<DimensionIdentifier, Iterable<?>>();
}
@Override
public String getLocaleInfoName() {
return localeInfoName;
}
@Override
public GrouperType getGrouperType() {
return grouperType;
}
@Override
public StatisticType getStatisticType() {
return statisticType;
}
@Override
public AggregatorType getAggregatorType() {
return aggregatorType;
}
@Override
public DataTypes getDataType() {
return dataType;
}
@Override
public List<DimensionIdentifier> getDimensionsToGroupBy() {
return dimensionsToGroupBy;
}
@Override
public Map<DimensionIdentifier, Iterable<?>> getSelection() {
return selectionMappedByDimension;
}
public void appendDimensionToGroupBy(DimensionIdentifier dimension) {
dimensionsToGroupBy.add(dimension);
}
public void setSelectionFor(DimensionIdentifier dimension, Collection<?> selection) {
selectionMappedByDimension.put(dimension, selection);
}
}
@@ -4,5 +4,6 @@
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -1,4 +1,5 @@
source.. = src/
source.. = src/,\
resources/
output.. = bin/
bin.includes = META-INF/,\
.
@@ -22,10 +22,9 @@ import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.AdditionalResultDataBuilder;
import com.sap.sse.datamining.components.FilterCriteria;
import com.sap.sse.datamining.components.Processor;
public class TestLeaderboardGroupFilteringRetrievalProcessor {
public class TestLeaderboardGroupRetrievalProcessor {
private RacingEventService service;
private Processor<RacingEventService> retriever;
@@ -36,13 +35,17 @@ public class TestLeaderboardGroupFilteringRetrievalProcessor {
public void initializeComponents() {
service = mock(RacingEventService.class);
stub(service.getLeaderboardGroups()).toReturn(getGroupsInService());
retrievedGroups = new HashSet<>();
Processor<LeaderboardGroup> receiver = new Processor<LeaderboardGroup>() {
@Override
public void onElement(LeaderboardGroup element) {
public void processElement(LeaderboardGroup element) {
retrievedGroups.add(element);
}
@Override
public void onFailure(Throwable failure) {
}
@Override
public void finish() throws InterruptedException {
}
@Override
@@ -54,14 +57,7 @@ public class TestLeaderboardGroupFilteringRetrievalProcessor {
}
};
FilterCriteria<LeaderboardGroup> criteria = new FilterCriteria<LeaderboardGroup>() {
@Override
public boolean matches(LeaderboardGroup element) {
String name = element.getName();
return name == "LG1" || name == "LG2" || name == "LG3";
}
};
retriever = new LeaderboardGroupFilteringRetrievalProcessor(ConcurrencyTestsUtil.getExecutor(), Arrays.asList(receiver), criteria);
retriever = new LeaderboardGroupRetrievalProcessor(ConcurrencyTestsUtil.getExecutor(), Arrays.asList(receiver));
}
private Map<String, LeaderboardGroup> getGroupsInService() {
@@ -77,7 +73,7 @@ public class TestLeaderboardGroupFilteringRetrievalProcessor {
@Ignore
@Test
public void testFilteringRetrieval() throws InterruptedException {
retriever.onElement(service);
retriever.processElement(service);
retriever.finish();
Collection<LeaderboardGroup> expectedGroups = getExpectedRetrievedGroups();
@@ -0,0 +1,103 @@
package com.sap.sailing.datamining.impl.functions;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import org.junit.BeforeClass;
import org.junit.Test;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.impl.data.SailingDataMiningClassesWithFunctionsService;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Moving;
import com.sap.sailing.domain.base.Nationality;
import com.sap.sailing.domain.base.Team;
import com.sap.sailing.domain.common.Speed;
import com.sap.sse.common.Named;
import com.sap.sse.datamining.factories.FunctionFactory;
import com.sap.sse.datamining.functions.Function;
import com.sap.sse.datamining.functions.FunctionRegistry;
import com.sap.sse.datamining.impl.functions.SimpleFunctionRegistry;
public class TestSailingFunctionsRegistration {
private static FunctionRegistry functionRegistry;
@BeforeClass
public static void setUpFunctionRegistryAndProvider() {
SailingDataMiningClassesWithFunctionsService classesWithFunctionsService = new SailingDataMiningClassesWithFunctionsService();
functionRegistry = new SimpleFunctionRegistry();
functionRegistry.registerAllWithInternalFunctionPolicy(classesWithFunctionsService.getInternalClassesWithMarkedMethods());
}
@Test
public void testImportantRegisteredDimensions() throws NoSuchMethodException, SecurityException {
Collection<Function<?>> expectedDimensions = createExpectedImportantRegisteredDimensions();
Collection<Function<?>> providedDimensions = functionRegistry.getDimensions();
for (Function<?> dimension : expectedDimensions) {
assertThat("The expected dimension '" + dimension + "' wasn't provided.",
providedDimensions.contains(dimension), is(true));
}
}
private Collection<Function<?>> createExpectedImportantRegisteredDimensions() throws NoSuchMethodException, SecurityException {
Collection<Function<?>> expectedDimensions = new HashSet<>();
Method getRegattaMethod = HasTrackedRaceContext.class.getMethod("getRegatta", new Class<?>[0]);
Function<?> getRegatta = FunctionFactory.createMethodWrappingFunction(getRegattaMethod);
Method getNameMethod = Named.class.getMethod("getName", new Class<?>[0]);
Function<?> getName = FunctionFactory.createMethodWrappingFunction(getNameMethod);
expectedDimensions.add(FunctionFactory.createCompoundFunction(Arrays.asList(getRegatta, getName)));
Method getYearMethod = HasTrackedRaceContext.class.getMethod("getYear", new Class<?>[0]);
expectedDimensions.add(FunctionFactory.createMethodWrappingFunction(getYearMethod));
Method getCompetitorMethod = HasTrackedLegOfCompetitorContext.class.getMethod("getCompetitor", new Class<?>[0]);
Function<?> getCompetitor = FunctionFactory.createMethodWrappingFunction(getCompetitorMethod);
Method getTeamMethod = Competitor.class.getMethod("getTeam", new Class<?>[0]);
Function<?> getTeam = FunctionFactory.createMethodWrappingFunction(getTeamMethod);
Method getNationalityMethod = Team.class.getMethod("getNationality", new Class<?>[0]);
Function<?> getNationality = FunctionFactory.createMethodWrappingFunction(getNationalityMethod);
Method getAcronymMethod = Nationality.class.getMethod("getThreeLetterIOCAcronym", new Class<?>[0]);
Function<?> getAcronym = FunctionFactory.createMethodWrappingFunction(getAcronymMethod);
expectedDimensions.add(FunctionFactory.createCompoundFunction(Arrays.asList(getCompetitor, getTeam, getNationality, getAcronym)));
return expectedDimensions;
}
@Test
public void testImportantRegisteredStatistics() throws NoSuchMethodException, SecurityException {
Collection<Function<?>> expectedStatistics = createExpectedImportantRegisteredStatistics();
Collection<Function<?>> providedStatistics = functionRegistry.getStatistics();
for (Function<?> statistic : expectedStatistics) {
assertThat("The expected statistic '" + statistic + "' wasn't provided.",
providedStatistics.contains(statistic), is(true));
}
}
private Collection<Function<?>> createExpectedImportantRegisteredStatistics() throws NoSuchMethodException, SecurityException {
Collection<Function<?>> expectedStatistics = new HashSet<>();
Method getDistanceTraveledMethod = HasTrackedLegOfCompetitorContext.class.getMethod("getDistanceTraveled", new Class<?>[0]);
expectedStatistics.add(FunctionFactory.createMethodWrappingFunction(getDistanceTraveledMethod));
Method getGPSFixMethod = HasGPSFixContext.class.getMethod("getGPSFix", new Class<?>[0]);
Function<?> getGPSFix = FunctionFactory.createMethodWrappingFunction(getGPSFixMethod);
Method getSpeedMethod = Moving.class.getMethod("getSpeed", new Class<?>[0]);
Function<?> getSpeed = FunctionFactory.createMethodWrappingFunction(getSpeedMethod);
Method getKnotsMethod = Speed.class.getMethod("getKnots", new Class<?>[0]);
Function<?> getKnots = FunctionFactory.createMethodWrappingFunction(getKnotsMethod);
expectedStatistics.add(FunctionFactory.createCompoundFunction(Arrays.asList(getGPSFix, getSpeed, getKnots)));
return expectedStatistics;
}
}
@@ -1,35 +0,0 @@
package com.sap.sailing.datamining.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.sap.sailing.datamining.Clusters;
import com.sap.sse.datamining.data.deprecated.ClusterOfComparable;
import com.sap.sse.datamining.impl.data.deprecated.ClusterOfComparableImpl;
public class TestClusters {
@Test
public void testClusterOfComparable() {
ClusterOfComparable<Integer> cluster = new ClusterOfComparableImpl<Integer>("Test", 3, 1);
assertTrue(cluster.isInRange(1));
assertTrue(cluster.isInRange(2));
assertTrue(cluster.isInRange(3));
assertFalse(cluster.isInRange(null));
assertFalse(cluster.isInRange(0));
assertFalse(cluster.isInRange(4));
}
@Test
public void testWindStrengthClusters() {
assertNull(Clusters.WindStrength.getClusterFor(15, Clusters.WindStrength.StandardClusters));
assertEquals(Clusters.WindStrength.VeryLight, Clusters.WindStrength.getClusterFor(1, Clusters.WindStrength.StandardClusters));
}
}
@@ -17,4 +17,5 @@ Require-Bundle: com.sap.sailing.domain;bundle-version="1.0.0",
com.sap.sse.datamining.shared;bundle-version="1.0.0",
com.sap.sse.common
Bundle-ClassPath: .
Bundle-Activator: com.sap.sailing.datamining.impl.Activator
Bundle-Activator: com.sap.sailing.datamining.Activator
Bundle-ActivationPolicy: lazy
@@ -0,0 +1,38 @@
package com.sap.sailing.datamining;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.datamining.impl.data.SailingDataMiningClassesWithFunctionsService;
import com.sap.sse.datamining.ClassesWithFunctionsService;
public class Activator implements BundleActivator {
public static final String dataRetrieverGroupName = "Sailing";
private static BundleContext context;
private ServiceRegistration<ClassesWithFunctionsService> classesWithFunctionsServiceRegistration;
@Override
public void start(BundleContext context) throws Exception {
Activator.context = context;
registerClassesWithFunctionsService();
}
@Override
public void stop(BundleContext context) throws Exception {
unregisterClassesWithFunctionsService();
}
private void unregisterClassesWithFunctionsService() {
context.ungetService(classesWithFunctionsServiceRegistration.getReference());
}
private void registerClassesWithFunctionsService() {
classesWithFunctionsServiceRegistration = context.registerService(ClassesWithFunctionsService.class,
new SailingDataMiningClassesWithFunctionsService(), null);
}
}
@@ -1,46 +0,0 @@
package com.sap.sailing.datamining;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.sap.sailing.datamining.impl.WindStrengthClusterImpl;
public class Clusters {
private Clusters() { }
public static class WindStrength {
public static WindStrengthCluster VeryLight = new WindStrengthClusterImpl("Very Light", 0.0, 2.5);
public static WindStrengthCluster Light = new WindStrengthClusterImpl("Very Light", 2.5, 5.0);
public static WindStrengthCluster Medium = new WindStrengthClusterImpl("Very Light", 5.0, 7.5);
public static WindStrengthCluster Strong = new WindStrengthClusterImpl("Very Light", 7.5, 10.0);
public static WindStrengthCluster VeryStrong = new WindStrengthClusterImpl("Very Light", 10.0, 12.0);
public static Collection<WindStrengthCluster> StandardClusters = Arrays.asList(VeryLight, Light, Medium, Strong, VeryStrong);
private WindStrength() { }
public static WindStrengthCluster getClusterFor(double windStrengthInBeafort, Collection<WindStrengthCluster> clusters) {
List<WindStrengthCluster> sortedClusters = new ArrayList<WindStrengthCluster>(clusters);
Collections.sort(sortedClusters, new Comparator<WindStrengthCluster>() {
@Override
public int compare(WindStrengthCluster cluster1, WindStrengthCluster cluster2) {
return cluster1.getUpperRange().compareTo(cluster2.getUpperRange());
}
});
for (WindStrengthCluster cluster : sortedClusters) {
if (cluster.isInRange(windStrengthInBeafort)) {
return cluster;
}
}
return null;
}
}
}
@@ -1,7 +0,0 @@
package com.sap.sailing.datamining;
import com.sap.sse.datamining.data.deprecated.ClusterOfComparable;
public interface WindStrengthCluster extends ClusterOfComparable<Double> {
}
@@ -1,52 +0,0 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.datamining.WindStrengthCluster;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface GPSFixWithContext extends GPSFixMoving {
@Dimension(messageKey="regatta")
public String getRegattaName();
@Dimension(messageKey="race")
public String getRaceName();
@Dimension(messageKey="legNumber")
public int getLegNumber();
@Dimension(messageKey="course")
public String getCourseAreaName();
@Dimension(messageKey="fleet")
public String getFleetName();
@Dimension(messageKey="boatClass")
public String getBoatClassName();
/**
* The year of the start of the race.
*/
@Dimension(messageKey="year")
public Integer getYear();
/**
* The leg type of the leg, which contains this gps fix. Can be <code>null</code> if there's no wind in the race.
*/
@Dimension(messageKey="legType")
public LegType getLegType();
@Dimension(messageKey="competitor")
public String getCompetitorName();
@Dimension(messageKey="sailID")
public String getCompetitorSailID();
@Dimension(messageKey="nationality")
public String getCompetitorNationality();
@Dimension(messageKey="windStrength")
public WindStrengthCluster getWindStrength();
}
@@ -1,5 +1,11 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sse.datamining.shared.annotations.Connector;
public interface HasGPSFixContext extends HasTrackedLegOfCompetitorContext {
@Connector
public GPSFixMoving getGPSFix();
}
@@ -1,9 +0,0 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.leaderboard.Leaderboard;
public interface HasLeaderboardContext extends HasLeaderboardGroupContext {
public Leaderboard getLeaderboard();
}
@@ -1,9 +0,0 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
public interface HasLeaderboardGroupContext {
public LeaderboardGroup getLeaderboardGroup();
}
@@ -2,11 +2,15 @@ package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface HasTrackedLegContext extends HasTrackedRaceContext {
public TrackedLeg getTrackedLeg();
@Dimension(messageKey="LegType", ordinal=5)
public LegType getLegType();
@Dimension(messageKey="LegNumber", ordinal=6)
public int getLegNumber();
}
@@ -1,9 +1,19 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Statistic;
public interface HasTrackedLegOfCompetitorContext extends HasTrackedLegContext {
public TrackedLegOfCompetitor getTrackedLegOfCompetitor();
@Connector(messageKey="Competitor")
public Competitor getCompetitor();
@Statistic(messageKey="DistanceTraveled", resultUnit=Unit.Meters, resultDecimals=0, ordinal=0)
public Double getDistanceTraveled();
}
@@ -1,14 +1,34 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface HasTrackedRaceContext extends HasLeaderboardContext {
public CourseArea getCourseArea();
public Fleet getFleet();
public interface HasTrackedRaceContext {
public TrackedRace getTrackedRace();
@Connector(messageKey="Regatta", ordinal=0)
public Regatta getRegatta();
@Connector(messageKey="CourseArea", ordinal=2)
public CourseArea getCourseArea();
@Connector(messageKey="BoatClass", ordinal=1)
public BoatClass getBoatClass();
@Connector(messageKey="Fleet", ordinal=3)
public Fleet getFleet();
@Connector(messageKey="Race", ordinal=4)
public RaceDefinition getRace();
@Dimension(messageKey="Year", ordinal=10)
public Integer getYear();
}
@@ -1,54 +0,0 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.datamining.WindStrengthCluster;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.LegType;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Dimension;
import com.sap.sse.datamining.shared.annotations.SideEffectFreeValue;
public interface TrackedLegOfCompetitorWithContext {
@Dimension(messageKey="regatta")
public String getRegattaName();
@Dimension(messageKey="race")
public String getRaceName();
@Dimension(messageKey="legNumber")
public int getLegNumber();
@Dimension(messageKey="course")
public String getCourseAreaName();
@Dimension(messageKey="fleet")
public String getFleetName();
@Dimension(messageKey="boatClass")
public String getBoatClassName();
/**
* The year of the start of the race.
*/
@Dimension(messageKey="year")
public Integer getYear();
@Dimension(messageKey="legType")
public LegType getLegType();
@Dimension(messageKey="competitor")
public String getCompetitorName();
@Dimension(messageKey="sailID")
public String getCompetitorSailID();
@Dimension(messageKey="nationality")
public String getCompetitorNationality();
@Dimension(messageKey="windStrength")
public WindStrengthCluster getWindStrength();
@SideEffectFreeValue(messageKey="distanceTraveled", resultUnit=Unit.Meters)
public Distance getDistanceTraveled();
}
@@ -1,10 +0,0 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sse.datamining.data.deprecated.Dimension;
public interface DimensionManager<DataType> {
public Dimension<DataType, ?> getDimensionFor(DimensionIdentifier sharedDimension);
}
@@ -1,26 +0,0 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.data.GPSFixWithContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.datamining.shared.DataTypes;
public final class DimensionManagerProvider {
private DimensionManagerProvider() { }
private static final DimensionManager<GPSFixWithContext> GPSFixDimensionManager = new GPSFixDimensionManager();
private static final DimensionManager<TrackedLegOfCompetitorWithContext> TrackedLegOfCompetitorDimensionManager = new TrackedLegOfCompetitorDimensionManager();
@SuppressWarnings("unchecked")
public static <DataType> DimensionManager<DataType> getDimensionManagerFor(DataTypes dataType) {
switch (dataType) {
case GPSFix:
return (DimensionManager<DataType>) GPSFixDimensionManager;
case TrackedLegOfCompetitor:
return (DimensionManager<DataType>) TrackedLegOfCompetitorDimensionManager;
}
throw new IllegalArgumentException("Not yet implemented for the given data type: "
+ dataType.toString());
}
}
@@ -1,133 +0,0 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.data.GPSFixWithContext;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.domain.common.LegType;
import com.sap.sse.datamining.data.deprecated.Dimension;
import com.sap.sse.datamining.impl.data.deprecated.AbstractDimension;
public final class GPSFixDimensionManager implements DimensionManager<GPSFixWithContext> {
public GPSFixDimensionManager() { }
/**
* @return The dimension for the given dimension type. Throws an exception, if the used <code>ValueType</code> doesn't match the <code>ValueType</code> of the returning dimension.
*/
@Override
public Dimension<GPSFixWithContext, ?> getDimensionFor(DimensionIdentifier dimension) {
switch (dimension) {
case BoatClassName:
return BoatClassNameDimension;
case CompetitorName:
return CompetitorNameDimension;
case CourseAreaName:
return CourseAreaNameDimension;
case FleetName:
return FleetNameDimension;
case LegNumber:
return LegNumberDimension;
case LegType:
return LegTypeDimension;
case Nationality:
return NationalityDimension;
case RaceName:
return RaceNameDimension;
case RegattaName:
return RegattaNameDimension;
case SailID:
return SailIDDimension;
case WindStrength:
return WindStrengthDimension;
case Year:
return YearDimension;
}
throw new IllegalArgumentException("Not yet implemented for the given dimension: "
+ dimension.toString());
}
public final static Dimension<GPSFixWithContext, String> RegattaNameDimension = new AbstractDimension<GPSFixWithContext, String>("Regatta") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getRegattaName();
}
};
public final static Dimension<GPSFixWithContext, String> RaceNameDimension = new AbstractDimension<GPSFixWithContext, String>("Race") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getRaceName();
}
};
public final static Dimension<GPSFixWithContext, Integer> LegNumberDimension = new AbstractDimension<GPSFixWithContext, Integer>("Leg Number") {
@Override
public Integer getDimensionValueFrom(GPSFixWithContext data) {
return data.getLegNumber();
}
};
public final static Dimension<GPSFixWithContext, String> CourseAreaNameDimension = new AbstractDimension<GPSFixWithContext, String>("Course Area") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getCourseAreaName();
}
};
public final static Dimension<GPSFixWithContext, String> FleetNameDimension = new AbstractDimension<GPSFixWithContext, String>("Fleet") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getFleetName();
}
};
public final static Dimension<GPSFixWithContext, String> BoatClassNameDimension = new AbstractDimension<GPSFixWithContext, String>("Boat Class") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getBoatClassName();
}
};
public final static Dimension<GPSFixWithContext, Integer> YearDimension = new AbstractDimension<GPSFixWithContext, Integer>("Year") {
@Override
public Integer getDimensionValueFrom(GPSFixWithContext data) {
return data.getYear();
}
};
public final static Dimension<GPSFixWithContext, LegType> LegTypeDimension = new AbstractDimension<GPSFixWithContext, LegType>("Leg Type") {
@Override
public LegType getDimensionValueFrom(GPSFixWithContext data) {
return data.getLegType();
}
};
public final static Dimension<GPSFixWithContext, String> CompetitorNameDimension = new AbstractDimension<GPSFixWithContext, String>("Competitor") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getCompetitorName();
}
};
public final static Dimension<GPSFixWithContext, String> SailIDDimension = new AbstractDimension<GPSFixWithContext, String>("Sail ID") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getCompetitorSailID();
}
};
public final static Dimension<GPSFixWithContext, String> NationalityDimension = new AbstractDimension<GPSFixWithContext, String>("Nationality") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getCompetitorNationality();
}
};
//TODO after new clusters
public final static Dimension<GPSFixWithContext, String> WindStrengthDimension = new AbstractDimension<GPSFixWithContext, String>("Wind Strength") {
@Override
public String getDimensionValueFrom(GPSFixWithContext data) {
return data.getWindStrength().getName();
}
};
}
@@ -1,132 +0,0 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.domain.common.LegType;
import com.sap.sse.datamining.data.deprecated.Dimension;
import com.sap.sse.datamining.impl.data.deprecated.AbstractDimension;
public final class TrackedLegOfCompetitorDimensionManager implements DimensionManager<TrackedLegOfCompetitorWithContext> {
public TrackedLegOfCompetitorDimensionManager() { }
/**
* @return The dimension for the given dimension type. Throws an exception, if the used <code>ValueType</code> doesn't match the <code>ValueType</code> of the returning dimension.
*/
public Dimension<TrackedLegOfCompetitorWithContext, ?> getDimensionFor(DimensionIdentifier dimension) {
switch (dimension) {
case BoatClassName:
return BoatClassNameDimension;
case CompetitorName:
return CompetitorNameDimension;
case CourseAreaName:
return CourseAreaNameDimension;
case FleetName:
return FleetNameDimension;
case LegNumber:
return LegNumberDimension;
case LegType:
return LegTypeDimension;
case Nationality:
return NationalityDimension;
case RaceName:
return RaceNameDimension;
case RegattaName:
return RegattaNameDimension;
case SailID:
return SailIDDimension;
case WindStrength:
return WindStrengthDimension;
case Year:
return YearDimension;
}
throw new IllegalArgumentException("Not yet implemented for the given dimension: "
+ dimension.toString());
}
public final static Dimension<TrackedLegOfCompetitorWithContext, String> RegattaNameDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Regatta") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getRegattaName();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> RaceNameDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Race") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getRaceName();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, Integer> LegNumberDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, Integer>("Leg Number") {
@Override
public Integer getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getLegNumber();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> CourseAreaNameDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Course Area") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getCourseAreaName();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> FleetNameDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Fleet") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getFleetName();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> BoatClassNameDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Boat Class") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getBoatClassName();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, Integer> YearDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, Integer>("Year") {
@Override
public Integer getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getYear();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, LegType> LegTypeDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, LegType>("Leg Type") {
@Override
public LegType getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getLegType();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> CompetitorNameDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Competitor") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getCompetitorName();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> SailIDDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Sail ID") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getCompetitorSailID();
}
};
public final static Dimension<TrackedLegOfCompetitorWithContext, String> NationalityDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Nationality") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getCompetitorNationality();
}
};
//TODO after new clusters
public final static Dimension<TrackedLegOfCompetitorWithContext, String> WindStrengthDimension = new AbstractDimension<TrackedLegOfCompetitorWithContext, String>("Wind Strength") {
@Override
public String getDimensionValueFrom(TrackedLegOfCompetitorWithContext data) {
return data.getWindStrength().getName();
}
};
}
@@ -1,57 +0,0 @@
package com.sap.sailing.datamining.factories;
import java.util.Locale;
import com.sap.sailing.datamining.shared.QueryDefinition;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.Query;
import com.sap.sse.datamining.components.ParallelAggregator;
import com.sap.sse.datamining.components.ParallelDataRetriever;
import com.sap.sse.datamining.components.ParallelExtractor;
import com.sap.sse.datamining.components.ParallelFilter;
import com.sap.sse.datamining.components.ParallelGrouper;
import com.sap.sse.datamining.factories.AggregatorFactory;
import com.sap.sse.datamining.i18n.DataMiningStringMessages;
import com.sap.sse.datamining.impl.DataMiningActivator;
import com.sap.sse.datamining.impl.deprecated.QueryImpl;
import com.sap.sse.datamining.workers.FiltrationWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public final class DataMiningFactory {
private DataMiningFactory() {
}
public static <DataType, AggregatedType extends Number> Query<AggregatedType> createQuery(
QueryDefinition queryDefinition, RacingEventService racingService) {
Locale locale = DataMiningStringMessages.Util.getLocaleFrom(queryDefinition.getLocaleInfoName());
ParallelDataRetriever<DataType> retriever = DataRetrieverFactory.createDataRetriever(
queryDefinition.getDataType(), racingService, DataMiningActivator.getExecutor());
ParallelFilter<DataType> filter = createFilter(queryDefinition);
ParallelGrouper<DataType> grouper = GrouperFactory.createGrouper(queryDefinition,
DataMiningActivator.getExecutor());
ParallelExtractor<DataType, AggregatedType> extractor = ExtractorFactory.createExtractor(
DataMiningActivator.getStringMessages(), locale, queryDefinition.getStatisticType(),
DataMiningActivator.getExecutor());
ParallelAggregator<AggregatedType, AggregatedType> aggregator = AggregatorFactory.createAggregator(
DataMiningActivator.getStringMessages(), locale, queryDefinition.getStatisticType().getValueType(),
queryDefinition.getAggregatorType(), DataMiningActivator.getExecutor());
return new QueryImpl<DataType, AggregatedType, AggregatedType>(DataMiningActivator.getStringMessages(), locale,
retriever, filter, grouper, extractor, aggregator);
}
private static <DataType> ParallelFilter<DataType> createFilter(QueryDefinition queryDefinition) {
if (queryDefinition.getSelection().isEmpty()) {
return FilterFactory.createNonFilteringFilter();
}
WorkerBuilder<FiltrationWorker<DataType>> workerBuilder = FilterFactory.createDimensionFilterBuilder(
queryDefinition.getDataType(), queryDefinition.getSelection());
return FilterFactory.createParallelFilter(workerBuilder, DataMiningActivator.getExecutor());
}
}
@@ -1,28 +0,0 @@
package com.sap.sailing.datamining.factories;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.impl.components.GroupDividingParallelDataRetriever;
import com.sap.sailing.datamining.impl.workers.builders.DataRetrieverWorkerBuilder;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.components.ParallelDataRetriever;
import com.sap.sse.datamining.workers.DataRetrievalWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public final class DataRetrieverFactory {
private DataRetrieverFactory() {
}
/**
* Creates a retriever for the given data type. Throws an exception, if the used <code>DataType</code> doesn't match
* the <code>DataType</code> of the returning retriever.
*/
public static <DataType> ParallelDataRetriever<DataType> createDataRetriever(DataTypes dataType, RacingEventService racingService, ThreadPoolExecutor executor) {
WorkerBuilder<DataRetrievalWorker<LeaderboardGroup, DataType>> workerBuilder = new DataRetrieverWorkerBuilder<DataType>(dataType);
return new GroupDividingParallelDataRetriever<DataType>(racingService, workerBuilder, executor);
}
}
@@ -1,29 +0,0 @@
package com.sap.sailing.datamining.factories;
import java.util.Locale;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.impl.workers.builders.ExtractionWorkerBuilder;
import com.sap.sailing.datamining.shared.StatisticType;
import com.sap.sse.datamining.components.ParallelExtractor;
import com.sap.sse.datamining.i18n.DataMiningStringMessages;
import com.sap.sse.datamining.impl.components.deprecated.GroupDividingParallelExtractor;
import com.sap.sse.datamining.shared.Message;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.workers.ExtractionWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public final class ExtractorFactory {
private ExtractorFactory() { }
public static <DataType, ExtractedType extends Number> ParallelExtractor<DataType, ExtractedType> createExtractor(DataMiningStringMessages stringMessages, Locale locale,
StatisticType statisticType, ThreadPoolExecutor executor) {
WorkerBuilder<ExtractionWorker<DataType, ExtractedType>> workerBuilder = new ExtractionWorkerBuilder<DataType, ExtractedType>(statisticType);
String signifier = statisticType.getUnit() == Unit.None ? stringMessages.get(locale, statisticType.getSignifierMessage()) :
stringMessages.get(locale, Message.SignifierInUnit, statisticType.getSignifierMessage(), statisticType.getUnitMessage());
return new GroupDividingParallelExtractor<DataType, ExtractedType>(signifier, statisticType.getUnit(), statisticType.getValueDecimals(),
workerBuilder, executor);
}
}
@@ -1,64 +0,0 @@
package com.sap.sailing.datamining.factories;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.dimensions.DimensionManager;
import com.sap.sailing.datamining.dimensions.DimensionManagerProvider;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sse.datamining.components.FilterCriteria;
import com.sap.sse.datamining.components.ParallelFilter;
import com.sap.sse.datamining.data.deprecated.Dimension;
import com.sap.sse.datamining.impl.components.deprecated.NonFilteringFilter;
import com.sap.sse.datamining.impl.components.deprecated.PartitioningParallelFilter;
import com.sap.sse.datamining.impl.criterias.AndCompoundFilterCriteria;
import com.sap.sse.datamining.impl.criterias.CompoundFilterCriteria;
import com.sap.sse.datamining.impl.criterias.deprecated.DimensionValuesFilterCriteria;
import com.sap.sse.datamining.impl.workers.builders.FilterByCriteriaBuilder;
import com.sap.sse.datamining.workers.FiltrationWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public final class FilterFactory {
private FilterFactory() { }
public static <DataType> ParallelFilter<DataType> createParallelFilter(WorkerBuilder<FiltrationWorker<DataType>> workerBuilder, ThreadPoolExecutor executor) {
return new PartitioningParallelFilter<DataType>(workerBuilder, executor);
}
public static <DataType> WorkerBuilder<FiltrationWorker<DataType>> createDimensionFilterBuilder(DataTypes dataType, Map<DimensionIdentifier, Iterable<?>> selection) {
FilterCriteria<DataType> criteria = createAndCompoundDimensionFilterCritera(dataType, selection);
WorkerBuilder<FiltrationWorker<DataType>> builder = new FilterByCriteriaBuilder<DataType>(criteria);
return builder;
}
/**
* @return A filter that filters nothing. So the returning collection is the same as the given one.
*/
public static <DataType> ParallelFilter<DataType> createNonFilteringFilter() {
return new NonFilteringFilter<DataType>();
}
private static <DataType> FilterCriteria<DataType> createAndCompoundDimensionFilterCritera(DataTypes dataType, Map<DimensionIdentifier, Iterable<?>> selection) {
DimensionManager<DataType> dimensionManager = DimensionManagerProvider.getDimensionManagerFor(dataType);
CompoundFilterCriteria<DataType> compoundCriteria = new AndCompoundFilterCriteria<DataType>();
for (Entry<DimensionIdentifier, Iterable<?>> entry : selection.entrySet()) {
Dimension<DataType, ?> dimension = dimensionManager.getDimensionFor(entry.getKey());
if (dimension != null) {
FilterCriteria<DataType> criteria = createDimensionFilterCriteria(dimension, entry.getValue());
compoundCriteria.addCriteria(criteria);
}
}
return compoundCriteria;
}
@SuppressWarnings("unchecked")
private static <DataType, ValueType> FilterCriteria<DataType> createDimensionFilterCriteria(Dimension<DataType, ValueType> dimension, Iterable<?> values) {
return new DimensionValuesFilterCriteria<DataType, ValueType>(dimension, (Collection<ValueType>) values);
}
}
@@ -1,49 +0,0 @@
package com.sap.sailing.datamining.factories;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.dimensions.DimensionManager;
import com.sap.sailing.datamining.dimensions.DimensionManagerProvider;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.QueryDefinition;
import com.sap.sse.datamining.components.ParallelGrouper;
import com.sap.sse.datamining.data.deprecated.Dimension;
import com.sap.sse.datamining.impl.components.deprecated.PartitioningParallelGrouper;
import com.sap.sse.datamining.impl.workers.builders.MultiDimensionalGroupingWorkerBuilder;
import com.sap.sse.datamining.workers.GroupingWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public final class GrouperFactory {
private GrouperFactory() { }
public static <DataType> ParallelGrouper<DataType> createGrouper(QueryDefinition queryDefinition, ThreadPoolExecutor executor) {
WorkerBuilder<GroupingWorker<DataType>> workerBuilder = createGroupingWorkerBuilder(queryDefinition);
return new PartitioningParallelGrouper<DataType>(workerBuilder, executor);
}
private static <DataType> WorkerBuilder<GroupingWorker<DataType>> createGroupingWorkerBuilder(QueryDefinition queryDefinition) {
switch (queryDefinition.getGrouperType()) {
case Dimensions:
return createMultiDimensionalGroupingWorkerBuilder(queryDefinition.getDataType(), queryDefinition.getDimensionsToGroupBy());
}
throw new IllegalArgumentException("Not yet implemented for the given grouper type: "
+ queryDefinition.getGrouperType().toString());
}
@SuppressWarnings("unchecked")
private static <DataType, ValueType> WorkerBuilder<GroupingWorker<DataType>> createMultiDimensionalGroupingWorkerBuilder(DataTypes dataType, List<DimensionIdentifier> dimensionsToGroupBy) {
DimensionManager<DataType> dimensionManager = DimensionManagerProvider.getDimensionManagerFor(dataType);
Collection<Dimension<DataType, ValueType>> dimensions = new LinkedHashSet<Dimension<DataType, ValueType>>();
for (DimensionIdentifier sharedDimension : dimensionsToGroupBy) {
Dimension<DataType, ValueType> dimension = (Dimension<DataType, ValueType>) dimensionManager.getDimensionFor(sharedDimension);
dimensions.add(dimension);
}
return new MultiDimensionalGroupingWorkerBuilder<DataType, ValueType>(dimensions);
}
}
@@ -0,0 +1,127 @@
package com.sap.sailing.datamining.factories;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.Query;
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.FunctionProvider;
import com.sap.sse.datamining.i18n.DataMiningStringMessages;
import com.sap.sse.datamining.impl.DataMiningActivator;
import com.sap.sse.datamining.impl.ProcessorQuery;
import com.sap.sse.datamining.impl.components.GroupedDataEntry;
import com.sap.sse.datamining.shared.QueryDefinition;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public final class SailingDataMiningFactory {
private SailingDataMiningFactory() {
}
public static <ElementType> Query<Double> createQuery(RacingEventService dataSource, final QueryDefinition queryDefinition, final FunctionProvider functionProvider) {
return new ProcessorQuery<Double, RacingEventService>(DataMiningActivator.getExecutor(), dataSource,
DataMiningActivator.getStringMessages(), DataMiningStringMessages.Util.getLocaleFor(queryDefinition.getLocaleInfoName())) {
@Override
protected Processor<RacingEventService> createFirstProcessor() {
Processor<GroupedDataEntry<Double>> aggregationProcessor = ProcessorFactory.createAggregationProcessor(/*query*/ this, queryDefinition.getAggregatorType());
@SuppressWarnings("unchecked") // TODO Clean, after the deprecated components have been removed
Function<Double> extractionFunction = (Function<Double>) functionProvider.getFunctionForDTO(queryDefinition.getStatisticToCalculate());
Processor<GroupedDataEntry<ElementType>> extractionProcessor = ProcessorFactory.createExtractionProcessor(aggregationProcessor, extractionFunction);
List<Function<?>> dimensionsToGroupBy = convertDTOsToFunctions(queryDefinition.getDimensionsToGroupBy(), functionProvider);
Processor<ElementType> groupingProcessor = ProcessorFactory.createGroupingProcessor(extractionProcessor, dimensionsToGroupBy);
SailingDataRetrievalLevels dataRetrievalLevel = calculateDataRetrievalLevel(extractionFunction);
Processor<RacingEventService> firstRetrievalProcessor = SailingDataRetrieverFactory.createRetrievalProcessorChain(dataRetrievalLevel, groupingProcessor, queryDefinition.getFilterSelection(), functionProvider);
return firstRetrievalProcessor;
}
};
}
@SuppressWarnings("unchecked")
public static Query<Set<Object>> createDimensionValuesQuery(RacingEventService dataSource, final Collection<FunctionDTO> dimensionDTOs, final FunctionProvider functionProvider) {
return new ProcessorQuery<Set<Object>, RacingEventService>(DataMiningActivator.getExecutor(), dataSource) {
@Override
protected Processor<RacingEventService> createFirstProcessor() {
Processor<GroupedDataEntry<Object>> valueCollector = ProcessorFactory.createGroupedDataCollectingAsSetProcessor(/*query*/ this);
Collection<Function<?>> dimensions = convertDTOsToFunctions(dimensionDTOs, functionProvider);
Map<SailingDataRetrievalLevels, Collection<Function<?>>> dimensionsMappedByRetrievalLevel = mapFunctionsByRetrievalLevel(dimensions);
SailingDataRetrievalLevels deepestRetrievalLevel = getDeepestRetrievalLevel(dimensionsMappedByRetrievalLevel.keySet());
Processor<?> retrievalProcessor = null;
for (int i = deepestRetrievalLevel.ordinal(); i >= 0; i--) {
SailingDataRetrievalLevels retrievalLevel = SailingDataRetrievalLevels.values()[i];
Collection<Function<?>> dimensionsForRetrievalLevel = dimensionsMappedByRetrievalLevel.containsKey(retrievalLevel) ? dimensionsMappedByRetrievalLevel.get(retrievalLevel) : new ArrayList<Function<?>>();
Collection<Processor<?>> retrievalResultReceivers = ProcessorFactory.createGroupingExtractorsForDimensions(valueCollector, dimensionsForRetrievalLevel);
if (retrievalProcessor != null) {
retrievalResultReceivers.add(retrievalProcessor);
}
retrievalProcessor = SailingDataRetrieverFactory.createRetrievalProcessorWithoutFilter(retrievalLevel, retrievalResultReceivers);
}
// A retrieval processor created this way results always in a Processor<RacingEventService>
return (Processor<RacingEventService>) retrievalProcessor;
}
};
}
private static List<Function<?>> convertDTOsToFunctions(Collection<FunctionDTO> functionDTOs, FunctionProvider functionProvider) {
List<Function<?>> dimensionsToGroupBy = new ArrayList<>();
for (FunctionDTO functionDTO : functionDTOs) {
dimensionsToGroupBy.add(functionProvider.getFunctionForDTO(functionDTO));
}
return dimensionsToGroupBy;
}
private static Map<SailingDataRetrievalLevels, Collection<Function<?>>> mapFunctionsByRetrievalLevel(Collection<Function<?>> functions) {
Map<SailingDataRetrievalLevels, Collection<Function<?>>> mappedFunctions = new HashMap<>();
for (Function<?> function : functions) {
SailingDataRetrievalLevels retrievalLevel = calculateDataRetrievalLevel(function);
if (!mappedFunctions.containsKey(retrievalLevel)) {
mappedFunctions.put(retrievalLevel, new HashSet<Function<?>>());
}
mappedFunctions.get(retrievalLevel).add(function);
}
return mappedFunctions;
}
private static SailingDataRetrievalLevels calculateDataRetrievalLevel(Function<?> function) {
if (function.getDeclaringType().equals(HasTrackedRaceContext.class)) {
return SailingDataRetrievalLevels.TrackedRace;
}
if (function.getDeclaringType().equals(HasTrackedLegContext.class)) {
return SailingDataRetrievalLevels.TrackedLeg;
}
if (function.getDeclaringType().equals(HasTrackedLegOfCompetitorContext.class)) {
return SailingDataRetrievalLevels.TrackedLegOfCompetitor;
}
if (function.getDeclaringType().equals(HasGPSFixContext.class)) {
return SailingDataRetrievalLevels.GPSFix;
}
return SailingDataRetrievalLevels.GPSFix;
}
private static SailingDataRetrievalLevels getDeepestRetrievalLevel(Collection<SailingDataRetrievalLevels> retrievalLevels) {
return Collections.max(retrievalLevels);
}
}
@@ -0,0 +1,7 @@
package com.sap.sailing.datamining.factories;
public enum SailingDataRetrievalLevels {
LeaderboardGroup, RegattaLeaderboard, TrackedRace, TrackedLeg, TrackedLegOfCompetitor, GPSFix
}
@@ -0,0 +1,141 @@
package com.sap.sailing.datamining.factories;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.RegattaLeaderboardFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorFilteringRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedRaceFilteringRetrievalProcessor;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sailing.server.RacingEventService;
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.FunctionProvider;
import com.sap.sse.datamining.impl.DataMiningActivator;
import com.sap.sse.datamining.impl.criterias.AndCompoundFilterCriterion;
import com.sap.sse.datamining.impl.criterias.CompoundFilterCriterion;
import com.sap.sse.datamining.impl.criterias.NonFilteringFilterCriterion;
import com.sap.sse.datamining.impl.criterias.NullaryFunctionValuesFilterCriterion;
import com.sap.sse.datamining.shared.dto.FunctionDTO;
public final class SailingDataRetrieverFactory {
private SailingDataRetrieverFactory() {
}
/**
* Creates the processor chain for the data retrieval and returns the first processor of the chain.
* @param groupingProcessor The result receiver after the retrieval
* @param filterSelection The filter functions and values for the filtration
* @param functionProvider
* @return The first processor of the retrieval chain.
*/
@SuppressWarnings("unchecked")
public static <ElementType> Processor<RacingEventService> createRetrievalProcessorChain(SailingDataRetrievalLevels dataRetrievalLevel, Processor<ElementType> groupingProcessor, Map<FunctionDTO, Iterable<? extends Serializable>> filterSelection, FunctionProvider functionProvider) {
Processor<?> resultReceiver = groupingProcessor;
for (int i = dataRetrievalLevel.ordinal(); i >= 0; i--) {
resultReceiver = createDataRetrieverFor(SailingDataRetrievalLevels.values()[i], resultReceiver, filterSelection, functionProvider);
}
return (Processor<RacingEventService>) resultReceiver;
}
@SuppressWarnings("unchecked")
/* The way this method is used should guarantee, that the result receiver matches the new processor
*/
private static Processor<?> createDataRetrieverFor(SailingDataRetrievalLevels dataRetrievalLevel,
Processor<?> resultReceiver, Map<FunctionDTO, Iterable<? extends Serializable>> filterSelection, FunctionProvider functionProvider) {
ThreadPoolExecutor executor = DataMiningActivator.getExecutor();
switch (dataRetrievalLevel) {
case GPSFix:
Processor<HasGPSFixContext> gpsFixSpecificResultReceiver = (Processor<HasGPSFixContext>) resultReceiver;
return new GPSFixRetrievalProcessor(executor, Arrays.asList(gpsFixSpecificResultReceiver));
case LeaderboardGroup:
Processor<LeaderboardGroup> leaderboardGroupSpecificResultReceiver = (Processor<LeaderboardGroup>) resultReceiver;
return new LeaderboardGroupRetrievalProcessor(executor, Arrays.asList(leaderboardGroupSpecificResultReceiver));
case RegattaLeaderboard:
Processor<RegattaLeaderboard> regattaLeaderboardSpecificResultReceiver = (Processor<RegattaLeaderboard>) resultReceiver;
return new RegattaLeaderboardFilteringRetrievalProcessor(executor, Arrays.asList(regattaLeaderboardSpecificResultReceiver), getFilterCriteriaForBaseDataType(RegattaLeaderboard.class, filterSelection, functionProvider));
case TrackedLeg:
Processor<HasTrackedLegContext> trackedLegSpecificResultReceiver = (Processor<HasTrackedLegContext>) resultReceiver;
return new TrackedLegFilteringRetrievalProcessor(executor, Arrays.asList(trackedLegSpecificResultReceiver), getFilterCriteriaForBaseDataType(HasTrackedLegContext.class, filterSelection, functionProvider));
case TrackedLegOfCompetitor:
Processor<HasTrackedLegOfCompetitorContext> trackedLegOfCompetitorSpecificResultReceiver = (Processor<HasTrackedLegOfCompetitorContext>) resultReceiver;
return new TrackedLegOfCompetitorFilteringRetrievalProcessor(executor, Arrays.asList(trackedLegOfCompetitorSpecificResultReceiver), getFilterCriteriaForBaseDataType(HasTrackedLegOfCompetitorContext.class, filterSelection, functionProvider));
case TrackedRace:
Processor<HasTrackedRaceContext> trackedRaceSpecificResultReceiver = (Processor<HasTrackedRaceContext>) resultReceiver;
return new TrackedRaceFilteringRetrievalProcessor(executor, Arrays.asList(trackedRaceSpecificResultReceiver), getFilterCriteriaForBaseDataType(HasTrackedRaceContext.class, filterSelection, functionProvider));
}
throw new IllegalArgumentException("No data retriever implemented for the given data retrieval level '"
+ dataRetrievalLevel + "'");
}
private static <BaseDataType> FilterCriterion<BaseDataType> getFilterCriteriaForBaseDataType(Class<BaseDataType> baseDataType,
Map<FunctionDTO, Iterable<? extends Serializable>> filterSelection, FunctionProvider functionProvider) {
CompoundFilterCriterion<BaseDataType> criteria = null;
for (Entry<FunctionDTO, Iterable<? extends Serializable>> filterSelectionEntry : filterSelection.entrySet()) {
Function<?> function = functionProvider.getFunctionForDTO(filterSelectionEntry.getKey());
if (baseDataType.equals(function.getDeclaringType())) {
if (criteria == null) {
criteria = new AndCompoundFilterCriterion<>();
}
Collection<Object> filterValues = new ArrayList<>();
for (Object filterValue : filterSelectionEntry.getValue()) {
filterValues.add(filterValue);
}
criteria.addCriteria(new NullaryFunctionValuesFilterCriterion<BaseDataType>(function, filterValues));
}
}
return criteria != null ? criteria : new NonFilteringFilterCriterion<BaseDataType>();
}
/**
* Creates a retrieval processor without filter for the given retrieval level and result receivers.<br>
* The input type of the result receivers has to match the result type of the created retrieval processor for the given retrievel level or a {@link ClassCastException} can be thrown.
* For example, if the retrieval Level is {@link SailingDataRetrievalLevels#TrackedRace} the input must be {@link HasTrackedRaceContext}.
*/
@SuppressWarnings("unchecked")
public static Processor<?> createRetrievalProcessorWithoutFilter(SailingDataRetrievalLevels retrievalLevel,
Collection<Processor<?>> retrievalResultReceivers) throws ClassCastException {
ThreadPoolExecutor executor = DataMiningActivator.getExecutor();
switch (retrievalLevel) {
case GPSFix:
Collection<Processor<HasGPSFixContext>> gpsFixSpecificResultReceivers = (Collection<Processor<HasGPSFixContext>>)(Collection<?>) retrievalResultReceivers;
return new GPSFixRetrievalProcessor(executor, gpsFixSpecificResultReceivers);
case LeaderboardGroup:
Collection<Processor<LeaderboardGroup>> leaderboardGroupSpecificResultReceivers = (Collection<Processor<LeaderboardGroup>>)(Collection<?>) retrievalResultReceivers;
return new LeaderboardGroupRetrievalProcessor(executor, leaderboardGroupSpecificResultReceivers);
case RegattaLeaderboard:
Collection<Processor<RegattaLeaderboard>> regattaLeaderboardSpecificResultReceivers = (Collection<Processor<RegattaLeaderboard>>)(Collection<?>) retrievalResultReceivers;
return new RegattaLeaderboardFilteringRetrievalProcessor(executor, regattaLeaderboardSpecificResultReceivers, new NonFilteringFilterCriterion<RegattaLeaderboard>());
case TrackedLeg:
Collection<Processor<HasTrackedLegContext>> trackedLegSpecificResultReceivers = (Collection<Processor<HasTrackedLegContext>>)(Collection<?>) retrievalResultReceivers;
return new TrackedLegFilteringRetrievalProcessor(executor, trackedLegSpecificResultReceivers, new NonFilteringFilterCriterion<HasTrackedLegContext>());
case TrackedLegOfCompetitor:
Collection<Processor<HasTrackedLegOfCompetitorContext>> trackedLegOfCompetitorSpecificResultReceivers = (Collection<Processor<HasTrackedLegOfCompetitorContext>>)(Collection<?>) retrievalResultReceivers;
return new TrackedLegOfCompetitorFilteringRetrievalProcessor(executor, trackedLegOfCompetitorSpecificResultReceivers, new NonFilteringFilterCriterion<HasTrackedLegOfCompetitorContext>());
case TrackedRace:
Collection<Processor<HasTrackedRaceContext>> trackedRaceSpecificResultReceivers = (Collection<Processor<HasTrackedRaceContext>>)(Collection<?>) retrievalResultReceivers;
return new TrackedRaceFilteringRetrievalProcessor(executor, trackedRaceSpecificResultReceivers, new NonFilteringFilterCriterion<HasTrackedRaceContext>());
}
throw new IllegalArgumentException("No data retriever implemented for the given data retrieval level '"
+ retrievalLevel + "'");
}
}
@@ -1,36 +0,0 @@
package com.sap.sailing.datamining.impl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import com.sap.sailing.datamining.impl.data.DataMiningClassesWithFunctionsService;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
public class Activator implements BundleActivator {
private static BundleContext context;
private ServiceRegistration<ClassesWithFunctionsService> classesWithFunctionsServiceReference;
@Override
public void start(BundleContext context) throws Exception {
Activator.context = context;
registerClassesWithFunctionsService();
}
@Override
public void stop(BundleContext context) throws Exception {
unregisterClassesWithFunctionsService();
}
private void unregisterClassesWithFunctionsService() {
context.ungetService(classesWithFunctionsServiceReference.getReference());
}
private void registerClassesWithFunctionsService() {
classesWithFunctionsServiceReference = context.registerService(ClassesWithFunctionsService.class,
new DataMiningClassesWithFunctionsService(), null);
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.datamining.impl;
import com.sap.sailing.datamining.WindStrengthCluster;
import com.sap.sse.datamining.impl.data.deprecated.ClusterOfComparableImpl;
public class WindStrengthClusterImpl extends ClusterOfComparableImpl<Double> implements WindStrengthCluster {
public WindStrengthClusterImpl(String name, Double lowerRangeInBeaufort, Double upperRangeInBeaufort) {
super(name, upperRangeInBeaufort, lowerRangeInBeaufort);
}
}
@@ -1,82 +0,0 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.HasTrackedLegContextImpl;
import com.sap.sailing.datamining.impl.data.HasTrackedLegOfCompetitorContextImpl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Leg;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.Util;
import com.sap.sse.datamining.impl.workers.retrievers.AbstractRetrievalWorker;
import com.sap.sse.datamining.workers.DataRetrievalWorker;
public abstract class AbstractLeaderboardGroupDataRetrievalWorker<DataType>
extends AbstractRetrievalWorker<Collection<DataType>>
implements DataRetrievalWorker<LeaderboardGroup, DataType> {
private LeaderboardGroup group;
@Override
public void setSource(LeaderboardGroup source) {
this.group = source;
}
protected LeaderboardGroup getGroup() {
return group;
}
private static Collection<Util.Pair<TrackedLeg, HasTrackedLegContext>> retrieveDataTillTrackedLeg(LeaderboardGroup group) {
Collection<Util.Pair<TrackedLeg, HasTrackedLegContext>> data = new ArrayList<Util.Pair<TrackedLeg, HasTrackedLegContext>>();
for (Leaderboard leaderboard : group.getLeaderboards()) {
CourseArea courseArea = leaderboard.getDefaultCourseArea();
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
for (Fleet fleet : raceColumn.getFleets()) {
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
if (trackedRace != null) {
int legNumber = 1;
for (Leg leg : trackedRace.getRace().getCourse().getLegs()) {
TrackedLeg trackedLeg = trackedRace.getTrackedLeg(leg);
if (trackedLeg != null) {
HasTrackedLegContext dataContext = new HasTrackedLegContextImpl(group, leaderboard,
courseArea, fleet, trackedRace, trackedLeg, legNumber);
data.add(new Util.Pair<TrackedLeg, HasTrackedLegContext>(trackedLeg, dataContext));
legNumber++;
}
}
}
}
}
}
return data;
}
protected static Collection<Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext>> retrieveDataTillTrackedLegOfCompetitor(
LeaderboardGroup group) {
Collection<Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext>> data = new ArrayList<Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext>>();
Collection<Util.Pair<TrackedLeg, HasTrackedLegContext>> baseData = retrieveDataTillTrackedLeg(group);
for (Util.Pair<TrackedLeg, HasTrackedLegContext> baseDataEntry : baseData) {
TrackedLeg trackedLeg = baseDataEntry.getA();
HasTrackedLegContext trackedLegContext = baseDataEntry.getB();
for (Competitor competitor : trackedLegContext.getTrackedRace().getRace().getCompetitors()) {
TrackedLegOfCompetitor trackedLegOfCompetitor = trackedLeg.getTrackedLeg(competitor);
HasTrackedLegOfCompetitorContext dataContext = new HasTrackedLegOfCompetitorContextImpl(trackedLegContext,
competitor);
data.add(new Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext>(trackedLegOfCompetitor,
dataContext));
}
}
return data;
}
}
@@ -0,0 +1,47 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.GPSFixWithContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
import com.sap.sse.datamining.shared.annotations.DataRetriever;
@DataRetriever(dataType=HasGPSFixContext.class,
groupName=Activator.dataRetrieverGroupName,
level=5)
public class GPSFixRetrievalProcessor extends AbstractSimpleRetrievalProcessor<HasTrackedLegOfCompetitorContext, HasGPSFixContext> {
public GPSFixRetrievalProcessor(ExecutorService executor, Collection<Processor<HasGPSFixContext>> resultReceivers) {
super(executor, resultReceivers);
}
@Override
protected Iterable<HasGPSFixContext> retrieveData(HasTrackedLegOfCompetitorContext element) {
Collection<HasGPSFixContext> gpsFixesWithContext = new ArrayList<>();
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = element.getTrackedRace().getTrack(element.getCompetitor());
competitorTrack.lockForRead();
try {
TrackedLegOfCompetitor trackedLegOfCompetitor = element.getTrackedLegOfCompetitor();
if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) {
for (GPSFixMoving gpsFix : competitorTrack.getFixes(trackedLegOfCompetitor.getStartTime(), true, trackedLegOfCompetitor.getFinishTime(), true)) {
HasGPSFixContext gpsFixWithContext = new GPSFixWithContext(element, gpsFix);
gpsFixesWithContext.add(gpsFixWithContext);
}
}
} finally {
competitorTrack.unlockAfterRead();
}
return gpsFixesWithContext;
}
}
@@ -1,54 +0,0 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.components.ParallelDataRetriever;
import com.sap.sse.datamining.impl.components.deprecated.AbstractParallelComponent;
import com.sap.sse.datamining.workers.DataRetrievalWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
/**
* Retrieves elements of type <code>DataType</code> from all {@link LeaderboardGroup}s known to the
* {@link RacingEventSErvice} passed to this object's constructor. See also
* {@link RacingEventService#getLeaderboardGroups()}.
*
* @param <DataType>
*/
public class GroupDividingParallelDataRetriever<DataType> extends AbstractParallelComponent<Void, Collection<DataType>>
implements ParallelDataRetriever<DataType> {
private RacingEventService racingService;
private WorkerBuilder<DataRetrievalWorker<LeaderboardGroup, DataType>> workerBuilder;
public GroupDividingParallelDataRetriever(RacingEventService racingService, WorkerBuilder<DataRetrievalWorker<LeaderboardGroup, DataType>> workerBuilder, ThreadPoolExecutor executor) {
super(executor);
this.racingService = racingService;
this.workerBuilder = workerBuilder;
}
@Override
protected void setUpWorkersFor(Void v) {
for (LeaderboardGroup group : racingService.getLeaderboardGroups().values()) {
DataRetrievalWorker<LeaderboardGroup, DataType> worker = workerBuilder.build();
worker.setReceiver(this);
worker.setSource(group);
addWorker(worker);
}
}
@Override
protected Collection<DataType> finalizeData() {
Collection<DataType> data = new ArrayList<DataType>();
for (Collection<DataType> results : getResults()) {
data.addAll(results);
}
return Collections.unmodifiableCollection(new CopyOnWriteArrayList<DataType>(data));
}
}
@@ -1,25 +0,0 @@
package com.sap.sailing.datamining.impl.components;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.components.FilterCriteria;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractFilteringRetrievalProcessor;
public class LeaderboardGroupFilteringRetrievalProcessor extends
AbstractFilteringRetrievalProcessor<RacingEventService, LeaderboardGroup> {
public LeaderboardGroupFilteringRetrievalProcessor(ExecutorService executor,
Collection<Processor<LeaderboardGroup>> resultReceivers, FilterCriteria<LeaderboardGroup> criteria) {
super(executor, resultReceivers, criteria);
}
@Override
protected Iterable<LeaderboardGroup> retrieveData(RacingEventService element) {
return element.getLeaderboardGroups().values();
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.impl.components;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.server.RacingEventService;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleRetrievalProcessor;
import com.sap.sse.datamining.shared.annotations.DataRetriever;
@DataRetriever(dataType=LeaderboardGroup.class,
groupName=Activator.dataRetrieverGroupName,
level=0)
public class LeaderboardGroupRetrievalProcessor extends
AbstractSimpleRetrievalProcessor<RacingEventService, LeaderboardGroup> {
public LeaderboardGroupRetrievalProcessor(ExecutorService executor,
Collection<Processor<LeaderboardGroup>> resultReceivers) {
super(executor, resultReceivers);
}
@Override
protected Iterable<LeaderboardGroup> retrieveData(RacingEventService element) {
return element.getLeaderboardGroups().values();
}
}
@@ -0,0 +1,38 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.leaderboard.RegattaLeaderboard;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleFilteringRetrievalProcessor;
import com.sap.sse.datamining.shared.annotations.DataRetriever;
@DataRetriever(dataType=RegattaLeaderboard.class,
groupName=Activator.dataRetrieverGroupName,
level=1)
public class RegattaLeaderboardFilteringRetrievalProcessor extends
AbstractSimpleFilteringRetrievalProcessor<LeaderboardGroup, RegattaLeaderboard> {
public RegattaLeaderboardFilteringRetrievalProcessor(ExecutorService executor,
Collection<Processor<RegattaLeaderboard>> resultReceivers, FilterCriterion<RegattaLeaderboard> criteria) {
super(executor, resultReceivers, criteria);
}
@Override
protected Iterable<RegattaLeaderboard> retrieveData(LeaderboardGroup element) {
Collection<RegattaLeaderboard> regattaLeaderboards = new ArrayList<>();
for (Leaderboard leaderboard : element.getLeaderboards()) {
if (leaderboard instanceof RegattaLeaderboard) {
regattaLeaderboards.add((RegattaLeaderboard) leaderboard);
}
}
return regattaLeaderboards;
}
}
@@ -0,0 +1,40 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.impl.data.TrackedLegWithContext;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleFilteringRetrievalProcessor;
import com.sap.sse.datamining.shared.annotations.DataRetriever;
@DataRetriever(dataType=HasTrackedLegContext.class,
groupName=Activator.dataRetrieverGroupName,
level=3)
public class TrackedLegFilteringRetrievalProcessor extends
AbstractSimpleFilteringRetrievalProcessor<HasTrackedRaceContext, HasTrackedLegContext> {
public TrackedLegFilteringRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasTrackedLegContext>> resultReceivers, FilterCriterion<HasTrackedLegContext> criteria) {
super(executor, resultReceivers, criteria);
}
@Override
protected Iterable<HasTrackedLegContext> retrieveData(HasTrackedRaceContext element) {
Collection<HasTrackedLegContext> trackedLegsWithContext = new ArrayList<>();
int legNumber = 1;
for (TrackedLeg trackedLeg : element.getTrackedRace().getTrackedLegs()) {
HasTrackedLegContext trackedLegWithContext = new TrackedLegWithContext(element, trackedLeg, legNumber);
trackedLegsWithContext.add(trackedLegWithContext);
legNumber++;
}
return trackedLegsWithContext;
}
}
@@ -0,0 +1,39 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleFilteringRetrievalProcessor;
import com.sap.sse.datamining.shared.annotations.DataRetriever;
@DataRetriever(dataType=HasTrackedLegOfCompetitorContext.class,
groupName=Activator.dataRetrieverGroupName,
level=4)
public class TrackedLegOfCompetitorFilteringRetrievalProcessor extends
AbstractSimpleFilteringRetrievalProcessor<HasTrackedLegContext, HasTrackedLegOfCompetitorContext> {
public TrackedLegOfCompetitorFilteringRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasTrackedLegOfCompetitorContext>> resultReceivers,
FilterCriterion<HasTrackedLegOfCompetitorContext> criteria) {
super(executor, resultReceivers, criteria);
}
@Override
protected Iterable<HasTrackedLegOfCompetitorContext> retrieveData(HasTrackedLegContext element) {
Collection<HasTrackedLegOfCompetitorContext> trackedLegOfCompetitorsWithContext = new ArrayList<>();
for (Competitor competitor : element.getRace().getCompetitors()) {
HasTrackedLegOfCompetitorContext trackedLegOfCompetitorWithContext = new TrackedLegOfCompetitorWithContext(element, element.getTrackedLeg().getTrackedLeg(competitor));
trackedLegOfCompetitorsWithContext.add(trackedLegOfCompetitorWithContext);
}
return trackedLegOfCompetitorsWithContext;
}
}
@@ -0,0 +1,46 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.impl.data.TrackedRaceWithContext;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.datamining.components.FilterCriterion;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractSimpleFilteringRetrievalProcessor;
import com.sap.sse.datamining.shared.annotations.DataRetriever;
@DataRetriever(dataType=HasTrackedRaceContext.class,
groupName="Sailing",
level=2)
public class TrackedRaceFilteringRetrievalProcessor extends
AbstractSimpleFilteringRetrievalProcessor<Leaderboard, HasTrackedRaceContext> {
public TrackedRaceFilteringRetrievalProcessor(ExecutorService executor,
Collection<Processor<HasTrackedRaceContext>> resultReceivers, FilterCriterion<HasTrackedRaceContext> criteria) {
super(executor, resultReceivers, criteria);
}
@Override
protected Iterable<HasTrackedRaceContext> retrieveData(Leaderboard element) {
Collection<HasTrackedRaceContext> trackedRacesWithContext = new ArrayList<>();
for (RaceColumn raceColumn : element.getRaceColumns()) {
for (Fleet fleet : raceColumn.getFleets()) {
TrackedRace trackedRace = raceColumn.getTrackedRace(fleet);
if (trackedRace != null) {
Regatta regatta = trackedRace.getTrackedRegatta().getRegatta();
HasTrackedRaceContext trackedRaceWithContext = new TrackedRaceWithContext(regatta, fleet, trackedRace);
trackedRacesWithContext.add(trackedRaceWithContext);
}
}
}
return trackedRacesWithContext;
}
}
@@ -1,35 +0,0 @@
package com.sap.sailing.datamining.impl.data;
import java.util.Collection;
import java.util.HashSet;
import com.sap.sailing.datamining.data.GPSFixWithContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sse.datamining.functions.ClassesWithFunctionsService;
public class DataMiningClassesWithFunctionsService implements ClassesWithFunctionsService {
@Override
public boolean hasInternalClassesWithMarkedMethods() {
return true;
}
@Override
public Collection<Class<?>> getInternalClassesWithMarkedMethods() {
Collection<Class<?>> internalClasses = new HashSet<>();
internalClasses.add(GPSFixWithContext.class);
internalClasses.add(TrackedLegOfCompetitorWithContext.class);
return internalClasses;
}
@Override
public boolean hasExternalLibraryClasses() {
return false;
}
@Override
public Collection<Class<?>> getExternalLibraryClasses() {
return new HashSet<>();
}
}
@@ -0,0 +1,32 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
public class GPSFixWithContext extends TrackedLegOfCompetitorWithContext implements HasGPSFixContext {
private final GPSFixMoving gpsFix;
public GPSFixWithContext(HasTrackedLegOfCompetitorContext legContext, GPSFixMoving gpsFix) {
this(legContext.getRegatta(), legContext.getFleet(), legContext.getTrackedRace(),
legContext.getTrackedLeg(), legContext.getLegNumber(), legContext.getTrackedLegOfCompetitor(), gpsFix);
}
public GPSFixWithContext(Regatta regatta, Fleet fleet, TrackedRace trackedRace,
TrackedLeg trackedLeg, int legNumber, TrackedLegOfCompetitor trackedLegOfCompetitor, GPSFixMoving gpsFix) {
super(regatta, fleet, trackedRace, trackedLeg, legNumber, trackedLegOfCompetitor);
this.gpsFix = gpsFix;
}
@Override
public GPSFixMoving getGPSFix() {
return gpsFix;
}
}
@@ -1,26 +0,0 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedRace;
public class HasGPSFixContextImpl extends HasTrackedLegOfCompetitorContextImpl implements HasGPSFixContext {
public HasGPSFixContextImpl(LeaderboardGroup leaderboardGroup, Leaderboard leaderboard, CourseArea courseArea,
Fleet fleet, TrackedRace trackedRace, TrackedLeg trackedLeg, int legNumber, Competitor competitor) {
super(leaderboardGroup, leaderboard, courseArea, fleet, trackedRace, trackedLeg, legNumber, competitor);
}
public HasGPSFixContextImpl(HasTrackedLegOfCompetitorContext baseContext) {
this(baseContext.getLeaderboardGroup(), baseContext.getLeaderboard(), baseContext.getCourseArea(), baseContext.getFleet(),
baseContext.getTrackedRace(), baseContext.getTrackedLeg(), baseContext.getLegNumber(),
baseContext.getCompetitor());
}
}
@@ -1,21 +0,0 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasLeaderboardContext;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
public class HasLeaderboardContextImpl extends HasLeaderboardGroupContextImpl implements HasLeaderboardContext {
private final Leaderboard leaderboard;
public HasLeaderboardContextImpl(LeaderboardGroup leaderboardGroup, Leaderboard leaderboard) {
super(leaderboardGroup);
this.leaderboard = leaderboard;
}
@Override
public Leaderboard getLeaderboard() {
return leaderboard;
}
}
@@ -1,19 +0,0 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
public class HasLeaderboardGroupContextImpl implements HasLeaderboardGroupContext {
private final LeaderboardGroup leaderboardGroup;
public HasLeaderboardGroupContextImpl(LeaderboardGroup leaderboardGroup) {
this.leaderboardGroup = leaderboardGroup;
}
@Override
public LeaderboardGroup getLeaderboardGroup() {
return leaderboardGroup;
}
}
@@ -1,34 +0,0 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedRace;
public class HasTrackedLegOfCompetitorContextImpl extends HasTrackedLegContextImpl implements HasTrackedLegOfCompetitorContext {
private final Competitor competitor;
public HasTrackedLegOfCompetitorContextImpl(LeaderboardGroup leaderboardGroup, Leaderboard leaderboard,
CourseArea courseArea, Fleet fleet, TrackedRace trackedRace, TrackedLeg trackedLeg, int legNumber, Competitor competitor) {
super(leaderboardGroup, leaderboard, courseArea, fleet, trackedRace, trackedLeg, legNumber);
this.competitor = competitor;
}
public HasTrackedLegOfCompetitorContextImpl(HasTrackedLegContext trackedLegContext, Competitor competitor) {
this(trackedLegContext.getLeaderboardGroup(), trackedLegContext.getLeaderboard(), trackedLegContext.getCourseArea(),
trackedLegContext.getFleet(), trackedLegContext.getTrackedRace(), trackedLegContext.getTrackedLeg(), trackedLegContext.getLegNumber(),
competitor);
}
@Override
public Competitor getCompetitor() {
return competitor;
}
}
@@ -1,69 +0,0 @@
package com.sap.sailing.datamining.impl.data;
import java.util.Calendar;
import com.sap.sailing.datamining.data.HasLeaderboardContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.tracking.TrackedRace;
public class HasTrackedRaceContextImpl extends HasLeaderboardContextImpl implements HasTrackedRaceContext {
private final CourseArea courseArea;
private final Fleet fleet;
private final TrackedRace trackedRace;
private Integer year;
private boolean yearHasBeenInitialized;
public HasTrackedRaceContextImpl(HasLeaderboardContext leaderboardContext, CourseArea courseArea, Fleet fleet,
TrackedRace trackedRace) {
this(leaderboardContext.getLeaderboardGroup(), leaderboardContext.getLeaderboard(), courseArea, fleet, trackedRace);
}
public HasTrackedRaceContextImpl(LeaderboardGroup leaderboardGroup, Leaderboard leaderboard, CourseArea courseArea,
Fleet fleet, TrackedRace trackedRace) {
super(leaderboardGroup, leaderboard);
this.courseArea = courseArea;
this.fleet = fleet;
this.trackedRace = trackedRace;
}
@Override
public CourseArea getCourseArea() {
return courseArea;
}
@Override
public Fleet getFleet() {
return fleet;
}
@Override
public TrackedRace getTrackedRace() {
return trackedRace;
}
@Override
public Integer getYear() {
if (!yearHasBeenInitialized) {
initializeYear();
}
return year;
}
private void initializeYear() {
TimePoint time = getTrackedRace().getStartOfRace() != null ? getTrackedRace().getStartOfRace() : getTrackedRace().getStartOfTracking();
if (time == null) {
year = 0;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(time.asDate());
year = calendar.get(Calendar.YEAR);
yearHasBeenInitialized = true;
}
}
@@ -0,0 +1,30 @@
package com.sap.sailing.datamining.impl.data;
import java.util.HashSet;
import java.util.Set;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sse.datamining.ClassesWithFunctionsService;
public class SailingDataMiningClassesWithFunctionsService implements ClassesWithFunctionsService {
@Override
public Set<Class<?>> getInternalClassesWithMarkedMethods() {
Set<Class<?>> internalClasses = new HashSet<>();
/*
* This also contains the marked methods of
* HasTrackedRaceContext,
* HasTrackedLegContext and
* HasTrackedLegOfCompetitorContext,
* because these are the super types of HasGPSFixContext.
*/
internalClasses.add(HasGPSFixContext.class);
return internalClasses;
}
@Override
public Set<Class<?>> getExternalLibraryClasses() {
return new HashSet<>();
}
}
@@ -0,0 +1,47 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
public class TrackedLegOfCompetitorWithContext extends TrackedLegWithContext implements HasTrackedLegOfCompetitorContext {
private final TrackedLegOfCompetitor trackedLegOfCompetitor;
private final Competitor competitor;
public TrackedLegOfCompetitorWithContext(HasTrackedLegContext trackedLegContext, TrackedLegOfCompetitor trackedLegOfCompetitor) {
this(trackedLegContext.getRegatta(), trackedLegContext.getFleet(),
trackedLegContext.getTrackedRace(), trackedLegContext.getTrackedLeg(),
trackedLegContext.getLegNumber(), trackedLegOfCompetitor);
}
public TrackedLegOfCompetitorWithContext(Regatta regatta, Fleet fleet, TrackedRace trackedRace,
TrackedLeg trackedLeg, int legNumber, TrackedLegOfCompetitor trackedLegOfCompetitor) {
super(regatta, fleet, trackedRace, trackedLeg, legNumber);
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
this.competitor = trackedLegOfCompetitor.getCompetitor();
}
@Override
public TrackedLegOfCompetitor getTrackedLegOfCompetitor() {
return trackedLegOfCompetitor;
}
@Override
public Competitor getCompetitor() {
return competitor;
}
@Override
public Double getDistanceTraveled() {
TimePoint timePoint = getTrackedRace().getEndOfTracking();
return getTrackedLegOfCompetitor().getDistanceTraveled(timePoint).getMeters();
}
}
@@ -2,34 +2,30 @@ package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
public class HasTrackedLegContextImpl extends HasTrackedRaceContextImpl implements HasTrackedLegContext {
public class TrackedLegWithContext extends TrackedRaceWithContext implements HasTrackedLegContext {
private final TrackedLeg trackedLeg;
private final int legNumber;
private LegType legType;
private boolean legTypeHasBeenInitialized;
public HasTrackedLegContextImpl(HasTrackedRaceContext trackedRaceContext, TrackedLeg trackedLeg, int legNumber) {
this(trackedRaceContext.getLeaderboardGroup(), trackedRaceContext.getLeaderboard(), trackedRaceContext
.getCourseArea(), trackedRaceContext.getFleet(), trackedRaceContext.getTrackedRace(), trackedLeg,
legNumber);
public TrackedLegWithContext(HasTrackedRaceContext trackedRaceContext, TrackedLeg trackedLeg, int legNumber) {
this(trackedRaceContext.getRegatta(), trackedRaceContext.getFleet(),
trackedRaceContext.getTrackedRace(), trackedLeg, legNumber);
}
public HasTrackedLegContextImpl(LeaderboardGroup leaderboardGroup, Leaderboard leaderboard, CourseArea courseArea, Fleet fleet,
TrackedRace trackedRace, TrackedLeg trackedLeg, int legNumber) {
super(leaderboardGroup, leaderboard, courseArea, fleet, trackedRace);
public TrackedLegWithContext(Regatta regatta, Fleet fleet, TrackedRace trackedRace, TrackedLeg trackedLeg, int legNumber) {
super(regatta, fleet, trackedRace);
this.trackedLeg = trackedLeg;
this.legNumber = legNumber;
}
@@ -0,0 +1,78 @@
package com.sap.sailing.datamining.impl.data;
import java.util.Calendar;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.domain.base.BoatClass;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.TrackedRace;
public class TrackedRaceWithContext implements HasTrackedRaceContext {
private final Regatta regatta;
private final Fleet fleet;
private final TrackedRace trackedRace;
private Integer year;
private boolean yearHasBeenInitialized;
public TrackedRaceWithContext(Regatta regatta, Fleet fleet, TrackedRace trackedRace) {
this.regatta = regatta;
this.fleet = fleet;
this.trackedRace = trackedRace;
}
@Override
public Regatta getRegatta() {
return regatta;
}
@Override
public CourseArea getCourseArea() {
return getRegatta().getDefaultCourseArea();
}
@Override
public BoatClass getBoatClass() {
return getRegatta().getBoatClass();
}
@Override
public TrackedRace getTrackedRace() {
return trackedRace;
}
@Override
public Fleet getFleet() {
return fleet;
}
@Override
public RaceDefinition getRace() {
return getTrackedRace().getRace();
}
@Override
public Integer getYear() {
if (!yearHasBeenInitialized) {
year = calculateYear();
yearHasBeenInitialized = true;
}
return year;
}
private Integer calculateYear() {
TimePoint startOfRace = getTrackedRace().getStartOfRace();
TimePoint time = startOfRace != null ? startOfRace : getTrackedRace().getStartOfTracking();
if (time == null) {
year = 0;
}
Calendar calendar = Calendar.getInstance();
calendar.setTime(time.asDate());
return calendar.get(Calendar.YEAR);
}
}
@@ -1,48 +0,0 @@
package com.sap.sailing.datamining.impl.gps_fix;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import com.sap.sailing.datamining.data.GPSFixWithContext;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.impl.components.AbstractLeaderboardGroupDataRetrievalWorker;
import com.sap.sailing.datamining.impl.data.HasGPSFixContextImpl;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.GPSFixTrack;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.common.Util;
public class GPSFixLeaderboardGroupDataRetrievalWorker extends AbstractLeaderboardGroupDataRetrievalWorker<GPSFixWithContext> {
@Override
public Collection<GPSFixWithContext> doWork() {
Collection<GPSFixWithContext> data = new ArrayList<GPSFixWithContext>();
Collection<Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext>> baseData = retrieveDataTillTrackedLegOfCompetitor(getGroup());
for (Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext> baseDataEntry : baseData) {
HasGPSFixContext context = new HasGPSFixContextImpl(baseDataEntry.getB());
data.addAll(retrieveDataFor(context));
}
return data;
}
private Collection<GPSFixWithContext> retrieveDataFor(HasGPSFixContext context) {
List<GPSFixWithContext> data = new ArrayList<GPSFixWithContext>();
TrackedLegOfCompetitor trackedLegOfCompetitor = context.getTrackedLeg().getTrackedLeg(context.getCompetitor());
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = context.getTrackedRace().getTrack(context.getCompetitor());
competitorTrack.lockForRead();
try {
if (trackedLegOfCompetitor.getStartTime() != null && trackedLegOfCompetitor.getFinishTime() != null) {
for (GPSFixMoving gpsFix : competitorTrack.getFixes(trackedLegOfCompetitor.getStartTime(), true, trackedLegOfCompetitor.getFinishTime(), true)) {
data.add(new GPSFixWithContextImpl(gpsFix, context));
}
}
} finally {
competitorTrack.unlockAfterRead();
}
return data;
}
}
@@ -1,118 +0,0 @@
package com.sap.sailing.datamining.impl.gps_fix;
import com.sap.sailing.datamining.Clusters.WindStrength;
import com.sap.sailing.datamining.WindStrengthCluster;
import com.sap.sailing.datamining.data.GPSFixWithContext;
import com.sap.sailing.datamining.data.HasGPSFixContext;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.tracking.GPSFixMoving;
import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.impl.GPSFixMovingImpl;
public class GPSFixWithContextImpl extends GPSFixMovingImpl implements GPSFixWithContext {
private static final long serialVersionUID = -5551381302809417831L;
private HasGPSFixContext context;
private Wind wind;
private boolean windHasBeenInitialized;
public GPSFixWithContextImpl(GPSFixMoving gpsFix, HasGPSFixContext context) {
super(copyPosition(gpsFix), copyTimePoint(gpsFix), copySpeed(gpsFix));
this.context = context;
windHasBeenInitialized= false;
}
private static SpeedWithBearing copySpeed(GPSFixMoving gpsFix) {
return new KnotSpeedWithBearingImpl(gpsFix.getSpeed().getKnots(), gpsFix.getSpeed().getBearing());
}
private static TimePoint copyTimePoint(GPSFixMoving gpsFix) {
return new MillisecondsTimePoint(gpsFix.getTimePoint().asMillis());
}
private static Position copyPosition(GPSFixMoving gpsFix) {
return new DegreePosition(gpsFix.getPosition().getLatDeg(), gpsFix.getPosition().getLngDeg());
}
@Override
public String getRegattaName() {
return context.getTrackedRace().getTrackedRegatta().getRegatta().getName();
}
@Override
public String getRaceName() {
return context.getTrackedRace().getRace().getName();
}
@Override
public int getLegNumber() {
return context.getLegNumber();
}
@Override
public String getCourseAreaName() {
return context.getCourseArea().getName();
}
@Override
public String getFleetName() {
return context.getFleet().getName();
}
@Override
public String getBoatClassName() {
return context.getCompetitor().getBoat().getBoatClass().getName();
}
@Override
public Integer getYear() {
return context.getYear();
}
@Override
public LegType getLegType() {
return context.getLegType();
}
@Override
public String getCompetitorName() {
return context.getCompetitor().getName();
}
@Override
public String getCompetitorSailID() {
return context.getCompetitor().getBoat().getSailID();
}
@Override
public String getCompetitorNationality() {
return context.getCompetitor().getTeam().getNationality().getThreeLetterIOCAcronym();
}
@Override
public WindStrengthCluster getWindStrength() {
if (getWind() == null) {
return null;
}
return WindStrength.getClusterFor(getWind().getBeaufort(), WindStrength.StandardClusters);
}
public Wind getWind() {
if (!windHasBeenInitialized) {
wind = context.getTrackedRace().getWind(getPosition(), getTimePoint());
windHasBeenInitialized = true;
}
return wind;
}
}
@@ -1,15 +0,0 @@
package com.sap.sailing.datamining.impl.tracked_leg_of_competitor;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.domain.common.Distance;
import com.sap.sse.datamining.impl.workers.extractors.AbstractExtractionWorker;
public class DistanceTraveledExtractionWorker extends AbstractExtractionWorker<TrackedLegOfCompetitorWithContext, Double> {
@Override
public Double extract(TrackedLegOfCompetitorWithContext dataEntry) {
Distance distanceTraveled = dataEntry.getDistanceTraveled();
return distanceTraveled != null ? distanceTraveled.getMeters() : 0;
}
}
@@ -1,24 +0,0 @@
package com.sap.sailing.datamining.impl.tracked_leg_of_competitor;
import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.datamining.impl.components.AbstractLeaderboardGroupDataRetrievalWorker;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.common.Util;
public class TrackedLegOfCompetitorLeaderboardGroupDataRetrievalWorker extends AbstractLeaderboardGroupDataRetrievalWorker<TrackedLegOfCompetitorWithContext> {
@Override
public Collection<TrackedLegOfCompetitorWithContext> doWork() {
Collection<TrackedLegOfCompetitorWithContext> data = new ArrayList<TrackedLegOfCompetitorWithContext>();
Collection<Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext>> baseData = retrieveDataTillTrackedLegOfCompetitor(getGroup());
for (Util.Pair<TrackedLegOfCompetitor, HasTrackedLegOfCompetitorContext> baseDataEntry : baseData) {
data.add(new TrackedLegOfCompetitorWithContextImpl(baseDataEntry.getA(), baseDataEntry.getB()));
}
return data;
}
}
@@ -1,88 +0,0 @@
package com.sap.sailing.datamining.impl.tracked_leg_of_competitor;
import com.sap.sailing.datamining.WindStrengthCluster;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.domain.common.Distance;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
public class TrackedLegOfCompetitorWithContextImpl implements TrackedLegOfCompetitorWithContext {
private TrackedLegOfCompetitor trackedLegOfCompetitor;
private HasTrackedLegOfCompetitorContext context;
public TrackedLegOfCompetitorWithContextImpl(TrackedLegOfCompetitor trackedLegOfCompetitor, HasTrackedLegOfCompetitorContext context) {
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
this.context = context;
}
@Override
public String getRegattaName() {
return context.getTrackedRace().getTrackedRegatta().getRegatta().getName();
}
@Override
public String getRaceName() {
return context.getTrackedRace().getRace().getName();
}
@Override
public int getLegNumber() {
return context.getLegNumber();
}
@Override
public String getCourseAreaName() {
return context.getCourseArea().getName();
}
@Override
public String getFleetName() {
return context.getFleet().getName();
}
@Override
public String getBoatClassName() {
return context.getCompetitor().getBoat().getBoatClass().getName();
}
@Override
public Integer getYear() {
return context.getYear();
}
@Override
public LegType getLegType() {
return context.getLegType();
}
@Override
public String getCompetitorName() {
return context.getCompetitor().getName();
}
@Override
public String getCompetitorSailID() {
return context.getCompetitor().getBoat().getSailID();
}
@Override
public String getCompetitorNationality() {
return context.getCompetitor().getTeam().getNationality().getThreeLetterIOCAcronym();
}
@Override
public WindStrengthCluster getWindStrength() {
// TODO Auto-generated method stub
return null;
}
@Override
public Distance getDistanceTraveled() {
TimePoint finishTime = trackedLegOfCompetitor.getFinishTime();
return finishTime != null ? trackedLegOfCompetitor.getDistanceTraveled(finishTime) : null;
}
}
@@ -1,13 +0,0 @@
package com.sap.sailing.datamining.impl.workers;
import com.sap.sailing.domain.base.Moving;
import com.sap.sse.datamining.impl.workers.extractors.AbstractExtractionWorker;
public class SpeedInKnotsExtractionWorker extends AbstractExtractionWorker<Moving, Double> {
@Override
public Double extract(Moving dataEntry) {
return dataEntry.getSpeed().getKnots();
}
}
@@ -1,30 +0,0 @@
package com.sap.sailing.datamining.impl.workers.builders;
import com.sap.sailing.datamining.impl.gps_fix.GPSFixLeaderboardGroupDataRetrievalWorker;
import com.sap.sailing.datamining.impl.tracked_leg_of_competitor.TrackedLegOfCompetitorLeaderboardGroupDataRetrievalWorker;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
import com.sap.sse.datamining.workers.DataRetrievalWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public class DataRetrieverWorkerBuilder<DataType> implements WorkerBuilder<DataRetrievalWorker<LeaderboardGroup, DataType>> {
private final DataTypes dataType;
public DataRetrieverWorkerBuilder(DataTypes dataType) {
this.dataType = dataType;
}
@Override
@SuppressWarnings("unchecked")
public DataRetrievalWorker<LeaderboardGroup, DataType> build() {
switch (dataType) {
case GPSFix:
return (DataRetrievalWorker<LeaderboardGroup, DataType>) new GPSFixLeaderboardGroupDataRetrievalWorker();
case TrackedLegOfCompetitor:
return (DataRetrievalWorker<LeaderboardGroup, DataType>) new TrackedLegOfCompetitorLeaderboardGroupDataRetrievalWorker();
}
throw new IllegalArgumentException("Not yet implemented for the given data type: " + dataType.toString());
}
}
@@ -1,30 +0,0 @@
package com.sap.sailing.datamining.impl.workers.builders;
import com.sap.sailing.datamining.impl.tracked_leg_of_competitor.DistanceTraveledExtractionWorker;
import com.sap.sailing.datamining.impl.workers.SpeedInKnotsExtractionWorker;
import com.sap.sailing.datamining.shared.StatisticType;
import com.sap.sse.datamining.workers.ExtractionWorker;
import com.sap.sse.datamining.workers.WorkerBuilder;
public class ExtractionWorkerBuilder<DataType, ExtractedType> implements WorkerBuilder<ExtractionWorker<DataType, ExtractedType>> {
private StatisticType statisticType;
public ExtractionWorkerBuilder(StatisticType statisticType) {
this.statisticType = statisticType;
}
@Override
@SuppressWarnings("unchecked")
public ExtractionWorker<DataType, ExtractedType> build() {
switch (statisticType) {
case Speed:
return (ExtractionWorker<DataType, ExtractedType>) new SpeedInKnotsExtractionWorker();
case Distance:
return (ExtractionWorker<DataType, ExtractedType>) new DistanceTraveledExtractionWorker();
}
throw new IllegalArgumentException("Not yet implemented for the given statistic type: "
+ statisticType.toString());
}
}
@@ -21,4 +21,5 @@ Export-Package: com.sap.sailing.domain.common,
com.sap.sailing.domain.common.scalablevalue,
com.sap.sailing.domain.common.scalablevalue.impl,
com.sap.sailing.domain.common.trackfiles
Require-Bundle: com.sap.sse.common
Require-Bundle: com.sap.sse.datamining.shared,
com.sap.sse.common
@@ -4,60 +4,58 @@ import com.sap.sailing.domain.common.impl.MeterDistance;
public enum BoatClassMasterdata {
_2_4M ("2.4 Meter", true, 4.11, 0.81, BoatHullType.MONOHULL, "2.4M", "2.4mR"),
_5O5 ("5O5", true, 5.03, 1.88, BoatHullType.MONOHULL, "505", "5o5", "505er", "5o5er"),
_12M ("12 Meter", true, 5.97, 1.43, BoatHullType.MONOHULL, "12M", "12mR", "12SQM"),
_29ER ("29er", true, 4.45, 1.70, BoatHullType.MONOHULL),
_29ERXX ("29erXX", true, 4.45, 1.77, BoatHullType.MONOHULL, "29XX"),
_49ER ("49er", true, 4.88, 1.93, BoatHullType.MONOHULL),
_49ERFX ("49erFX", true, 4.88, 1.93, BoatHullType.MONOHULL, "49FX"),
_420 ("420", true, 4.20, 1.65, BoatHullType.MONOHULL, "420er", "420M", "420W"),
_470 ("470", true, 4.70, 1.68, BoatHullType.MONOHULL, "470er", "470M", "470W"),
A_CAT ("A-Catamaran", true, 5.49, 2.30, BoatHullType.CATAMARAN, "A-Cat", "ACat", "A-Class Catamaran"),
ALBIN_EXPRESS ("Albin Express", true, 7.77, 2.50, BoatHullType.MONOHULL),
B_ONE ("B/ONE", true, 7.80, 2.49, BoatHullType.MONOHULL, "B-ONE"),
DRAGON_INT ("Dragon Int.", true, 8.89, 1.96, BoatHullType.MONOHULL, "Drachen", "Dragon"),
EXTREME_40 ("Extreme 40", false, 12.2, 6.60, BoatHullType.CATAMARAN, "Extreme-40", "Extreme40", "ESS40"),
D_35 ("D35", false, 10.81, 6.89, BoatHullType.CATAMARAN),
EUROPE_INT ("Europe Int.", true, 3.35, 1.35, BoatHullType.MONOHULL, "Europe"),
F_18 ("Formula 18", true, 6.85, 2.25, BoatHullType.CATAMARAN, "F18", "F-18"),
FARR_30 ("Farr 30", true, 9.42, 3.08, BoatHullType.MONOHULL, "F30", "F-30", "Farr-30"),
FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL),
FOLKBOAT ("Folkboat", true, 7.68, 2.20, BoatHullType.MONOHULL, "Folke", "Folkeboot"),
F_16 ("Formula 16", true, 5.00, 2.50, BoatHullType.CATAMARAN, "F16", "F-16"),
HOBIE_16 ("Hobie 16", true, 5.05, 2.41, BoatHullType.CATAMARAN, "H16"),
H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, "HB"),
HOBIE_TIGER ("Hobie Tiger", true, 5.51, 2.60, BoatHullType.CATAMARAN),
HOBIE_WILD_CAT ("Hobie Wild Cat", true, 5.49, 2.59, BoatHullType.CATAMARAN, "Hobie Wild Cat F18"),
J70 ("J/70", true, 6.93, 2.25, BoatHullType.MONOHULL, "J70", "J-70"),
J80 ("J/80", true, 8.0, 2.51, BoatHullType.MONOHULL, "J80", "J-80"),
J24 ("J/24", true, 7.32, 2.67, BoatHullType.MONOHULL, "J24", "J-24"),
KITE ("Kite", true, 3.35, 1.52, BoatHullType.MONOHULL), //
LASER_4_7 ("Laser 4.7", true, 4.20, 1.39, BoatHullType.MONOHULL, "L4.7"),
LASER_RADIAL ("Laser Radial", true, 4.19, 1.41, BoatHullType.MONOHULL, "LAR", "Laser RAD", "RAD", "Radial"),
LASER_INT ("Laser Int.", true, 4.19, 1.39, BoatHullType.MONOHULL, "Laser", "LSR"),
LASER_SB3 ("Laser SB3", true, 6.15, 2.15, BoatHullType.MONOHULL, "LSB3", "SB20"),
MELGES_24 ("Melges 24", true, 7.32, 2.50, BoatHullType.MONOHULL, "Melges-24", "M24"),
MINI_TRANSAT ("Mini Transat 6.50", true, 6.50, 3.00, BoatHullType.MONOHULL, "Mini Transat"),
MUSTO_SKIFF ("Musto Skiff", true, 4.55, 1.35, BoatHullType.MONOHULL, "Musto Performance Skiff", "MPS", "Musto"),
NACRA_17 ("Nacra 17", true, 5.25, 2.59, BoatHullType.CATAMARAN, "N17", "Nacra-17"),
OK ("OK Dinghy", true, 5.25, 2.59, BoatHullType.MONOHULL, "OK-Dinghy", "OK-Jolle", "OK"),
OPTIMIST ("Optimist", true, 2.34, 1.07, BoatHullType.MONOHULL, "Opti", "Optimist Dinghy"),
PLATU_25 ("Platu 25", true, 7.53, 2.62, BoatHullType.MONOHULL, "Platu", "Platu-25", "PLA", "B25"),
RS_X ("RS:X", true, 2.86, 0.93, BoatHullType.SURFERBOARD, "RS-X", "RSX", "RS:X"),
SONAR ("Sonar", true, 7.01, 2.39, BoatHullType.MONOHULL),
STAR ("Star", true, 6.92, 1.74, BoatHullType.MONOHULL),
STREAMLINE ("Streamline", true, 7.15, 2.55, BoatHullType.MONOHULL),
SWAN_45 ("Swan 45", true, 13.83, 3.91, BoatHullType.MONOHULL, "Swan", "Swan-45"),
//TODO: which boatclasses of swan are important (there are several ones)
TORNADO ("Tornado Catamaran", true, 6.10, 3.02, BoatHullType.CATAMARAN, "Tornado", "Tornado Cat"),
X_99 ("X-99", true, 9.96, 2.95, BoatHullType.MONOHULL, "X99"),
CONTENDER ("Contender", true, 4.88, 1.42, BoatHullType.MONOHULL),
RC44 ("RC44", true, 13.35, 2.75, BoatHullType.MONOHULL),
FLYING_DUTCHMAN ("Flying Dutchman", true, 6.10, 1.80, BoatHullType.MONOHULL),
DYAS("Dyas", true, 7.15, 1.95, BoatHullType.MONOHULL),
INTERNATIONAL_14("International 14", true, 4.27, 1.83, BoatHullType.MONOHULL, "I14"),
OPEN_BIC("O'pen BIC", true, 2.75, 1.14, BoatHullType.MONOHULL, "OpenBIC");
_2_4M ("2.4 Meter", true, 4.11, 0.81, BoatHullType.MONOHULL, false, "2.4M", "2.4mR"),
_5O5 ("5O5", true, 5.03, 1.88, BoatHullType.MONOHULL, true, "505", "5o5", "505er", "5o5er"),
_12M ("12 Meter", true, 5.97, 1.43, BoatHullType.MONOHULL, true, "12M", "12mR", "12SQM"),
_29ER ("29er", true, 4.45, 1.70, BoatHullType.MONOHULL, true),
_49ER ("49er", true, 4.88, 1.93, BoatHullType.MONOHULL, true),
_49ERFX ("49erFX", true, 4.88, 1.93, BoatHullType.MONOHULL, true, "49FX"),
_420 ("420", true, 4.20, 1.65, BoatHullType.MONOHULL, true, "420er", "420M", "420W"),
_470 ("470", true, 4.70, 1.68, BoatHullType.MONOHULL, true, "470er", "470M", "470W"),
A_CAT ("A-Catamaran", true, 5.49, 2.30, BoatHullType.CATAMARAN, false, "A-Cat", "ACat", "A-Class Catamaran"),
ALBIN_EXPRESS ("Albin Express", true, 7.77, 2.50, BoatHullType.MONOHULL, false),
B_ONE ("B/ONE", true, 7.80, 2.49, BoatHullType.MONOHULL, true, "B-ONE"),
DRAGON_INT ("Dragon Int.", true, 8.89, 1.96, BoatHullType.MONOHULL, true, "Drachen", "Dragon"),
EXTREME_40 ("Extreme 40", false, 12.2, 6.60, BoatHullType.CATAMARAN, true, "Extreme-40", "Extreme40", "ESS40"),
D_35 ("D35", false, 10.81, 6.89, BoatHullType.CATAMARAN, false),
EUROPE_INT ("Europe Int.", true, 3.35, 1.35, BoatHullType.MONOHULL, false, "Europe"),
F_18 ("Formula 18", true, 6.85, 2.25, BoatHullType.CATAMARAN, true, "F18", "F-18"),
FARR_30 ("Farr 30", true, 9.42, 3.08, BoatHullType.MONOHULL, true, "F30", "F-30", "Farr-30"),
FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL, false),
FOLKBOAT ("Folkboat", true, 7.68, 2.20, BoatHullType.MONOHULL, false, "Folke", "Folkeboot"),
F_16 ("Formula 16", true, 5.00, 2.50, BoatHullType.CATAMARAN, true, "F16", "F-16"),
HOBIE_16 ("Hobie 16", true, 5.05, 2.41, BoatHullType.CATAMARAN, false, "H16"),
H_BOAT ("H-Boat", true, 8.28, 2.18, BoatHullType.MONOHULL, true, "HB"),
HOBIE_TIGER ("Hobie Tiger", true, 5.51, 2.60, BoatHullType.CATAMARAN, true),
HOBIE_WILD_CAT ("Hobie Wild Cat", true, 5.49, 2.59, BoatHullType.CATAMARAN, true, "Hobie Wild Cat F18"),
J70 ("J/70", true, 6.93, 2.25, BoatHullType.MONOHULL, true, "J70", "J-70"),
J80 ("J/80", true, 8.0, 2.51, BoatHullType.MONOHULL, true, "J80", "J-80"),
J24 ("J/24", true, 7.32, 2.67, BoatHullType.MONOHULL, true, "J24", "J-24"),
KITE ("Kite", true, 3.35, 1.52, BoatHullType.MONOHULL, false),
LASER_4_7 ("Laser 4.7", true, 4.20, 1.39, BoatHullType.MONOHULL, false, "L4.7"),
LASER_RADIAL ("Laser Radial", true, 4.19, 1.41, BoatHullType.MONOHULL, false, "LAR", "Laser RAD", "RAD", "Radial"),
LASER_INT ("Laser Int.", true, 4.19, 1.39, BoatHullType.MONOHULL, false, "Laser", "LSR"),
LASER_SB3 ("Laser SB3", true, 6.15, 2.15, BoatHullType.MONOHULL, false, "LSB3", "SB20"),
MELGES_24 ("Melges 24", true, 7.32, 2.50, BoatHullType.MONOHULL, true, "Melges-24", "M24"),
MINI_TRANSAT ("Mini Transat 6.50", true, 6.50, 3.00, BoatHullType.MONOHULL, true, "Mini Transat"),
MUSTO_SKIFF ("Musto Skiff", true, 4.55, 1.35, BoatHullType.MONOHULL, true, "Musto Performance Skiff", "MPS", "Musto"),
NACRA_17 ("Nacra 17", true, 5.25, 2.59, BoatHullType.CATAMARAN, true, "N17", "Nacra-17"),
OK ("OK Dinghy", true, 5.25, 2.59, BoatHullType.MONOHULL, false, "OK-Dinghy", "OK-Jolle", "OK"),
OPTIMIST ("Optimist", true, 2.34, 1.07, BoatHullType.MONOHULL, false, "Opti", "Optimist Dinghy"),
PLATU_25 ("Platu 25", true, 7.53, 2.62, BoatHullType.MONOHULL, true, "Platu", "Platu-25", "PLA", "B25"),
RS_X ("RS:X", true, 2.86, 0.93, BoatHullType.SURFERBOARD, false, "RS-X", "RSX", "RS:X"),
SONAR ("Sonar", true, 7.01, 2.39, BoatHullType.MONOHULL, true),
STAR ("Star", true, 6.92, 1.74, BoatHullType.MONOHULL, false),
STREAMLINE ("Streamline", true, 7.15, 2.55, BoatHullType.MONOHULL, true),
SWAN_45 ("Swan 45", true, 13.83, 3.91, BoatHullType.MONOHULL, true, "Swan", "Swan-45"),
TORNADO ("Tornado Catamaran", true, 6.10, 3.02, BoatHullType.CATAMARAN, true, "Tornado", "Tornado Cat"),
X_99 ("X-99", true, 9.96, 2.95, BoatHullType.MONOHULL, true, "X99"),
CONTENDER ("Contender", true, 4.88, 1.42, BoatHullType.MONOHULL, false),
RC44 ("RC44", true, 13.35, 2.75, BoatHullType.MONOHULL, true),
FLYING_DUTCHMAN ("Flying Dutchman", true, 6.10, 1.80, BoatHullType.MONOHULL, true),
DYAS("Dyas", true, 7.15, 1.95, BoatHullType.MONOHULL, true),
INTERNATIONAL_14("International 14", true, 4.27, 1.83, BoatHullType.MONOHULL, true, "I14"),
OPEN_BIC("O'pen BIC", true, 2.75, 1.14, BoatHullType.MONOHULL, false, "OpenBIC");
private final String displayName;
private final String[] alternativeNames;
@@ -65,24 +63,27 @@ public enum BoatClassMasterdata {
private final double hullBeamInMeter;
private final BoatHullType hullType;
private final boolean typicallyStartsUpwind;
private final boolean hasAdditionalDownwindSail;
private BoatClassMasterdata(String displayName, boolean typicallyStartsUpwind, double hullLengthInMeter,
double hullBeamInMeter, BoatHullType hullType, String... alternativeNames) {
double hullBeamInMeter, BoatHullType hullType, boolean hasAdditionalDownwindSail, String... alternativeNames) {
this.displayName = displayName;
this.typicallyStartsUpwind = typicallyStartsUpwind;
this.hullLengthInMeter = hullLengthInMeter;
this.hullBeamInMeter = hullBeamInMeter;
this.hullType = hullType;
this.hasAdditionalDownwindSail = hasAdditionalDownwindSail;
this.alternativeNames = alternativeNames;
}
private BoatClassMasterdata(String displayName, boolean typicallyStartsUpwind, double hullLengthInMeter,
double hullBeamInMeter, BoatHullType hullType) {
double hullBeamInMeter, BoatHullType hullType, boolean hasAdditionalDownwindSail) {
this.displayName = displayName;
this.typicallyStartsUpwind = typicallyStartsUpwind;
this.hullLengthInMeter = hullLengthInMeter;
this.hullBeamInMeter = hullBeamInMeter;
this.hullType = hullType;
this.hasAdditionalDownwindSail = hasAdditionalDownwindSail;
this.alternativeNames = null;
}
@@ -131,4 +132,9 @@ public enum BoatClassMasterdata {
public boolean isTypicallyStartsUpwind() {
return typicallyStartsUpwind;
}
public boolean hasAdditionalDownwindSail() {
return hasAdditionalDownwindSail;
}
}
@@ -17,6 +17,7 @@ public interface Duration extends Serializable, Comparable<Duration> {
static final Duration ONE_MINUTE = ONE_SECOND.times(60);
static final Duration ONE_HOUR = ONE_MINUTE.times(60);
static final Duration ONE_DAY = ONE_HOUR.times(24);
static final Duration ONE_WEEK = ONE_DAY.times(7);
long asMillis();
@@ -2,6 +2,9 @@ package com.sap.sailing.domain.common;
import java.io.Serializable;
import com.sap.sse.datamining.shared.Unit;
import com.sap.sse.datamining.shared.annotations.Statistic;
/**
* A speed, convertable in various units of measure. Can be negative.
*
@@ -48,6 +51,7 @@ public interface Speed extends Comparable<Speed>, Serializable {
}
};
@Statistic(messageKey="InKnots", resultDecimals=2, resultUnit=Unit.Knots)
double getKnots();
double getMetersPerSecond();
@@ -201,9 +201,10 @@ public abstract class AbstractLeaderboardDTO implements Serializable {
public int getTrackedRacesCount() {
int result = 0;
for (RaceColumnDTO race : getRaceList()) {
for (FleetDTO fleet : race.getFleets()) {
if (race.isTrackedRace(fleet)) {
for (RaceColumnDTO raceColumn : getRaceList()) {
for (FleetDTO fleet : raceColumn.getFleets()) {
RaceDTO race = raceColumn.getRace(fleet);
if(race != null && race.trackedRace != null && race.trackedRace.hasGPSData && race.trackedRace.hasWindData) {
result++;
}
}
@@ -7,6 +7,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sap.sailing.domain.common.ScoringSchemeType;
/**
* Captures the serializable properties of a leaderboard which in particular has the competitors, any optional display
* name mappings for the competitors, races and their net / total points as well as possible reasons for maximum points
@@ -62,10 +64,11 @@ public class LeaderboardDTO extends AbstractLeaderboardDTO implements Serializab
* from it by the {@link #clone()} operation.
* @param hasOverallDetails TODO
*/
public LeaderboardDTO(Date timePointOfLastCorrectionsValidity, String comment, boolean higherScoreIsBetter, UUIDGenerator uuidGenerator, boolean hasOverallDetails) {
public LeaderboardDTO(Date timePointOfLastCorrectionsValidity, String comment, ScoringSchemeType scoringScheme, boolean higherScoreIsBetter, UUIDGenerator uuidGenerator, boolean hasOverallDetails) {
initCollections();
id = uuidGenerator.generateRandomUUID();
this.timePointOfLastCorrectionsValidity = timePointOfLastCorrectionsValidity;
this.scoringScheme = scoringScheme;
this.comment = comment;
this.higherScoresIsBetter = higherScoreIsBetter;
this.hasOverallDetails = hasOverallDetails;
@@ -19,6 +19,7 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;
import com.sap.sailing.declination.DeclinationService;
import com.sap.sailing.domain.common.Duration;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.igtimiadapter.Account;
@@ -45,6 +46,17 @@ import com.sap.sse.common.Util;
public class IgtimiConnectionImpl implements IgtimiConnection {
private static final Logger logger = Logger.getLogger(IgtimiConnectionImpl.class.getName());
/**
* name of the JSON property indicating an error reason in a response document
*/
private static final String REASON = "reason";
/**
* name of the JSON property indicating an error condition in a response document
*/
private static final String ERROR = "error";
private final Account account;
private final IgtimiConnectionFactoryImpl connectionFactory;
private final LiveDataConnectionFactory liveDataConnectionFactory;
@@ -143,13 +155,35 @@ public class IgtimiConnectionImpl implements IgtimiConnection {
}
@Override
public Iterable<Fix> getResourceData(TimePoint startTime, TimePoint endTime,
public Iterable<Fix> getResourceData(final TimePoint startTime, final TimePoint endTime,
Iterable<String> deviceSerialNumbers, Map<Type, Double> typeAndCompression) throws IllegalStateException, ClientProtocolException, IOException, ParseException {
logger.info("Obtaining resource data from "+startTime+" to "+endTime+" for devices "+deviceSerialNumbers+" for types "+typeAndCompression);
HttpClient client = connectionFactory.getHttpClient();
HttpGet getResourceData = new HttpGet(connectionFactory.getResourceDataUrl(startTime, endTime, deviceSerialNumbers, typeAndCompression, account));
JSONObject resourceDataJson = ConnectivityUtils.getJsonFromResponse(client.execute(getResourceData));
return new FixFactory().createFixes(resourceDataJson);
logger.info("Requested resource data from "+startTime+" to "+endTime+" for devices "+deviceSerialNumbers+" for types "+typeAndCompression);
List<Fix> result = new ArrayList<>();
// Cut interval into slices that are at most one week long. See also the discussion at
// http://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=2002 that talks about a one-month limitation
// imposed by the Igtimi API
TimePoint windowStartTime = startTime;
while (!windowStartTime.after(endTime)) {
TimePoint windowEndTime = windowStartTime.plus(Duration.ONE_WEEK);
if (windowEndTime.after(endTime)) {
windowEndTime = endTime;
}
logger.info("Obtaining resource data from "+windowStartTime+" to "+windowEndTime+" for devices "+deviceSerialNumbers+" for types "+typeAndCompression);
HttpClient client = connectionFactory.getHttpClient();
HttpGet getResourceData = new HttpGet(connectionFactory.getResourceDataUrl(windowStartTime, windowEndTime,
deviceSerialNumbers, typeAndCompression, account));
JSONObject resourceDataJson = ConnectivityUtils.getJsonFromResponse(client.execute(getResourceData));
String error = (String) resourceDataJson.get(ERROR);
if (error != null) {
String reason = (String) resourceDataJson.get(REASON);
throw new ClientProtocolException("Error trying to obtain Igtimi resource data from " + windowStartTime
+ " to " + windowEndTime + " from devices " + deviceSerialNumbers + ": " + error
+ (reason == null ? "" : ". Reason: " + reason));
}
Util.addAll(new FixFactory().createFixes(resourceDataJson), result);
windowStartTime = windowEndTime.plus(1);
}
return result;
}
@Override
@@ -1119,7 +1119,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
if (scoringSchemeTypeName == null) {
scoringSchemeType = ScoringSchemeType.LOW_POINT; // the default
} else {
scoringSchemeType = ScoringSchemeType.valueOf(scoringSchemeTypeName);
try {
scoringSchemeType = ScoringSchemeType.valueOf(scoringSchemeTypeName);
} catch (IllegalArgumentException ila) {
// can happen that the database contains a scoring scheme that
// has not yet been implemented - fall back with a warning
scoringSchemeType = ScoringSchemeType.LOW_POINT;
logger.warning("Could not find scoring scheme " + scoringSchemeTypeName + "! Most probably this has not yet been implemented or even been removed.");
}
}
return scoringSchemeType;
}
@@ -6,6 +6,7 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: com.sap.sailing.domain.common;bundle-version="1.0.0",
com.sap.sse.datamining.shared;bundle-version="1.0.0",
com.sap.sse.common
Export-Package: com.sap.sailing.domain.base,
com.sap.sailing.domain.base.configuration,
@@ -1,9 +1,11 @@
package com.sap.sailing.domain.base;
import com.sap.sse.common.Named;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface Boat extends Named {
BoatClass getBoatClass();
@Dimension(messageKey="SailID")
String getSailID();
}
@@ -2,11 +2,14 @@ package com.sap.sailing.domain.base;
import com.sap.sailing.domain.common.Color;
import com.sap.sailing.domain.common.WithID;
import com.sap.sse.datamining.shared.annotations.Connector;
import com.sap.sse.common.Named;
public interface Competitor extends Named, WithID, IsManagedBySharedDomainFactory {
@Connector(messageKey="Team", ordinal=8)
Team getTeam();
@Connector(messageKey="Boat", ordinal=9)
Boat getBoat();
Color getColor();
@@ -2,8 +2,10 @@ package com.sap.sailing.domain.base;
import com.sap.sailing.domain.common.CountryCode;
import com.sap.sse.common.Named;
import com.sap.sse.datamining.shared.annotations.Dimension;
public interface Nationality extends Named, WithImage, IsManagedBySharedDomainFactory {
@Dimension(messageKey="NationalityAcronym")
String getThreeLetterIOCAcronym();
CountryCode getCountryCode();
@@ -1,5 +1,8 @@
package com.sap.sailing.domain.base;
import com.sap.sse.datamining.shared.annotations.Connector;
public interface WithNationality {
@Connector(ordinal=7)
Nationality getNationality();
}
@@ -60,7 +60,7 @@ public class CompetitorImpl implements DynamicCompetitor {
public Serializable getId() {
return id;
}
@Override
public DynamicTeam getTeam() {
return team;
@@ -3,8 +3,8 @@ package com.sap.sailing.domain.racelog.impl;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -22,7 +22,7 @@ import com.sap.sailing.domain.racelog.RaceLogEvent;
public class WeakRaceLogChangedVisitor extends AbstractRaceLogChangedVisitor {
private static final Logger logger = Logger.getLogger(WeakRaceLogChangedVisitor.class.getName());
private static ReferenceQueue<? super RaceLogChangedListener> queue = new ReferenceQueue<RaceLogChangedListener>();
private static Map<Reference<?>, WeakRaceLogChangedVisitor> referenceToVisitor = new HashMap<Reference<?>, WeakRaceLogChangedVisitor>();
private static Map<Reference<?>, WeakRaceLogChangedVisitor> referenceToVisitor = new ConcurrentHashMap<Reference<?>, WeakRaceLogChangedVisitor>();
static {
new Thread(WeakRaceLogChangedVisitor.class.getSimpleName() + " weak reference cleaner") {
@Override
+8 -8
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1,253 @@
package com.sap.sailing.domain.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.junit.Test;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Regatta;
import com.sap.sailing.domain.base.Sideline;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.BoatClassImpl;
import com.sap.sailing.domain.base.impl.CourseAreaImpl;
import com.sap.sailing.domain.base.impl.CourseImpl;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
import com.sap.sailing.domain.base.impl.RegattaImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.BoatClassMasterdata;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.racelog.impl.EmptyRaceLogStore;
import com.sap.sailing.domain.racelog.tracking.EmptyGPSFixStore;
import com.sap.sailing.domain.tracking.TrackedRegatta;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
import com.sap.sailing.domain.tracking.impl.TrackedRaceAsWaypointList;
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.TrackedRegattaImpl;
import com.sap.sse.common.Util;
import difflib.DiffUtils;
import difflib.Patch;
import difflib.PatchFailedException;
/**
* Related to bug 2223; updates a course while serialization is in progress and validates that the
* resulting TrackedRace's structures are eventually consistent with the modified course.
*
* @author Axel Uhl (d043530)
*
*/
public class CourseUpdateDuringNonAtomicSerializationTest implements Serializable {
private static final long serialVersionUID = -6207158826716014865L;
private Course course;
private Map<Integer, Waypoint> addCalls;
private Map<Integer, Waypoint> removeCalls;
private TrackedRaceImpl trackedRace;
private TrackedRaceAsWaypointList trackedRaceWaypoints;
public void setUp(int numberOfWaypoints) {
final List<Waypoint> waypoints = new ArrayList<>();
for (int i=0; i<numberOfWaypoints; i++) {
waypoints.add(new WaypointImpl(new MarkImpl("Mark "+i)));
}
addCalls = new HashMap<>();
removeCalls = new HashMap<>();
course = new CourseImpl("Test Course", waypoints);
Regatta regatta = new RegattaImpl(EmptyRaceLogStore.INSTANCE, "Test Regatta",
new BoatClassImpl("505", BoatClassMasterdata._5O5), /* trackedRegattaRegistry */ null,
new LowPoint(), UUID.randomUUID(), new CourseAreaImpl("Alpha", UUID.randomUUID()));
TrackedRegatta trackedRegatta = new TrackedRegattaImpl(regatta);
RaceDefinition race = new RaceDefinitionImpl("Test Race", course, regatta.getBoatClass(), Collections.<Competitor>emptySet());
trackedRace = new DynamicTrackedRaceImpl(trackedRegatta, race, Collections.<Sideline> emptySet(),
EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE,
/* delayToLiveInMillis */10000, /* millisecondsOverWhichToAverageWind */30000, /* millisecondsOverWhichToAverageSpeed */
7000) {
private static final long serialVersionUID = 9114777576548711763L;
@Override
public void waypointAdded(int zeroBasedIndex, Waypoint waypointThatGotAdded) {
try {
addCalls.put(zeroBasedIndex, waypointThatGotAdded);
} catch (NullPointerException npe) {
// if the reference to the enclosing object hasn't been de-serialized yet, don't fail
}
super.waypointAdded(zeroBasedIndex, waypointThatGotAdded);
}
@Override
public void waypointRemoved(int zeroBasedIndex, Waypoint waypointThatGotRemoved) {
try {
removeCalls.put(zeroBasedIndex, waypointThatGotRemoved);
} catch (NullPointerException npe) {
// if the reference to the enclosing object hasn't been de-serialized yet, don't fail
}
super.waypointRemoved(zeroBasedIndex, waypointThatGotRemoved);
}
};
trackedRaceWaypoints = new TrackedRaceAsWaypointList(trackedRace);
}
@Test
public void simpleStructureConsistencyTest() {
// don't test one waypoint only because the tracked race will report an empty waypoint list in this case
// because there is no leg
for (int numberOfWaypoints = 0; numberOfWaypoints < 5; numberOfWaypoints+=2) {
setUp(numberOfWaypoints);
Iterable<Waypoint> courseWaypoints = course.getWaypoints();
assertEquals(courseWaypoints, trackedRaceWaypoints);
assertTrue(addCalls.isEmpty());
assertTrue(removeCalls.isEmpty());
}
}
@Test
public void testSingleWaypoint() throws PatchFailedException {
// with one waypoint only the tracked race will also report the single waypoint because the
// mark passings collection has it in its key set; so there will be no difference between the
// two lists.
setUp(1);
Iterable<Waypoint> courseWaypoints = course.getWaypoints();
Patch<Waypoint> patch = DiffUtils.diff(trackedRaceWaypoints, courseWaypoints);
patch.applyToInPlace(trackedRaceWaypoints);
assertTrue(Util.isEmpty(trackedRace.getTrackedLegs()));
assertTrue(addCalls.isEmpty());
}
@Test
public void testCourseUpdateEndToEnd() throws PatchFailedException {
setUp(5);
assertEquals(5, Util.size(course.getWaypoints()));
course.addWaypoint(2, new WaypointImpl(new MarkImpl("Mark 2.5")));
assertEquals(6, Util.size(course.getWaypoints()));
assertEquals(course.getWaypoints(), trackedRaceWaypoints);
assertEquals(course.getLegs().size(), Util.size(trackedRace.getTrackedLegs()));
}
@Test
public void testAddingOneWaypointHalfWayIntoSerialization() throws IOException, ClassNotFoundException {
setUp(5);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(course); // now the course has been written to the stream and won't be written a second time
// update the course:
course.addWaypoint(2, new WaypointImpl(new MarkImpl("Mark 2.5")));
assertEquals(course.getLegs().size(), Util.size(trackedRace.getTrackedLegs()));
oos.writeObject(trackedRace);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Course deserializedCourse = (Course) ois.readObject();
TrackedRaceImpl deserializedTrackedRace = (TrackedRaceImpl) ois.readObject();
ois.close();
assertFalse(course.getWaypoints().equals(deserializedCourse.getWaypoints())); // the deserialized course is expected to have one fewer waypoint
assertEquals(Util.size(course.getWaypoints())-1, Util.size(deserializedCourse.getWaypoints()));
assertEquals(Util.size(deserializedTrackedRace.getTrackedLegs())+1, Util.size(deserializedTrackedRace.getRace().getCourse().getWaypoints()));
}
@Test
public void testAddingTwoWaypointsHalfWayIntoSerialization() throws IOException, ClassNotFoundException {
setUp(5);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(course); // now the course has been written to the stream and won't be written a second time
// update the course:
course.addWaypoint(2, new WaypointImpl(new MarkImpl("Mark 2.5")));
course.addWaypoint(4, new WaypointImpl(new MarkImpl("Mark 4.5")));
assertEquals(course.getLegs().size(), Util.size(trackedRace.getTrackedLegs()));
oos.writeObject(trackedRace);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Course deserializedCourse = (Course) ois.readObject();
TrackedRaceImpl deserializedTrackedRace = (TrackedRaceImpl) ois.readObject();
ois.close();
assertFalse(course.getWaypoints().equals(deserializedCourse.getWaypoints())); // the deserialized course is expected to have one fewer waypoint
assertEquals(Util.size(course.getWaypoints())-2, Util.size(deserializedCourse.getWaypoints()));
assertEquals(Util.size(deserializedTrackedRace.getTrackedLegs())+1, Util.size(deserializedTrackedRace.getRace().getCourse().getWaypoints()));
}
@Test
public void testRemovingOneWaypointHalfWayIntoSerialization() throws IOException, ClassNotFoundException {
setUp(5);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(course); // now the course has been written to the stream and won't be written a second time
// update the course:
course.removeWaypoint(2);
assertEquals(course.getLegs().size(), Util.size(trackedRace.getTrackedLegs()));
oos.writeObject(trackedRace);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Course deserializedCourse = (Course) ois.readObject();
TrackedRaceImpl deserializedTrackedRace = (TrackedRaceImpl) ois.readObject();
ois.close();
assertFalse(course.getWaypoints().equals(deserializedCourse.getWaypoints())); // the deserialized course is expected to have one more waypoint
assertEquals(Util.size(course.getWaypoints())+1, Util.size(deserializedCourse.getWaypoints()));
assertEquals(Util.size(deserializedTrackedRace.getTrackedLegs())+1, Util.size(deserializedTrackedRace.getRace().getCourse().getWaypoints()));
}
@Test
public void testRemovingTwoWaypointsHalfWayIntoSerialization() throws IOException, ClassNotFoundException {
setUp(5);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(course); // now the course has been written to the stream and won't be written a second time
// update the course:
course.removeWaypoint(2);
course.removeWaypoint(3);
assertEquals(course.getLegs().size(), Util.size(trackedRace.getTrackedLegs()));
oos.writeObject(trackedRace);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Course deserializedCourse = (Course) ois.readObject();
TrackedRaceImpl deserializedTrackedRace = (TrackedRaceImpl) ois.readObject();
ois.close();
assertFalse(course.getWaypoints().equals(deserializedCourse.getWaypoints())); // the deserialized course is expected to have one fewer waypoint
assertEquals(Util.size(course.getWaypoints())+2, Util.size(deserializedCourse.getWaypoints()));
assertEquals(Util.size(deserializedTrackedRace.getTrackedLegs())+1, Util.size(deserializedTrackedRace.getRace().getCourse().getWaypoints()));
}
@Test
public void testAddingTwoAndRemovingOneWaypointHalfWayIntoSerialization() throws IOException, ClassNotFoundException {
setUp(5);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(course); // now the course has been written to the stream and won't be written a second time
// update the course:
course.addWaypoint(2, new WaypointImpl(new MarkImpl("Mark 2.5")));
course.removeWaypoint(3);
course.addWaypoint(4, new WaypointImpl(new MarkImpl("Mark 4.5")));
assertEquals(course.getLegs().size(), Util.size(trackedRace.getTrackedLegs()));
oos.writeObject(trackedRace);
oos.close();
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Course deserializedCourse = (Course) ois.readObject();
TrackedRaceImpl deserializedTrackedRace = (TrackedRaceImpl) ois.readObject();
ois.close();
assertFalse(course.getWaypoints().equals(deserializedCourse.getWaypoints())); // the deserialized course is expected to have one fewer waypoint
assertEquals(Util.size(course.getWaypoints())-1, Util.size(deserializedCourse.getWaypoints()));
assertEquals(Util.size(deserializedTrackedRace.getTrackedLegs())+1, Util.size(deserializedTrackedRace.getRace().getCourse().getWaypoints()));
}
}
@@ -56,25 +56,25 @@ public class MultipleClassesInRegattaTest {
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=cce678c8-97e6-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false,
EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
kiwotest2 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=11290bd6-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
kiwotest3 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=39635b24-97e7-11e0-9aed-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
weym470may112014_2 = domainFactory
.createRaceTracker(
new URL(
httpAndHost+"/events/event_20110505_SailingTea/clientparams.php?event=event_20110505_SailingTea&race=04498426-7dfd-11e0-8236-406186cbf87c"),
new URI(liveURI), new URI(storedURI), new URI(courseDesignUpdateURI),
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, new DummyTrackedRegattaRegistry());
/* startOfTracking */ null, /* endOfTracking */ null, /* delayToLiveInMillis */ 0l, /* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY, new DummyTrackedRegattaRegistry());
assertEquals("STG", kiwotest1.getRegatta().getBoatClass().getName());
assertEquals("505", kiwotest2.getRegatta().getBoatClass().getName());
@@ -0,0 +1,99 @@
package com.sap.sailing.domain.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import com.sap.sailing.domain.base.Course;
import com.sap.sailing.domain.base.Mark;
import com.sap.sailing.domain.base.RaceDefinition;
import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.base.impl.MarkImpl;
import com.sap.sailing.domain.base.impl.WaypointImpl;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.TimePoint;
import com.sap.sailing.domain.common.impl.DegreePosition;
import com.sap.sailing.domain.common.impl.MillisecondsTimePoint;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
import com.sap.sailing.domain.tracking.GPSFix;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.impl.DynamicGPSFixTrackImpl;
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.GPSFixImpl;
/**
* Tests the calculation of the center of the course, particularly the
* {@link TrackedRace#getCenterOfCourse(com.sap.sailing.domain.common.TimePoint)} method.
*
* @author Axel Uhl (D043530)
*
*/
public class TrackedRaceCenterTest {
private Mark mark1;
private Mark mark2;
private Waypoint wp1;
private Waypoint wp2;
private Course course;
private DynamicGPSFixTrack<Mark, GPSFix> mark1Track;
private DynamicGPSFixTrack<Mark, GPSFix> mark2Track;
private DynamicTrackedRaceImpl trackedRace;
@Before
public void setUp() {
trackedRace = mock(DynamicTrackedRaceImpl.class);
when(trackedRace.getCenterOfCourse(Matchers.any(TimePoint.class))).thenCallRealMethod();
when(trackedRace.getApproximatePosition(Matchers.any(Waypoint.class), Matchers.any(TimePoint.class))).thenCallRealMethod();
RaceDefinition race = mock(RaceDefinition.class);
when(trackedRace.getRace()).thenReturn(race);
course = mock(Course.class);
when(race.getCourse()).thenReturn(course);
mark1 = new MarkImpl("1");
mark2 = new MarkImpl("2");
wp1 = new WaypointImpl(mark1);
wp2 = new WaypointImpl(mark2);
when(course.getWaypoints()).thenReturn(Arrays.asList(new Waypoint[] { wp1, wp2 }));
mark1Track = new DynamicGPSFixTrackImpl<Mark>(mark1, /* millisecondsOverWhichToAverage */ 10);
mark2Track = new DynamicGPSFixTrackImpl<Mark>(mark1, /* millisecondsOverWhichToAverage */ 10);
when(trackedRace.getOrCreateTrack(mark1)).thenReturn(mark1Track);
when(trackedRace.getOrCreateTrack(mark2)).thenReturn(mark2Track);
}
@Test
public void testSimpleAverage() {
MillisecondsTimePoint now = MillisecondsTimePoint.now();
Position mark1Pos = new DegreePosition(10, 10);
mark1Track.add(new GPSFixImpl(mark1Pos, now));
Position mark2Pos = new DegreePosition(20, 10);
mark2Track.add(new GPSFixImpl(mark2Pos, now));
Position center = trackedRace.getCenterOfCourse(now);
assertEquals(15, center.getLatDeg(), 0.00001);
assertEquals(10, center.getLngDeg(), 0.00001);
}
@Test
public void testTriangle() {
Mark mark3 = new MarkImpl("3");
Waypoint wp3 = new WaypointImpl(mark3);
when(course.getWaypoints()).thenReturn(Arrays.asList(new Waypoint[] { wp1, wp2, wp3 }));
DynamicGPSFixTrackImpl<Mark> mark3Track = new DynamicGPSFixTrackImpl<Mark>(mark3, /* millisecondsOverWhichToAverage */ 10);
when(trackedRace.getOrCreateTrack(mark3)).thenReturn(mark3Track);
MillisecondsTimePoint now = MillisecondsTimePoint.now();
Position mark1Pos = new DegreePosition(0, 0);
mark1Track.add(new GPSFixImpl(mark1Pos, now));
Position mark2Pos = new DegreePosition(0, 10);
mark2Track.add(new GPSFixImpl(mark2Pos, now));
Position mark3Pos = new DegreePosition(10, 5);
mark3Track.add(new GPSFixImpl(mark3Pos, now));
Position center = trackedRace.getCenterOfCourse(now);
assertTrue(2 < center.getLatDeg() && center.getLatDeg() < 8);
assertEquals(5, center.getLngDeg(), 0.00001);
}
}
@@ -62,7 +62,7 @@ public class UnicodeCharactersInCompetitorNamesTest {
+ TracTracConnectionConstants.PORT_STORED),
new URI("http://tracms.traclive.dk/update_course"),
/* startOfTracking */null, /* endOfTracking */null, /* delayToLiveInMillis */0l,
/* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "",
/* simulateWithStartTimeNow */ false, EmptyRaceLogStore.INSTANCE, EmptyWindStore.INSTANCE, EmptyGPSFixStore.INSTANCE, "tracTest", "tracTest", "", "",
new DummyTrackedRegattaRegistry());
Iterable<Competitor> competitors = fourtyninerYellow_2.getRacesHandle().getRace().getCompetitors();
@@ -1005,4 +1005,10 @@ public class MockedTrackedRace implements DynamicTrackedRace {
}
@Override
public Position getCenterOfCourse(TimePoint at) {
// TODO Auto-generated method stub
return null;
}
}
@@ -657,4 +657,10 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
}
@Override
public Position getCenterOfCourse(TimePoint at) {
// TODO Auto-generated method stub
return null;
}
}
@@ -134,7 +134,8 @@ public interface DomainFactory {
*/
TracTracRaceTracker createRaceTracker(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
URISyntaxException, CreateModelException, SubscriberInitializationException;
/**
@@ -143,7 +144,7 @@ public interface DomainFactory {
*/
RaceTracker createRaceTracker(Regatta regatta, URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI, TimePoint startOfTracking,
TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
WindStore windStore, GPSFixStore gpsFixStore, String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility, TrackedRegattaRegistry trackedRegattaRegistry) throws MalformedURLException, FileNotFoundException,
URISyntaxException, CreateModelException, SubscriberInitializationException;
BoatClass getOrCreateBoatClass(String competitorClassName);
@@ -245,7 +246,7 @@ public interface DomainFactory {
RaceTrackingConnectivityParameters createTrackingConnectivityParameters(URL paramURL, URI liveURI, URI storedURI, URI courseDesignUpdateURI,
TimePoint startOfTracking, TimePoint endOfTracking, long delayToLiveInMillis, boolean simulateWithStartTimeNow, RaceLogStore raceLogStore,
String tracTracUsername, String tracTracPassword, String raceStatus);
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility);
/**
* Removes all knowledge about <code>tractracRace</code> which includes removing it from the race cache, from the
* {@link com.sap.sailing.domain.base.Regatta} and, if a {@link TrackedRace} for the corresponding
@@ -38,17 +38,19 @@ public class RaceRecord {
private final URI storedURI;
private final List<String> boatClassNames;
private final String raceStatus;
private final String raceVisibility;
private final URL jsonUrl;
public RaceRecord(URL jsonURL, String regattaName, String name, String replayURL, String paramURLAsString,
String ID, String trackingstarttime, String trackingendtime, String racestarttime,
String commaSeparatedBoatClassNames, String status, boolean loadLiveAndStoredURI)
String commaSeparatedBoatClassNames, String status, String visibility, boolean loadLiveAndStoredURI)
throws URISyntaxException, IOException {
super();
this.regattaName = regattaName;
this.name = name;
this.replayURL = replayURL;
this.raceStatus = status;
this.raceVisibility = visibility;
this.ID = ID;
this.jsonUrl = jsonURL;
this.boatClassNames = new ArrayList<String>();
@@ -188,6 +190,10 @@ public class RaceRecord {
return raceStatus;
}
public String getRaceVisibility() {
return raceVisibility;
}
public URL getJsonURL() {
return jsonUrl;
}
@@ -48,7 +48,7 @@ public interface TracTracAdapter {
*/
RaceHandle addTracTracRace(TrackerManager trackerManager, URL paramURL, URI liveURI, URI storedURI,
URI courseDesignUpdateURI, RaceLogStore raceLogStore, long timeoutInMilliseconds,
String tracTracUsername, String tracTracPassword, String raceStatus) throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
String tracTracUsername, String tracTracPassword, String raceStatus, String raceVisibility) throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
* Same as {@link #addTracTracRace(URL, URI, URI, WindStore, long)}, only that start and end of tracking are
@@ -68,7 +68,9 @@ public interface TracTracAdapter {
RaceHandle addTracTracRace(TrackerManager trackerManager, RegattaIdentifier regattaToAddTo, URL paramURL, URI liveURI,
URI storedURI, URI courseDesignUpdateURI, TimePoint trackingStartTime,
TimePoint trackingEndTime, RaceLogStore raceLogStore,
long timeoutForReceivingRaceDefinitionInMilliseconds, boolean simulateWithStartTimeNow, String tracTracUsername, String tracTracPassword, String raceStatus)
long timeoutForReceivingRaceDefinitionInMilliseconds, boolean simulateWithStartTimeNow,
String tracTracUsername, String tracTracPassword,
String raceStatus, String raceVisibility)
throws MalformedURLException, FileNotFoundException, URISyntaxException, Exception;
/**
@@ -9,9 +9,27 @@ public interface TracTracConnectionConstants {
final int PORT_LIVE = 1520; //For official usage use 4400; for SAP-dedicated server use 1520
final int PORT_STORED = PORT_LIVE + 1; //For official usage use 4401;
/*
* ‘Status’ is the one that we used originally and is an enumerate with the values:
* - HIDDEN: the race is hidden
* - OFFLINE: the race is visible but it can not be loaded
* - ONLINE: the race is visible and online
* - REPLAY: the race is online and the mtb-file has been created (this value is no longer being used as we no longer display information about whether data are being retrieved from data base or file)
* ‘Visibility’ was introduced this year to improve some short comings of the ‘status’ attribute and is an enumerate with the values:
* - HIDDEN: the race is hidden (same meaning as above)
* - OFFLINE: the race is visible but it can not be loaded (same meaning as above)
* - ONLINE: the race can be loaded and it is in a live status (live or future)
* - REPLAY: the race can be loaded and it is over (a race in the past)
* In addition to these we would like to add a new value for the visibility attribute called "UPCOMING" that means that the race is online (can be loaded) and it is in the future.
*/
final String HIDDEN_STATUS = "HIDDEN";
final String ONLINE_STATUS = "ONLINE";
final Object REPLAY_STATUS = "REPLAY";
final String HIDDEN_VISIBILITY = "HIDDEN";
final String ONLINE_VISIBILITY = "ONLINE";
final Object REPLAY_VISIBILITY = "REPLAY";
}
Loaded 100 of 763 files, more files were not shown because too many files have changed in this diff. Show more