diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoreCorrectionProvider.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoreCorrectionProvider.java index 48d8c6b00e5..f1d405ab53e 100755 --- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoreCorrectionProvider.java +++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoreCorrectionProvider.java @@ -21,5 +21,16 @@ public interface ScoreCorrectionProvider extends Named { */ public Map>> getHasResultsForBoatClassFromDateByEventName() throws Exception; + /** + * @param eventName + * as provided by the keys of the result map returned by + * {@link #getHasResultsForBoatClassFromDateByEventName()} + * @param boatClassName + * as provided by the {@link Pair#getA()} method on the values of the map returned by + * {@link #getHasResultsForBoatClassFromDateByEventName()} + * @param millisecondsTimePoint + * a time point as returned in the {@link Pair#getB()} component of the values in the map returned by + * {@link #getHasResultsForBoatClassFromDateByEventName()}. + */ public RegattaScoreCorrections getScoreCorrections(String eventName, String boatClassName, TimePoint millisecondsTimePoint) throws Exception; } diff --git a/java/com.sap.sailing.ess40.resultimport.test/.classpath b/java/com.sap.sailing.ess40.resultimport.test/.classpath new file mode 100755 index 00000000000..b1dabee3829 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sailing.ess40.resultimport.test/.project b/java/com.sap.sailing.ess40.resultimport.test/.project new file mode 100755 index 00000000000..bd580f7a446 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/.project @@ -0,0 +1,28 @@ + + + com.sap.sailing.ess40.resultimport.test + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/java/com.sap.sailing.ess40.resultimport.test/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sailing.ess40.resultimport.test/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..11f6e462df7 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/java/com.sap.sailing.ess40.resultimport.test/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sailing.ess40.resultimport.test/.settings/org.eclipse.pde.core.prefs new file mode 100755 index 00000000000..b7e72d019c2 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/java/com.sap.sailing.ess40.resultimport.test/META-INF/MANIFEST.MF b/java/com.sap.sailing.ess40.resultimport.test/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..d3147584d1e --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/META-INF/MANIFEST.MF @@ -0,0 +1,12 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Test +Bundle-SymbolicName: com.sap.sailing.ess40.resultimport.test +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: SAP +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: org.osgi.framework;version="1.3.0" +Bundle-ActivationPolicy: lazy +Require-Bundle: com.sap.sailing.ess40.resultimport, + org.junit4;bundle-version="4.8.2", + com.sap.sailing.domain.common diff --git a/java/com.sap.sailing.ess40.resultimport.test/build.properties b/java/com.sap.sailing.ess40.resultimport.test/build.properties new file mode 100755 index 00000000000..41eb6ade2b4 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sailing.ess40.resultimport.test/src/com/sap/sailing/ess40/resultimport/test/SimpleESS40ResultImportTest.java b/java/com.sap.sailing.ess40.resultimport.test/src/com/sap/sailing/ess40/resultimport/test/SimpleESS40ResultImportTest.java new file mode 100755 index 00000000000..ab464e78e99 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport.test/src/com/sap/sailing/ess40/resultimport/test/SimpleESS40ResultImportTest.java @@ -0,0 +1,34 @@ +package com.sap.sailing.ess40.resultimport.test; + + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import com.sap.sailing.domain.common.RegattaScoreCorrections; +import com.sap.sailing.domain.common.ScoreCorrectionProvider; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.common.impl.Util.Pair; +import com.sap.sailing.ess40.resultimport.impl.ScoreCorrectionProviderImpl; + +public class SimpleESS40ResultImportTest { + @Test + public void testProviderFound() throws Exception { + ScoreCorrectionProvider scp = new ScoreCorrectionProviderImpl(); + Map>> hasResult = scp.getHasResultsForBoatClassFromDateByEventName(); + assertTrue(hasResult.containsKey("qingdao")); + } + + @Test + public void testQingdaoResults() throws Exception { + ScoreCorrectionProvider scp = new ScoreCorrectionProviderImpl(); + Map>> hasResult = scp.getHasResultsForBoatClassFromDateByEventName(); + RegattaScoreCorrections qingdaoResults = scp.getScoreCorrections("qingdao", "extreme 40", hasResult.get("qingdao").iterator().next().getB()); + assertNotNull(qingdaoResults); + // TODO continue here and require results to match what we see in the CSV + } +} diff --git a/java/com.sap.sailing.ess40.resultimport/.classpath b/java/com.sap.sailing.ess40.resultimport/.classpath new file mode 100755 index 00000000000..b1dabee3829 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/java/com.sap.sailing.ess40.resultimport/.project b/java/com.sap.sailing.ess40.resultimport/.project new file mode 100755 index 00000000000..8f71cd0ec7a --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/.project @@ -0,0 +1,28 @@ + + + com.sap.sailing.ess40.resultimport + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/java/com.sap.sailing.ess40.resultimport/.settings/org.eclipse.jdt.core.prefs b/java/com.sap.sailing.ess40.resultimport/.settings/org.eclipse.jdt.core.prefs new file mode 100755 index 00000000000..11f6e462df7 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/java/com.sap.sailing.ess40.resultimport/.settings/org.eclipse.pde.core.prefs b/java/com.sap.sailing.ess40.resultimport/.settings/org.eclipse.pde.core.prefs new file mode 100755 index 00000000000..b7e72d019c2 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/java/com.sap.sailing.ess40.resultimport/META-INF/MANIFEST.MF b/java/com.sap.sailing.ess40.resultimport/META-INF/MANIFEST.MF new file mode 100755 index 00000000000..891823af4ff --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Resultimport +Bundle-SymbolicName: com.sap.sailing.ess40.resultimport +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.sap.sailing.ess40.resultimport.Activator +Bundle-Vendor: SAP +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Import-Package: org.osgi.framework;version="1.3.0" +Bundle-ActivationPolicy: lazy +Require-Bundle: com.sap.sailing.domain, + com.sap.sailing.domain.common +Export-Package: com.sap.sailing.ess40.resultimport, + com.sap.sailing.ess40.resultimport.impl;x-friends:="com.sap.sailing.ess40.resultimport.test" diff --git a/java/com.sap.sailing.ess40.resultimport/build.properties b/java/com.sap.sailing.ess40.resultimport/build.properties new file mode 100755 index 00000000000..41eb6ade2b4 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/Activator.java b/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/Activator.java new file mode 100755 index 00000000000..5df8c0f9684 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/Activator.java @@ -0,0 +1,36 @@ +package com.sap.sailing.ess40.resultimport; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.sap.sailing.domain.common.ScoreCorrectionProvider; +import com.sap.sailing.ess40.resultimport.impl.ScoreCorrectionProviderImpl; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + final ScoreCorrectionProviderImpl service = new ScoreCorrectionProviderImpl(); + context.registerService(ScoreCorrectionProvider.class, service, /* properties */null); + } + + /* + * (non-Javadoc) + * + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } +} diff --git a/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/impl/RegattaScoreCorrectionsImpl.java b/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/impl/RegattaScoreCorrectionsImpl.java new file mode 100755 index 00000000000..7c6d35f49dd --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/impl/RegattaScoreCorrectionsImpl.java @@ -0,0 +1,36 @@ +package com.sap.sailing.ess40.resultimport.impl; + +import java.util.List; +import java.util.Map; + +import com.sap.sailing.domain.common.RegattaScoreCorrections; +import com.sap.sailing.domain.common.ScoreCorrectionProvider; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.common.impl.Util.Pair; + +public class RegattaScoreCorrectionsImpl implements RegattaScoreCorrections { + private final ScoreCorrectionProviderImpl provider; + + public RegattaScoreCorrectionsImpl(ScoreCorrectionProviderImpl scoreCorrectionProviderImpl, + Pair>>> actResults) { + this.provider = scoreCorrectionProviderImpl; + } + + @Override + public ScoreCorrectionProvider getProvider() { + return provider; + } + + @Override + public String getRegattaName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable getScoreCorrectionsForRaces() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/impl/ScoreCorrectionProviderImpl.java b/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/impl/ScoreCorrectionProviderImpl.java new file mode 100755 index 00000000000..a525851a072 --- /dev/null +++ b/java/com.sap.sailing.ess40.resultimport/src/com/sap/sailing/ess40/resultimport/impl/ScoreCorrectionProviderImpl.java @@ -0,0 +1,93 @@ +package com.sap.sailing.ess40.resultimport.impl; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.sap.sailing.domain.base.impl.MillisecondsTimePoint; +import com.sap.sailing.domain.common.RegattaScoreCorrections; +import com.sap.sailing.domain.common.ScoreCorrectionProvider; +import com.sap.sailing.domain.common.TimePoint; +import com.sap.sailing.domain.common.impl.Util.Pair; + +public class ScoreCorrectionProviderImpl implements ScoreCorrectionProvider { + private static final long serialVersionUID = -4870646572106575667L; + + private static final String[] ACT_NAMES = { "muscat", "qingdao", "istanbul", "porto" /*, "cardiff" */}; + + private static final String EXTREME_40_CLASS_NAME = "extreme 40"; + + @Override + public String getName() { + return "Extreme Sailing Series 40 Scores from SailRacer.org"; + } + + private List getCsvUrls(String... actNames) throws MalformedURLException { + List result = new ArrayList(); + for (String actName : actNames) { + result.add(new URL("http://www.extremesailingseries.com/app/results/csv_uploads/"+actName+".csv")); + } + return result; + } + + /** + * @return A pair whose first component is the time point of the last modification to the act results, the second + * element is a map whose keys are the sail IDs (in the Extreme Sailing Series we'll use the team names as + * the sail IDs, such as "SAP Extreme Sailing Team" or just "SAP" for short); values with be a list + * representing the act's races, from first to last, where each {@link Pair} holds in its first component a + * string describing the rank, which could be an integer number formatted as a string, or a three-letter + * disqualification reason such as "DNC", "DNF" or "DNS"; the second component is the points the competitor + * scored in that race. Usually, if the first component is a number, the score can be expected to be + * #competitors+1 - rank. A disqualification gets 0 points. + */ + private Pair>>> getActResults(URL actUrl) throws IOException { + Map>> result = new HashMap>>(); + HttpURLConnection conn = (HttpURLConnection) actUrl.openConnection(); + TimePoint lastModified = new MillisecondsTimePoint(conn.getLastModified()); + BufferedReader br = new BufferedReader(new InputStreamReader((InputStream) conn.getContent())); + String line = br.readLine(); + while (line != null) { + String[] split = line.split(","); + String sailID = split[0].trim(); + List> competitorEntry = new ArrayList>(); + result.put(sailID, competitorEntry); + for (int i=1; i(rankOrMaxPointsReason, points)); + } + line = br.readLine(); + } + return new Pair>>>(lastModified, result); + } + + @Override + public Map>> getHasResultsForBoatClassFromDateByEventName() throws Exception { + Map>> result = new HashMap>>(); + for (String actName : ACT_NAMES) { + URL actUrl = getCsvUrls(actName).iterator().next(); + Pair>>> actResults = getActResults(actUrl); + result.put(actName, Collections.singleton(new Pair(EXTREME_40_CLASS_NAME, actResults.getA()))); + } + return result; + } + + @Override + public RegattaScoreCorrections getScoreCorrections(String actName, String boatClassName, + TimePoint millisecondsTimePoint) throws Exception { + URL actUrl = getCsvUrls(actName).iterator().next(); + Pair>>> actResults = getActResults(actUrl); + return new RegattaScoreCorrectionsImpl(this, actResults); + } + +}