Merge remote-tracking branch 'origin/master' into mark-rounding-inference

Conflicts:
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
This commit is contained in:
Nick Klose committed 2014-01-15 17:52:07 +01:00
commit 6f89b80167
215 files changed
+8139 -361

No files matched your search

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
@@ -0,0 +1 @@
/bin
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.datamining.shared</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false
@@ -0,0 +1,11 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Datamining-Shared
Bundle-SymbolicName: com.sap.sailing.datamining.shared
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
Export-Package: com.sap.sailing.datamining.shared
Import-Package: com.google.gwt.i18n.client
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.datamining.shared</artifactId>
<packaging>eclipse-plugin</packaging>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-source-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>plugin-source</id>
<phase>generate-sources</phase>
<goals>
<goal>plugin-source</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.4.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-module.dtd">
<module>
<source path='shared'/>
</module>
@@ -0,0 +1,18 @@
package com.sap.sailing.datamining.shared;
public abstract class AbstractGroupKey implements GroupKey {
private static final long serialVersionUID = 183947887066745315L;
@Override
public String toString() {
return asString();
}
//Enforce hash code and equals in all subclasses
@Override
public abstract boolean equals(Object other);
@Override
public abstract int hashCode();
}
@@ -0,0 +1,84 @@
package com.sap.sailing.datamining.shared;
public final class Components {
public enum GrouperType {
Dimensions
}
public enum AggregatorType {
Sum, Average, Median;
public Message getNameMessage() {
switch (this) {
case Average:
return Message.Average;
case Median:
return Message.Median;
case Sum:
return Message.Sum;
};
throw new IllegalArgumentException("No message available for the aggregator type '" + this + "'");
}
}
public static enum ValueType {
Integer, Double
}
public enum StatisticType {
Speed(ValueType.Double, Unit.Knots, 2),
Distance(ValueType.Double, Unit.Meters, 2);
private final ValueType valueType;
private final Unit unit;
private final int valueDecimals;
private StatisticType(ValueType valueType, Unit unit, int valueDecimals) {
this.valueType = valueType;
this.unit = unit;
this.valueDecimals = valueDecimals;
}
public ValueType 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;
}
}
private Components() {
}
}
@@ -0,0 +1,82 @@
package com.sap.sailing.datamining.shared;
public class CompoundGroupKey extends AbstractGroupKey {
private static final long serialVersionUID = -7902450253393172550L;
private GroupKey mainKey;
private GroupKey subKey;
/**
* Constructor for the GWT-Serialization. Don't use this!
*/
@Deprecated
CompoundGroupKey() { }
public CompoundGroupKey(GroupKey mainKey) {
this(mainKey, null);
}
public CompoundGroupKey(GroupKey mainKey, GroupKey subKey) {
this.mainKey = mainKey;
this.subKey = subKey;
}
@Override
public String asString() {
return mainKey.asString() + " (" + subKey.asString() + ")";
}
@Override
public boolean hasSubKey() {
return subKey != null;
}
@Override
public GroupKey getMainKey() {
return mainKey;
}
@Override
public GroupKey getSubKey() {
return subKey;
}
public void setSubKey(GroupKey subKey) {
this.subKey = subKey;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((mainKey == null) ? 0 : mainKey.hashCode());
result = prime * result + ((subKey == null) ? 0 : subKey.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CompoundGroupKey other = (CompoundGroupKey) obj;
if (mainKey == null) {
if (other.mainKey != null)
return false;
} else if (!mainKey.equals(other.mainKey))
return false;
if (subKey == null) {
if (other.subKey != null)
return false;
} else if (!subKey.equals(other.subKey))
return false;
return true;
}
}
@@ -0,0 +1,13 @@
package com.sap.sailing.datamining.shared;
import java.io.Serializable;
@SuppressWarnings("unused")
public final class DataMiningSerializationDummy implements Serializable {
private static final long serialVersionUID = 1L;
private GenericGroupKey<String> groupKey;
private DataMiningSerializationDummy() { }
}
@@ -0,0 +1,7 @@
package com.sap.sailing.datamining.shared;
public enum DataTypes {
GPSFix, TrackedLegOfCompetitor
}
@@ -0,0 +1,21 @@
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);
}
}
}
@@ -0,0 +1,64 @@
package com.sap.sailing.datamining.shared;
public class GenericGroupKey<T> extends AbstractGroupKey {
private static final long serialVersionUID = -3838535617341226965L;
private T value;
/**
* Constructor for the GWT-Serialization. Don't use this!
*/
@Deprecated
GenericGroupKey() { }
public GenericGroupKey(T value) {
this.value = value;
}
@Override
public boolean hasSubKey() {
return false;
}
@Override
public GroupKey getMainKey() {
return this;
}
@Override
public GroupKey getSubKey() {
return null;
}
@Override
public String asString() {
return value.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GenericGroupKey<?> other = (GenericGroupKey<?>) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.shared;
import java.io.Serializable;
public interface GroupKey extends Serializable {
/**
* @return a string representation of this group key.
*/
public String asString();
/**
* Checks if this group key has a sub key. For example if the data was grouped primary by competitor and secondary by leg type.
* @return true, if this group key has a sub key
*/
public boolean hasSubKey();
/**
* @return the main key, if there is one. Otherwise it returns <code>this</code>.
*/
public GroupKey getMainKey();
/**
* @return the sub key or null, if there's none.
*/
public GroupKey getSubKey();
}
@@ -0,0 +1,6 @@
package com.sap.sailing.datamining.shared;
public enum Message {
Average, Median, Sum, Distance, Speed, Knots, Meters, ResultSignifier, SignifierInUnit
}
@@ -0,0 +1,27 @@
package com.sap.sailing.datamining.shared;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import com.sap.sailing.datamining.shared.Components.AggregatorType;
import com.sap.sailing.datamining.shared.Components.GrouperType;
import com.sap.sailing.datamining.shared.Components.StatisticType;
public interface QueryDefinition extends Serializable {
public String getLocaleName();
public GrouperType getGrouperType();
public StatisticType getStatisticType();
public AggregatorType getAggregatorType();
public DataTypes getDataType();
public List<DimensionIdentifier> getDimensionsToGroupBy();
public Map<DimensionIdentifier, Iterable<?>> getSelection();
}
@@ -0,0 +1,22 @@
package com.sap.sailing.datamining.shared;
import java.io.Serializable;
import java.util.Map;
public interface QueryResult<AggregatedType> extends Serializable {
int getRetrievedDataAmount();
public int getFilteredDataAmount();
public double getCalculationTimeInSeconds();
public boolean isEmpty();
/**
* @return a description what kind of results are contained.
*/
public String getResultSignifier();
public Unit getUnit();
public int getValueDecimals();
public Map<GroupKey, AggregatedType> getResults();
}
@@ -0,0 +1,82 @@
package com.sap.sailing.datamining.shared;
import java.util.HashMap;
import java.util.Map;
public class QueryResultImpl<AggregatedType> implements QueryResult<AggregatedType> {
private static final long serialVersionUID = -8347731622150585715L;
private int retrievedDataAmount;
private int filteredDataAmount;
private long calculationTimeInNanos;
private String resultSignifier;
private Unit unit;
private int valueDecimals;
private Map<GroupKey, AggregatedType> results;
/**
* Constructor for the GWT-Serialization. Don't use this!
*/
@Deprecated
QueryResultImpl() { }
public QueryResultImpl(int retrievedDataAmount, int filteredDataAmount, String resultSiginifier, Unit unit, int valueDecimals) {
this.retrievedDataAmount = retrievedDataAmount;
this.filteredDataAmount = filteredDataAmount;
results = new HashMap<GroupKey, AggregatedType>();
this.resultSignifier = resultSiginifier;
this.unit = unit;
this.valueDecimals = valueDecimals;
}
@Override
public int getRetrievedDataAmount() {
return retrievedDataAmount;
}
@Override
public int getFilteredDataAmount() {
return filteredDataAmount;
}
@Override
public double getCalculationTimeInSeconds() {
return calculationTimeInNanos / 1000000000.0;
}
public void setCalculationTimeInNanos(long calculationTimeInNanos) {
this.calculationTimeInNanos = calculationTimeInNanos;
}
@Override
public boolean isEmpty() {
return results.isEmpty();
}
@Override
public String getResultSignifier() {
return resultSignifier;
}
@Override
public Unit getUnit() {
return unit;
}
@Override
public int getValueDecimals() {
return valueDecimals;
}
@Override
public Map<GroupKey, AggregatedType> getResults() {
return results;
}
public void addResult(GroupKey key, AggregatedType value) {
results.put(key, value);
}
}
@@ -0,0 +1,87 @@
package com.sap.sailing.datamining.shared;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gwt.i18n.client.LocaleInfo;
import com.sap.sailing.datamining.shared.Components.AggregatorType;
import com.sap.sailing.datamining.shared.Components.GrouperType;
import com.sap.sailing.datamining.shared.Components.StatisticType;
public class SimpleQueryDefinition implements QueryDefinition {
private static final long serialVersionUID = 3476324726640558091L;
private String localeName;
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(LocaleInfo localeInfo, GrouperType grouperType, StatisticType statisticType, AggregatorType aggregatorType, DataTypes dataType) {
this.localeName = localeInfo.getLocaleName();
this.grouperType = grouperType;
this.statisticType = statisticType;
this.aggregatorType = aggregatorType;
this.dataType = dataType;
dimensionsToGroupBy = new ArrayList<DimensionIdentifier>();
selectionMappedByDimension = new HashMap<DimensionIdentifier, Iterable<?>>();
}
@Override
public String getLocaleName() {
return localeName;
}
@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);
}
}
@@ -0,0 +1,7 @@
package com.sap.sailing.datamining.shared;
public enum Unit {
None, Knots, Meters
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<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="output" path="bin"/>
</classpath>
@@ -0,0 +1 @@
/bin
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.datamining.test</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
@@ -0,0 +1,12 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Test
Bundle-SymbolicName: com.sap.sailing.datamining.test
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Fragment-Host: com.sap.sailing.datamining
Import-Package: junit.framework;version="4.8.2",
org.junit;version="4.8.2"
Require-Bundle: org.mockito.mockito-core;bundle-version="1.9.5",
org.hamcrest;bundle-version="1.1.0"
@@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.datamining.test</artifactId>
<packaging>eclipse-test-plugin</packaging>
</project>
@@ -0,0 +1,78 @@
package com.sap.sailing.datamining.test;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.sap.sailing.datamining.AggregationWorker;
import com.sap.sailing.datamining.WorkReceiver;
import com.sap.sailing.datamining.impl.aggregators.SimpleIntegerArithmeticAverageAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.SumAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.helpers.SimpleIntegerSumAggregator;
import com.sap.sailing.datamining.shared.GenericGroupKey;
import com.sap.sailing.datamining.shared.GroupKey;
public class TestAggregators {
@Test
public void testSumAggregator() {
AggregationWorker<Integer, Integer> sumAggregator = new SumAggregationWorker<Integer, Integer>(new SimpleIntegerSumAggregator());
Map<GroupKey, Collection<Integer>> data = asDataToAggregate(1, 7, 6, 3);
sumAggregator.setDataToAggregate(data);
DataReceiver receiver = new DataReceiver();
sumAggregator.setReceiver(receiver);
sumAggregator.run();
Map<GroupKey, Integer> expectedAggregation = asAggregatedData(17);
assertEquals(expectedAggregation, receiver.result);
data = asDataToAggregate(7);
sumAggregator.setDataToAggregate(data);
sumAggregator.run();
expectedAggregation = asAggregatedData(7);
assertEquals(expectedAggregation, receiver.result);
}
@Test
public void testAverageAggregator() {
AggregationWorker<Integer, Integer> averageAggregator = new SimpleIntegerArithmeticAverageAggregationWorker();
Map<GroupKey, Collection<Integer>> data = asDataToAggregate(1, 7, 6, 3);
averageAggregator.setDataToAggregate(data);
DataReceiver receiver = new DataReceiver();
averageAggregator.setReceiver(receiver);
averageAggregator.run();
Map<GroupKey, Integer> expectedAggregation = asAggregatedData(4);
assertEquals(expectedAggregation, receiver.result);
}
private Map<GroupKey, Collection<Integer>> asDataToAggregate(Integer... values) {
Collection<Integer> dataEntries = Arrays.asList(values);
Map<GroupKey, Collection<Integer>> data = new HashMap<GroupKey, Collection<Integer>>();
data.put(new GenericGroupKey<Integer>(100), dataEntries);
return data;
}
private Map<GroupKey, Integer> asAggregatedData(Integer value) {
Map<GroupKey,Integer> data = new HashMap<GroupKey, Integer>();
data.put(new GenericGroupKey<Integer>(100), value);
return data;
}
private class DataReceiver implements WorkReceiver<Map<GroupKey, Integer>> {
public Map<GroupKey, Integer> result;
@Override
public void receiveWork(Map<GroupKey, Integer> result) {
this.result = result;
}
}
}
@@ -0,0 +1,32 @@
package com.sap.sailing.datamining.test;
import static org.junit.Assert.*;
import org.junit.Test;
import com.sap.sailing.datamining.ClusterOfComparable;
import com.sap.sailing.datamining.Clusters;
import com.sap.sailing.datamining.impl.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));
}
}
@@ -0,0 +1,59 @@
package com.sap.sailing.datamining.test;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.sap.sailing.datamining.ExtractionWorker;
import com.sap.sailing.datamining.WorkReceiver;
import com.sap.sailing.datamining.impl.AbstractExtractionWorker;
import com.sap.sailing.datamining.shared.GenericGroupKey;
import com.sap.sailing.datamining.shared.GroupKey;
public class TestExtractors {
@Test
public void testAbstractExtractor() {
ExtractionWorker<String, Integer> lengthExtractor = new LengthExtractor();
DataReceiver receiver = new DataReceiver();
lengthExtractor.setReceiver(receiver);
Collection<String> dataEntries = Arrays.asList("Fu", "Bar", "Blub");
Map<GroupKey, Collection<String>> data = new HashMap<GroupKey, Collection<String>>();
data.put(new GenericGroupKey<Integer>(100), dataEntries);
lengthExtractor.setDataToExtractFrom(data);
Collection<Integer> expectedExtractedDataEntries = Arrays.asList(2, 3, 4);
Map<GroupKey, Collection<Integer>> expectedExtractedData = new HashMap<GroupKey, Collection<Integer>>();
expectedExtractedData.put(new GenericGroupKey<Integer>(100), expectedExtractedDataEntries);
lengthExtractor.run();
assertEquals(expectedExtractedData, receiver.result);
}
private class LengthExtractor extends AbstractExtractionWorker<String, Integer> {
@Override
public Integer extract(String dataEntry) {
return dataEntry.length();
}
}
private class DataReceiver implements WorkReceiver<Map<GroupKey, Collection<Integer>>> {
public Map<GroupKey, Collection<Integer>> result;
@Override
public void receiveWork(Map<GroupKey, Collection<Integer>> result) {
this.result = result;
}
}
}
@@ -0,0 +1,87 @@
package com.sap.sailing.datamining.test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.sap.sailing.datamining.ClusterOfComparable;
import com.sap.sailing.datamining.ConcurrentFilterCriteria;
import com.sap.sailing.datamining.impl.ClusterOfComparableImpl;
import com.sap.sailing.datamining.impl.criterias.AndCompoundFilterCriteria;
import com.sap.sailing.datamining.impl.criterias.CompoundFilterCriteria;
import com.sap.sailing.datamining.impl.criterias.OrCompoundFilterCriteria;
import com.sap.sailing.datamining.impl.criterias.RegexFilterCriteria;
import com.sap.sailing.datamining.impl.criterias.SimpleRangeFilterCriteria;
public class TestFilterCriterias {
@Test
public void testRegexFilterCriteria() {
ConcurrentFilterCriteria<String> regexFilterCriteria = new StringRegexFilterCriteria(".*");
assertTrue(regexFilterCriteria.matches("some Random stuff"));
assertFalse(regexFilterCriteria.matches(null));
String[] stringsToMatch = new String[] {"Regatta", "Other Regatta", "Third Regatta"};
regexFilterCriteria = new StringRegexFilterCriteria(stringsToMatch[0] + "|" + stringsToMatch[1] + "|" + stringsToMatch[2]);
for (String stringToMatch : stringsToMatch) {
assertTrue("Failed to match " + stringToMatch, regexFilterCriteria.matches(stringToMatch));
}
assertFalse("'Fourth Regatta' shouldn't be matched", regexFilterCriteria.matches("Fourth Regatta"));
regexFilterCriteria = new StringRegexFilterCriteria(".*Regatta");
for (String stringToMatch : stringsToMatch) {
assertTrue("Failed to match " + stringToMatch, regexFilterCriteria.matches(stringToMatch));
}
assertFalse("'Regatta (29ER)' shouldn't be matched", regexFilterCriteria.matches("Regatta (29ER)"));
}
@Test
public void testRangeFilterCriteria() {
ClusterOfComparable<Integer> cluster = new ClusterOfComparableImpl<Integer>("Test", 3, 1);
ConcurrentFilterCriteria<Integer> rangeFilterCriteria = new SimpleRangeFilterCriteria<Integer>(cluster);
assertTrue(rangeFilterCriteria.matches(1));
assertTrue(rangeFilterCriteria.matches(2));
assertTrue(rangeFilterCriteria.matches(3));
assertFalse(rangeFilterCriteria.matches(0));
assertFalse(rangeFilterCriteria.matches(4));
}
@Test
public void testCompoundFilterCriterias() {
StringRegexFilterCriteria startsWithBar = new StringRegexFilterCriteria("Bar.*");
StringRegexFilterCriteria endWithFoo = new StringRegexFilterCriteria(".*Foo");
CompoundFilterCriteria<String> compoundCriteria = new AndCompoundFilterCriteria<String>();
compoundCriteria.addCriteria(startsWithBar);
compoundCriteria.addCriteria(endWithFoo);
assertTrue(compoundCriteria.matches("BarAndFoo"));
assertFalse(compoundCriteria.matches("BarFo"));
compoundCriteria = new OrCompoundFilterCriteria<String>();
compoundCriteria.addCriteria(startsWithBar);
compoundCriteria.addCriteria(endWithFoo);
assertTrue(compoundCriteria.matches("BarF"));
assertTrue(compoundCriteria.matches("BraFoo"));
assertFalse(compoundCriteria.matches("Nothing"));
}
private class StringRegexFilterCriteria extends RegexFilterCriteria<String> {
public StringRegexFilterCriteria(String regex) {
super(regex);
}
@Override
protected String getValueToMatch(String data) {
return data;
}
}
}
@@ -0,0 +1,49 @@
package com.sap.sailing.datamining.test;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import com.sap.sailing.datamining.ClusterOfComparable;
import com.sap.sailing.datamining.ConcurrentFilterCriteria;
import com.sap.sailing.datamining.FiltrationWorker;
import com.sap.sailing.datamining.WorkReceiver;
import com.sap.sailing.datamining.impl.ClusterOfComparableImpl;
import com.sap.sailing.datamining.impl.CriteriaFiltrationWorker;
import com.sap.sailing.datamining.impl.criterias.SimpleRangeFilterCriteria;
public class TestFilters {
@Test
public void testFilterByCriteria() {
List<Integer> data = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
ClusterOfComparable<Integer> cluster = new ClusterOfComparableImpl<Integer>("Test", 5, 1);
ConcurrentFilterCriteria<Integer> criteria = new SimpleRangeFilterCriteria<Integer>(cluster);
FiltrationWorker<Integer> filter = new CriteriaFiltrationWorker<Integer>(criteria);
filter.setDataToFilter(data);
Receiver receiver = new Receiver();
filter.setReceiver(receiver);
filter.run();
Collection<Integer> expectedFilteredData = Arrays.asList(1, 2, 3, 4, 5);
assertEquals(expectedFilteredData, receiver.data);
}
private class Receiver implements WorkReceiver<Collection<Integer>> {
public Collection<Integer> data;
@Override
public void receiveWork(Collection<Integer> data) {
this.data = data;
}
}
}
@@ -0,0 +1,69 @@
package com.sap.sailing.datamining.test;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
import com.sap.sailing.datamining.i18n.DataMiningResourceBundleManager;
public class TestI18N {
private static final String SIMPLE_TEST_MESSAGE_KEY = "SimpleTestMessage";
private static final String TEST_MESSAGE_WITH_PARAMETERS = "TestMessageWithParameters";
private OpenResourceBundleManager bundleManager;
@Before
public void initializeBundleManager() {
bundleManager = new OpenResourceBundleManager(Locale.ENGLISH);
}
@Test
public void testGettingASimpleMessage() {
assertThat(bundleManager.get("default", SIMPLE_TEST_MESSAGE_KEY), is("English"));
assertThat(bundleManager.get("en", SIMPLE_TEST_MESSAGE_KEY), is("English"));
assertThat(bundleManager.get("de", SIMPLE_TEST_MESSAGE_KEY), is("Deutsch"));
assertThat(bundleManager.get(Locale.ENGLISH, SIMPLE_TEST_MESSAGE_KEY), is("English"));
assertThat(bundleManager.get(Locale.GERMAN, SIMPLE_TEST_MESSAGE_KEY), is("Deutsch"));
}
@Test
public void testGettingAMessageWithParameters() {
assertThat(bundleManager.get("default", TEST_MESSAGE_WITH_PARAMETERS, "Param0", "Param1"), is("English Param0 - Param1"));
assertThat(bundleManager.get("en", TEST_MESSAGE_WITH_PARAMETERS, "Param0", "Param1"), is("English Param0 - Param1"));
assertThat(bundleManager.get("de", TEST_MESSAGE_WITH_PARAMETERS, "Param0", "Param1"), is("Deutsch Param0 - Param1"));
assertThat(bundleManager.get(Locale.ENGLISH, TEST_MESSAGE_WITH_PARAMETERS, "Param0", "Param1"), is("English Param0 - Param1"));
assertThat(bundleManager.get(Locale.GERMAN, TEST_MESSAGE_WITH_PARAMETERS, "Param0", "Param1"), is("Deutsch Param0 - Param1"));
}
private class OpenResourceBundleManager extends DataMiningResourceBundleManager {
public OpenResourceBundleManager(Locale defaultLocale) {
super(defaultLocale);
}
public String get(Locale locale, String message, String... parameters) {
return super.get(locale, message, parameters);
}
public String get(Locale locale, String message) {
return super.get(locale, message, new String[0]);
}
public String get(String localeName, String message, String... parameters) {
return this.get(getLocaleFrom(localeName), message, parameters);
}
public String get(String localeName, String message) {
return this.get(getLocaleFrom(localeName), message);
}
}
}
@@ -0,0 +1,172 @@
package com.sap.sailing.datamining.test.groupers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.junit.Test;
import com.sap.sailing.datamining.Dimension;
import com.sap.sailing.datamining.GroupingWorker;
import com.sap.sailing.datamining.WorkReceiver;
import com.sap.sailing.datamining.impl.AbstractDimension;
import com.sap.sailing.datamining.impl.MultiDimensionalGroupingWorker;
import com.sap.sailing.datamining.shared.CompoundGroupKey;
import com.sap.sailing.datamining.shared.GenericGroupKey;
import com.sap.sailing.datamining.shared.GroupKey;
public class TestDimensionGroupers {
@Test
public void testGroupByDimension() {
Dimension<Integer, String> crossSum = createCrossSumDimension();
GroupingWorker<Integer> groupByDimension = new OpenGrouper<Integer>(Arrays.asList(crossSum));
DataReceiver receiver = new DataReceiver();
groupByDimension.setReceiver(receiver);
Collection<Integer> data = Arrays.asList(11, 2, 13, 4, 22, 3, 21, 111);
groupByDimension.setDataToGroup(data);
Map<GroupKey, Collection<Integer>> expectedGroups = new HashMap<GroupKey, Collection<Integer>>();
Collection<Integer> group = new ArrayList<Integer>();
group.add(11);
group.add(2);
expectedGroups.put(new GenericGroupKey<String>("2"), group);
group = new ArrayList<Integer>();
group.add(3);
group.add(21);
group.add(111);
expectedGroups.put(new GenericGroupKey<String>("3"), group);
group = new ArrayList<Integer>();
group.add(13);
group.add(4);
group.add(22);
expectedGroups.put(new GenericGroupKey<String>("4"), group);
groupByDimension.run();
assertEquals(expectedGroups, receiver.groupedData);
}
@Test
public void testGroupKeyGeneration() {
Dimension<Integer, String> first = new AbstractDimension<Integer, String>("First") {
@Override
public String getDimensionValueFrom(Integer data) {
return "First";
}
};
Dimension<Integer, String> second = new AbstractDimension<Integer, String>("Second") {
@Override
public String getDimensionValueFrom(Integer data) {
return "Second";
}
};
Dimension<Integer, String> third = new AbstractDimension<Integer, String>("Third") {
@Override
public String getDimensionValueFrom(Integer data) {
return "Third";
}
};
OpenGrouper<Integer> grouper = new OpenGrouper<Integer>(Arrays.asList(first, second, third));
GroupKey expectedGroupKey = new CompoundGroupKey(new GenericGroupKey<String>("First"), new CompoundGroupKey(new GenericGroupKey<String>("Second"), new GenericGroupKey<String>("Third")));
assertEquals(expectedGroupKey, grouper.getGroupKey(1));
}
@Test
public void testGroupByMultipleDimensions() {
Dimension<Integer, String> crossSum = createCrossSumDimension();
Dimension<Integer, String> signum = createSignumDimension();
GroupingWorker<Integer> groupByDimensions = new OpenGrouper<Integer>(Arrays.asList(crossSum, signum));
DataReceiver receiver = new DataReceiver();
groupByDimensions.setReceiver(receiver);
Collection<Integer> data = Arrays.asList(13, -4, 22, -3, 21, -111);
groupByDimensions.setDataToGroup(data);
Map<GroupKey, Collection<Integer>> expectedGroups = new HashMap<GroupKey, Collection<Integer>>();
Collection<Integer> expectedGroup = new ArrayList<Integer>();
expectedGroup.add(-3);
expectedGroup.add(-111);
expectedGroups.put(new CompoundGroupKey(new GenericGroupKey<String>("3"), new GenericGroupKey<String>("-1")), expectedGroup);
expectedGroup = new ArrayList<Integer>();
expectedGroup.add(13);
expectedGroup.add(22);
expectedGroups.put(new CompoundGroupKey(new GenericGroupKey<String>("4"), new GenericGroupKey<String>("1")), expectedGroup);
expectedGroup = new ArrayList<Integer>();
expectedGroup.add(21);
expectedGroups.put(new CompoundGroupKey(new GenericGroupKey<String>("3"), new GenericGroupKey<String>("1")), expectedGroup);
expectedGroup = new ArrayList<Integer>();
expectedGroup.add(-4);
expectedGroups.put(new CompoundGroupKey(new GenericGroupKey<String>("4"), new GenericGroupKey<String>("-1")), expectedGroup);
groupByDimensions.run();
Map<GroupKey, Collection<Integer>> groups = receiver.groupedData;
for (Entry<GroupKey, Collection<Integer>> expectedGroupEntry : expectedGroups.entrySet()) {
Collection<Integer> group = groups.get(expectedGroupEntry.getKey());
assertNotNull("No group for key: " + expectedGroupEntry.getKey().asString(), group);
assertEquals(expectedGroupEntry.getValue(), group);
}
}
private Dimension<Integer, String> createCrossSumDimension() {
return new AbstractDimension<Integer, String>("Cross Sum") {
@Override
public String getDimensionValueFrom(Integer data) {
int crossSum = 0;
int value = Math.abs(data);
while (value > 0) {
crossSum += value % 10;
value /= 10;
}
return crossSum + "";
}
};
}
private AbstractDimension<Integer, String> createSignumDimension() {
return new AbstractDimension<Integer, String>("Signum") {
@Override
public String getDimensionValueFrom(Integer data) {
return ((int) Math.signum(data)) + "";
}
};
}
private static class OpenGrouper<DataType> extends MultiDimensionalGroupingWorker<DataType, String> {
public OpenGrouper(Collection<Dimension<DataType, String>> dimensions) {
super(dimensions);
}
@Override
protected GroupKey createGroupKeyFor(DataType dataEntry, Dimension<DataType, String> dimension) {
return new GenericGroupKey<String>(dimension.getDimensionValueFrom(dataEntry));
}
public GroupKey getGroupKey(DataType dataEntry) {
return getGroupKeyFor(dataEntry);
}
}
private static class DataReceiver implements WorkReceiver<Map<GroupKey, Collection<Integer>>> {
public Map<GroupKey, Collection<Integer>> groupedData;
@Override
public void receiveWork(Map<GroupKey, Collection<Integer>> result) {
groupedData = result;
}
}
}
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<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>
@@ -0,0 +1 @@
/bin
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.sap.sailing.datamining</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
<arguments>
</arguments>
</buildCommand> </buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
</natures>
</projectDescription>
@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
@@ -0,0 +1,3 @@
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false
@@ -0,0 +1,15 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Datamining
Bundle-SymbolicName: com.sap.sailing.datamining
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: SAP
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Import-Package: com.google.gwt.i18n.client,
com.sap.sailing.server
Export-Package: com.sap.sailing.datamining
Require-Bundle: com.sap.sailing.domain;bundle-version="1.0.0",
com.sap.sailing.domain.common,
com.sap.sailing.datamining.shared;bundle-version="1.0.0"
Bundle-ClassPath: .
@@ -0,0 +1,6 @@
source.. = src/,\
resources/
output.. = bin/
bin.includes = META-INF/,\
.
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>root</artifactId>
<groupId>com.sap.sailing</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>com.sap.sailing.datamining</artifactId>
<packaging>eclipse-plugin</packaging>
</project>
@@ -0,0 +1,11 @@
SimpleTestMessage=Deutsch
TestMessageWithParameters=Deutsch {0} - {1}
Average=Durchschnitt
Median=Median
Sum=Summe
Distance=Distanz
Speed=Geschwindigkeit
Meters=Metern
Knots=Knoten
ResultSignifier={0} ({1})
SignifierInUnit={0} in {1}
@@ -0,0 +1,11 @@
SimpleTestMessage=English
TestMessageWithParameters=English {0} - {1}
Average=Average
Median=Median
Sum=Sum
Distance=Distance
Speed=Speed
Meters=meters
Knots=knots
ResultSignifier={0} ({1})
SignifierInUnit={0} in {1}
@@ -0,0 +1,12 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import java.util.Map;
import com.sap.sailing.datamining.shared.GroupKey;
public interface AggregationWorker<ExtractedType, AggregatedType> extends ComponentWorker<Map<GroupKey, AggregatedType>> {
public void setDataToAggregate(Map<GroupKey, Collection<ExtractedType>> data);
}
@@ -0,0 +1,13 @@
package com.sap.sailing.datamining;
import java.util.Comparator;
public interface Cluster<ValueType> {
public String getName();
public ValueType getUpperRange();
public ValueType getLowerRange();
public boolean isInRange(ValueType value, Comparator<ValueType> comparator);
}
@@ -0,0 +1,7 @@
package com.sap.sailing.datamining;
public interface ClusterOfComparable<ValueType extends Comparable<ValueType>> extends Cluster<ValueType> {
public boolean isInRange(ValueType value);
}
@@ -0,0 +1,46 @@
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;
}
}
}
@@ -0,0 +1,10 @@
package com.sap.sailing.datamining;
public interface ComponentWorker<ResultType> extends Runnable {
public void setReceiver(WorkReceiver<ResultType> receiver);
public boolean isDone();
}
@@ -0,0 +1,7 @@
package com.sap.sailing.datamining;
public interface ConcurrentFilterCriteria<DataType> {
public boolean matches(DataType dataEntry);
}
@@ -0,0 +1,50 @@
package com.sap.sailing.datamining;
import java.util.Locale;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.sap.sailing.datamining.factories.AggregatorFactory;
import com.sap.sailing.datamining.factories.DataRetrieverFactory;
import com.sap.sailing.datamining.factories.ExtractorFactory;
import com.sap.sailing.datamining.factories.FilterFactory;
import com.sap.sailing.datamining.factories.GrouperFactory;
import com.sap.sailing.datamining.i18n.DataMiningResourceBundleManager;
import com.sap.sailing.datamining.impl.QueryImpl;
import com.sap.sailing.datamining.shared.QueryDefinition;
public final class DataMiningFactory {
private static final int THREAD_POOL_SIZE = Math.max(Runtime.getRuntime().availableProcessors(), 3);
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
private static final DataMiningStringMessages stringMessages = new DataMiningResourceBundleManager(Locale.ENGLISH);
private DataMiningFactory() { }
public static <DataType, AggregatedType extends Number> Query<DataType, AggregatedType> createQuery(QueryDefinition queryDefinition) {
Locale locale = stringMessages.getLocaleFrom(queryDefinition.getLocaleName());
ParallelDataRetriever<DataType> retriever = DataRetrieverFactory.createDataRetriever(queryDefinition.getDataType(), executor);
ParallelFilter<DataType> filter = createFilter(queryDefinition);
ParallelGrouper<DataType> grouper = GrouperFactory.createGrouper(queryDefinition, executor);
ParallelExtractor<DataType, AggregatedType> extractor = ExtractorFactory.createExtractor(stringMessages, locale, queryDefinition.getStatisticType(), executor);
ParallelAggregator<AggregatedType, AggregatedType> aggregator = AggregatorFactory.createAggregator(stringMessages, locale, queryDefinition.getStatisticType().getValueType(),
queryDefinition.getAggregatorType(), executor);
return new QueryImpl<DataType, AggregatedType, AggregatedType>(stringMessages, 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, executor);
}
}
@@ -0,0 +1,19 @@
package com.sap.sailing.datamining;
import java.util.Locale;
import com.sap.sailing.datamining.shared.Message;
public interface DataMiningStringMessages {
Locale getLocaleFrom(String localeName);
public String get(String localeName, Message message);
public String get(String localeName, Message message, String... parameters);
public String get(String localeName, Message message, Message... parameters);
public String get(Locale locale, Message message);
public String get(Locale locale, Message message, String... parameters);
public String get(Locale locale, Message message, Message... parameters);
}
@@ -0,0 +1,11 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import com.sap.sailing.domain.leaderboard.LeaderboardGroup;
public interface DataRetrievalWorker<DataType> extends ComponentWorker<Collection<DataType>> {
public void setGroup(LeaderboardGroup group);
}
@@ -0,0 +1,10 @@
package com.sap.sailing.datamining;
public interface Dimension<DataType, ValueType> {
public String getName();
public ValueType getDimensionValueFrom(DataType dataEntry);
}
@@ -0,0 +1,12 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import java.util.Map;
import com.sap.sailing.datamining.shared.GroupKey;
public interface ExtractionWorker<DataType, ExtractedType> extends ComponentWorker<Map<GroupKey, Collection<ExtractedType>>> {
public void setDataToExtractFrom(Map<GroupKey, Collection<DataType>> data);
}
@@ -0,0 +1,9 @@
package com.sap.sailing.datamining;
import java.util.Collection;
public interface FiltrationWorker<DataType> extends ComponentWorker<Collection<DataType>> {
public void setDataToFilter(Collection<DataType> data);
}
@@ -0,0 +1,12 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import java.util.Map;
import com.sap.sailing.datamining.shared.GroupKey;
public interface GroupingWorker<DataType> extends ComponentWorker<Map<GroupKey, Collection<DataType>>> {
public void setDataToGroup(Collection<DataType> data);
}
@@ -0,0 +1,14 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import java.util.Map;
import com.sap.sailing.datamining.impl.ParallelComponent;
import com.sap.sailing.datamining.shared.GroupKey;
public interface ParallelAggregator<ExtractedType, AggregatedType> extends ParallelComponent<Map<GroupKey, Collection<ExtractedType>>,
Map<GroupKey, AggregatedType>> {
public String getName();
}
@@ -0,0 +1,10 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import com.sap.sailing.datamining.impl.ParallelComponent;
import com.sap.sailing.server.RacingEventService;
public interface ParallelDataRetriever<DataType> extends ParallelComponent<RacingEventService, Collection<DataType>> {
}
@@ -0,0 +1,19 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import java.util.Map;
import com.sap.sailing.datamining.impl.ParallelComponent;
import com.sap.sailing.datamining.shared.GroupKey;
import com.sap.sailing.datamining.shared.Unit;
public interface ParallelExtractor<DataType, ExtractedType> extends ParallelComponent<Map<GroupKey, Collection<DataType>>,
Map<GroupKey, Collection<ExtractedType>>> {
public Unit getUnit();
public int getValueDecimals();
public String getSignifier();
}
@@ -0,0 +1,9 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import com.sap.sailing.datamining.impl.ParallelComponent;
public interface ParallelFilter<DataType> extends ParallelComponent<Collection<DataType>, Collection<DataType>> {
}
@@ -0,0 +1,11 @@
package com.sap.sailing.datamining;
import java.util.Collection;
import java.util.Map;
import com.sap.sailing.datamining.impl.ParallelComponent;
import com.sap.sailing.datamining.shared.GroupKey;
public interface ParallelGrouper<DataType> extends ParallelComponent<Collection<DataType>, Map<GroupKey, Collection<DataType>>> {
}
@@ -0,0 +1,12 @@
package com.sap.sailing.datamining;
import java.util.concurrent.ExecutionException;
import com.sap.sailing.datamining.shared.QueryResult;
import com.sap.sailing.server.RacingEventService;
public interface Query<DataType, AggregatedType> {
public QueryResult<AggregatedType> run(RacingEventService racingEventService) throws InterruptedException, ExecutionException;
}
@@ -0,0 +1,5 @@
package com.sap.sailing.datamining;
public interface WindStrengthCluster extends ClusterOfComparable<Double> {
}
@@ -0,0 +1,7 @@
package com.sap.sailing.datamining;
public interface WorkReceiver<ResultType> {
public void receiveWork(ResultType result);
}
@@ -0,0 +1,8 @@
package com.sap.sailing.datamining;
public interface WorkerBuilder<WorkerType> {
public WorkerType build();
}
@@ -0,0 +1,64 @@
package com.sap.sailing.datamining.builders;
import com.sap.sailing.datamining.AggregationWorker;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.impl.aggregators.SimpleDoubleArithmeticAverageAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.SimpleDoubleMedianAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.SimpleIntegerArithmeticAverageAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.SimpleIntegerMedianAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.SumAggregationWorker;
import com.sap.sailing.datamining.impl.aggregators.helpers.SimpleDoubleSumAggregator;
import com.sap.sailing.datamining.impl.aggregators.helpers.SimpleIntegerSumAggregator;
import com.sap.sailing.datamining.shared.Components.AggregatorType;
import com.sap.sailing.datamining.shared.Components.ValueType;
public class AggregationWorkerBuilder<ExtractedType, AggregatedType> implements WorkerBuilder<AggregationWorker<ExtractedType, AggregatedType>> {
private ValueType valueType;
private AggregatorType aggregatorType;
public AggregationWorkerBuilder(ValueType valueType, AggregatorType aggregatorType) {
this.valueType = valueType;
this.aggregatorType = aggregatorType;
}
@Override
@SuppressWarnings("unchecked")
public AggregationWorker<ExtractedType, AggregatedType> build() {
switch (valueType) {
case Double:
return (AggregationWorker<ExtractedType, AggregatedType>) createDoubleAggregationWorker(aggregatorType);
case Integer:
return (AggregationWorker<ExtractedType, AggregatedType>) createIntegerAggregationWorker(aggregatorType);
}
throw new IllegalArgumentException("Not yet implemented for the given statistics value type: "
+ valueType.toString());
}
public static AggregationWorker<Integer, Integer> createIntegerAggregationWorker(AggregatorType aggregatorType) {
switch (aggregatorType) {
case Average:
return new SimpleIntegerArithmeticAverageAggregationWorker();
case Sum:
return new SumAggregationWorker<Integer, Integer>(new SimpleIntegerSumAggregator());
case Median:
return new SimpleIntegerMedianAggregationWorker();
}
throw new IllegalArgumentException("Not yet implemented for the given aggregator type: "
+ aggregatorType.toString());
}
public static AggregationWorker<Double, Double> createDoubleAggregationWorker(AggregatorType aggregatorType) {
switch (aggregatorType) {
case Average:
return new SimpleDoubleArithmeticAverageAggregationWorker();
case Sum:
return new SumAggregationWorker<Double, Double>(new SimpleDoubleSumAggregator());
case Median:
return new SimpleDoubleMedianAggregationWorker();
}
throw new IllegalArgumentException("Not yet implemented for the given aggregator type: "
+ aggregatorType.toString());
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.builders;
import com.sap.sailing.datamining.DataRetrievalWorker;
import com.sap.sailing.datamining.WorkerBuilder;
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;
public class DataRetrieverWorkerBuilder<DataType> implements WorkerBuilder<DataRetrievalWorker<DataType>> {
private final DataTypes dataType;
public DataRetrieverWorkerBuilder(DataTypes dataType) {
this.dataType = dataType;
}
@Override
@SuppressWarnings("unchecked")
public DataRetrievalWorker<DataType> build() {
switch (dataType) {
case GPSFix:
return (DataRetrievalWorker<DataType>) new GPSFixLeaderboardGroupDataRetrievalWorker();
case TrackedLegOfCompetitor:
return (DataRetrievalWorker<DataType>) new TrackedLegOfCompetitorLeaderboardGroupDataRetrievalWorker();
}
throw new IllegalArgumentException("Not yet implemented for the given data type: " + dataType.toString());
}
}
@@ -0,0 +1,30 @@
package com.sap.sailing.datamining.builders;
import com.sap.sailing.datamining.ExtractionWorker;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.impl.SpeedInKnotsExtractionWorker;
import com.sap.sailing.datamining.impl.tracked_leg_of_competitor.DistanceTraveledExtractionWorker;
import com.sap.sailing.datamining.shared.Components.StatisticType;
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());
}
}
@@ -0,0 +1,21 @@
package com.sap.sailing.datamining.builders;
import com.sap.sailing.datamining.ConcurrentFilterCriteria;
import com.sap.sailing.datamining.FiltrationWorker;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.impl.CriteriaFiltrationWorker;
public class FilterByCriteriaBuilder<DataType> implements WorkerBuilder<FiltrationWorker<DataType>> {
private ConcurrentFilterCriteria<DataType> criteria;
public FilterByCriteriaBuilder(ConcurrentFilterCriteria<DataType> criteria) {
this.criteria = criteria;
}
@Override
public FiltrationWorker<DataType> build() {
return new CriteriaFiltrationWorker<DataType>(criteria);
}
}
@@ -0,0 +1,23 @@
package com.sap.sailing.datamining.builders;
import java.util.Collection;
import com.sap.sailing.datamining.Dimension;
import com.sap.sailing.datamining.GroupingWorker;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.impl.MultiDimensionalGroupingWorker;
public class MultiDimensionalGroupingWorkerBuilder<DataType, ValueType> implements WorkerBuilder<GroupingWorker<DataType>> {
private Collection<Dimension<DataType, ValueType>> dimensions;
public MultiDimensionalGroupingWorkerBuilder(Collection<Dimension<DataType, ValueType>> dimensions) {
this.dimensions = dimensions;
}
@Override
public GroupingWorker<DataType> build() {
return new MultiDimensionalGroupingWorker<DataType, ValueType>(dimensions);
}
}
@@ -0,0 +1,5 @@
package com.sap.sailing.datamining.data;
public interface GPSFixContext extends TrackedLegOfCompetitorContext {
}
@@ -0,0 +1,28 @@
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;
public interface GPSFixWithContext extends GPSFixMoving {
public String getRegattaName();
public String getRaceName();
public int getLegNumber();
public String getCourseAreaName();
public String getFleetName();
public String getBoatClassName();
/**
* The year of the start of the race.
*/
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.
*/
public LegType getLegType();
public String getCompetitorName();
public String getCompetitorSailID();
public String getCompetitorNationality();
public WindStrengthCluster getWindStrength();
}
@@ -0,0 +1,23 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.common.LegType;
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 interface TrackedLegContext {
public LeaderboardGroup getLeaderboardGroup();
public Leaderboard getLeaderboard();
public CourseArea getCourseArea();
public Fleet getFleet();
public TrackedRace getTrackedRace();
public TrackedLeg getTrackedLeg();
public LegType getLegType();
public int getLegNumber();
public Integer getYear();
}
@@ -0,0 +1,9 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.Competitor;
public interface TrackedLegOfCompetitorContext extends TrackedLegContext {
public Competitor getCompetitor();
}
@@ -0,0 +1,26 @@
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;
public interface TrackedLegOfCompetitorWithContext {
public String getRegattaName();
public String getRaceName();
public int getLegNumber();
public String getCourseAreaName();
public String getFleetName();
public String getBoatClassName();
/**
* The year of the start of the race.
*/
public Integer getYear();
public LegType getLegType();
public String getCompetitorName();
public String getCompetitorSailID();
public String getCompetitorNationality();
public WindStrengthCluster getWindStrength();
public Distance getDistanceTraveled();
}
@@ -0,0 +1,26 @@
package com.sap.sailing.datamining.data.impl;
import com.sap.sailing.datamining.data.GPSFixContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorContext;
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 GPSFixContextImpl extends TrackedLegOfCompetitorContextImpl implements GPSFixContext {
public GPSFixContextImpl(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 GPSFixContextImpl(TrackedLegOfCompetitorContext baseContext) {
this(baseContext.getLeaderboardGroup(), baseContext.getLeaderboard(), baseContext.getCourseArea(), baseContext.getFleet(),
baseContext.getTrackedRace(), baseContext.getTrackedLeg(), baseContext.getLegNumber(),
baseContext.getCompetitor());
}
}
@@ -0,0 +1,128 @@
package com.sap.sailing.datamining.data.impl;
import java.util.Calendar;
import com.sap.sailing.datamining.data.TrackedLegContext;
import com.sap.sailing.domain.base.CourseArea;
import com.sap.sailing.domain.base.Fleet;
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 TrackedLegContextImpl implements TrackedLegContext {
private LeaderboardGroup leaderboardGroup;
private Leaderboard leaderboard;
private CourseArea courseArea;
private Fleet fleet;
private TrackedRace trackedRace;
private TrackedLeg trackedLeg;
private LegType legType;
private int legNumber;
private Integer year;
private boolean legTypeHasBeenInitialized;
private boolean yearHasBeenInitialized;
public TrackedLegContextImpl(LeaderboardGroup leaderboardGroup, Leaderboard leaderboard, CourseArea courseArea, Fleet fleet,
TrackedRace trackedRace, TrackedLeg trackedLeg, int legNumber) {
this.leaderboardGroup = leaderboardGroup;
this.leaderboard = leaderboard;
this.courseArea = courseArea;
this.fleet = fleet;
this.trackedRace = trackedRace;
this.trackedLeg = trackedLeg;
this.legNumber = legNumber;
}
@Override
public LeaderboardGroup getLeaderboardGroup() {
return leaderboardGroup;
}
@Override
public Leaderboard getLeaderboard() {
return leaderboard;
}
@Override
public CourseArea getCourseArea() {
return courseArea;
}
@Override
public Fleet getFleet() {
return fleet;
}
@Override
public TrackedRace getTrackedRace() {
return trackedRace;
}
@Override
public TrackedLeg getTrackedLeg() {
return trackedLeg;
}
@Override
public LegType getLegType() {
if (!legTypeHasBeenInitialized) {
initializeLegType();
}
return legType;
}
@Override
public int getLegNumber() {
return legNumber;
}
@Override
public Integer getYear() {
if (!yearHasBeenInitialized) {
initializeYear();
}
return year;
}
private void initializeLegType() {
try {
legType = getTrackedLeg() == null ? null : getTrackedLeg().getLegType(getTimePointForLegType());
} catch (NoWindException e) {
legType = null;
}
legTypeHasBeenInitialized = true;
}
private TimePoint getTimePointForLegType() {
TimePoint at = null;
for (TrackedLegOfCompetitor trackedLegOfCompetitor : getTrackedLeg().getTrackedLegsOfCompetitors()) {
TimePoint start = trackedLegOfCompetitor.getStartTime();
TimePoint finish = trackedLegOfCompetitor.getFinishTime();
if (start != null && finish != null) {
at = new MillisecondsTimePoint((start.asMillis() + finish.asMillis()) / 2);
break;
}
}
return at;
}
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,34 @@
package com.sap.sailing.datamining.data.impl;
import com.sap.sailing.datamining.data.TrackedLegContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorContext;
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 TrackedLegOfCompetitorContextImpl extends TrackedLegContextImpl implements TrackedLegOfCompetitorContext {
private Competitor competitor;
public TrackedLegOfCompetitorContextImpl(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 TrackedLegOfCompetitorContextImpl(TrackedLegContext 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;
}
}
@@ -0,0 +1,10 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.Dimension;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
public interface DimensionManager<DataType> {
public Dimension<DataType, ?> getDimensionFor(DimensionIdentifier sharedDimension);
}
@@ -0,0 +1,26 @@
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());
}
}
@@ -0,0 +1,133 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.Dimension;
import com.sap.sailing.datamining.data.GPSFixWithContext;
import com.sap.sailing.datamining.impl.AbstractDimension;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.domain.common.LegType;
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();
}
};
}
@@ -0,0 +1,132 @@
package com.sap.sailing.datamining.dimensions;
import com.sap.sailing.datamining.Dimension;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorWithContext;
import com.sap.sailing.datamining.impl.AbstractDimension;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.domain.common.LegType;
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();
}
};
}
@@ -0,0 +1,26 @@
package com.sap.sailing.datamining.factories;
import java.util.Locale;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.AggregationWorker;
import com.sap.sailing.datamining.DataMiningStringMessages;
import com.sap.sailing.datamining.ParallelAggregator;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.builders.AggregationWorkerBuilder;
import com.sap.sailing.datamining.impl.GroupDividingParallelAggregator;
import com.sap.sailing.datamining.shared.Components.AggregatorType;
import com.sap.sailing.datamining.shared.Components.ValueType;
public final class AggregatorFactory {
private AggregatorFactory() { }
public static <ExtractedType, AggregatedType> ParallelAggregator<ExtractedType, AggregatedType> createAggregator(DataMiningStringMessages stringMessages,
Locale locale,
ValueType valueType, AggregatorType aggregatorType, ThreadPoolExecutor executor) {
WorkerBuilder<AggregationWorker<ExtractedType, AggregatedType>> workerBuilder = new AggregationWorkerBuilder<ExtractedType, AggregatedType>(valueType, aggregatorType);
return new GroupDividingParallelAggregator<ExtractedType, AggregatedType>(stringMessages.get(locale, aggregatorType.getNameMessage()), workerBuilder, executor);
}
}
@@ -0,0 +1,27 @@
package com.sap.sailing.datamining.factories;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.ParallelDataRetriever;
import com.sap.sailing.datamining.DataRetrievalWorker;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.builders.DataRetrieverWorkerBuilder;
import com.sap.sailing.datamining.impl.GroupDividingParallelDataRetriever;
import com.sap.sailing.datamining.shared.DataTypes;
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.
* @param racingService
*/
public static <DataType> ParallelDataRetriever<DataType> createDataRetriever(DataTypes dataType, ThreadPoolExecutor executor) {
WorkerBuilder<DataRetrievalWorker<DataType>> workerBuilder = new DataRetrieverWorkerBuilder<DataType>(dataType);
return new GroupDividingParallelDataRetriever<DataType>(workerBuilder, executor);
}
}
@@ -0,0 +1,29 @@
package com.sap.sailing.datamining.factories;
import java.util.Locale;
import java.util.concurrent.ThreadPoolExecutor;
import com.sap.sailing.datamining.DataMiningStringMessages;
import com.sap.sailing.datamining.ExtractionWorker;
import com.sap.sailing.datamining.ParallelExtractor;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.builders.ExtractionWorkerBuilder;
import com.sap.sailing.datamining.impl.GroupDividingParallelExtractor;
import com.sap.sailing.datamining.shared.Message;
import com.sap.sailing.datamining.shared.Unit;
import com.sap.sailing.datamining.shared.Components.StatisticType;
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);
}
}
@@ -0,0 +1,64 @@
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.Dimension;
import com.sap.sailing.datamining.ParallelFilter;
import com.sap.sailing.datamining.ConcurrentFilterCriteria;
import com.sap.sailing.datamining.FiltrationWorker;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.builders.FilterByCriteriaBuilder;
import com.sap.sailing.datamining.dimensions.DimensionManager;
import com.sap.sailing.datamining.dimensions.DimensionManagerProvider;
import com.sap.sailing.datamining.impl.NonFilteringFilter;
import com.sap.sailing.datamining.impl.PartitioningParallelFilter;
import com.sap.sailing.datamining.impl.criterias.AndCompoundFilterCriteria;
import com.sap.sailing.datamining.impl.criterias.CompoundFilterCriteria;
import com.sap.sailing.datamining.impl.criterias.DimensionValuesFilterCriteria;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
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) {
ConcurrentFilterCriteria<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> ConcurrentFilterCriteria<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) {
ConcurrentFilterCriteria<DataType> criteria = createDimensionFilterCriteria(dimension, entry.getValue());
compoundCriteria.addCriteria(criteria);
}
}
return compoundCriteria;
}
@SuppressWarnings("unchecked")
private static <DataType, ValueType> ConcurrentFilterCriteria<DataType> createDimensionFilterCriteria(Dimension<DataType, ValueType> dimension, Iterable<?> values) {
return new DimensionValuesFilterCriteria<DataType, ValueType>(dimension, (Collection<ValueType>) values);
}
}
@@ -0,0 +1,49 @@
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.Dimension;
import com.sap.sailing.datamining.GroupingWorker;
import com.sap.sailing.datamining.ParallelGrouper;
import com.sap.sailing.datamining.WorkerBuilder;
import com.sap.sailing.datamining.builders.MultiDimensionalGroupingWorkerBuilder;
import com.sap.sailing.datamining.dimensions.DimensionManager;
import com.sap.sailing.datamining.dimensions.DimensionManagerProvider;
import com.sap.sailing.datamining.impl.PartitioningParallelGrouper;
import com.sap.sailing.datamining.shared.DataTypes;
import com.sap.sailing.datamining.shared.DimensionIdentifier;
import com.sap.sailing.datamining.shared.QueryDefinition;
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,91 @@
package com.sap.sailing.datamining.i18n;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import com.sap.sailing.datamining.DataMiningStringMessages;
import com.sap.sailing.datamining.shared.Message;
public class DataMiningResourceBundleManager implements DataMiningStringMessages {
private static final String DEFAULT_LOCALE_NAME = "default";
private static final String STRING_MESSAGES_BASE_NAME = "stringmessages/StringMessages";
private static final String MESSAGE_PARAMETER_START = "\\{";
private static final String MESSAGE_PARAMETER_END = "\\}";
private Map<String, Locale> supportedLocalesMappedByLocaleInfo;
private Map<Locale, ResourceBundle> messagesMappedByLocale;
public DataMiningResourceBundleManager(Locale defaultLocale) {
supportedLocalesMappedByLocaleInfo = new HashMap<>();
messagesMappedByLocale = new HashMap<>();
initializeSupportedLocales(defaultLocale);
}
protected String get(Locale locale, String message, String... parameters) {
String result = getResourceBundle(locale).getString(message);
for (int i = 0; i < parameters.length; i++) {
String replacementRegex = MESSAGE_PARAMETER_START + i + MESSAGE_PARAMETER_END;
result = result.replaceAll(replacementRegex, parameters[i]);
}
return result;
}
@Override
public String get(Locale locale, Message message, String... parameters) {
return get(locale, message.toString(), parameters);
}
@Override
public String get(Locale locale, Message message, Message... parameters) {
String[] parametersAsString = new String[parameters.length];
for (int i = 0; i < parameters.length; i++) {
parametersAsString[i] = get(locale, parameters[i]);
}
return get(locale, message, parametersAsString);
}
@Override
public String get(Locale locale, Message message) {
return get(locale, message, new String[0]);
}
@Override
public String get(String localeName, Message message, String... parameters) {
return get(getLocaleFrom(localeName), message, parameters);
}
@Override
public String get(String localeName, Message message, Message... parameters) {
return get(getLocaleFrom(localeName), message, parameters);
}
@Override
public String get(String localeName, Message message) {
return get(getLocaleFrom(localeName), message);
}
@Override
public Locale getLocaleFrom(String localeName) {
Locale locale = supportedLocalesMappedByLocaleInfo.get(localeName);
return locale != null ? locale : supportedLocalesMappedByLocaleInfo.get(DEFAULT_LOCALE_NAME);
}
private ResourceBundle getResourceBundle(Locale locale) {
if (!messagesMappedByLocale.containsKey(locale)) {
messagesMappedByLocale.put(locale, ResourceBundle.getBundle(STRING_MESSAGES_BASE_NAME, locale));
}
return messagesMappedByLocale.get(locale);
}
private void initializeSupportedLocales(Locale defaultLocale) {
supportedLocalesMappedByLocaleInfo.put(DEFAULT_LOCALE_NAME, defaultLocale);
supportedLocalesMappedByLocaleInfo.put("en", Locale.ENGLISH);
supportedLocalesMappedByLocaleInfo.put("de", Locale.GERMAN);
}
}
@@ -0,0 +1,33 @@
package com.sap.sailing.datamining.impl;
import com.sap.sailing.datamining.ComponentWorker;
import com.sap.sailing.datamining.WorkReceiver;
public abstract class AbstractComponentWorker<ResultType> implements ComponentWorker<ResultType> {
private WorkReceiver<ResultType> receiver;
private boolean done;
@Override
public void run() {
receiver.receiveWork(doWork());
done = true;
}
protected abstract ResultType doWork();
@Override
public void setReceiver(WorkReceiver<ResultType> receiver) {
this.receiver = receiver;
}
@Override
public boolean isDone() {
return done;
}
protected WorkReceiver<ResultType> getReceiver() {
return receiver;
}
}
@@ -0,0 +1,48 @@
package com.sap.sailing.datamining.impl;
import com.sap.sailing.datamining.Dimension;
public abstract class AbstractDimension<DataType, ValueType> implements Dimension<DataType, ValueType> {
private String name;
public AbstractDimension(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public String toString() {
return getName();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractDimension<?, ?> other = (AbstractDimension<?, ?>) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
@@ -0,0 +1,43 @@
package com.sap.sailing.datamining.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import com.sap.sailing.datamining.ExtractionWorker;
import com.sap.sailing.datamining.shared.GroupKey;
public abstract class AbstractExtractionWorker<DataType, ExtractedType> extends AbstractComponentWorker<Map<GroupKey, Collection<ExtractedType>>>
implements ExtractionWorker<DataType, ExtractedType> {
private Map<GroupKey, Collection<DataType>> data;
@Override
public void setDataToExtractFrom(Map<GroupKey, Collection<DataType>> data) {
this.data = data;
}
@Override
protected Map<GroupKey, Collection<ExtractedType>> doWork() {
Map<GroupKey, Collection<ExtractedType>> extractedData = new HashMap<GroupKey, Collection<ExtractedType>>();
for (Entry<GroupKey, Collection<DataType>> dataEntry : data.entrySet()) {
GroupKey key = dataEntry.getKey();
if (!extractedData.containsKey(key)) {
extractedData.put(key, new ArrayList<ExtractedType>());
};
for (DataType dateElement : dataEntry.getValue()) {
ExtractedType extractedDataElement = extract(dateElement);
if (extractedDataElement != null) {
extractedData.get(key).add(extractedDataElement);
}
}
}
return extractedData;
}
protected abstract ExtractedType extract(DataType dataEntry);
}
@@ -0,0 +1,31 @@
package com.sap.sailing.datamining.impl;
import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.datamining.FiltrationWorker;
public abstract class AbstractFiltrationWorker<DataType> extends AbstractComponentWorker<Collection<DataType>>
implements FiltrationWorker<DataType> {
private Collection<DataType> data;
@Override
protected Collection<DataType> doWork() {
Collection<DataType> filteredData = new ArrayList<DataType>();
for (DataType dataEntry : data) {
if (matches(dataEntry)) {
filteredData.add(dataEntry);
}
}
return filteredData;
}
protected abstract boolean matches(DataType dataEntry);
@Override
public void setDataToFilter(Collection<DataType> data) {
this.data = data;
}
}
@@ -0,0 +1,38 @@
package com.sap.sailing.datamining.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.sap.sailing.datamining.GroupingWorker;
import com.sap.sailing.datamining.shared.GroupKey;
public abstract class AbstractGroupingWorker<DataType> extends AbstractComponentWorker<Map<GroupKey, Collection<DataType>>>
implements GroupingWorker<DataType> {
private Collection<DataType> data;
@Override
public void setDataToGroup(Collection<DataType> data) {
this.data = data;
}
@Override
protected Map<GroupKey, Collection<DataType>> doWork() {
Map<GroupKey, Collection<DataType>> groupedData = new HashMap<GroupKey, Collection<DataType>>();
for (DataType dataEntry : data) {
GroupKey key = getGroupKeyFor(dataEntry);
if (key != null) {
if (!groupedData.containsKey(key)) {
groupedData.put(key, new ArrayList<DataType>());
}
groupedData.get(key).add(dataEntry);
}
}
return groupedData;
}
protected abstract GroupKey getGroupKeyFor(DataType dataEntry);
}
@@ -0,0 +1,79 @@
package com.sap.sailing.datamining.impl;
import java.util.ArrayList;
import java.util.Collection;
import com.sap.sailing.datamining.DataRetrievalWorker;
import com.sap.sailing.datamining.data.TrackedLegContext;
import com.sap.sailing.datamining.data.TrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.impl.TrackedLegContextImpl;
import com.sap.sailing.datamining.data.impl.TrackedLegOfCompetitorContextImpl;
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.common.impl.Util.Pair;
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 abstract class AbstractLeaderboardGroupDataRetrievalWorker<DataType> extends AbstractComponentWorker<Collection<DataType>> implements DataRetrievalWorker<DataType> {
private LeaderboardGroup group;
@Override
public void setGroup(LeaderboardGroup group) {
this.group = group;
}
protected LeaderboardGroup getGroup() {
return group;
}
private static Collection<Pair<TrackedLeg, TrackedLegContext>> retrieveDataTillTrackedLeg(LeaderboardGroup group) {
Collection<Pair<TrackedLeg, TrackedLegContext>> data = new ArrayList<Pair<TrackedLeg, TrackedLegContext>>();
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) {
TrackedLegContext dataContext = new TrackedLegContextImpl(group, leaderboard,
courseArea, fleet, trackedRace, trackedLeg, legNumber);
data.add(new Pair<TrackedLeg, TrackedLegContext>(trackedLeg, dataContext));
legNumber++;
}
}
}
}
}
}
return data;
}
protected static Collection<Pair<TrackedLegOfCompetitor, TrackedLegOfCompetitorContext>> retrieveDataTillTrackedLegOfCompetitor(
LeaderboardGroup group) {
Collection<Pair<TrackedLegOfCompetitor, TrackedLegOfCompetitorContext>> data = new ArrayList<Pair<TrackedLegOfCompetitor, TrackedLegOfCompetitorContext>>();
Collection<Pair<TrackedLeg, TrackedLegContext>> baseData = retrieveDataTillTrackedLeg(group);
for (Pair<TrackedLeg, TrackedLegContext> baseDataEntry : baseData) {
TrackedLeg trackedLeg = baseDataEntry.getA();
TrackedLegContext trackedLegContext = baseDataEntry.getB();
for (Competitor competitor : trackedLegContext.getTrackedRace().getRace().getCompetitors()) {
TrackedLegOfCompetitor trackedLegOfCompetitor = trackedLeg.getTrackedLeg(competitor);
TrackedLegOfCompetitorContext dataContext = new TrackedLegOfCompetitorContextImpl(trackedLegContext,
competitor);
data.add(new Pair<TrackedLegOfCompetitor, TrackedLegOfCompetitorContext>(trackedLegOfCompetitor,
dataContext));
}
}
return data;
}
}
@@ -0,0 +1,102 @@
package com.sap.sailing.datamining.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.sap.sailing.datamining.ComponentWorker;
import com.sap.sailing.datamining.WorkReceiver;
public abstract class AbstractParallelComponent<WorkingType, ResultType> implements ParallelComponent<WorkingType, ResultType>,
WorkReceiver<ResultType> {
private ThreadPoolExecutor executor;
private Collection<ComponentWorker<ResultType>> workers;
private Set<ResultType> results;
public AbstractParallelComponent(ThreadPoolExecutor executor) {
this.executor = executor;
workers = new HashSet<ComponentWorker<ResultType>>();
results = Collections.newSetFromMap(new ConcurrentHashMap<ResultType, Boolean>());
}
@Override
public ParallelComponent<WorkingType, ResultType> start(WorkingType data) {
setUpWorkersFor(data);
for (ComponentWorker<ResultType> worker : workers) {
executor.execute(worker);
}
return this;
}
protected abstract void setUpWorkersFor(WorkingType data);
@Override
public void receiveWork(ResultType result) {
results.add(result);
}
protected Collection<ResultType> getResults() {
return results;
}
@Override
public ResultType get() throws InterruptedException, ExecutionException {
while (!isDone()) {
Thread.sleep(100);
}
return finalizeData();
}
@Override
public ResultType get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException,
TimeoutException {
long timeRun = 0;
long timeoutInMillis = unit.toMillis(timeout);
while (!isDone() && timeRun < timeoutInMillis) {
Thread.sleep(100);
timeRun = timeRun + 100;
}
if (timeRun >= timeoutInMillis) {
throw new TimeoutException();
}
return finalizeData();
}
protected abstract ResultType finalizeData();
@Override
public boolean isDone() {
for (ComponentWorker<ResultType> worker : workers) {
if (!worker.isDone()) {
return false;
}
}
return true;
}
protected ThreadPoolExecutor getExecutor() {
return executor;
}
protected void addWorker(ComponentWorker<ResultType> worker) {
workers.add(worker);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
}
@@ -0,0 +1,39 @@
package com.sap.sailing.datamining.impl;
import java.util.Comparator;
import com.sap.sailing.datamining.Cluster;
public class ClusterImpl<ValueType> implements Cluster<ValueType> {
private String name;
private ValueType upperRange;
private ValueType lowerRange;
public ClusterImpl(String name, ValueType upperRange, ValueType lowerRange) {
this.name = name;
this.upperRange = upperRange;
this.lowerRange = lowerRange;
}
@Override
public String getName() {
return name;
}
@Override
public ValueType getUpperRange() {
return upperRange;
}
@Override
public ValueType getLowerRange() {
return lowerRange;
}
@Override
public boolean isInRange(ValueType value, Comparator<ValueType> comparator) {
return comparator.compare(value, getLowerRange()) >= 0 && comparator.compare(value, getUpperRange()) <= 0;
}
}
Loaded 100 of 215 files, more files were not shown because too many files have changed in this diff. Show more